The Samba-Bugzilla – Attachment 16973 Details for
Bug 14725
[SECURITY] Andrew's Kerberos Concerns (November 9 2021)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Combined patchset for 4.10 v13 (CVE-2020-25717 CVE-2020-25721 CVE-2020-25718 CVE-2020-25719 CVE-2020-25722)
security-2021-11-v4.10-v13-bug14725.patches.txt (text/plain), 4.99 MB, created by
Jo Sutton
on 2021-11-09 04:04:33 UTC
(
hide
)
Description:
Combined patchset for 4.10 v13 (CVE-2020-25717 CVE-2020-25721 CVE-2020-25718 CVE-2020-25719 CVE-2020-25722)
Filename:
MIME Type:
Creator:
Jo Sutton
Created:
2021-11-09 04:04:33 UTC
Size:
4.99 MB
patch
obsolete
>From 7157d920e843522403bf4cfb1936c09135c1f854 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 20 Apr 2020 20:00:51 +0200 >Subject: [PATCH 001/686] python/tests: add DynamicTestCase > setUpDynamicTestCases() infrastructure > >This can be used in order to run a sepcific test (coded just once) >with an autogenerated set of arguments. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531 > >Pair-Programmed-With: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 80347deb544b38be6c6814e5d1b82e48ebe83fd1) >--- > python/samba/tests/__init__.py | 27 +++++++++++++++++++++++++++ > 1 file changed, 27 insertions(+) > >diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py >index ef0fdabbfa2..13d42779262 100644 >--- a/python/samba/tests/__init__.py >+++ b/python/samba/tests/__init__.py >@@ -62,10 +62,37 @@ BINDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), > > HEXDUMP_FILTER = bytearray([x if ((len(repr(chr(x))) == 3) and (x < 127)) else ord('.') for x in range(256)]) > >+def DynamicTestCase(cls): >+ cls.setUpDynamicTestCases() >+ return cls > > class TestCase(unittest.TestCase): > """A Samba test case.""" > >+ @classmethod >+ def generate_dynamic_test(cls, fnname, suffix, *args): >+ """ >+ fnname is something like "test_dynamic_sum" >+ suffix is something like "1plus2" >+ argstr could be (1, 2) >+ >+ This would generate a test case called >+ "test_dynamic_sum_1plus2(self)" that >+ calls >+ self._test_dynamic_sum_with_args(1, 2) >+ """ >+ def fn(self): >+ getattr(self, "_%s_with_args" % fnname)(*args) >+ setattr(cls, "%s_%s" % (fnname, suffix), fn) >+ >+ @classmethod >+ def setUpDynamicTestCases(cls): >+ """This can be implemented in order to call cls.generate_dynamic_test() >+ In order to implement autogenerated testcase permutations. >+ """ >+ msg = "%s needs setUpDynamicTestCases() if @DynamicTestCase is used!" % (cls) >+ raise Exception(msg) >+ > def setUp(self): > super(TestCase, self).setUp() > test_debug_level = os.getenv("TEST_DEBUG_LEVEL") >-- >2.25.1 > > >From 1d414e2a5f4da66265c635eb6bf69e386568f4d2 Mon Sep 17 00:00:00 2001 >From: Noel Power <noel.power@suse.com> >Date: Wed, 15 May 2019 10:30:29 +0100 >Subject: [PATCH 002/686] lib/ldb: Fix incorrect return type for (setter) func > type > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13948 > >Signed-off-by: Noel Power <noel.power@suse.com> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit 27d99eefe7676669343b9040f550480df6554a6e) >--- > lib/ldb/pyldb.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index b2cac8a3497..794b2184941 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -199,7 +199,7 @@ static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self) > return PyBool_FromLong(self->data->critical); > } > >-static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure) >+static int py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure) > { > if (PyObject_IsTrue(value)) { > self->data->critical = true; >-- >2.25.1 > > >From 1f7fe0155f289e04fea00054e13d141c705c4a90 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Sun, 17 Mar 2019 14:47:40 +1300 >Subject: [PATCH 003/686] tests: ensure that most python scripts have usage > text > >When a script is run with the wrong arguments, it should at least say >something like this: > > Usage: samba-foo [OPTIONS] > >For many samba scripts, especially without a server environment, having >no arguments is the wrong arguments. > >Here we look for every executable file with '#![...]python[3]' on the >first line, and exclude certain files and directories that have excuses >to fail the test. For example, many selftest scripts are stream-oriented >and will hang forever waiting for stdin, which is not an error. Some >test modules are designed so they can be optionally run from the command >line, but this option is typically only used by the developer who is >writing them. > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 538ffe1960a8640875759ca194cc4cc9fae2c5bc) > >[jsutton@samba.org Backported to fix conflict in > source4/selftest/tests.py] >--- > python/samba/tests/usage.py | 205 ++++++++++++++++++++++++++++++++++++ > selftest/knownfail.d/usage | 28 +++++ > source4/selftest/tests.py | 2 + > 3 files changed, 235 insertions(+) > create mode 100644 python/samba/tests/usage.py > create mode 100644 selftest/knownfail.d/usage > >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >new file mode 100644 >index 00000000000..30c083076ff >--- /dev/null >+++ b/python/samba/tests/usage.py >@@ -0,0 +1,205 @@ >+# Unix SMB/CIFS implementation. >+# Copyright © Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >+# >+# 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 <http://www.gnu.org/licenses/>. >+ >+import os >+import sys >+import subprocess >+from samba.tests import TestCase >+from unittest import TestSuite >+import re >+import stat >+ >+if 'SRCDIR_ABS' in os.environ: >+ BASEDIR = os.environ['SRCDIR_ABS'] >+else: >+ BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), >+ '../../..')) >+ >+TEST_DIRS = [ >+ "bootstrap", >+ "testdata", >+ "ctdb", >+ "dfs_server", >+ "pidl", >+ "auth", >+ "packaging", >+ "python", >+ "include", >+ "nsswitch", >+ "libcli", >+ "coverity", >+ "release-scripts", >+ "testprogs", >+ "bin", >+ "source3", >+ "docs-xml", >+ "buildtools", >+ "file_server", >+ "dynconfig", >+ "source4", >+ "tests", >+ "libds", >+ "selftest", >+ "lib", >+ "script", >+ "traffic", >+ "testsuite", >+ "libgpo", >+ "wintest", >+ "librpc", >+] >+ >+ >+EXCLUDE_USAGE = { >+ 'script/autobuild.py', # defaults to mount /memdisk/ >+ 'script/bisect-test.py', >+ 'ctdb/utils/etcd/ctdb_etcd_lock', >+ 'selftest/filter-subunit', >+ 'selftest/format-subunit', >+ 'bin/gen_output.py', # too much output! >+ 'source4/scripting/bin/gen_output.py', >+ 'lib/ldb/tests/python/index.py', >+ 'lib/ldb/tests/python/api.py', >+ 'source4/selftest/tests.py', >+ 'buildtools/bin/waf', >+ 'selftest/tap2subunit', >+ 'script/show_test_time', >+ 'source4/scripting/bin/subunitrun', >+ 'source3/selftest/tests.py', >+ 'selftest/tests.py', >+ 'python/samba/subunit/run.py', >+ 'bin/python/samba/subunit/run.py', >+ 'python/samba/tests/dcerpc/raw_protocol.py' >+} >+ >+ >+EXCLUDE_DIRS = { >+ 'source3/script/tests', >+ 'python/examples', >+ 'source4/dsdb/tests/python', >+ 'bin/ab', >+ 'bin/python/samba/tests', >+ 'bin/python/samba/tests/dcerpc', >+} >+ >+ >+def _init_git_file_finder(): >+ """Generate a function that quickly answers the question: >+ 'is this a git file?' >+ """ >+ git_file_cache = set() >+ p = subprocess.run(['git', >+ '-C', BASEDIR, >+ 'ls-files', >+ '-z'], >+ stdout=subprocess.PIPE) >+ if p.returncode == 0: >+ for fn in p.stdout.split(b'\0'): >+ git_file_cache.add(os.path.join(BASEDIR, fn.decode('utf-8'))) >+ return git_file_cache.__contains__ >+ >+ >+is_git_file = _init_git_file_finder() >+ >+ >+def python_script_iterator(d=BASEDIR, _cache={}): >+ """Generate an iterator over executable Python scripts. By default it >+ walks the entire source tree. >+ """ >+ if d not in _cache: >+ cache = {} >+ _cache[d] = cache >+ pyshebang = re.compile(br'#!.+python').match >+ safename = re.compile(r'\W+').sub >+ for subdir in TEST_DIRS: >+ sd = os.path.join(d, subdir) >+ for root, dirs, files in os.walk(sd, followlinks=False): >+ for fn in files: >+ if fn.endswith('~'): >+ continue >+ if fn.endswith('.inst'): >+ continue >+ ffn = os.path.join(root, fn) >+ if not (subdir == 'bin' or is_git_file(ffn)): >+ continue >+ >+ try: >+ s = os.stat(ffn) >+ except FileNotFoundError: >+ continue >+ if not s.st_mode & stat.S_IXUSR: >+ continue >+ try: >+ f = open(ffn, 'rb') >+ except OSError as e: >+ print("could not open %s: %s" % (ffn, e)) >+ continue >+ line = f.read(40) >+ f.close() >+ if not pyshebang(line): >+ continue >+ name = safename('_', fn) >+ while name in cache: >+ name += '_' >+ cache[name] = ffn >+ >+ return _cache[d].items() >+ >+ >+class PythonScriptUsageTests(TestCase): >+ """Python scripts run without arguments should print a usage string, >+ not fail with a traceback. >+ """ >+ >+ @classmethod >+ def initialise(cls): >+ for name, filename in python_script_iterator(): >+ # We add the actual tests after the class definition so we >+ # can give individual names to them, so we can have a >+ # knownfail list. >+ fn = filename.replace(BASEDIR, '').lstrip('/') >+ >+ if fn in EXCLUDE_USAGE: >+ print("skipping %s (EXCLUDE_USAGE)" % filename) >+ continue >+ >+ if os.path.dirname(fn) in EXCLUDE_DIRS: >+ print("skipping %s (EXCLUDE_DIRS)" % filename) >+ continue >+ >+ def _f(self, filename=filename): >+ print(filename) >+ try: >+ p = subprocess.Popen(['python3', filename], >+ stderr=subprocess.PIPE, >+ stdout=subprocess.PIPE) >+ out, err = p.communicate(timeout=5) >+ except OSError as e: >+ self.fail("Error: %s" % e) >+ except subprocess.SubprocessError as e: >+ self.fail("Subprocess error: %s" % e) >+ >+ err = err.decode('utf-8') >+ out = out.decode('utf-8') >+ self.assertNotIn('Traceback', err) >+ >+ self.assertIn('usage', out.lower() + err.lower(), >+ 'stdout:\n%s\nstderr:\n%s' % (out, err)) >+ >+ setattr(cls, 'test_%s' % name, _f) >+ >+ >+PythonScriptUsageTests.initialise() >diff --git a/selftest/knownfail.d/usage b/selftest/knownfail.d/usage >new file mode 100644 >index 00000000000..3c526f32f22 >--- /dev/null >+++ b/selftest/knownfail.d/usage >@@ -0,0 +1,28 @@ >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_chgtdcpass.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_compare_cc_results_py.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_demodirsync_py.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_dns_hub_py.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_findprovisionusnranges.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_get_descriptors.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_mymachinepw.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_rebuildextendeddn.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_renamedc.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_repl_cleartext_pwd_py.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_rodcdns.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_dnsupdate.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_dnsupdate_.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_sambadowngradedatabase.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_gpupdate.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_gpupdate_.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_kcc.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_kcc_.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_spnupdate.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_spnupdate_.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_upgradedns.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_upgradedns_.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_upgradeprovision.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_upgradeprovision_.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_smbstatus.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_test_s3_py.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_test_s4_howto_py.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_traffic_learner.none. >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 8cf54841e86..1561f068ca1 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1333,3 +1333,5 @@ planoldpythontestsuite("proclimitdc:local", > 'SOCKET_WRAPPER_DEFAULT_IFACE': 11}, > name="samba.tests.process_limits", > py3_compatible=True) >+ >+planoldpythontestsuite("none", "samba.tests.usage") >-- >2.25.1 > > >From 2a00441070b72b19934332241d4eca4db37209d2 Mon Sep 17 00:00:00 2001 >From: Michael Hanselmann <public@hansmi.ch> >Date: Fri, 12 Apr 2019 00:46:37 +0200 >Subject: [PATCH 004/686] ldb: Avoid read beyond buffer > >Calling the "ldb_parse_tree" function with a filter consisting of >exactly a single space (" ") would trigger a read beyond the input >buffer. A unittest is included. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13900 > >Signed-off-by: Michael Hanselmann <public@hansmi.ch> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Tim Beale <timbeale@catalyst.net.nz> >(cherry picked from commit 7f48fbcf7bad06a6df7812bb4fd3b0fca8edb4ea) > >[jsutton@samba.org Adapted to fix conflicts in lib/ldb/wscript] >--- > lib/ldb/common/ldb_parse.c | 6 +-- > lib/ldb/tests/ldb_parse_test.c | 93 ++++++++++++++++++++++++++++++++++ > lib/ldb/wscript | 8 ++- > 3 files changed, 103 insertions(+), 4 deletions(-) > create mode 100644 lib/ldb/tests/ldb_parse_test.c > >diff --git a/lib/ldb/common/ldb_parse.c b/lib/ldb/common/ldb_parse.c >index db420091311..452c5830ed5 100644 >--- a/lib/ldb/common/ldb_parse.c >+++ b/lib/ldb/common/ldb_parse.c >@@ -328,7 +328,7 @@ static enum ldb_parse_op ldb_parse_filtertype(TALLOC_CTX *mem_ctx, char **type, > > if (*p == '=') { > filter = LDB_OP_EQUALITY; >- } else if (*(p + 1) == '=') { >+ } else if (*p != '\0' && *(p + 1) == '=') { > switch (*p) { > case '<': > filter = LDB_OP_LESS; >@@ -679,12 +679,12 @@ static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char * > */ > struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) > { >+ while (s && isspace((unsigned char)*s)) s++; >+ > if (s == NULL || *s == 0) { > s = "(|(objectClass=*)(distinguishedName=*))"; > } > >- while (isspace((unsigned char)*s)) s++; >- > if (*s == '(') { > return ldb_parse_filter(mem_ctx, &s); > } >diff --git a/lib/ldb/tests/ldb_parse_test.c b/lib/ldb/tests/ldb_parse_test.c >new file mode 100644 >index 00000000000..a739d7795d1 >--- /dev/null >+++ b/lib/ldb/tests/ldb_parse_test.c >@@ -0,0 +1,93 @@ >+/* >+ * Tests exercising the ldb parse operations. >+ * >+ * Copyright (C) Catalyst.NET Ltd 2017 >+ * Copyright (C) Michael Hanselmann 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 <http://www.gnu.org/licenses/>. >+ * >+ */ >+ >+#include <stdarg.h> >+#include <stddef.h> >+#include <stdint.h> >+#include <setjmp.h> >+#include <cmocka.h> >+ >+#include "../include/ldb.h" >+ >+struct test_ctx >+{ >+}; >+ >+static int setup(void **state) >+{ >+ struct test_ctx *ctx; >+ >+ ctx = talloc_zero(NULL, struct test_ctx); >+ assert_non_null(ctx); >+ >+ *state = ctx; >+ >+ return 0; >+} >+ >+static int teardown(void **state) >+{ >+ struct test_ctx *ctx = >+ talloc_get_type_abort(*state, struct test_ctx); >+ >+ talloc_free(ctx); >+ >+ return 0; >+} >+ >+static void test_roundtrip(TALLOC_CTX *mem_ctx, const char *filter, const char *expected) >+{ >+ struct ldb_parse_tree *tree; >+ char *serialized; >+ >+ assert_non_null(filter); >+ assert_non_null(expected); >+ >+ tree = ldb_parse_tree(mem_ctx, filter); >+ assert_non_null(tree); >+ >+ serialized = ldb_filter_from_tree(mem_ctx, tree); >+ assert_non_null(serialized); >+ >+ assert_string_equal(serialized, expected); >+} >+ >+static void test_parse_filtertype(void **state) >+{ >+ struct test_ctx *ctx = >+ talloc_get_type_abort(*state, struct test_ctx); >+ >+ test_roundtrip(ctx, "", "(|(objectClass=*)(distinguishedName=*))"); >+ test_roundtrip(ctx, "a=value", "(a=value)"); >+ test_roundtrip(ctx, "(|(foo=bar)(baz=hello))", "(|(foo=bar)(baz=hello))"); >+ test_roundtrip(ctx, " ", "(|(objectClass=*)(distinguishedName=*))"); >+} >+ >+int main(int argc, const char **argv) >+{ >+ const struct CMUnitTest tests[] = { >+ cmocka_unit_test_setup_teardown(test_parse_filtertype, setup, teardown), >+ }; >+ >+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >+ >+ return cmocka_run_group_tests(tests, NULL, NULL); >+} >diff --git a/lib/ldb/wscript b/lib/ldb/wscript >index 58240222d5f..2197a304e94 100644 >--- a/lib/ldb/wscript >+++ b/lib/ldb/wscript >@@ -516,6 +516,11 @@ def build(bld): > deps='cmocka ldb', > install=False) > >+ bld.SAMBA_BINARY('ldb_parse_test', >+ source='tests/ldb_parse_test.c', >+ deps='cmocka ldb ldb_tdb_err_map', >+ install=False) >+ > if bld.CONFIG_SET('HAVE_LMDB'): > bld.SAMBA_BINARY('ldb_mdb_mod_op_test', > source='tests/ldb_mod_op_test.c', >@@ -584,7 +589,8 @@ def test(ctx): > # fit > 4G of data into the DB), it would fill up the disk on > # many of our test instances > 'ldb_mdb_kv_ops_test', >- 'ldb_match_test'] >+ 'ldb_match_test', >+ 'ldb_parse_test'] > > for test_exe in test_exes: > cmd = os.path.join(Context.g_module.out, test_exe) >-- >2.25.1 > > >From 372d300a4c2fe23e4aa9e3623064ba4be44c22f7 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Tue, 8 Dec 2020 21:32:09 +1300 >Subject: [PATCH 005/686] CVE-2021-20277 ldb/attrib_handlers casefold: stay in > bounds > >For a string that had N spaces at the beginning, we would >try to move N bytes beyond the end of the string. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14655 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1fe8c790b2294fd10fe9c9c6254ecf2b6c00b709) >--- > lib/ldb/common/attrib_handlers.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/ldb/common/attrib_handlers.c b/lib/ldb/common/attrib_handlers.c >index 4b94d392cc6..409b8c62025 100644 >--- a/lib/ldb/common/attrib_handlers.c >+++ b/lib/ldb/common/attrib_handlers.c >@@ -76,7 +76,7 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, > > /* remove leading spaces if any */ > if (*s == ' ') { >- for (t = s; *s == ' '; s++) ; >+ for (t = s; *s == ' '; s++, l--) ; > > /* remove leading spaces by moving down the string */ > memmove(t, s, l); >-- >2.25.1 > > >From a1d9a82afd9792e4c0f48bbb5805f0dba668c273 Mon Sep 17 00:00:00 2001 >From: Noel Power <noel.power@suse.com> >Date: Tue, 22 Jan 2019 18:26:23 +0000 >Subject: [PATCH 006/686] Decrement references to python objects passed to > Py_BuildValue > >Py_BuildValue when processing format 'O' will > 'Pass a Python object untouched (except for its reference count, > which is incremented by one' > >Basically this means if you are using a new reference to a PyObject >to pass to BuildValue (to be used with the 'O' format) the reference >*isn't* stolen so you really do need to DECREF it in order to ensure >it gets cleaned up. > >Signed-off-by: Noel Power <noel.power@suse.com> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit a8e10a12493fdb6b8347b14e157aeb619cf2d2da) >--- > auth/credentials/pycredentials.c | 7 ++++--- > lib/ldb/pyldb.c | 15 +++++++++++---- > source3/libsmb/pylibsmb.c | 7 +++++-- > source4/dns_server/pydns.c | 6 +++++- > 4 files changed, 25 insertions(+), 10 deletions(-) > >diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c >index 7f9bc38af8e..6fb2c807ed6 100644 >--- a/auth/credentials/pycredentials.c >+++ b/auth/credentials/pycredentials.c >@@ -75,9 +75,10 @@ static PyObject *py_creds_get_ntlm_username_domain(PyObject *self, PyObject *unu > PyObject *ret = NULL; > cli_credentials_get_ntlm_username_domain(PyCredentials_AsCliCredentials(self), > frame, &user, &domain); >- ret = Py_BuildValue("(OO)", >- PyString_FromStringOrNULL(user), >- PyString_FromStringOrNULL(domain)); >+ ret = Py_BuildValue("(ss)", >+ user, >+ domain); >+ > TALLOC_FREE(frame); > return ret; > } >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index 794b2184941..9dd5c2019b6 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -1673,9 +1673,13 @@ static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif) > Py_RETURN_NONE; > } else { > /* We don't want this attached to the 'ldb' any more */ >- return Py_BuildValue(discard_const_p(char, "(iO)"), >- ldif->changetype, >- PyLdbMessage_FromMessage(ldif->msg)); >+ PyObject *obj = PyLdbMessage_FromMessage(ldif->msg); >+ PyObject *result = >+ Py_BuildValue(discard_const_p(char, "(iO)"), >+ ldif->changetype, >+ obj); >+ Py_CLEAR(obj); >+ return result; > } > } > >@@ -3427,12 +3431,15 @@ static PyObject *py_ldb_msg_items(PyLdbMessageObject *self) > Py_ssize_t i, j = 0; > PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1)); > if (msg->dn != NULL) { >- PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn))); >+ PyObject *obj = pyldb_Dn_FromDn(msg->dn); >+ PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", obj)); >+ Py_CLEAR(obj); > j++; > } > for (i = 0; i < msg->num_elements; i++, j++) { > PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements); > PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el); >+ Py_CLEAR(py_el); > PyList_SetItem(l, j, value); > } > return l; >diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c >index b4903a9b8c5..b63101b85a0 100644 >--- a/source3/libsmb/pylibsmb.c >+++ b/source3/libsmb/pylibsmb.c >@@ -1124,13 +1124,14 @@ static NTSTATUS list_helper(const char *mntpoint, struct file_info *finfo, > { > PyObject *result = (PyObject *)state; > PyObject *file = NULL; >+ PyObject *size = NULL; > int ret; > > /* suppress '.' and '..' in the results we return */ > if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) { > return NT_STATUS_OK; > } >- >+ size = PyLong_FromUnsignedLongLong(finfo->size); > /* > * Build a dictionary representing the file info. > * Note: Windows does not always return short_name (so it may be None) >@@ -1139,10 +1140,12 @@ static NTSTATUS list_helper(const char *mntpoint, struct file_info *finfo, > "name", finfo->name, > "attrib", (int)finfo->mode, > "short_name", finfo->short_name, >- "size", PyLong_FromUnsignedLongLong(finfo->size), >+ "size", size, > "mtime", > convert_timespec_to_time_t(finfo->mtime_ts)); > >+ Py_CLEAR(size); >+ > if (file == NULL) { > return NT_STATUS_NO_MEMORY; > } >diff --git a/source4/dns_server/pydns.c b/source4/dns_server/pydns.c >index a4441ddef56..16d22dfe4b8 100644 >--- a/source4/dns_server/pydns.c >+++ b/source4/dns_server/pydns.c >@@ -100,6 +100,7 @@ static PyObject *py_dsdb_dns_lookup(PyObject *self, > struct ldb_context *samdb; > PyObject *py_ldb, *ret, *pydn; > PyObject *py_dns_partition = NULL; >+ PyObject *result = NULL; > char *dns_name; > TALLOC_CTX *frame; > NTSTATUS status; >@@ -156,7 +157,10 @@ static PyObject *py_dsdb_dns_lookup(PyObject *self, > ret = py_dnsp_DnssrvRpcRecord_get_list(records, num_records); > pydn = pyldb_Dn_FromDn(dn); > talloc_free(frame); >- return Py_BuildValue("(OO)", pydn, ret); >+ result = Py_BuildValue("(OO)", pydn, ret); >+ Py_CLEAR(ret); >+ Py_CLEAR(pydn); >+ return result; > } > > static PyObject *py_dsdb_dns_extract(PyObject *self, PyObject *args) >-- >2.25.1 > > >From 14134c1fa16f342b2626806769a054908ffdd0e0 Mon Sep 17 00:00:00 2001 >From: Noel Power <noel.power@suse.com> >Date: Fri, 25 Jan 2019 12:02:50 +0000 >Subject: [PATCH 007/686] Examine result of SetList (and prevent sending NULL > to PyList_SetItem) > >Signed-off-by: Noel Power <noel.power@suse.com> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 1be9b0cf1bc95715e83c27eabecbd4fa2022530b) >--- > lib/ldb/pyldb.c | 30 +++++++++++++++++++++++++++--- > 1 file changed, 27 insertions(+), 3 deletions(-) > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index 9dd5c2019b6..56614a850df 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -3430,17 +3430,41 @@ static PyObject *py_ldb_msg_items(PyLdbMessageObject *self) > struct ldb_message *msg = pyldb_Message_AsMessage(self); > Py_ssize_t i, j = 0; > PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1)); >+ if (l == NULL) { >+ return PyErr_NoMemory(); >+ } > if (msg->dn != NULL) { >+ PyObject *value = NULL; > PyObject *obj = pyldb_Dn_FromDn(msg->dn); >- PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", obj)); >+ int res = 0; >+ value = Py_BuildValue("(sO)", "dn", obj); > Py_CLEAR(obj); >+ if (value == NULL) { >+ Py_CLEAR(l); >+ return NULL; >+ } >+ res = PyList_SetItem(l, 0, value); >+ if (res == -1) { >+ Py_CLEAR(l); >+ return NULL; >+ } > j++; > } > for (i = 0; i < msg->num_elements; i++, j++) { >+ PyObject *value = NULL; > PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements); >- PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el); >+ int res = 0; > Py_CLEAR(py_el); >- PyList_SetItem(l, j, value); >+ value = Py_BuildValue("(sO)", msg->elements[i].name, py_el); >+ if (value == NULL ) { >+ Py_CLEAR(l); >+ return NULL; >+ } >+ res = PyList_SetItem(l, 0, value); >+ if (res == -1) { >+ Py_CLEAR(l); >+ return NULL; >+ } > } > return l; > } >-- >2.25.1 > > >From 129a3656ece39f157afebcd1b2b65307eca3a657 Mon Sep 17 00:00:00 2001 >From: Noel Power <noel.power@suse.com> >Date: Thu, 2 May 2019 19:51:05 +0100 >Subject: [PATCH 008/686] lib/ldb: squash 'cast between incompatible function > types' warning > >To avoid warning above produced by using >-Wcast-function-type we; > > + ensure PyCFunctions of type METH_NOARGS defined dummy arg > + ensure PyCFunctions of type METH_KEYWORDS use PY_DISCARD_FUNC_SIG > macro > >Signed-off-by: Noel Power <noel.power@suse.com> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit 51f146de5adbb5a58a528e168e7fe9faa4477880) >--- > lib/ldb/pyldb.c | 139 ++++++++++++++++++++++++++++++++---------------- > 1 file changed, 94 insertions(+), 45 deletions(-) > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index 56614a850df..92a4e206feb 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -34,6 +34,9 @@ > #include "pyldb.h" > #include "dlinklist.h" > >+/* discard signature of 'func' in favour of 'target_sig' */ >+#define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func >+ > struct py_ldb_search_iterator_reply; > > typedef struct { >@@ -189,12 +192,14 @@ static PyObject *wrap_text(const char *type, PyObject *wrapped) > return inst; > } > >-static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self) >+static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > return PyStr_FromString(self->data->oid); > } > >-static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self) >+static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > return PyBool_FromLong(self->data->critical); > } >@@ -487,27 +492,32 @@ static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, > return res; > } > >-static PyObject *py_ldb_dn_validate(PyLdbDnObject *self) >+static PyObject *py_ldb_dn_validate(PyLdbDnObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > return PyBool_FromLong(ldb_dn_validate(self->dn)); > } > >-static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self) >+static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > return PyBool_FromLong(ldb_dn_is_valid(self->dn)); > } > >-static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self) >+static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > return PyBool_FromLong(ldb_dn_is_special(self->dn)); > } > >-static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self) >+static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > return PyBool_FromLong(ldb_dn_is_null(self->dn)); > } > >-static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self) >+static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > return PyStr_FromString(ldb_dn_get_casefold(self->dn)); > } >@@ -517,12 +527,14 @@ static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self) > return PyStr_FromString(ldb_dn_get_linearized(self->dn)); > } > >-static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self) >+static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > return PyStr_FromString(ldb_dn_canonical_string(self->dn, self->dn)); > } > >-static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self) >+static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > return PyStr_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn)); > } >@@ -618,7 +630,8 @@ static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op) > return richcmp(ret, op); > } > >-static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self) >+static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self); > struct ldb_dn *parent; >@@ -760,7 +773,8 @@ static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args) > Py_RETURN_NONE; > } > >-static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self) >+static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_dn *dn; > const char *name; >@@ -775,7 +789,8 @@ static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self) > return PyStr_FromString(name); > } > >-static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self) >+static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_dn *dn; > const struct ldb_val *val; >@@ -803,7 +818,9 @@ static PyMethodDef py_ldb_dn_methods[] = { > "Check whether this is a null DN." }, > { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS, > NULL }, >- { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS, >+ { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction, >+ py_ldb_dn_get_linearized), >+ METH_NOARGS, > NULL }, > { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS, > "S.canonical_str() -> string\n" >@@ -813,7 +830,9 @@ static PyMethodDef py_ldb_dn_methods[] = { > { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS, > "S.canonical_ex_str() -> string\n" > "Canonical version of this DN (like a posix path, with terminating newline)." }, >- { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS, >+ { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction, >+ py_ldb_dn_extended_str), >+ METH_VARARGS | METH_KEYWORDS, > "S.extended_str(mode=1) -> string\n" > "Extended version of this DN" }, > { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS, >@@ -1027,7 +1046,8 @@ static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args) > Py_RETURN_NONE; > } > >-static PyObject *py_ldb_transaction_start(PyLdbObject *self) >+static PyObject *py_ldb_transaction_start(PyLdbObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); > int ldb_err; >@@ -1036,7 +1056,8 @@ static PyObject *py_ldb_transaction_start(PyLdbObject *self) > Py_RETURN_NONE; > } > >-static PyObject *py_ldb_transaction_commit(PyLdbObject *self) >+static PyObject *py_ldb_transaction_commit(PyLdbObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); > int ldb_err; >@@ -1045,7 +1066,8 @@ static PyObject *py_ldb_transaction_commit(PyLdbObject *self) > Py_RETURN_NONE; > } > >-static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self) >+static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); > int ldb_err; >@@ -1054,7 +1076,8 @@ static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self) > Py_RETURN_NONE; > } > >-static PyObject *py_ldb_transaction_cancel(PyLdbObject *self) >+static PyObject *py_ldb_transaction_cancel(PyLdbObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); > int ldb_err; >@@ -1063,7 +1086,8 @@ static PyObject *py_ldb_transaction_cancel(PyLdbObject *self) > Py_RETURN_NONE; > } > >-static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self) >+static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); > int ldb_err; >@@ -1077,7 +1101,8 @@ static PyObject *py_ldb_repr(PyLdbObject *self) > return PyStr_FromString("<ldb connection>"); > } > >-static PyObject *py_ldb_get_root_basedn(PyLdbObject *self) >+static PyObject *py_ldb_get_root_basedn(PyLdbObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self)); > if (dn == NULL) >@@ -1086,7 +1111,8 @@ static PyObject *py_ldb_get_root_basedn(PyLdbObject *self) > } > > >-static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self) >+static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self)); > if (dn == NULL) >@@ -1094,7 +1120,8 @@ static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self) > return py_ldb_dn_copy(dn); > } > >-static PyObject *py_ldb_get_config_basedn(PyLdbObject *self) >+static PyObject *py_ldb_get_config_basedn(PyLdbObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self)); > if (dn == NULL) >@@ -1102,7 +1129,8 @@ static PyObject *py_ldb_get_config_basedn(PyLdbObject *self) > return py_ldb_dn_copy(dn); > } > >-static PyObject *py_ldb_get_default_basedn(PyLdbObject *self) >+static PyObject *py_ldb_get_default_basedn(PyLdbObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self)); > if (dn == NULL) >@@ -2195,7 +2223,8 @@ static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args) > Py_RETURN_NONE; > } > >-static PyObject *py_ldb_modules(PyLdbObject *self) >+static PyObject *py_ldb_modules(PyLdbObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self); > PyObject *ret = PyList_New(0); >@@ -2234,7 +2263,8 @@ static const struct ldb_dn_extended_syntax test_dn_syntax = { > .write_hex_fn = ldb_handler_copy, > }; > >-static PyObject *py_ldb_register_test_extensions(PyLdbObject *self) >+static PyObject *py_ldb_register_test_extensions(PyLdbObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self); > int ret; >@@ -2280,22 +2310,28 @@ static PyMethodDef py_ldb_methods[] = { > NULL }, > { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS, > NULL }, >- { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, >+ { "connect", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_connect), >+ METH_VARARGS|METH_KEYWORDS, > "S.connect(url, flags=0, options=None) -> None\n" > "Connect to a LDB URL." }, >- { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS, >+ { "modify", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_modify), >+ METH_VARARGS|METH_KEYWORDS, > "S.modify(message, controls=None, validate=False) -> None\n" > "Modify an entry." }, >- { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS, >+ { "add", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_add), >+ METH_VARARGS|METH_KEYWORDS, > "S.add(message, controls=None) -> None\n" > "Add an entry." }, >- { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS, >+ { "delete", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_delete), >+ METH_VARARGS|METH_KEYWORDS, > "S.delete(dn, controls=None) -> None\n" > "Remove an entry." }, >- { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS, >+ { "rename", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_rename), >+ METH_VARARGS|METH_KEYWORDS, > "S.rename(old_dn, new_dn, controls=None) -> None\n" > "Rename an entry." }, >- { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS, >+ { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_search), >+ METH_VARARGS|METH_KEYWORDS, > "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n" > "Search in a database.\n" > "\n" >@@ -2306,7 +2342,9 @@ static PyMethodDef py_ldb_methods[] = { > ":param controls: Optional list of controls\n" > ":return: ldb.Result object\n" > }, >- { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS, >+ { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction, >+ py_ldb_search_iterator), >+ METH_VARARGS|METH_KEYWORDS, > "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n" > "Search in a database.\n" > "\n" >@@ -2623,7 +2661,8 @@ static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self) > return py_ret; > } > >-static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self) >+static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > PyObject *py_ret = NULL; > >@@ -2657,7 +2696,8 @@ static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self) > return py_ret; > } > >-static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self) >+static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > if (self->state.req == NULL) { > PyErr_SetString(PyExc_RuntimeError, >@@ -2707,19 +2747,22 @@ static PyObject *py_ldb_module_str(PyLdbModuleObject *self) > return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name); > } > >-static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self) >+static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self)); > Py_RETURN_NONE; > } > >-static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self) >+static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self)); > Py_RETURN_NONE; > } > >-static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self) >+static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self)); > Py_RETURN_NONE; >@@ -2859,7 +2902,8 @@ static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args) > } > > static PyMethodDef py_ldb_module_methods[] = { >- { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL }, >+ { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_module_search), >+ METH_VARARGS|METH_KEYWORDS, NULL }, > { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL }, > { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL }, > { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL }, >@@ -3345,7 +3389,8 @@ static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args > Py_RETURN_NONE; > } > >-static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self) >+static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_message *msg = pyldb_Message_AsMessage(self); > Py_ssize_t i, j = 0; >@@ -3425,7 +3470,8 @@ static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObje > return PyObject_FromLdbValue(&el->values[idx]); > } > >-static PyObject *py_ldb_msg_items(PyLdbMessageObject *self) >+static PyObject *py_ldb_msg_items(PyLdbMessageObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_message *msg = pyldb_Message_AsMessage(self); > Py_ssize_t i, j = 0; >@@ -3469,7 +3515,8 @@ static PyObject *py_ldb_msg_items(PyLdbMessageObject *self) > return l; > } > >-static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self) >+static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self, >+ PyObject *Py_UNUSED(ignored)) > { > struct ldb_message *msg = pyldb_Message_AsMessage(self); > Py_ssize_t i = 0; >@@ -3525,13 +3572,14 @@ static PyMethodDef py_ldb_msg_methods[] = { > "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n" > "Class method to create ldb.Message object from Dictionary.\n" > "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."}, >- { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, >+ { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, > "S.keys() -> list\n\n" > "Return sequence of all attribute names." }, > { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, > "S.remove(name)\n\n" > "Remove all entries for attributes with the specified name."}, >- { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS, >+ { "get", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_msg_get), >+ METH_VARARGS | METH_KEYWORDS, > "msg.get(name,default=None,idx=None) -> string\n" > "idx is the index into the values array\n" > "if idx is None, then a list is returned\n" >@@ -3549,7 +3597,7 @@ static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self) > { > PyObject *list, *iter; > >- list = py_ldb_msg_keys(self); >+ list = py_ldb_msg_keys(self, NULL); > iter = PyObject_GetIter(list); > Py_DECREF(list); > return iter; >@@ -4202,7 +4250,8 @@ static PyMethodDef py_ldb_global_methods[] = { > { "valid_attr_name", py_valid_attr_name, METH_VARARGS, > "S.valid_attr_name(name) -> bool\n\nn" > "Check whether the supplied name is a valid attribute name." }, >- { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS, >+ { "open", PY_DISCARD_FUNC_SIG(PyCFunction,py_ldb_new), >+ METH_VARARGS|METH_KEYWORDS, > "S.open() -> Ldb\n\n" > "Open a new LDB context." }, > { "binary_encode", py_binary_encode, METH_VARARGS, >-- >2.25.1 > > >From bf97046b8e4b975f478abbba3cedf459cdafa312 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 5 Mar 2021 15:47:56 +1300 >Subject: [PATCH 009/686] ldb: add tests for ldb_wildcard_compare >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14044 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Björn Jacke <bjacke@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 33a95a1e75b85e9795c4490b78ead2162e2a1f47) >--- > lib/ldb/tests/ldb_match_test.c | 134 ++++++++++++++++++++++++++++++--- > 1 file changed, 124 insertions(+), 10 deletions(-) > >diff --git a/lib/ldb/tests/ldb_match_test.c b/lib/ldb/tests/ldb_match_test.c >index e09f50c86ba..3028aed072c 100644 >--- a/lib/ldb/tests/ldb_match_test.c >+++ b/lib/ldb/tests/ldb_match_test.c >@@ -91,6 +91,33 @@ static int teardown(void **state) > return 0; > } > >+static void escape_string(uint8_t *buf, size_t buflen, >+ const uint8_t *s, size_t len) >+{ >+ size_t i; >+ size_t j = 0; >+ for (i = 0; i < len; i++) { >+ if (j == buflen - 1) { >+ goto fin; >+ } >+ if (s[i] >= 0x20) { >+ buf[j] = s[i]; >+ j++; >+ } else { >+ if (j >= buflen - 4) { >+ goto fin; >+ } >+ /* utf-8 control char representation */ >+ buf[j] = 0xE2; >+ buf[j + 1] = 0x90; >+ buf[j + 2] = 0x80 + s[i]; >+ j+= 3; >+ } >+ } >+fin: >+ buf[j] = 0; >+} >+ > > /* > * The wild card pattern "attribute=*" is parsed as an LDB_OP_PRESENT operation >@@ -122,23 +149,110 @@ static void test_wildcard_match_star(void **state) > * Test basic wild card matching > * > */ >+struct wildcard_test { >+ uint8_t *val; >+ size_t val_size; >+ const char *search; >+ bool should_match; >+ bool fold; >+}; >+ >+/* >+ * Q: Why this macro rather than plain struct values? >+ * A: So we can get the size of the const char[] value while it is still a >+ * true array, not a pointer. >+ * >+ * Q: but why not just use strlen? >+ * A: so values can contain '\0', which we supposedly allow. >+ */ >+ >+#define TEST_ENTRY(val, search, should_match, fold) \ >+ { \ >+ (uint8_t*)discard_const(val), \ >+ sizeof(val) - 1, \ >+ search, \ >+ should_match, \ >+ fold \ >+ } >+ > static void test_wildcard_match(void **state) > { > struct ldbtest_ctx *ctx = *state; >- bool matched = false; >- >- uint8_t value[] = "The value.......end"; >- struct ldb_val val = { >- .data = value, >- .length = (sizeof(value)) >+ size_t failed = 0; >+ size_t i; >+ struct wildcard_test tests[] = { >+ TEST_ENTRY("The value.......end", "*end", true, true), >+ TEST_ENTRY("The value.......end", "*fend", false, true), >+ TEST_ENTRY("The value.......end", "*eel", false, true), >+ TEST_ENTRY("The value.......end", "*d", true, true), >+ TEST_ENTRY("The value.......end", "*D*", true, true), >+ TEST_ENTRY("The value.......end", "*e*d*", true, true), >+ TEST_ENTRY("end", "*e*d*", true, true), >+ TEST_ENTRY("end", " *e*d*", true, true), >+ TEST_ENTRY("1.0.0.0.0.0.0.0aaaaaaaaaaaa", "*aaaaa", true, true), >+ TEST_ENTRY("1.0..0.0.0.0.0.0.0aAaaaAAAAAAA", "*a", true, true), >+ TEST_ENTRY("1.0.0.0.0.0.0.0.0.0.0aaaa", "*aaaaa", false, true), >+ TEST_ENTRY("1.0.0.0.0.0.0.0.0.0.0", "*0.0", true, true), >+ TEST_ENTRY("1.0.0.0.0.0.0.0.0.0.0", "*0.0.0", true, true), >+ TEST_ENTRY("1.0.0.0.0.0.0.0.0.0", "1*0*0*0*0*0*0*0*0*0", true, >+ true), >+ TEST_ENTRY("1.0.0.0.0.0.0.0.0", "1*0*0*0*0*0*0*0*0*0", false, >+ true), >+ TEST_ENTRY("1.0.0.0.000.0.0.0.0", "1*0*0*0*0*0*0*0*0*0", true, >+ true), >+ TEST_ENTRY("1\n0\r0\t000.0.0.0.0", "1*0*0*0*0*0*0*0*0", true, >+ true), >+ /* >+ * We allow NUL bytes in non-casefolding syntaxes. >+ */ >+ TEST_ENTRY("1\x00 x", "1*x", true, false), >+ TEST_ENTRY("1\x00 x", "*x", true, false), >+ TEST_ENTRY("1\x00 x", "*x*", true, false), >+ TEST_ENTRY("1\x00 x", "* *", true, false), >+ TEST_ENTRY("1\x00 x", "1*", true, false), >+ TEST_ENTRY("1\x00 b* x", "1*b*", true, false), >+ TEST_ENTRY("1.0..0.0.0.0.0.0.0aAaaaAAAAAAA", "*a", false, false), > }; >- struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "objectClass=*end"); >- assert_non_null(tree); > >- ldb_wildcard_compare(ctx->ldb, tree, val, &matched); >- assert_true(matched); >+ for (i = 0; i < ARRAY_SIZE(tests); i++) { >+ bool matched; >+ int ret; >+ struct ldb_val val = { >+ .data = (uint8_t *)tests[i].val, >+ .length = tests[i].val_size >+ }; >+ const char *attr = tests[i].fold ? "objectclass" : "birthLocation"; >+ const char *s = talloc_asprintf(ctx, "%s=%s", >+ attr, tests[i].search); >+ struct ldb_parse_tree *tree = ldb_parse_tree(ctx, s); >+ assert_non_null(tree); >+ ret = ldb_wildcard_compare(ctx->ldb, tree, val, &matched); >+ if (ret != LDB_SUCCESS) { >+ uint8_t buf[100]; >+ escape_string(buf, sizeof(buf), >+ tests[i].val, tests[i].val_size); >+ print_error("%zu val: «%s», search «%s» FAILED with %d\n", >+ i, buf, tests[i].search, ret); >+ failed++; >+ } >+ if (matched != tests[i].should_match) { >+ uint8_t buf[100]; >+ escape_string(buf, sizeof(buf), >+ tests[i].val, tests[i].val_size); >+ print_error("%zu val: «%s», search «%s» should %s\n", >+ i, buf, tests[i].search, >+ matched ? "not match" : "match"); >+ failed++; >+ } >+ } >+ if (failed != 0) { >+ fail_msg("wrong results for %zu/%zu wildcard searches\n", >+ failed, ARRAY_SIZE(tests)); >+ } > } > >+#undef TEST_ENTRY >+ > > /* > * ldb_handler_copy and ldb_val_dup over allocate by one and add a trailing '\0' >-- >2.25.1 > > >From 6649b2c2c134dda674709d5cb8fc0890cc76ffdf Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 5 Mar 2021 20:13:01 +1300 >Subject: [PATCH 010/686] CVE-2021-20277 ldb tests: ldb_match tests with extra > spaces > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14655 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ea4bd2c437fbb5801fb82e2a038d9cdb5abea4c0) >--- > lib/ldb/tests/ldb_match_test.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > >diff --git a/lib/ldb/tests/ldb_match_test.c b/lib/ldb/tests/ldb_match_test.c >index 3028aed072c..ba6ea56be15 100644 >--- a/lib/ldb/tests/ldb_match_test.c >+++ b/lib/ldb/tests/ldb_match_test.c >@@ -181,6 +181,8 @@ static void test_wildcard_match(void **state) > size_t failed = 0; > size_t i; > struct wildcard_test tests[] = { >+ TEST_ENTRY(" 1 0", "1*0*", true, true), >+ TEST_ENTRY(" 1 0", "1 *0", true, true), > TEST_ENTRY("The value.......end", "*end", true, true), > TEST_ENTRY("The value.......end", "*fend", false, true), > TEST_ENTRY("The value.......end", "*eel", false, true), >@@ -203,8 +205,12 @@ static void test_wildcard_match(void **state) > TEST_ENTRY("1\n0\r0\t000.0.0.0.0", "1*0*0*0*0*0*0*0*0", true, > true), > /* >- * We allow NUL bytes in non-casefolding syntaxes. >+ * We allow NUL bytes and redundant spaces in non-casefolding >+ * syntaxes. > */ >+ TEST_ENTRY(" 1 0", "*1 0", true, false), >+ TEST_ENTRY(" 1 0", "*1 0", true, false), >+ TEST_ENTRY("1 0", "*1 0", false, false), > TEST_ENTRY("1\x00 x", "1*x", true, false), > TEST_ENTRY("1\x00 x", "*x", true, false), > TEST_ENTRY("1\x00 x", "*x*", true, false), >-- >2.25.1 > > >From 4e0166bb9c41981d01307540cc845472244fc237 Mon Sep 17 00:00:00 2001 >From: Joe Guo <joeg@catalyst.net.nz> >Date: Thu, 7 Mar 2019 12:34:15 +1300 >Subject: [PATCH 011/686] subunit/run.py: make iso8601 UTC usage python 2/3 > compatible > >In `iso8601/iso8601.py`: > > if sys.version_info >= (3, 2, 0): > UTC = datetime.timezone.utc > ... > else: > class Utc(datetime.tzinfo): > ... > > UTC = Utc() > >The class `Utc` is only available for python < 3.2.0. >Use `UTC` instance instead, which is python 2/3 compatible. > >Signed-off-by: Joe Guo <joeg@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Noel Power <npower@samba.org> >(cherry picked from commit 02c7b8c03d4970421a5170e44c57cbc3cda82827) >--- > python/samba/subunit/run.py | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > >diff --git a/python/samba/subunit/run.py b/python/samba/subunit/run.py >index 8f32d46ef49..89ca8a8050b 100755 >--- a/python/samba/subunit/run.py >+++ b/python/samba/subunit/run.py >@@ -24,7 +24,7 @@ > $ python -m samba.subunit.run mylib.tests.test_suite > """ > >-from iso8601.iso8601 import Utc >+from iso8601.iso8601 import UTC > > import datetime > import os >@@ -184,7 +184,7 @@ class TestProtocolClient(unittest.TestResult): > > ":param datetime: A datetime.datetime object. > """ >- time = a_datetime.astimezone(Utc()) >+ time = a_datetime.astimezone(UTC) > self._stream.write("time: %04d-%02d-%02d %02d:%02d:%02d.%06dZ\n" % ( > time.year, time.month, time.day, time.hour, time.minute, > time.second, time.microsecond)) >@@ -458,7 +458,7 @@ class AutoTimingTestResultDecorator(HookedTestResultDecorator): > time = self._time > if time is not None: > return >- time = datetime.datetime.utcnow().replace(tzinfo=Utc()) >+ time = datetime.datetime.utcnow().replace(tzinfo=UTC) > self.decorated.time(time) > > @property >-- >2.25.1 > > >From 4d872b97aac79402d7959bbca864cd36be9409ae Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Feb 2019 14:01:10 +0100 >Subject: [PATCH 012/686] selftest:Samba4: add fl2008dc as alias to ad_dc_ntvfs > >Using aliases it will be possible to split the large amount >of tests which use ad_dc_ntvfs into multiple autobuild/ci >tasks/jobs later. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit 62eeab8f6cb6d9c85353738a2da073e0a16bd418) > >[jsutton@samba.org Adapted to fix conflicts and remove autobuild.py > changes] >--- > selftest/target/Samba4.pm | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > >diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm >index a7a6c4c9587..b4c89a5a4bb 100755 >--- a/selftest/target/Samba4.pm >+++ b/selftest/target/Samba4.pm >@@ -2371,9 +2371,26 @@ sub check_env($$) > labdc => ["backupfromdc"], > proclimitdc => [], > >+ # aliases in order to split autbuild tasks >+ fl2008dc => ["ad_dc_ntvfs"], >+ > none => [], > ); > >+sub return_alias_env >+{ >+ my ($self, $path, $env) = @_; >+ >+ # just an alias >+ return $env; >+} >+ >+sub setup_fl2008dc >+{ >+ my ($self, $path, $dep_env) = @_; >+ return $self->return_alias_env($path, $dep_env) >+} >+ > sub setup_s4member > { > my ($self, $path, $dc_vars) = @_; >-- >2.25.1 > > >From 7133e36647b3d6a51f68b55d9f8cdb9aa89b6da4 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Feb 2019 14:03:29 +0100 >Subject: [PATCH 013/686] selftest:Samba4: add ad_dc_default alias to > ad_dc_ntvfs > >This will allow us to run really most tests in an isolated >autobuild/ci task later. > >This will apply to tests, which may not rely on the ntvfs backend, so >the ad_dc_default alias can point to another environment in future. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit c217a15a2c3c6b6c171d28a57f9b0248dacaec53) > >[jsutton@samba.org Adapted to fix conflicts and remove autobuild.py > changes] >--- > selftest/target/Samba4.pm | 7 +++++++ > 1 file changed, 7 insertions(+) > >diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm >index b4c89a5a4bb..2fbd5e24928 100755 >--- a/selftest/target/Samba4.pm >+++ b/selftest/target/Samba4.pm >@@ -2373,6 +2373,7 @@ sub check_env($$) > > # aliases in order to split autbuild tasks > fl2008dc => ["ad_dc_ntvfs"], >+ ad_dc_default => ["ad_dc_ntvfs"], > > none => [], > ); >@@ -2391,6 +2392,12 @@ sub setup_fl2008dc > return $self->return_alias_env($path, $dep_env) > } > >+sub setup_ad_dc_default >+{ >+ my ($self, $path, $dep_env) = @_; >+ return $self->return_alias_env($path, $dep_env) >+} >+ > sub setup_s4member > { > my ($self, $path, $dc_vars) = @_; >-- >2.25.1 > > >From c839dceddcc0f16632b3c1e268efffb624708777 Mon Sep 17 00:00:00 2001 >From: Michael Hanselmann <public@hansmi.ch> >Date: Thu, 4 Apr 2019 00:04:23 +0200 >Subject: [PATCH 014/686] ndrdump: Remove local variables for pipes > >There's no need for the local variables as the NDR call structure >pointer is kept around anyway. > >Signed-off-by: Michael Hanselmann <public@hansmi.ch> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 10dd15010bddb929128b3585f1280ae1eb7b6b99) >--- > librpc/tools/ndrdump.c | 12 ++++-------- > 1 file changed, 4 insertions(+), 8 deletions(-) > >diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c >index e26d3719429..b7eae70833e 100644 >--- a/librpc/tools/ndrdump.c >+++ b/librpc/tools/ndrdump.c >@@ -229,8 +229,6 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > POPT_COMMON_VERSION > { NULL } > }; >- const struct ndr_interface_call_pipes *in_pipes = NULL; >- const struct ndr_interface_call_pipes *out_pipes = NULL; > uint32_t highest_ofs; > struct dcerpc_sec_verification_trailer *sec_vt = NULL; > >@@ -319,11 +317,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > if (strcmp(inout, "in") == 0 || > strcmp(inout, "request") == 0) { > flags = NDR_IN; >- in_pipes = &f->in_pipes; > } else if (strcmp(inout, "out") == 0 || > strcmp(inout, "response") == 0) { > flags = NDR_OUT; >- out_pipes = &f->out_pipes; > } else { > printf("Bad inout value '%s'\n", inout); > exit(1); >@@ -445,8 +441,8 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > } > TALLOC_FREE(sec_vt); > >- if (out_pipes) { >- status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, out_pipes); >+ if (flags & NDR_OUT) { >+ status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, &f->out_pipes); > if (!NT_STATUS_IS_OK(status)) { > printf("dump FAILED\n"); > exit(1); >@@ -483,8 +479,8 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > exit(1); > } > >- if (in_pipes) { >- status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, in_pipes); >+ if (flags & NDR_IN) { >+ status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, &f->in_pipes); > if (!NT_STATUS_IS_OK(status)) { > printf("dump FAILED\n"); > exit(1); >-- >2.25.1 > > >From 601afa324cd55f2c12cb28ca7dbc1a6f9a67e090 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 12 Apr 2019 15:10:35 +1200 >Subject: [PATCH 015/686] ndrdump: change behaviour of flags to operate as > flags > >These are called flags because that is what they become to the ndr_pull function, >but to avoid total confusion treat them as flags generally even if the values are >always exclusive (at the moment). > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit c9e6331afc1ee0e85a9582c6682ff95885135792) >--- > librpc/tools/ndrdump.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > >diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c >index b7eae70833e..ef7f9c66139 100644 >--- a/librpc/tools/ndrdump.c >+++ b/librpc/tools/ndrdump.c >@@ -201,7 +201,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > struct ndr_pull *ndr_pull; > struct ndr_print *ndr_print; > TALLOC_CTX *mem_ctx; >- int flags; >+ int flags = 0; > poptContext pc; > NTSTATUS status; > enum ndr_err_code ndr_err; >@@ -316,10 +316,10 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > > if (strcmp(inout, "in") == 0 || > strcmp(inout, "request") == 0) { >- flags = NDR_IN; >+ flags |= NDR_IN; > } else if (strcmp(inout, "out") == 0 || > strcmp(inout, "response") == 0) { >- flags = NDR_OUT; >+ flags |= NDR_OUT; > } else { > printf("Bad inout value '%s'\n", inout); > exit(1); >@@ -340,7 +340,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > } > > if (ctx_filename) { >- if (flags == NDR_IN) { >+ if (flags & NDR_IN) { > printf("Context file can only be used for \"out\" packages\n"); > exit(1); > } >-- >2.25.1 > > >From 36ff31e285f22e430c9c54c848c6b90db82402d6 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 4 Jun 2019 14:01:49 +1200 >Subject: [PATCH 016/686] tests blackbox ndrdump: Add test for struct printing > >Add test for the dumping of a public structure with ndrdump. This >removes the need to define decode_* functions in the idl. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 0e771f0ed6cb900e6eccc3a4205120ae8c0f7ee2) >--- > python/samba/tests/blackbox/ndrdump.py | 12 ++++++++++-- > selftest/knownfail.d/ndrdump | 1 + > 2 files changed, 11 insertions(+), 2 deletions(-) > create mode 100644 selftest/knownfail.d/ndrdump > >diff --git a/python/samba/tests/blackbox/ndrdump.py b/python/samba/tests/blackbox/ndrdump.py >index 350d576bc81..7ca7b93f559 100644 >--- a/python/samba/tests/blackbox/ndrdump.py >+++ b/python/samba/tests/blackbox/ndrdump.py >@@ -22,7 +22,7 @@ from __future__ import print_function > """Blackbox tests for ndrdump.""" > > import os >-from samba.tests import BlackboxTestCase >+from samba.tests import BlackboxTestCase, BlackboxProcessError > > for p in ["../../../../../source4/librpc/tests", "../../../../../librpc/tests"]: > data_path_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), p)) >@@ -49,6 +49,14 @@ class NdrDumpTests(BlackboxTestCase): > def test_ndrdump_with_validate(self): > self.check_run("ndrdump --validate samr samr_CreateUser in %s" % (self.data_path("samr-CreateUser-in.dat"))) > >- def test_ndrdump_with_hex(self): >+ def test_ndrdump_with_hex_decode_function(self): > self.check_run("ndrdump dns decode_dns_name_packet in --hex-input %s" % > self.data_path("dns-decode_dns_name_packet-hex.dat")) >+ >+ def test_ndrdump_with_hex_struct_name(self): >+ try: >+ self.check_run( >+ "ndrdump dns dns_name_packet struct --hex-input %s" % >+ self.data_path("dns-decode_dns_name_packet-hex.dat")) >+ except BlackboxProcessError as e: >+ self.fail(e) >diff --git a/selftest/knownfail.d/ndrdump b/selftest/knownfail.d/ndrdump >new file mode 100644 >index 00000000000..9f7335f5d0b >--- /dev/null >+++ b/selftest/knownfail.d/ndrdump >@@ -0,0 +1 @@ >+^samba.tests.blackbox.ndrdump.samba.tests.blackbox.ndrdump.NdrDumpTests.test_ndrdump_with_hex_struct_name\(none\) >-- >2.25.1 > > >From 224c964cd6ac4c49d2ec04041ac0472729b5a87e Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Wed, 5 Jun 2019 08:43:33 +1200 >Subject: [PATCH 017/686] pidl: Allow ndrdump to print public structures > >Generate code to allow ndrdump to operate on public structures. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 5d67e87d1c4504593f5da712f00de85371f8942f) >--- > librpc/ndr/libndr.h | 10 ++++++ > pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 41 +++++++++++++++++++++++- > 2 files changed, 50 insertions(+), 1 deletion(-) > >diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h >index 8a15fccfe09..8ece7374b9a 100644 >--- a/librpc/ndr/libndr.h >+++ b/librpc/ndr/libndr.h >@@ -455,6 +455,14 @@ struct ndr_interface_call { > struct ndr_interface_call_pipes out_pipes; > }; > >+struct ndr_interface_public_struct { >+ const char *name; >+ size_t struct_size; >+ ndr_push_flags_fn_t ndr_push; >+ ndr_pull_flags_fn_t ndr_pull; >+ ndr_print_function_t ndr_print; >+}; >+ > struct ndr_interface_string_array { > uint32_t count; > const char * const *names; >@@ -466,6 +474,8 @@ struct ndr_interface_table { > const char *helpstring; > uint32_t num_calls; > const struct ndr_interface_call *calls; >+ uint32_t num_public_structs; >+ const struct ndr_interface_public_struct *public_structs; > const struct ndr_interface_string_array *endpoints; > const struct ndr_interface_string_array *authservices; > }; >diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm >index 432e52f89c4..2fc4327faf4 100644 >--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm >+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm >@@ -1833,6 +1833,9 @@ sub ParseStructNdrSize($$$$) > sub DeclStruct($$$$) > { > my ($e,$t,$name,$varname) = @_; >+ if ($t eq "base") { >+ return "struct $name $varname"; >+ } > return ($t ne "pull"?"const ":"") . "struct $name *$varname"; > } > >@@ -2175,6 +2178,9 @@ sub ParseUnionPull($$$$) > sub DeclUnion($$$$) > { > my ($e,$t,$name,$varname) = @_; >+ if ($t eq "base") { >+ return "union $name $varname"; >+ } > return ($t ne "pull"?"const ":"") . "union $name *$varname"; > } > >@@ -2752,21 +2758,52 @@ sub FunctionCallEntry($$) > return 1; > } > >+sub StructEntry($$) >+{ >+ my ($self, $d) = @_; >+ my $type_decl = $typefamily{$d->{TYPE}}->{DECL}->($d, "base", $d->{NAME}, ""); >+ >+ $self->pidl("\t{"); >+ $self->pidl("\t\t.name = \"$d->{NAME}\","); >+ $self->pidl("\t\t.struct_size = sizeof($type_decl),"); >+ $self->pidl("\t\t.ndr_push = (ndr_push_flags_fn_t) ndr_push_$d->{NAME},"); >+ $self->pidl("\t\t.ndr_pull = (ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},"); >+ $self->pidl("\t\t.ndr_print = (ndr_print_function_t) ndr_print_$d->{NAME},"); >+ $self->pidl("\t},"); >+ return 1; >+} >+ > ##################################################################### > # produce a function call table > sub FunctionTable($$) > { > my($self,$interface) = @_; > my $count = 0; >+ my $count_public_structs = 0; > my $uname = uc $interface->{NAME}; > >- return if ($#{$interface->{FUNCTIONS}}+1 == 0); >+ foreach my $d (@{$interface->{TYPES}}) { >+ next unless (has_property($d, "public")); >+ $count_public_structs += 1; >+ } >+ return if ($#{$interface->{FUNCTIONS}}+1 == 0 and >+ $count_public_structs == 0); > return unless defined ($interface->{PROPERTIES}->{uuid}); > > foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) { > $self->FunctionCallPipes($d); > } > >+ $self->pidl("static const struct ndr_interface_public_struct $interface->{NAME}\_public_structs[] = {"); >+ >+ foreach my $d (@{$interface->{TYPES}}) { >+ next unless (has_property($d, "public")); >+ $self->StructEntry($d) >+ } >+ $self->pidl("\t{ .name = NULL }"); >+ $self->pidl("};"); >+ $self->pidl(""); >+ > $self->pidl("static const struct ndr_interface_call $interface->{NAME}\_calls[] = {"); > > foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) { >@@ -2807,6 +2844,8 @@ sub FunctionTable($$) > $self->pidl("\t.helpstring\t= NDR_$uname\_HELPSTRING,"); > $self->pidl("\t.num_calls\t= $count,"); > $self->pidl("\t.calls\t\t= $interface->{NAME}\_calls,"); >+ $self->pidl("\t.num_public_structs\t= $count_public_structs,"); >+ $self->pidl("\t.public_structs\t\t= $interface->{NAME}\_public_structs,"); > $self->pidl("\t.endpoints\t= &$interface->{NAME}\_endpoints,"); > $self->pidl("\t.authservices\t= &$interface->{NAME}\_authservices"); > $self->pidl("};"); >-- >2.25.1 > > >From 920b85eb4735af78bc32e6b10dd869cdcdcec529 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Wed, 5 Jun 2019 08:44:09 +1200 >Subject: [PATCH 018/686] ndrdump: print public structures > >Add a struct option to ndrdump that will allow it to print public >structures. > i.e. binn/ndrdump dns dns_name_packet struct data.file > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 3bf05fbfd7106f46b35ee027f57be4c6af72f22e) >--- > librpc/tools/ndrdump.1.xml | 15 +++--- > librpc/tools/ndrdump.c | 98 +++++++++++++++++++++++++++++------- > selftest/knownfail.d/ndrdump | 1 - > 3 files changed, 88 insertions(+), 26 deletions(-) > delete mode 100644 selftest/knownfail.d/ndrdump > >diff --git a/librpc/tools/ndrdump.1.xml b/librpc/tools/ndrdump.1.xml >index e148eee0f03..fa6d763d18f 100644 >--- a/librpc/tools/ndrdump.1.xml >+++ b/librpc/tools/ndrdump.1.xml >@@ -21,8 +21,8 @@ > <command>ndrdump</command> > <arg choice="opt">-c context</arg> > <arg choice="req">pipe</arg> >- <arg choice="req">function</arg> >- <arg choice="req">in|out</arg> >+ <arg choice="req">format</arg> >+ <arg choice="req">in|out|struct</arg> > <arg choice="req">filename</arg> > </cmdsynopsis> > <cmdsynopsis> >@@ -38,15 +38,18 @@ > <title>DESCRIPTION</title> > > <para>ndrdump tries to parse the specified <replaceable>filename</replaceable> >- using Samba's parser for the specified pipe and function. The >+ using Samba's parser for the specified pipe and format. The > third argument should be >- either <emphasis>in</emphasis> or <emphasis>out</emphasis>, depending >- on whether the data should be parsed as a request or a reply.</para> >+ either <emphasis>in</emphasis>, <emphasis>out</emphasis> >+ or <emphasis>struct</emphasis>depending >+ on whether the data should be parsed as a request, reply or a >+ public structure.</para> > > <para>Running ndrdump without arguments will list the pipes for which > parsers are available.</para> > >- <para>Running ndrdump with one argument will list the functions that >+ <para>Running ndrdump with one argument will list the functions and >+ public structures that > Samba can parse for the specified pipe.</para> > > <para>The primary function of ndrdump is debugging Samba's internal >diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c >index ef7f9c66139..bd4f277607b 100644 >--- a/librpc/tools/ndrdump.c >+++ b/librpc/tools/ndrdump.c >@@ -48,6 +48,35 @@ static const struct ndr_interface_call *find_function( > return &p->calls[i]; > } > >+/* >+ * Find a public structure on the pipe and return it as if it were >+ * a function (as the rest of ndrdump is based around functions) >+ */ >+static const struct ndr_interface_call *find_struct( >+ const struct ndr_interface_table *p, >+ const char *struct_name, >+ struct ndr_interface_call *out_buffer) >+{ >+ int i; >+ for (i=0;i<p->num_public_structs;i++) { >+ if (strcmp(p->public_structs[i].name, struct_name) == 0) { >+ break; >+ } >+ } >+ if (i == p->num_public_structs) { >+ printf("Public structure '%s' not found\n", struct_name); >+ exit(1); >+ } >+ *out_buffer = (struct ndr_interface_call) { >+ .name = p->public_structs[i].name, >+ .struct_size = p->public_structs[i].struct_size, >+ .ndr_pull = p->public_structs[i].ndr_pull, >+ .ndr_push = p->public_structs[i].ndr_push, >+ .ndr_print = p->public_structs[i].ndr_print >+ }; >+ return out_buffer; >+} >+ > _NORETURN_ static void show_pipes(void) > { > const struct ndr_interface_list *l; >@@ -71,6 +100,10 @@ _NORETURN_ static void show_functions(const struct ndr_interface_table *p) > for (i=0;i<p->num_calls;i++) { > printf("\t0x%02x (%2d) %s\n", i, i, p->calls[i].name); > } >+ printf("known public structures on '%s' are:\n", p->name); >+ for (i=0;i<p->num_public_structs;i++) { >+ printf("\t%s\n", p->public_structs[i].name); >+ } > exit(1); > } > >@@ -194,7 +227,21 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > { > const struct ndr_interface_table *p = NULL; > const struct ndr_interface_call *f; >- const char *pipe_name, *function, *inout, *filename; >+ struct ndr_interface_call f_buffer; >+ const char *pipe_name = NULL; >+ const char *filename = NULL; >+ /* >+ * The format type: >+ * in: a request >+ * out: a response >+ * struct: a public structure >+ */ >+ const char *type = NULL; >+ /* >+ * Format is either the name of the decoding function or the >+ * name of a public structure >+ */ >+ const char *format = NULL; > uint8_t *data; > size_t size; > DATA_BLOB blob; >@@ -244,7 +291,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > pc = poptGetContext("ndrdump", argc, argv, long_options, 0); > > poptSetOtherOptionHelp( >- pc, "<pipe|uuid> <function> <inout> [<filename>]"); >+ pc, "<pipe|uuid> <format> <in|out|struct> [<filename>]"); > > while ((opt = poptGetNextOpt(pc)) != -1) { > switch (opt) { >@@ -302,29 +349,34 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > exit(1); > } > >- function = poptGetArg(pc); >- inout = poptGetArg(pc); >+ format = poptGetArg(pc); >+ type = poptGetArg(pc); > filename = poptGetArg(pc); > >- if (!function || !inout) { >+ if (!format || !type) { > poptPrintUsage(pc, stderr, 0); > show_functions(p); > exit(1); > } > >- f = find_function(p, function); >- >- if (strcmp(inout, "in") == 0 || >- strcmp(inout, "request") == 0) { >- flags |= NDR_IN; >- } else if (strcmp(inout, "out") == 0 || >- strcmp(inout, "response") == 0) { >- flags |= NDR_OUT; >+ if (strcmp(type, "struct") == 0) { >+ flags = 0; /* neither NDR_IN nor NDR_OUT */ >+ f = find_struct(p, format, &f_buffer); > } else { >- printf("Bad inout value '%s'\n", inout); >- exit(1); >+ f = find_function(p, format); >+ if (strcmp(type, "in") == 0 || >+ strcmp(type, "request") == 0) { >+ flags |= NDR_IN; >+ } else if (strcmp(type, "out") == 0 || >+ strcmp(type, "response") == 0) { >+ flags |= NDR_OUT; >+ } else { >+ printf("Bad type value '%s'\n", type); >+ exit(1); >+ } > } > >+ > mem_ctx = talloc_init("ndrdump"); > > st = talloc_zero_size(mem_ctx, f->struct_size); >@@ -442,7 +494,10 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > TALLOC_FREE(sec_vt); > > if (flags & NDR_OUT) { >- status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, &f->out_pipes); >+ status = ndrdump_pull_and_print_pipes(format, >+ ndr_pull, >+ ndr_print, >+ &f->out_pipes); > if (!NT_STATUS_IS_OK(status)) { > printf("dump FAILED\n"); > exit(1); >@@ -472,7 +527,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > ndrdump_data(blob.data, blob.length, dumpdata); > } > >- f->ndr_print(ndr_print, function, flags, st); >+ f->ndr_print(ndr_print, format, flags, st); > > if (!NT_STATUS_IS_OK(status)) { > printf("dump FAILED\n"); >@@ -480,7 +535,10 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > } > > if (flags & NDR_IN) { >- status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, &f->in_pipes); >+ status = ndrdump_pull_and_print_pipes(format, >+ ndr_pull, >+ ndr_print, >+ &f->in_pipes); > if (!NT_STATUS_IS_OK(status)) { > printf("dump FAILED\n"); > exit(1); >@@ -554,7 +612,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > ndr_v_print = talloc_zero(mem_ctx, struct ndr_print); > ndr_v_print->print = ndr_print_debug_helper; > ndr_v_print->depth = 1; >- f->ndr_print(ndr_v_print, function, flags, v_st); >+ f->ndr_print(ndr_v_print, >+ format, >+ flags, v_st); > > if (blob.length != v_blob.length) { > printf("WARNING! orig bytes:%llu validated pushed bytes:%llu\n", >diff --git a/selftest/knownfail.d/ndrdump b/selftest/knownfail.d/ndrdump >deleted file mode 100644 >index 9f7335f5d0b..00000000000 >--- a/selftest/knownfail.d/ndrdump >+++ /dev/null >@@ -1 +0,0 @@ >-^samba.tests.blackbox.ndrdump.samba.tests.blackbox.ndrdump.NdrDumpTests.test_ndrdump_with_hex_struct_name\(none\) >-- >2.25.1 > > >From 4a8eeffaf9e1a01e340d0c80070ad49b4a26022c Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Sat, 15 Feb 2020 18:33:33 +0100 >Subject: [PATCH 019/686] python/tests/krb5: add crypto.py from greghudson/pyk5 > as kcrypto.py > >This is crypto.py of commit f0612aa908062fb239d1c3873595e7204ae1691d >from https://github.com/greghudson/pyk5.git > >This will be used in order to do raw protocol testing against >[MS-KILE] KDCs. > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Isaac Boukris <iboukris@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 679bb52c957dafcec96ff37f87d8c3496996b909) >--- > python/samba/tests/krb5/kcrypto.py | 713 +++++++++++++++++++++++++++++ > python/samba/tests/source.py | 6 + > python/samba/tests/usage.py | 4 +- > 3 files changed, 722 insertions(+), 1 deletion(-) > create mode 100644 python/samba/tests/krb5/kcrypto.py > >diff --git a/python/samba/tests/krb5/kcrypto.py b/python/samba/tests/krb5/kcrypto.py >new file mode 100644 >index 00000000000..18c0f71c24c >--- /dev/null >+++ b/python/samba/tests/krb5/kcrypto.py >@@ -0,0 +1,713 @@ >+# Copyright (C) 2013 by the Massachusetts Institute of Technology. >+# All rights reserved. >+# >+# Redistribution and use in source and binary forms, with or without >+# modification, are permitted provided that the following conditions >+# are met: >+# >+# * Redistributions of source code must retain the above copyright >+# notice, this list of conditions and the following disclaimer. >+# >+# * Redistributions in binary form must reproduce the above copyright >+# notice, this list of conditions and the following disclaimer in >+# the documentation and/or other materials provided with the >+# distribution. >+# >+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT >+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS >+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE >+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, >+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR >+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, >+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED >+# OF THE POSSIBILITY OF SUCH DAMAGE. >+ >+# XXX current status: >+# * Done and tested >+# - AES encryption, checksum, string2key, prf >+# - cf2 (needed for FAST) >+# * Still to do: >+# - DES enctypes and cksumtypes >+# - RC4 exported enctype (if we need it for anything) >+# - Unkeyed checksums >+# - Special RC4, raw DES/DES3 operations for GSSAPI >+# * Difficult or low priority: >+# - Camellia not supported by PyCrypto >+# - Cipher state only needed for kcmd suite >+# - Nonstandard enctypes and cksumtypes like des-hmac-sha1 >+ >+from math import gcd >+from functools import reduce >+from struct import pack, unpack >+from Crypto.Cipher import AES, DES3, ARC4 >+from Crypto.Hash import HMAC, MD4, MD5, SHA >+from Crypto.Protocol.KDF import PBKDF2 >+from Crypto.Random import get_random_bytes >+ >+ >+class Enctype(object): >+ DES_CRC = 1 >+ DES_MD4 = 2 >+ DES_MD5 = 3 >+ DES3 = 16 >+ AES128 = 17 >+ AES256 = 18 >+ RC4 = 23 >+ >+ >+class Cksumtype(object): >+ CRC32 = 1 >+ MD4 = 2 >+ MD4_DES = 3 >+ MD5 = 7 >+ MD5_DES = 8 >+ SHA1 = 9 >+ SHA1_DES3 = 12 >+ SHA1_AES128 = 15 >+ SHA1_AES256 = 16 >+ HMAC_MD5 = -138 >+ >+ >+class InvalidChecksum(ValueError): >+ pass >+ >+ >+def _zeropad(s, padsize): >+ # Return s padded with 0 bytes to a multiple of padsize. >+ padlen = (padsize - (len(s) % padsize)) % padsize >+ return s + bytes(padlen) >+ >+ >+def _xorbytes(b1, b2): >+ # xor two strings together and return the resulting string. >+ assert len(b1) == len(b2) >+ return bytes([x ^ y for x, y in zip(b1, b2)]) >+ >+ >+def _mac_equal(mac1, mac2): >+ # Constant-time comparison function. (We can't use HMAC.verify >+ # since we use truncated macs.) >+ assert len(mac1) == len(mac2) >+ res = 0 >+ for x, y in zip(mac1, mac2): >+ res |= x ^ y >+ return res == 0 >+ >+ >+def _nfold(str, nbytes): >+ # Convert str to a string of length nbytes using the RFC 3961 nfold >+ # operation. >+ >+ # Rotate the bytes in str to the right by nbits bits. >+ def rotate_right(str, nbits): >+ nbytes, remain = (nbits//8) % len(str), nbits % 8 >+ return bytes([(str[i-nbytes] >> remain) | >+ (str[i-nbytes-1] << (8-remain) & 0xff) >+ for i in range(len(str))]) >+ >+ # Add equal-length strings together with end-around carry. >+ def add_ones_complement(str1, str2): >+ n = len(str1) >+ v = [a + b for a, b in zip(str1, str2)] >+ # Propagate carry bits to the left until there aren't any left. >+ while any(x & ~0xff for x in v): >+ v = [(v[i-n+1]>>8) + (v[i]&0xff) for i in range(n)] >+ return bytes([x for x in v]) >+ >+ # Concatenate copies of str to produce the least common multiple >+ # of len(str) and nbytes, rotating each copy of str to the right >+ # by 13 bits times its list position. Decompose the concatenation >+ # into slices of length nbytes, and add them together as >+ # big-endian ones' complement integers. >+ slen = len(str) >+ lcm = nbytes * slen // gcd(nbytes, slen) >+ bigstr = b''.join((rotate_right(str, 13 * i) for i in range(lcm // slen))) >+ slices = (bigstr[p:p+nbytes] for p in range(0, lcm, nbytes)) >+ return reduce(add_ones_complement, slices) >+ >+ >+def _is_weak_des_key(keybytes): >+ return keybytes in (b'\x01\x01\x01\x01\x01\x01\x01\x01', >+ b'\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE', >+ b'\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E', >+ b'\xE0\xE0\xE0\xE0\xF1\xF1\xF1\xF1', >+ b'\x01\xFE\x01\xFE\x01\xFE\x01\xFE', >+ b'\xFE\x01\xFE\x01\xFE\x01\xFE\x01', >+ b'\x1F\xE0\x1F\xE0\x0E\xF1\x0E\xF1', >+ b'\xE0\x1F\xE0\x1F\xF1\x0E\xF1\x0E', >+ b'\x01\xE0\x01\xE0\x01\xF1\x01\xF1', >+ b'\xE0\x01\xE0\x01\xF1\x01\xF1\x01', >+ b'\x1F\xFE\x1F\xFE\x0E\xFE\x0E\xFE', >+ b'\xFE\x1F\xFE\x1F\xFE\x0E\xFE\x0E', >+ b'\x01\x1F\x01\x1F\x01\x0E\x01\x0E', >+ b'\x1F\x01\x1F\x01\x0E\x01\x0E\x01', >+ b'\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE', >+ b'\xFE\xE0\xFE\xE0\xFE\xF1\xFE\xF1') >+ >+ >+class _EnctypeProfile(object): >+ # Base class for enctype profiles. Usable enctype classes must define: >+ # * enctype: enctype number >+ # * keysize: protocol size of key in bytes >+ # * seedsize: random_to_key input size in bytes >+ # * random_to_key (if the keyspace is not dense) >+ # * string_to_key >+ # * encrypt >+ # * decrypt >+ # * prf >+ >+ @classmethod >+ def random_to_key(cls, seed): >+ if len(seed) != cls.seedsize: >+ raise ValueError('Wrong seed length') >+ return Key(cls.enctype, seed) >+ >+ >+class _SimplifiedEnctype(_EnctypeProfile): >+ # Base class for enctypes using the RFC 3961 simplified profile. >+ # Defines the encrypt, decrypt, and prf methods. Subclasses must >+ # define: >+ # * blocksize: Underlying cipher block size in bytes >+ # * padsize: Underlying cipher padding multiple (1 or blocksize) >+ # * macsize: Size of integrity MAC in bytes >+ # * hashmod: PyCrypto hash module for underlying hash function >+ # * basic_encrypt, basic_decrypt: Underlying CBC/CTS cipher >+ >+ @classmethod >+ def derive(cls, key, constant): >+ # RFC 3961 only says to n-fold the constant only if it is >+ # shorter than the cipher block size. But all Unix >+ # implementations n-fold constants if their length is larger >+ # than the block size as well, and n-folding when the length >+ # is equal to the block size is a no-op. >+ plaintext = _nfold(constant, cls.blocksize) >+ rndseed = b'' >+ while len(rndseed) < cls.seedsize: >+ ciphertext = cls.basic_encrypt(key, plaintext) >+ rndseed += ciphertext >+ plaintext = ciphertext >+ return cls.random_to_key(rndseed[0:cls.seedsize]) >+ >+ @classmethod >+ def encrypt(cls, key, keyusage, plaintext, confounder): >+ ki = cls.derive(key, pack('>iB', keyusage, 0x55)) >+ ke = cls.derive(key, pack('>iB', keyusage, 0xAA)) >+ if confounder is None: >+ confounder = get_random_bytes(cls.blocksize) >+ basic_plaintext = confounder + _zeropad(plaintext, cls.padsize) >+ hmac = HMAC.new(ki.contents, basic_plaintext, cls.hashmod).digest() >+ return cls.basic_encrypt(ke, basic_plaintext) + hmac[:cls.macsize] >+ >+ @classmethod >+ def decrypt(cls, key, keyusage, ciphertext): >+ ki = cls.derive(key, pack('>iB', keyusage, 0x55)) >+ ke = cls.derive(key, pack('>iB', keyusage, 0xAA)) >+ if len(ciphertext) < cls.blocksize + cls.macsize: >+ raise ValueError('ciphertext too short') >+ basic_ctext, mac = ciphertext[:-cls.macsize], ciphertext[-cls.macsize:] >+ if len(basic_ctext) % cls.padsize != 0: >+ raise ValueError('ciphertext does not meet padding requirement') >+ basic_plaintext = cls.basic_decrypt(ke, basic_ctext) >+ hmac = HMAC.new(ki.contents, basic_plaintext, cls.hashmod).digest() >+ expmac = hmac[:cls.macsize] >+ if not _mac_equal(mac, expmac): >+ raise InvalidChecksum('ciphertext integrity failure') >+ # Discard the confounder. >+ return basic_plaintext[cls.blocksize:] >+ >+ @classmethod >+ def prf(cls, key, string): >+ # Hash the input. RFC 3961 says to truncate to the padding >+ # size, but implementations truncate to the block size. >+ hashval = cls.hashmod.new(string).digest() >+ truncated = hashval[:-(len(hashval) % cls.blocksize)] >+ # Encrypt the hash with a derived key. >+ kp = cls.derive(key, b'prf') >+ return cls.basic_encrypt(kp, truncated) >+ >+ >+class _DES3CBC(_SimplifiedEnctype): >+ enctype = Enctype.DES3 >+ keysize = 24 >+ seedsize = 21 >+ blocksize = 8 >+ padsize = 8 >+ macsize = 20 >+ hashmod = SHA >+ >+ @classmethod >+ def random_to_key(cls, seed): >+ # XXX Maybe reframe as _DESEnctype.random_to_key and use that >+ # way from DES3 random-to-key when DES is implemented, since >+ # MIT does this instead of the RFC 3961 random-to-key. >+ def expand(seed): >+ def parity(b): >+ # Return b with the low-order bit set to yield odd parity. >+ b &= ~1 >+ return b if bin(b & ~1).count('1') % 2 else b | 1 >+ assert len(seed) == 7 >+ firstbytes = [parity(b & ~1) for b in seed] >+ lastbyte = parity(sum((seed[i]&1) << i+1 for i in range(7))) >+ keybytes = bytes([b for b in firstbytes + [lastbyte]]) >+ if _is_weak_des_key(keybytes): >+ keybytes[7] = bytes([keybytes[7] ^ 0xF0]) >+ return keybytes >+ >+ if len(seed) != 21: >+ raise ValueError('Wrong seed length') >+ k1, k2, k3 = expand(seed[:7]), expand(seed[7:14]), expand(seed[14:]) >+ return Key(cls.enctype, k1 + k2 + k3) >+ >+ @classmethod >+ def string_to_key(cls, string, salt, params): >+ if params is not None and params != b'': >+ raise ValueError('Invalid DES3 string-to-key parameters') >+ k = cls.random_to_key(_nfold(string + salt, 21)) >+ return cls.derive(k, b'kerberos') >+ >+ @classmethod >+ def basic_encrypt(cls, key, plaintext): >+ assert len(plaintext) % 8 == 0 >+ des3 = DES3.new(key.contents, AES.MODE_CBC, bytes(8)) >+ return des3.encrypt(plaintext) >+ >+ @classmethod >+ def basic_decrypt(cls, key, ciphertext): >+ assert len(ciphertext) % 8 == 0 >+ des3 = DES3.new(key.contents, AES.MODE_CBC, bytes(8)) >+ return des3.decrypt(ciphertext) >+ >+ >+class _AESEnctype(_SimplifiedEnctype): >+ # Base class for aes128-cts and aes256-cts. >+ blocksize = 16 >+ padsize = 1 >+ macsize = 12 >+ hashmod = SHA >+ >+ @classmethod >+ def string_to_key(cls, string, salt, params): >+ (iterations,) = unpack('>L', params or b'\x00\x00\x10\x00') >+ prf = lambda p, s: HMAC.new(p, s, SHA).digest() >+ seed = PBKDF2(string, salt, cls.seedsize, iterations, prf) >+ tkey = cls.random_to_key(seed) >+ return cls.derive(tkey, b'kerberos') >+ >+ @classmethod >+ def basic_encrypt(cls, key, plaintext): >+ assert len(plaintext) >= 16 >+ aes = AES.new(key.contents, AES.MODE_CBC, bytes(16)) >+ ctext = aes.encrypt(_zeropad(plaintext, 16)) >+ if len(plaintext) > 16: >+ # Swap the last two ciphertext blocks and truncate the >+ # final block to match the plaintext length. >+ lastlen = len(plaintext) % 16 or 16 >+ ctext = ctext[:-32] + ctext[-16:] + ctext[-32:-16][:lastlen] >+ return ctext >+ >+ @classmethod >+ def basic_decrypt(cls, key, ciphertext): >+ assert len(ciphertext) >= 16 >+ aes = AES.new(key.contents, AES.MODE_ECB) >+ if len(ciphertext) == 16: >+ return aes.decrypt(ciphertext) >+ # Split the ciphertext into blocks. The last block may be partial. >+ cblocks = [ciphertext[p:p+16] for p in range(0, len(ciphertext), 16)] >+ lastlen = len(cblocks[-1]) >+ # CBC-decrypt all but the last two blocks. >+ prev_cblock = bytes(16) >+ plaintext = b'' >+ for b in cblocks[:-2]: >+ plaintext += _xorbytes(aes.decrypt(b), prev_cblock) >+ prev_cblock = b >+ # Decrypt the second-to-last cipher block. The left side of >+ # the decrypted block will be the final block of plaintext >+ # xor'd with the final partial cipher block; the right side >+ # will be the omitted bytes of ciphertext from the final >+ # block. >+ b = aes.decrypt(cblocks[-2]) >+ lastplaintext =_xorbytes(b[:lastlen], cblocks[-1]) >+ omitted = b[lastlen:] >+ # Decrypt the final cipher block plus the omitted bytes to get >+ # the second-to-last plaintext block. >+ plaintext += _xorbytes(aes.decrypt(cblocks[-1] + omitted), prev_cblock) >+ return plaintext + lastplaintext >+ >+ >+class _AES128CTS(_AESEnctype): >+ enctype = Enctype.AES128 >+ keysize = 16 >+ seedsize = 16 >+ >+ >+class _AES256CTS(_AESEnctype): >+ enctype = Enctype.AES256 >+ keysize = 32 >+ seedsize = 32 >+ >+ >+class _RC4(_EnctypeProfile): >+ enctype = Enctype.RC4 >+ keysize = 16 >+ seedsize = 16 >+ >+ @staticmethod >+ def usage_str(keyusage): >+ # Return a four-byte string for an RFC 3961 keyusage, using >+ # the RFC 4757 rules. Per the errata, do not map 9 to 8. >+ table = {3: 8, 23: 13} >+ msusage = table[keyusage] if keyusage in table else keyusage >+ return pack('<i', msusage) >+ >+ @classmethod >+ def string_to_key(cls, string, salt, params): >+ utf16string = string.decode('UTF-8').encode('UTF-16LE') >+ return Key(cls.enctype, MD4.new(utf16string).digest()) >+ >+ @classmethod >+ def encrypt(cls, key, keyusage, plaintext, confounder): >+ if confounder is None: >+ confounder = get_random_bytes(8) >+ ki = HMAC.new(key.contents, cls.usage_str(keyusage), MD5).digest() >+ cksum = HMAC.new(ki, confounder + plaintext, MD5).digest() >+ ke = HMAC.new(ki, cksum, MD5).digest() >+ return cksum + ARC4.new(ke).encrypt(confounder + plaintext) >+ >+ @classmethod >+ def decrypt(cls, key, keyusage, ciphertext): >+ if len(ciphertext) < 24: >+ raise ValueError('ciphertext too short') >+ cksum, basic_ctext = ciphertext[:16], ciphertext[16:] >+ ki = HMAC.new(key.contents, cls.usage_str(keyusage), MD5).digest() >+ ke = HMAC.new(ki, cksum, MD5).digest() >+ basic_plaintext = ARC4.new(ke).decrypt(basic_ctext) >+ exp_cksum = HMAC.new(ki, basic_plaintext, MD5).digest() >+ ok = _mac_equal(cksum, exp_cksum) >+ if not ok and keyusage == 9: >+ # Try again with usage 8, due to RFC 4757 errata. >+ ki = HMAC.new(key.contents, pack('<i', 8), MD5).digest() >+ exp_cksum = HMAC.new(ki, basic_plaintext, MD5).digest() >+ ok = _mac_equal(cksum, exp_cksum) >+ if not ok: >+ raise InvalidChecksum('ciphertext integrity failure') >+ # Discard the confounder. >+ return basic_plaintext[8:] >+ >+ @classmethod >+ def prf(cls, key, string): >+ return HMAC.new(key.contents, string, SHA).digest() >+ >+ >+class _ChecksumProfile(object): >+ # Base class for checksum profiles. Usable checksum classes must >+ # define: >+ # * checksum >+ # * verify (if verification is not just checksum-and-compare) >+ @classmethod >+ def verify(cls, key, keyusage, text, cksum): >+ expected = cls.checksum(key, keyusage, text) >+ if not _mac_equal(cksum, expected): >+ raise InvalidChecksum('checksum verification failure') >+ >+ >+class _SimplifiedChecksum(_ChecksumProfile): >+ # Base class for checksums using the RFC 3961 simplified profile. >+ # Defines the checksum and verify methods. Subclasses must >+ # define: >+ # * macsize: Size of checksum in bytes >+ # * enc: Profile of associated enctype >+ >+ @classmethod >+ def checksum(cls, key, keyusage, text): >+ kc = cls.enc.derive(key, pack('>iB', keyusage, 0x99)) >+ hmac = HMAC.new(kc.contents, text, cls.enc.hashmod).digest() >+ return hmac[:cls.macsize] >+ >+ @classmethod >+ def verify(cls, key, keyusage, text, cksum): >+ if key.enctype != cls.enc.enctype: >+ raise ValueError('Wrong key type for checksum') >+ super(_SimplifiedChecksum, cls).verify(key, keyusage, text, cksum) >+ >+ >+class _SHA1AES128(_SimplifiedChecksum): >+ macsize = 12 >+ enc = _AES128CTS >+ >+ >+class _SHA1AES256(_SimplifiedChecksum): >+ macsize = 12 >+ enc = _AES256CTS >+ >+ >+class _SHA1DES3(_SimplifiedChecksum): >+ macsize = 20 >+ enc = _DES3CBC >+ >+ >+class _HMACMD5(_ChecksumProfile): >+ @classmethod >+ def checksum(cls, key, keyusage, text): >+ ksign = HMAC.new(key.contents, b'signaturekey\0', MD5).digest() >+ md5hash = MD5.new(_RC4.usage_str(keyusage) + text).digest() >+ return HMAC.new(ksign, md5hash, MD5).digest() >+ >+ @classmethod >+ def verify(cls, key, keyusage, text, cksum): >+ if key.enctype != Enctype.RC4: >+ raise ValueError('Wrong key type for checksum') >+ super(_HMACMD5, cls).verify(key, keyusage, text, cksum) >+ >+ >+_enctype_table = { >+ Enctype.DES3: _DES3CBC, >+ Enctype.AES128: _AES128CTS, >+ Enctype.AES256: _AES256CTS, >+ Enctype.RC4: _RC4 >+} >+ >+ >+_checksum_table = { >+ Cksumtype.SHA1_DES3: _SHA1DES3, >+ Cksumtype.SHA1_AES128: _SHA1AES128, >+ Cksumtype.SHA1_AES256: _SHA1AES256, >+ Cksumtype.HMAC_MD5: _HMACMD5 >+} >+ >+ >+def _get_enctype_profile(enctype): >+ if enctype not in _enctype_table: >+ raise ValueError('Invalid enctype %d' % enctype) >+ return _enctype_table[enctype] >+ >+ >+def _get_checksum_profile(cksumtype): >+ if cksumtype not in _checksum_table: >+ raise ValueError('Invalid cksumtype %d' % cksumtype) >+ return _checksum_table[cksumtype] >+ >+ >+class Key(object): >+ def __init__(self, enctype, contents): >+ e = _get_enctype_profile(enctype) >+ if len(contents) != e.keysize: >+ raise ValueError('Wrong key length') >+ self.enctype = enctype >+ self.contents = contents >+ >+ >+def seedsize(enctype): >+ e = _get_enctype_profile(enctype) >+ return e.seedsize >+ >+ >+def random_to_key(enctype, seed): >+ e = _get_enctype_profile(enctype) >+ if len(seed) != e.seedsize: >+ raise ValueError('Wrong crypto seed length') >+ return e.random_to_key(seed) >+ >+ >+def string_to_key(enctype, string, salt, params=None): >+ e = _get_enctype_profile(enctype) >+ return e.string_to_key(string, salt, params) >+ >+ >+def encrypt(key, keyusage, plaintext, confounder=None): >+ e = _get_enctype_profile(key.enctype) >+ return e.encrypt(key, keyusage, plaintext, confounder) >+ >+ >+def decrypt(key, keyusage, ciphertext): >+ # Throw InvalidChecksum on checksum failure. Throw ValueError on >+ # invalid key enctype or malformed ciphertext. >+ e = _get_enctype_profile(key.enctype) >+ return e.decrypt(key, keyusage, ciphertext) >+ >+ >+def prf(key, string): >+ e = _get_enctype_profile(key.enctype) >+ return e.prf(key, string) >+ >+ >+def make_checksum(cksumtype, key, keyusage, text): >+ c = _get_checksum_profile(cksumtype) >+ return c.checksum(key, keyusage, text) >+ >+ >+def verify_checksum(cksumtype, key, keyusage, text, cksum): >+ # Throw InvalidChecksum exception on checksum failure. Throw >+ # ValueError on invalid cksumtype, invalid key enctype, or >+ # malformed checksum. >+ c = _get_checksum_profile(cksumtype) >+ c.verify(key, keyusage, text, cksum) >+ >+ >+def prfplus(key, pepper, l): >+ # Produce l bytes of output using the RFC 6113 PRF+ function. >+ out = b'' >+ count = 1 >+ while len(out) < l: >+ out += prf(key, bytes([count]) + pepper) >+ count += 1 >+ return out[:l] >+ >+ >+def cf2(enctype, key1, key2, pepper1, pepper2): >+ # Combine two keys and two pepper strings to produce a result key >+ # of type enctype, using the RFC 6113 KRB-FX-CF2 function. >+ e = _get_enctype_profile(enctype) >+ return e.random_to_key(_xorbytes(prfplus(key1, pepper1, e.seedsize), >+ prfplus(key2, pepper2, e.seedsize))) >+ >+ >+if __name__ == '__main__': >+ def h(hexstr): >+ return bytes.fromhex(hexstr) >+ >+ # AES128 encrypt and decrypt >+ kb = h('9062430C8CDA3388922E6D6A509F5B7A') >+ conf = h('94B491F481485B9A0678CD3C4EA386AD') >+ keyusage = 2 >+ plain = b'9 bytesss' >+ ctxt = h('68FB9679601F45C78857B2BF820FD6E53ECA8D42FD4B1D7024A09205ABB7CD2E' >+ 'C26C355D2F') >+ k = Key(Enctype.AES128, kb) >+ assert(encrypt(k, keyusage, plain, conf) == ctxt) >+ assert(decrypt(k, keyusage, ctxt) == plain) >+ >+ # AES256 encrypt and decrypt >+ kb = h('F1C795E9248A09338D82C3F8D5B567040B0110736845041347235B1404231398') >+ conf = h('E45CA518B42E266AD98E165E706FFB60') >+ keyusage = 4 >+ plain = b'30 bytes bytes bytes bytes byt' >+ ctxt = h('D1137A4D634CFECE924DBC3BF6790648BD5CFF7DE0E7B99460211D0DAEF3D79A' >+ '295C688858F3B34B9CBD6EEBAE81DAF6B734D4D498B6714F1C1D') >+ k = Key(Enctype.AES256, kb) >+ assert(encrypt(k, keyusage, plain, conf) == ctxt) >+ assert(decrypt(k, keyusage, ctxt) == plain) >+ >+ # AES128 checksum >+ kb = h('9062430C8CDA3388922E6D6A509F5B7A') >+ keyusage = 3 >+ plain = b'eight nine ten eleven twelve thirteen' >+ cksum = h('01A4B088D45628F6946614E3') >+ k = Key(Enctype.AES128, kb) >+ verify_checksum(Cksumtype.SHA1_AES128, k, keyusage, plain, cksum) >+ >+ # AES256 checksum >+ kb = h('B1AE4CD8462AFF1677053CC9279AAC30B796FB81CE21474DD3DDBCFEA4EC76D7') >+ keyusage = 4 >+ plain = b'fourteen' >+ cksum = h('E08739E3279E2903EC8E3836') >+ k = Key(Enctype.AES256, kb) >+ verify_checksum(Cksumtype.SHA1_AES256, k, keyusage, plain, cksum) >+ >+ # AES128 string-to-key >+ string = b'password' >+ salt = b'ATHENA.MIT.EDUraeburn' >+ params = h('00000002') >+ kb = h('C651BF29E2300AC27FA469D693BDDA13') >+ k = string_to_key(Enctype.AES128, string, salt, params) >+ assert(k.contents == kb) >+ >+ # AES256 string-to-key >+ string = b'X' * 64 >+ salt = b'pass phrase equals block size' >+ params = h('000004B0') >+ kb = h('89ADEE3608DB8BC71F1BFBFE459486B05618B70CBAE22092534E56C553BA4B34') >+ k = string_to_key(Enctype.AES256, string, salt, params) >+ assert(k.contents == kb) >+ >+ # AES128 prf >+ kb = h('77B39A37A868920F2A51F9DD150C5717') >+ k = string_to_key(Enctype.AES128, b'key1', b'key1') >+ assert(prf(k, b'\x01\x61') == kb) >+ >+ # AES256 prf >+ kb = h('0D674DD0F9A6806525A4D92E828BD15A') >+ k = string_to_key(Enctype.AES256, b'key2', b'key2') >+ assert(prf(k, b'\x02\x62') == kb) >+ >+ # AES128 cf2 >+ kb = h('97DF97E4B798B29EB31ED7280287A92A') >+ k1 = string_to_key(Enctype.AES128, b'key1', b'key1') >+ k2 = string_to_key(Enctype.AES128, b'key2', b'key2') >+ k = cf2(Enctype.AES128, k1, k2, b'a', b'b') >+ assert(k.contents == kb) >+ >+ # AES256 cf2 >+ kb = h('4D6CA4E629785C1F01BAF55E2E548566B9617AE3A96868C337CB93B5E72B1C7B') >+ k1 = string_to_key(Enctype.AES256, b'key1', b'key1') >+ k2 = string_to_key(Enctype.AES256, b'key2', b'key2') >+ k = cf2(Enctype.AES256, k1, k2, b'a', b'b') >+ assert(k.contents == kb) >+ >+ # DES3 encrypt and decrypt >+ kb = h('0DD52094E0F41CECCB5BE510A764B35176E3981332F1E598') >+ conf = h('94690A17B2DA3C9B') >+ keyusage = 3 >+ plain = b'13 bytes byte' >+ ctxt = h('839A17081ECBAFBCDC91B88C6955DD3C4514023CF177B77BF0D0177A16F705E8' >+ '49CB7781D76A316B193F8D30') >+ k = Key(Enctype.DES3, kb) >+ assert(encrypt(k, keyusage, plain, conf) == ctxt) >+ assert(decrypt(k, keyusage, ctxt) == _zeropad(plain, 8)) >+ >+ # DES3 string-to-key >+ string = b'password' >+ salt = b'ATHENA.MIT.EDUraeburn' >+ kb = h('850BB51358548CD05E86768C313E3BFEF7511937DCF72C3E') >+ k = string_to_key(Enctype.DES3, string, salt) >+ assert(k.contents == kb) >+ >+ # DES3 checksum >+ kb = h('7A25DF8992296DCEDA0E135BC4046E2375B3C14C98FBC162') >+ keyusage = 2 >+ plain = b'six seven' >+ cksum = h('0EEFC9C3E049AABC1BA5C401677D9AB699082BB4') >+ k = Key(Enctype.DES3, kb) >+ verify_checksum(Cksumtype.SHA1_DES3, k, keyusage, plain, cksum) >+ >+ # DES3 cf2 >+ kb = h('E58F9EB643862C13AD38E529313462A7F73E62834FE54A01') >+ k1 = string_to_key(Enctype.DES3, b'key1', b'key1') >+ k2 = string_to_key(Enctype.DES3, b'key2', b'key2') >+ k = cf2(Enctype.DES3, k1, k2, b'a', b'b') >+ assert(k.contents == kb) >+ >+ # RC4 encrypt and decrypt >+ kb = h('68F263DB3FCE15D031C9EAB02D67107A') >+ conf = h('37245E73A45FBF72') >+ keyusage = 4 >+ plain = b'30 bytes bytes bytes bytes byt' >+ ctxt = h('95F9047C3AD75891C2E9B04B16566DC8B6EB9CE4231AFB2542EF87A7B5A0F260' >+ 'A99F0460508DE0CECC632D07C354124E46C5D2234EB8') >+ k = Key(Enctype.RC4, kb) >+ assert(encrypt(k, keyusage, plain, conf) == ctxt) >+ assert(decrypt(k, keyusage, ctxt) == plain) >+ >+ # RC4 string-to-key >+ string = b'foo' >+ kb = h('AC8E657F83DF82BEEA5D43BDAF7800CC') >+ k = string_to_key(Enctype.RC4, string, None) >+ assert(k.contents == kb) >+ >+ # RC4 checksum >+ kb = h('F7D3A155AF5E238A0B7A871A96BA2AB2') >+ keyusage = 6 >+ plain = b'seventeen eighteen nineteen twenty' >+ cksum = h('EB38CC97E2230F59DA4117DC5859D7EC') >+ k = Key(Enctype.RC4, kb) >+ verify_checksum(Cksumtype.HMAC_MD5, k, keyusage, plain, cksum) >+ >+ # RC4 cf2 >+ kb = h('24D7F6B6BAE4E5C00D2082C5EBAB3672') >+ k1 = string_to_key(Enctype.RC4, b'key1', b'key1') >+ k2 = string_to_key(Enctype.RC4, b'key2', b'key2') >+ k = cf2(Enctype.RC4, k1, k2, b'a', b'b') >+ assert(k.contents == kb) >diff --git a/python/samba/tests/source.py b/python/samba/tests/source.py >index 4bb652c4204..b7608b1bab3 100644 >--- a/python/samba/tests/source.py >+++ b/python/samba/tests/source.py >@@ -90,6 +90,9 @@ class TestSource(TestCase): > if "wafsamba" in fname: > # FIXME: No copyright headers in wafsamba > continue >+ if fname.endswith("python/samba/tests/krb5/kcrypto.py"): >+ # Imported from MIT testing repo >+ continue > match = copyright_re.search(text) > if not match: > incorrect.append((fname, 'no copyright line found\n')) >@@ -132,6 +135,9 @@ class TestSource(TestCase): > # Imported from subunit/testtools, which are dual > # Apache2/BSD-3. > continue >+ if fname.endswith("python/samba/tests/krb5/kcrypto.py"): >+ # Imported from MIT testing repo >+ continue > if not gpl_re.search(text): > incorrect.append(fname) > >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 30c083076ff..cebc54461b9 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -82,7 +82,8 @@ EXCLUDE_USAGE = { > 'selftest/tests.py', > 'python/samba/subunit/run.py', > 'bin/python/samba/subunit/run.py', >- 'python/samba/tests/dcerpc/raw_protocol.py' >+ 'python/samba/tests/dcerpc/raw_protocol.py', >+ 'python/samba/tests/krb5/kcrypto.py', > } > > >@@ -93,6 +94,7 @@ EXCLUDE_DIRS = { > 'bin/ab', > 'bin/python/samba/tests', > 'bin/python/samba/tests/dcerpc', >+ 'bin/python/samba/tests/krb5', > } > > >-- >2.25.1 > > >From 1e463ef49a352d92486c0018e7b77b9009cb9988 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 20 Mar 2020 12:47:39 +0100 >Subject: [PATCH 020/686] python/tests/krb5: convert kcrypto.py to > python3-cryptography and a few Samba helpers > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 8bdd37997686d4ca60584bdfda78440be8432405) >--- > python/samba/tests/krb5/kcrypto.py | 460 +++++++++++++++++------------ > 1 file changed, 273 insertions(+), 187 deletions(-) > mode change 100644 => 100755 python/samba/tests/krb5/kcrypto.py > >diff --git a/python/samba/tests/krb5/kcrypto.py b/python/samba/tests/krb5/kcrypto.py >old mode 100644 >new mode 100755 >index 18c0f71c24c..0907d881b68 >--- a/python/samba/tests/krb5/kcrypto.py >+++ b/python/samba/tests/krb5/kcrypto.py >@@ -1,3 +1,5 @@ >+#!/usr/bin/env python3 >+# > # Copyright (C) 2013 by the Massachusetts Institute of Technology. > # All rights reserved. > # >@@ -40,14 +42,26 @@ > # - Cipher state only needed for kcmd suite > # - Nonstandard enctypes and cksumtypes like des-hmac-sha1 > >+import sys >+import os >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ > from math import gcd > from functools import reduce > from struct import pack, unpack >-from Crypto.Cipher import AES, DES3, ARC4 >-from Crypto.Hash import HMAC, MD4, MD5, SHA >-from Crypto.Protocol.KDF import PBKDF2 >-from Crypto.Random import get_random_bytes >- >+from cryptography.hazmat.primitives import hashes >+from cryptography.hazmat.primitives import hmac >+from cryptography.hazmat.primitives.ciphers import algorithms as ciphers >+from cryptography.hazmat.primitives.ciphers import modes >+from cryptography.hazmat.primitives.ciphers.base import Cipher >+from cryptography.hazmat.backends import default_backend >+from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC >+from samba.tests import TestCase >+from samba.credentials import Credentials >+from samba import generate_random_bytes as get_random_bytes >+from samba.compat import get_string, get_bytes > > class Enctype(object): > DES_CRC = 1 >@@ -97,6 +111,15 @@ def _mac_equal(mac1, mac2): > res |= x ^ y > return res == 0 > >+def SIMPLE_HASH(string, algo_cls): >+ hash_ctx = hashes.Hash(algo_cls(), default_backend()) >+ hash_ctx.update(string) >+ return hash_ctx.finalize() >+ >+def HMAC_HASH(key, string, algo_cls): >+ hmac_ctx = hmac.HMAC(key, algo_cls(), default_backend()) >+ hmac_ctx.update(string) >+ return hmac_ctx.finalize() > > def _nfold(str, nbytes): > # Convert str to a string of length nbytes using the RFC 3961 nfold >@@ -199,7 +222,7 @@ class _SimplifiedEnctype(_EnctypeProfile): > if confounder is None: > confounder = get_random_bytes(cls.blocksize) > basic_plaintext = confounder + _zeropad(plaintext, cls.padsize) >- hmac = HMAC.new(ki.contents, basic_plaintext, cls.hashmod).digest() >+ hmac = HMAC_HASH(ki.contents, basic_plaintext, cls.hashalgo) > return cls.basic_encrypt(ke, basic_plaintext) + hmac[:cls.macsize] > > @classmethod >@@ -212,7 +235,7 @@ class _SimplifiedEnctype(_EnctypeProfile): > if len(basic_ctext) % cls.padsize != 0: > raise ValueError('ciphertext does not meet padding requirement') > basic_plaintext = cls.basic_decrypt(ke, basic_ctext) >- hmac = HMAC.new(ki.contents, basic_plaintext, cls.hashmod).digest() >+ hmac = HMAC_HASH(ki.contents, basic_plaintext, cls.hashalgo) > expmac = hmac[:cls.macsize] > if not _mac_equal(mac, expmac): > raise InvalidChecksum('ciphertext integrity failure') >@@ -223,7 +246,7 @@ class _SimplifiedEnctype(_EnctypeProfile): > def prf(cls, key, string): > # Hash the input. RFC 3961 says to truncate to the padding > # size, but implementations truncate to the block size. >- hashval = cls.hashmod.new(string).digest() >+ hashval = SIMPLE_HASH(string, cls.hashalgo) > truncated = hashval[:-(len(hashval) % cls.blocksize)] > # Encrypt the hash with a derived key. > kp = cls.derive(key, b'prf') >@@ -237,7 +260,7 @@ class _DES3CBC(_SimplifiedEnctype): > blocksize = 8 > padsize = 8 > macsize = 20 >- hashmod = SHA >+ hashalgo = hashes.SHA1 > > @classmethod > def random_to_key(cls, seed): >@@ -272,14 +295,20 @@ class _DES3CBC(_SimplifiedEnctype): > @classmethod > def basic_encrypt(cls, key, plaintext): > assert len(plaintext) % 8 == 0 >- des3 = DES3.new(key.contents, AES.MODE_CBC, bytes(8)) >- return des3.encrypt(plaintext) >+ algo = ciphers.TripleDES(key.contents) >+ cbc = modes.CBC(bytes(8)) >+ encryptor = Cipher(algo, cbc, default_backend()).encryptor() >+ ciphertext = encryptor.update(plaintext) >+ return ciphertext > > @classmethod > def basic_decrypt(cls, key, ciphertext): > assert len(ciphertext) % 8 == 0 >- des3 = DES3.new(key.contents, AES.MODE_CBC, bytes(8)) >- return des3.decrypt(ciphertext) >+ algo = ciphers.TripleDES(key.contents) >+ cbc = modes.CBC(bytes(8)) >+ decryptor = Cipher(algo, cbc, default_backend()).decryptor() >+ plaintext = decryptor.update(ciphertext) >+ return plaintext > > > class _AESEnctype(_SimplifiedEnctype): >@@ -287,21 +316,35 @@ class _AESEnctype(_SimplifiedEnctype): > blocksize = 16 > padsize = 1 > macsize = 12 >- hashmod = SHA >+ hashalgo = hashes.SHA1 > > @classmethod > def string_to_key(cls, string, salt, params): > (iterations,) = unpack('>L', params or b'\x00\x00\x10\x00') >- prf = lambda p, s: HMAC.new(p, s, SHA).digest() >- seed = PBKDF2(string, salt, cls.seedsize, iterations, prf) >+ pwbytes = get_bytes(string) >+ kdf = PBKDF2HMAC(algorithm=hashes.SHA1(), >+ length=cls.seedsize, >+ salt=salt, >+ iterations=iterations, >+ backend=default_backend()) >+ seed = kdf.derive(pwbytes) > tkey = cls.random_to_key(seed) > return cls.derive(tkey, b'kerberos') > > @classmethod > def basic_encrypt(cls, key, plaintext): > assert len(plaintext) >= 16 >- aes = AES.new(key.contents, AES.MODE_CBC, bytes(16)) >- ctext = aes.encrypt(_zeropad(plaintext, 16)) >+ >+ algo = ciphers.AES(key.contents) >+ cbc = modes.CBC(bytes(16)) >+ aes_ctx = Cipher(algo, cbc, default_backend()) >+ >+ def aes_encrypt(plaintext): >+ encryptor = aes_ctx.encryptor() >+ ciphertext = encryptor.update(plaintext) >+ return ciphertext >+ >+ ctext = aes_encrypt(_zeropad(plaintext, 16)) > if len(plaintext) > 16: > # Swap the last two ciphertext blocks and truncate the > # final block to match the plaintext length. >@@ -312,9 +355,18 @@ class _AESEnctype(_SimplifiedEnctype): > @classmethod > def basic_decrypt(cls, key, ciphertext): > assert len(ciphertext) >= 16 >- aes = AES.new(key.contents, AES.MODE_ECB) >+ >+ algo = ciphers.AES(key.contents) >+ cbc = modes.CBC(bytes(16)) >+ aes_ctx = Cipher(algo, cbc, default_backend()) >+ >+ def aes_decrypt(ciphertext): >+ decryptor = aes_ctx.decryptor() >+ plaintext = decryptor.update(ciphertext) >+ return plaintext >+ > if len(ciphertext) == 16: >- return aes.decrypt(ciphertext) >+ return aes_decrypt(ciphertext) > # Split the ciphertext into blocks. The last block may be partial. > cblocks = [ciphertext[p:p+16] for p in range(0, len(ciphertext), 16)] > lastlen = len(cblocks[-1]) >@@ -322,19 +374,19 @@ class _AESEnctype(_SimplifiedEnctype): > prev_cblock = bytes(16) > plaintext = b'' > for b in cblocks[:-2]: >- plaintext += _xorbytes(aes.decrypt(b), prev_cblock) >+ plaintext += _xorbytes(aes_decrypt(b), prev_cblock) > prev_cblock = b > # Decrypt the second-to-last cipher block. The left side of > # the decrypted block will be the final block of plaintext > # xor'd with the final partial cipher block; the right side > # will be the omitted bytes of ciphertext from the final > # block. >- b = aes.decrypt(cblocks[-2]) >+ b = aes_decrypt(cblocks[-2]) > lastplaintext =_xorbytes(b[:lastlen], cblocks[-1]) > omitted = b[lastlen:] > # Decrypt the final cipher block plus the omitted bytes to get > # the second-to-last plaintext block. >- plaintext += _xorbytes(aes.decrypt(cblocks[-1] + omitted), prev_cblock) >+ plaintext += _xorbytes(aes_decrypt(cblocks[-1] + omitted), prev_cblock) > return plaintext + lastplaintext > > >@@ -365,32 +417,43 @@ class _RC4(_EnctypeProfile): > > @classmethod > def string_to_key(cls, string, salt, params): >- utf16string = string.decode('UTF-8').encode('UTF-16LE') >- return Key(cls.enctype, MD4.new(utf16string).digest()) >+ utf8string = get_string(string) >+ tmp = Credentials() >+ tmp.set_anonymous() >+ tmp.set_password(utf8string) >+ nthash = tmp.get_nt_hash() >+ return Key(cls.enctype, nthash) > > @classmethod > def encrypt(cls, key, keyusage, plaintext, confounder): > if confounder is None: > confounder = get_random_bytes(8) >- ki = HMAC.new(key.contents, cls.usage_str(keyusage), MD5).digest() >- cksum = HMAC.new(ki, confounder + plaintext, MD5).digest() >- ke = HMAC.new(ki, cksum, MD5).digest() >- return cksum + ARC4.new(ke).encrypt(confounder + plaintext) >+ ki = HMAC_HASH(key.contents, cls.usage_str(keyusage), hashes.MD5) >+ cksum = HMAC_HASH(ki, confounder + plaintext, hashes.MD5) >+ ke = HMAC_HASH(ki, cksum, hashes.MD5) >+ >+ encryptor = Cipher(ciphers.ARC4(ke), None, default_backend()).encryptor() >+ ctext = encryptor.update(confounder + plaintext) >+ >+ return cksum + ctext > > @classmethod > def decrypt(cls, key, keyusage, ciphertext): > if len(ciphertext) < 24: > raise ValueError('ciphertext too short') > cksum, basic_ctext = ciphertext[:16], ciphertext[16:] >- ki = HMAC.new(key.contents, cls.usage_str(keyusage), MD5).digest() >- ke = HMAC.new(ki, cksum, MD5).digest() >- basic_plaintext = ARC4.new(ke).decrypt(basic_ctext) >- exp_cksum = HMAC.new(ki, basic_plaintext, MD5).digest() >+ ki = HMAC_HASH(key.contents, cls.usage_str(keyusage), hashes.MD5) >+ ke = HMAC_HASH(ki, cksum, hashes.MD5) >+ >+ decryptor = Cipher(ciphers.ARC4(ke), None, default_backend()).decryptor() >+ basic_plaintext = decryptor.update(basic_ctext) >+ >+ exp_cksum = HMAC_HASH(ki, basic_plaintext, hashes.MD5) > ok = _mac_equal(cksum, exp_cksum) > if not ok and keyusage == 9: > # Try again with usage 8, due to RFC 4757 errata. >- ki = HMAC.new(key.contents, pack('<i', 8), MD5).digest() >- exp_cksum = HMAC.new(ki, basic_plaintext, MD5).digest() >+ ki = HMAC_HASH(key.contents, pack('<i', 8), hashes.MD5) >+ exp_cksum = HMAC_HASH(ki, basic_plaintext, hashes.MD5) > ok = _mac_equal(cksum, exp_cksum) > if not ok: > raise InvalidChecksum('ciphertext integrity failure') >@@ -399,7 +462,7 @@ class _RC4(_EnctypeProfile): > > @classmethod > def prf(cls, key, string): >- return HMAC.new(key.contents, string, SHA).digest() >+ return HMAC_HASH(key.contents, string, hashes.SHA1) > > > class _ChecksumProfile(object): >@@ -424,7 +487,7 @@ class _SimplifiedChecksum(_ChecksumProfile): > @classmethod > def checksum(cls, key, keyusage, text): > kc = cls.enc.derive(key, pack('>iB', keyusage, 0x99)) >- hmac = HMAC.new(kc.contents, text, cls.enc.hashmod).digest() >+ hmac = HMAC_HASH(kc.contents, text, cls.enc.hashalgo) > return hmac[:cls.macsize] > > @classmethod >@@ -452,9 +515,9 @@ class _SHA1DES3(_SimplifiedChecksum): > class _HMACMD5(_ChecksumProfile): > @classmethod > def checksum(cls, key, keyusage, text): >- ksign = HMAC.new(key.contents, b'signaturekey\0', MD5).digest() >- md5hash = MD5.new(_RC4.usage_str(keyusage) + text).digest() >- return HMAC.new(ksign, md5hash, MD5).digest() >+ ksign = HMAC_HASH(key.contents, b'signaturekey\0', hashes.MD5) >+ md5hash = SIMPLE_HASH(_RC4.usage_str(keyusage) + text, hashes.MD5) >+ return HMAC_HASH(ksign, md5hash, hashes.MD5) > > @classmethod > def verify(cls, key, keyusage, text, cksum): >@@ -564,150 +627,173 @@ def cf2(enctype, key1, key2, pepper1, pepper2): > return e.random_to_key(_xorbytes(prfplus(key1, pepper1, e.seedsize), > prfplus(key2, pepper2, e.seedsize))) > >- >-if __name__ == '__main__': >- def h(hexstr): >- return bytes.fromhex(hexstr) >- >- # AES128 encrypt and decrypt >- kb = h('9062430C8CDA3388922E6D6A509F5B7A') >- conf = h('94B491F481485B9A0678CD3C4EA386AD') >- keyusage = 2 >- plain = b'9 bytesss' >- ctxt = h('68FB9679601F45C78857B2BF820FD6E53ECA8D42FD4B1D7024A09205ABB7CD2E' >- 'C26C355D2F') >- k = Key(Enctype.AES128, kb) >- assert(encrypt(k, keyusage, plain, conf) == ctxt) >- assert(decrypt(k, keyusage, ctxt) == plain) >- >- # AES256 encrypt and decrypt >- kb = h('F1C795E9248A09338D82C3F8D5B567040B0110736845041347235B1404231398') >- conf = h('E45CA518B42E266AD98E165E706FFB60') >- keyusage = 4 >- plain = b'30 bytes bytes bytes bytes byt' >- ctxt = h('D1137A4D634CFECE924DBC3BF6790648BD5CFF7DE0E7B99460211D0DAEF3D79A' >- '295C688858F3B34B9CBD6EEBAE81DAF6B734D4D498B6714F1C1D') >- k = Key(Enctype.AES256, kb) >- assert(encrypt(k, keyusage, plain, conf) == ctxt) >- assert(decrypt(k, keyusage, ctxt) == plain) >- >- # AES128 checksum >- kb = h('9062430C8CDA3388922E6D6A509F5B7A') >- keyusage = 3 >- plain = b'eight nine ten eleven twelve thirteen' >- cksum = h('01A4B088D45628F6946614E3') >- k = Key(Enctype.AES128, kb) >- verify_checksum(Cksumtype.SHA1_AES128, k, keyusage, plain, cksum) >- >- # AES256 checksum >- kb = h('B1AE4CD8462AFF1677053CC9279AAC30B796FB81CE21474DD3DDBCFEA4EC76D7') >- keyusage = 4 >- plain = b'fourteen' >- cksum = h('E08739E3279E2903EC8E3836') >- k = Key(Enctype.AES256, kb) >- verify_checksum(Cksumtype.SHA1_AES256, k, keyusage, plain, cksum) >- >- # AES128 string-to-key >- string = b'password' >- salt = b'ATHENA.MIT.EDUraeburn' >- params = h('00000002') >- kb = h('C651BF29E2300AC27FA469D693BDDA13') >- k = string_to_key(Enctype.AES128, string, salt, params) >- assert(k.contents == kb) >- >- # AES256 string-to-key >- string = b'X' * 64 >- salt = b'pass phrase equals block size' >- params = h('000004B0') >- kb = h('89ADEE3608DB8BC71F1BFBFE459486B05618B70CBAE22092534E56C553BA4B34') >- k = string_to_key(Enctype.AES256, string, salt, params) >- assert(k.contents == kb) >- >- # AES128 prf >- kb = h('77B39A37A868920F2A51F9DD150C5717') >- k = string_to_key(Enctype.AES128, b'key1', b'key1') >- assert(prf(k, b'\x01\x61') == kb) >- >- # AES256 prf >- kb = h('0D674DD0F9A6806525A4D92E828BD15A') >- k = string_to_key(Enctype.AES256, b'key2', b'key2') >- assert(prf(k, b'\x02\x62') == kb) >- >- # AES128 cf2 >- kb = h('97DF97E4B798B29EB31ED7280287A92A') >- k1 = string_to_key(Enctype.AES128, b'key1', b'key1') >- k2 = string_to_key(Enctype.AES128, b'key2', b'key2') >- k = cf2(Enctype.AES128, k1, k2, b'a', b'b') >- assert(k.contents == kb) >- >- # AES256 cf2 >- kb = h('4D6CA4E629785C1F01BAF55E2E548566B9617AE3A96868C337CB93B5E72B1C7B') >- k1 = string_to_key(Enctype.AES256, b'key1', b'key1') >- k2 = string_to_key(Enctype.AES256, b'key2', b'key2') >- k = cf2(Enctype.AES256, k1, k2, b'a', b'b') >- assert(k.contents == kb) >- >- # DES3 encrypt and decrypt >- kb = h('0DD52094E0F41CECCB5BE510A764B35176E3981332F1E598') >- conf = h('94690A17B2DA3C9B') >- keyusage = 3 >- plain = b'13 bytes byte' >- ctxt = h('839A17081ECBAFBCDC91B88C6955DD3C4514023CF177B77BF0D0177A16F705E8' >- '49CB7781D76A316B193F8D30') >- k = Key(Enctype.DES3, kb) >- assert(encrypt(k, keyusage, plain, conf) == ctxt) >- assert(decrypt(k, keyusage, ctxt) == _zeropad(plain, 8)) >- >- # DES3 string-to-key >- string = b'password' >- salt = b'ATHENA.MIT.EDUraeburn' >- kb = h('850BB51358548CD05E86768C313E3BFEF7511937DCF72C3E') >- k = string_to_key(Enctype.DES3, string, salt) >- assert(k.contents == kb) >- >- # DES3 checksum >- kb = h('7A25DF8992296DCEDA0E135BC4046E2375B3C14C98FBC162') >- keyusage = 2 >- plain = b'six seven' >- cksum = h('0EEFC9C3E049AABC1BA5C401677D9AB699082BB4') >- k = Key(Enctype.DES3, kb) >- verify_checksum(Cksumtype.SHA1_DES3, k, keyusage, plain, cksum) >- >- # DES3 cf2 >- kb = h('E58F9EB643862C13AD38E529313462A7F73E62834FE54A01') >- k1 = string_to_key(Enctype.DES3, b'key1', b'key1') >- k2 = string_to_key(Enctype.DES3, b'key2', b'key2') >- k = cf2(Enctype.DES3, k1, k2, b'a', b'b') >- assert(k.contents == kb) >- >- # RC4 encrypt and decrypt >- kb = h('68F263DB3FCE15D031C9EAB02D67107A') >- conf = h('37245E73A45FBF72') >- keyusage = 4 >- plain = b'30 bytes bytes bytes bytes byt' >- ctxt = h('95F9047C3AD75891C2E9B04B16566DC8B6EB9CE4231AFB2542EF87A7B5A0F260' >- 'A99F0460508DE0CECC632D07C354124E46C5D2234EB8') >- k = Key(Enctype.RC4, kb) >- assert(encrypt(k, keyusage, plain, conf) == ctxt) >- assert(decrypt(k, keyusage, ctxt) == plain) >- >- # RC4 string-to-key >- string = b'foo' >- kb = h('AC8E657F83DF82BEEA5D43BDAF7800CC') >- k = string_to_key(Enctype.RC4, string, None) >- assert(k.contents == kb) >- >- # RC4 checksum >- kb = h('F7D3A155AF5E238A0B7A871A96BA2AB2') >- keyusage = 6 >- plain = b'seventeen eighteen nineteen twenty' >- cksum = h('EB38CC97E2230F59DA4117DC5859D7EC') >- k = Key(Enctype.RC4, kb) >- verify_checksum(Cksumtype.HMAC_MD5, k, keyusage, plain, cksum) >- >- # RC4 cf2 >- kb = h('24D7F6B6BAE4E5C00D2082C5EBAB3672') >- k1 = string_to_key(Enctype.RC4, b'key1', b'key1') >- k2 = string_to_key(Enctype.RC4, b'key2', b'key2') >- k = cf2(Enctype.RC4, k1, k2, b'a', b'b') >- assert(k.contents == kb) >+def h(hexstr): >+ return bytes.fromhex(hexstr) >+ >+class KcrytoTest(TestCase): >+ """kcrypto Test case.""" >+ >+ def test_aes128_crypr(self): >+ # AES128 encrypt and decrypt >+ kb = h('9062430C8CDA3388922E6D6A509F5B7A') >+ conf = h('94B491F481485B9A0678CD3C4EA386AD') >+ keyusage = 2 >+ plain = b'9 bytesss' >+ ctxt = h('68FB9679601F45C78857B2BF820FD6E53ECA8D42FD4B1D7024A09205ABB7CD2E' >+ 'C26C355D2F') >+ k = Key(Enctype.AES128, kb) >+ self.assertEqual(encrypt(k, keyusage, plain, conf), ctxt) >+ self.assertEqual(decrypt(k, keyusage, ctxt), plain) >+ >+ def test_aes256_crypt(self): >+ # AES256 encrypt and decrypt >+ kb = h('F1C795E9248A09338D82C3F8D5B567040B0110736845041347235B1404231398') >+ conf = h('E45CA518B42E266AD98E165E706FFB60') >+ keyusage = 4 >+ plain = b'30 bytes bytes bytes bytes byt' >+ ctxt = h('D1137A4D634CFECE924DBC3BF6790648BD5CFF7DE0E7B99460211D0DAEF3D79A' >+ '295C688858F3B34B9CBD6EEBAE81DAF6B734D4D498B6714F1C1D') >+ k = Key(Enctype.AES256, kb) >+ self.assertEqual(encrypt(k, keyusage, plain, conf), ctxt) >+ self.assertEqual(decrypt(k, keyusage, ctxt), plain) >+ >+ def test_aes128_checksum(self): >+ # AES128 checksum >+ kb = h('9062430C8CDA3388922E6D6A509F5B7A') >+ keyusage = 3 >+ plain = b'eight nine ten eleven twelve thirteen' >+ cksum = h('01A4B088D45628F6946614E3') >+ k = Key(Enctype.AES128, kb) >+ verify_checksum(Cksumtype.SHA1_AES128, k, keyusage, plain, cksum) >+ >+ def test_aes256_checksum(self): >+ # AES256 checksum >+ kb = h('B1AE4CD8462AFF1677053CC9279AAC30B796FB81CE21474DD3DDBCFEA4EC76D7') >+ keyusage = 4 >+ plain = b'fourteen' >+ cksum = h('E08739E3279E2903EC8E3836') >+ k = Key(Enctype.AES256, kb) >+ verify_checksum(Cksumtype.SHA1_AES256, k, keyusage, plain, cksum) >+ >+ def test_aes128_string_to_key(self): >+ # AES128 string-to-key >+ string = b'password' >+ salt = b'ATHENA.MIT.EDUraeburn' >+ params = h('00000002') >+ kb = h('C651BF29E2300AC27FA469D693BDDA13') >+ k = string_to_key(Enctype.AES128, string, salt, params) >+ self.assertEqual(k.contents, kb) >+ >+ def test_aes256_string_to_key(self): >+ # AES256 string-to-key >+ string = b'X' * 64 >+ salt = b'pass phrase equals block size' >+ params = h('000004B0') >+ kb = h('89ADEE3608DB8BC71F1BFBFE459486B05618B70CBAE22092534E56C553BA4B34') >+ k = string_to_key(Enctype.AES256, string, salt, params) >+ self.assertEqual(k.contents, kb) >+ >+ def test_aes128_prf(self): >+ # AES128 prf >+ kb = h('77B39A37A868920F2A51F9DD150C5717') >+ k = string_to_key(Enctype.AES128, b'key1', b'key1') >+ self.assertEqual(prf(k, b'\x01\x61'), kb) >+ >+ def test_aes256_prf(self): >+ # AES256 prf >+ kb = h('0D674DD0F9A6806525A4D92E828BD15A') >+ k = string_to_key(Enctype.AES256, b'key2', b'key2') >+ self.assertEqual(prf(k, b'\x02\x62'), kb) >+ >+ def test_aes128_cf2(self): >+ # AES128 cf2 >+ kb = h('97DF97E4B798B29EB31ED7280287A92A') >+ k1 = string_to_key(Enctype.AES128, b'key1', b'key1') >+ k2 = string_to_key(Enctype.AES128, b'key2', b'key2') >+ k = cf2(Enctype.AES128, k1, k2, b'a', b'b') >+ self.assertEqual(k.contents, kb) >+ >+ def test_aes256_cf2(self): >+ # AES256 cf2 >+ kb = h('4D6CA4E629785C1F01BAF55E2E548566B9617AE3A96868C337CB93B5E72B1C7B') >+ k1 = string_to_key(Enctype.AES256, b'key1', b'key1') >+ k2 = string_to_key(Enctype.AES256, b'key2', b'key2') >+ k = cf2(Enctype.AES256, k1, k2, b'a', b'b') >+ self.assertEqual(k.contents, kb) >+ >+ def test_des3_crypt(self): >+ # DES3 encrypt and decrypt >+ kb = h('0DD52094E0F41CECCB5BE510A764B35176E3981332F1E598') >+ conf = h('94690A17B2DA3C9B') >+ keyusage = 3 >+ plain = b'13 bytes byte' >+ ctxt = h('839A17081ECBAFBCDC91B88C6955DD3C4514023CF177B77BF0D0177A16F705E8' >+ '49CB7781D76A316B193F8D30') >+ k = Key(Enctype.DES3, kb) >+ self.assertEqual(encrypt(k, keyusage, plain, conf), ctxt) >+ self.assertEqual(decrypt(k, keyusage, ctxt), _zeropad(plain, 8)) >+ >+ def test_des3_string_to_key(self): >+ # DES3 string-to-key >+ string = b'password' >+ salt = b'ATHENA.MIT.EDUraeburn' >+ kb = h('850BB51358548CD05E86768C313E3BFEF7511937DCF72C3E') >+ k = string_to_key(Enctype.DES3, string, salt) >+ self.assertEqual(k.contents, kb) >+ >+ def test_des3_checksum(self): >+ # DES3 checksum >+ kb = h('7A25DF8992296DCEDA0E135BC4046E2375B3C14C98FBC162') >+ keyusage = 2 >+ plain = b'six seven' >+ cksum = h('0EEFC9C3E049AABC1BA5C401677D9AB699082BB4') >+ k = Key(Enctype.DES3, kb) >+ verify_checksum(Cksumtype.SHA1_DES3, k, keyusage, plain, cksum) >+ >+ def test_des3_cf2(self): >+ # DES3 cf2 >+ kb = h('E58F9EB643862C13AD38E529313462A7F73E62834FE54A01') >+ k1 = string_to_key(Enctype.DES3, b'key1', b'key1') >+ k2 = string_to_key(Enctype.DES3, b'key2', b'key2') >+ k = cf2(Enctype.DES3, k1, k2, b'a', b'b') >+ self.assertEqual(k.contents, kb) >+ >+ def test_rc4_crypt(self): >+ # RC4 encrypt and decrypt >+ kb = h('68F263DB3FCE15D031C9EAB02D67107A') >+ conf = h('37245E73A45FBF72') >+ keyusage = 4 >+ plain = b'30 bytes bytes bytes bytes byt' >+ ctxt = h('95F9047C3AD75891C2E9B04B16566DC8B6EB9CE4231AFB2542EF87A7B5A0F260' >+ 'A99F0460508DE0CECC632D07C354124E46C5D2234EB8') >+ k = Key(Enctype.RC4, kb) >+ self.assertEqual(encrypt(k, keyusage, plain, conf), ctxt) >+ self.assertEqual(decrypt(k, keyusage, ctxt), plain) >+ >+ def test_rc4_string_to_key(self): >+ # RC4 string-to-key >+ string = b'foo' >+ kb = h('AC8E657F83DF82BEEA5D43BDAF7800CC') >+ k = string_to_key(Enctype.RC4, string, None) >+ self.assertEqual(k.contents, kb) >+ >+ def test_rc4_checksum(self): >+ # RC4 checksum >+ kb = h('F7D3A155AF5E238A0B7A871A96BA2AB2') >+ keyusage = 6 >+ plain = b'seventeen eighteen nineteen twenty' >+ cksum = h('EB38CC97E2230F59DA4117DC5859D7EC') >+ k = Key(Enctype.RC4, kb) >+ verify_checksum(Cksumtype.HMAC_MD5, k, keyusage, plain, cksum) >+ >+ def test_rc4_cf2(self): >+ # RC4 cf2 >+ kb = h('24D7F6B6BAE4E5C00D2082C5EBAB3672') >+ k1 = string_to_key(Enctype.RC4, b'key1', b'key1') >+ k2 = string_to_key(Enctype.RC4, b'key2', b'key2') >+ k = cf2(Enctype.RC4, k1, k2, b'a', b'b') >+ self.assertEqual(k.contents, kb) >+ >+if __name__ == "__main__": >+ import unittest >+ unittest.main() >-- >2.25.1 > > >From ee3891b9bcd52030989c657f63db32cd74168367 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 25 Mar 2020 22:07:39 +0100 >Subject: [PATCH 021/686] s4:selftest: run samba.tests.krb5.kcrypto test > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 7010a1311d193c78e9f26adeafe98458217edbca) >--- > source4/selftest/tests.py | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 1561f068ca1..e627158d2f9 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -713,6 +713,8 @@ planoldpythontestsuite("nt4_dc", "samba.tests.netbios", extra_args=['-U"$USERNAM > planoldpythontestsuite("ad_dc:local", "samba.tests.gpo", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) > planoldpythontestsuite("ad_dc:local", "samba.tests.dckeytab", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) > >+planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") >+ > for env in ["ad_dc", smbv1_disabled_testenv]: > planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) > planoldpythontestsuite(env + ":local", "samba.tests.ntacls_backup", >-- >2.25.1 > > >From 092e785d1ba31b625bda4d3b1bd45b7a0d0a9d7d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 23 Mar 2020 08:53:54 +0100 >Subject: [PATCH 022/686] python/tests/krb5: add support for Cksumtype.MD5 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 47385248c8e462162e01afc3d3d68b97dff3542c) >--- > python/samba/tests/krb5/kcrypto.py | 43 +++++++++++++++++++++++++++++- > 1 file changed, 42 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kcrypto.py b/python/samba/tests/krb5/kcrypto.py >index 0907d881b68..ed3c84fa186 100755 >--- a/python/samba/tests/krb5/kcrypto.py >+++ b/python/samba/tests/krb5/kcrypto.py >@@ -526,6 +526,13 @@ class _HMACMD5(_ChecksumProfile): > super(_HMACMD5, cls).verify(key, keyusage, text, cksum) > > >+class _MD5(_ChecksumProfile): >+ @classmethod >+ def checksum(cls, key, keyusage, text): >+ # This is unkeyed! >+ return SIMPLE_HASH(text, hashes.MD5) >+ >+ > _enctype_table = { > Enctype.DES3: _DES3CBC, > Enctype.AES128: _AES128CTS, >@@ -538,7 +545,8 @@ _checksum_table = { > Cksumtype.SHA1_DES3: _SHA1DES3, > Cksumtype.SHA1_AES128: _SHA1AES128, > Cksumtype.SHA1_AES256: _SHA1AES256, >- Cksumtype.HMAC_MD5: _HMACMD5 >+ Cksumtype.HMAC_MD5: _HMACMD5, >+ Cksumtype.MD5: _MD5, > } > > >@@ -794,6 +802,39 @@ class KcrytoTest(TestCase): > k = cf2(Enctype.RC4, k1, k2, b'a', b'b') > self.assertEqual(k.contents, kb) > >+ def _test_md5_unkeyed_checksum(self, etype, usage): >+ # MD5 unkeyed checksum >+ pw = b'pwd' >+ salt = b'bytes' >+ key = string_to_key(etype, pw, salt) >+ plain = b'seventeen eighteen nineteen twenty' >+ cksum = h('9d9588cdef3a8cefc9d2c208d978f60c') >+ verify_checksum(Cksumtype.MD5, key, usage, plain, cksum) >+ >+ def test_md5_unkeyed_checksum_des3_usage_40(self): >+ return self._test_md5_unkeyed_checksum(Enctype.DES3, 40) >+ >+ def test_md5_unkeyed_checksum_des3_usage_50(self): >+ return self._test_md5_unkeyed_checksum(Enctype.DES3, 50) >+ >+ def test_md5_unkeyed_checksum_rc4_usage_40(self): >+ return self._test_md5_unkeyed_checksum(Enctype.RC4, 40) >+ >+ def test_md5_unkeyed_checksum_rc4_usage_50(self): >+ return self._test_md5_unkeyed_checksum(Enctype.RC4, 50) >+ >+ def test_md5_unkeyed_checksum_aes128_usage_40(self): >+ return self._test_md5_unkeyed_checksum(Enctype.AES128, 40) >+ >+ def test_md5_unkeyed_checksum_aes128_usage_50(self): >+ return self._test_md5_unkeyed_checksum(Enctype.AES128, 50) >+ >+ def test_md5_unkeyed_checksum_aes256_usage_40(self): >+ return self._test_md5_unkeyed_checksum(Enctype.AES256, 40) >+ >+ def test_md5_unkeyed_checksum_aes256_usage_50(self): >+ return self._test_md5_unkeyed_checksum(Enctype.AES256, 50) >+ > if __name__ == "__main__": > import unittest > unittest.main() >-- >2.25.1 > > >From 5bf5da02dbb1c2cbee4e6f083c85f8147b75217f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 13 Feb 2020 16:29:38 +0100 >Subject: [PATCH 023/686] python/tests/krb5: add rfc4120.asn1 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit a2f75c314e9946f74e9dacceac690295999925b5) >--- > python/samba/tests/krb5/rfc4120.asn1 | 392 +++++++++++++++++++++++++++ > 1 file changed, 392 insertions(+) > create mode 100644 python/samba/tests/krb5/rfc4120.asn1 > >diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 >new file mode 100644 >index 00000000000..ec44557f45a >--- /dev/null >+++ b/python/samba/tests/krb5/rfc4120.asn1 >@@ -0,0 +1,392 @@ >+KerberosV5Spec2 { >+ iso(1) identified-organization(3) dod(6) internet(1) >+ security(5) kerberosV5(2) modules(4) krb5spec2(2) >+} DEFINITIONS EXPLICIT TAGS ::= BEGIN >+ >+-- OID arc for KerberosV5 >+-- >+-- This OID may be used to identify Kerberos protocol messages >+-- encapsulated in other protocols. >+-- >+-- This OID also designates the OID arc for KerberosV5-related OIDs. >+-- >+-- NOTE: RFC 1510 had an incorrect value (5) for "dod" in its OID. >+id-krb5 OBJECT IDENTIFIER ::= { >+ iso(1) identified-organization(3) dod(6) internet(1) >+ security(5) kerberosV5(2) >+} >+ >+Int32 ::= INTEGER (-2147483648..2147483647) >+ -- signed values representable in 32 bits >+ >+UInt32 ::= INTEGER (0..4294967295) >+ -- unsigned 32 bit values >+ >+Microseconds ::= INTEGER (0..999999) >+ -- microseconds >+ >+KerberosString ::= GeneralString (IA5String) >+ >+Realm ::= KerberosString >+ >+PrincipalName ::= SEQUENCE { >+ name-type [0] Int32, >+ name-string [1] SEQUENCE OF KerberosString >+} >+ >+KerberosTime ::= GeneralizedTime -- with no fractional seconds >+ >+HostAddress ::= SEQUENCE { >+ addr-type [0] Int32, >+ address [1] OCTET STRING >+} >+ >+-- NOTE: HostAddresses is always used as an OPTIONAL field and >+-- should not be empty. >+HostAddresses -- NOTE: subtly different from rfc1510, >+ -- but has a value mapping and encodes the same >+ ::= SEQUENCE OF HostAddress >+ >+-- NOTE: AuthorizationData is always used as an OPTIONAL field and >+-- should not be empty. >+AuthorizationData ::= SEQUENCE OF SEQUENCE { >+ ad-type [0] Int32, >+ ad-data [1] OCTET STRING >+} >+ >+PA-DATA ::= SEQUENCE { >+ -- NOTE: first tag is [1], not [0] >+ padata-type [1] Int32, >+ padata-value [2] OCTET STRING -- might be encoded AP-REQ >+} >+ >+KerberosFlags ::= BIT STRING (SIZE (32..MAX)) >+ -- minimum number of bits shall be sent, >+ -- but no fewer than 32 >+ >+EncryptedData ::= SEQUENCE { >+ etype [0] Int32 -- EncryptionType --, >+ kvno [1] UInt32 OPTIONAL, >+ cipher [2] OCTET STRING -- ciphertext >+} >+ >+EncryptionKey ::= SEQUENCE { >+ keytype [0] Int32 -- actually encryption type --, >+ keyvalue [1] OCTET STRING >+} >+ >+Checksum ::= SEQUENCE { >+ cksumtype [0] Int32, >+ checksum [1] OCTET STRING >+} >+ >+Ticket ::= [APPLICATION 1] SEQUENCE { >+ tkt-vno [0] INTEGER (5), >+ realm [1] Realm, >+ sname [2] PrincipalName, >+ enc-part [3] EncryptedData -- EncTicketPart >+} >+ >+-- Encrypted part of ticket >+EncTicketPart ::= [APPLICATION 3] SEQUENCE { >+ flags [0] TicketFlags, >+ key [1] EncryptionKey, >+ crealm [2] Realm, >+ cname [3] PrincipalName, >+ transited [4] TransitedEncoding, >+ authtime [5] KerberosTime, >+ starttime [6] KerberosTime OPTIONAL, >+ endtime [7] KerberosTime, >+ renew-till [8] KerberosTime OPTIONAL, >+ caddr [9] HostAddresses OPTIONAL, >+ authorization-data [10] AuthorizationData OPTIONAL >+} >+ >+-- encoded Transited field >+TransitedEncoding ::= SEQUENCE { >+ tr-type [0] Int32 -- must be registered --, >+ contents [1] OCTET STRING >+} >+ >+TicketFlags ::= KerberosFlags >+ -- reserved(0), >+ -- forwardable(1), >+ -- forwarded(2), >+ -- proxiable(3), >+ -- proxy(4), >+ -- may-postdate(5), >+ -- postdated(6), >+ -- invalid(7), >+ -- renewable(8), >+ -- initial(9), >+ -- pre-authent(10), >+ -- hw-authent(11), >+-- the following are new since 1510 >+ -- transited-policy-checked(12), >+ -- ok-as-delegate(13) >+ >+AS-REQ ::= [APPLICATION 10] KDC-REQ >+ >+TGS-REQ ::= [APPLICATION 12] KDC-REQ >+ >+KDC-REQ ::= SEQUENCE { >+ -- NOTE: first tag is [1], not [0] >+ pvno [1] INTEGER (5) , >+ msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), >+ padata [3] SEQUENCE OF PA-DATA OPTIONAL >+ -- NOTE: not empty --, >+ req-body [4] KDC-REQ-BODY >+} >+ >+KDC-REQ-BODY ::= SEQUENCE { >+ kdc-options [0] KDCOptions, >+ cname [1] PrincipalName OPTIONAL >+ -- Used only in AS-REQ --, >+ realm [2] Realm >+ -- Server's realm >+ -- Also client's in AS-REQ --, >+ sname [3] PrincipalName OPTIONAL, >+ from [4] KerberosTime OPTIONAL, >+ till [5] KerberosTime, >+ rtime [6] KerberosTime OPTIONAL, >+ nonce [7] UInt32, >+ etype [8] SEQUENCE OF Int32 -- EncryptionType >+ -- in preference order --, >+ addresses [9] HostAddresses OPTIONAL, >+ enc-authorization-data [10] EncryptedData OPTIONAL >+ -- AuthorizationData --, >+ additional-tickets [11] SEQUENCE OF Ticket OPTIONAL >+ -- NOTE: not empty >+} >+ >+KDCOptions ::= KerberosFlags >+ -- reserved(0), >+ -- forwardable(1), >+ -- forwarded(2), >+ -- proxiable(3), >+ -- proxy(4), >+ -- allow-postdate(5), >+ -- postdated(6), >+ -- unused7(7), >+ -- renewable(8), >+ -- unused9(9), >+ -- unused10(10), >+ -- opt-hardware-auth(11), >+ -- unused12(12), >+ -- unused13(13), >+-- 15 is reserved for canonicalize >+ -- unused15(15), >+-- 26 was unused in 1510 >+ -- disable-transited-check(26), >+-- >+ -- renewable-ok(27), >+ -- enc-tkt-in-skey(28), >+ -- renew(30), >+ -- validate(31) >+ >+AS-REP ::= [APPLICATION 11] KDC-REP >+ >+TGS-REP ::= [APPLICATION 13] KDC-REP >+ >+KDC-REP ::= SEQUENCE { >+ pvno [0] INTEGER (5), >+ msg-type [1] INTEGER (11 -- AS -- | 13 -- TGS --), >+ padata [2] SEQUENCE OF PA-DATA OPTIONAL >+ -- NOTE: not empty --, >+ crealm [3] Realm, >+ cname [4] PrincipalName, >+ ticket [5] Ticket, >+ enc-part [6] EncryptedData >+ -- EncASRepPart or EncTGSRepPart, >+ -- as appropriate >+} >+ >+EncASRepPart ::= [APPLICATION 25] EncKDCRepPart >+ >+EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart >+ >+EncKDCRepPart ::= SEQUENCE { >+ key [0] EncryptionKey, >+ last-req [1] LastReq, >+ nonce [2] UInt32, >+ key-expiration [3] KerberosTime OPTIONAL, >+ flags [4] TicketFlags, >+ authtime [5] KerberosTime, >+ starttime [6] KerberosTime OPTIONAL, >+ endtime [7] KerberosTime, >+ renew-till [8] KerberosTime OPTIONAL, >+ srealm [9] Realm, >+ sname [10] PrincipalName, >+ caddr [11] HostAddresses OPTIONAL >+} >+ >+LastReq ::= SEQUENCE OF SEQUENCE { >+ lr-type [0] Int32, >+ lr-value [1] KerberosTime >+} >+ >+AP-REQ ::= [APPLICATION 14] SEQUENCE { >+ pvno [0] INTEGER (5), >+ msg-type [1] INTEGER (14), >+ ap-options [2] APOptions, >+ ticket [3] Ticket, >+ authenticator [4] EncryptedData -- Authenticator >+} >+ >+APOptions ::= KerberosFlags >+ -- reserved(0), >+ -- use-session-key(1), >+ -- mutual-required(2) >+ >+-- Unencrypted authenticator >+Authenticator ::= [APPLICATION 2] SEQUENCE { >+ authenticator-vno [0] INTEGER (5), >+ crealm [1] Realm, >+ cname [2] PrincipalName, >+ cksum [3] Checksum OPTIONAL, >+ cusec [4] Microseconds, >+ ctime [5] KerberosTime, >+ subkey [6] EncryptionKey OPTIONAL, >+ seq-number [7] UInt32 OPTIONAL, >+ authorization-data [8] AuthorizationData OPTIONAL >+} >+ >+AP-REP ::= [APPLICATION 15] SEQUENCE { >+ pvno [0] INTEGER (5), >+ msg-type [1] INTEGER (15), >+ enc-part [2] EncryptedData -- EncAPRepPart >+} >+ >+EncAPRepPart ::= [APPLICATION 27] SEQUENCE { >+ ctime [0] KerberosTime, >+ cusec [1] Microseconds, >+ subkey [2] EncryptionKey OPTIONAL, >+ seq-number [3] UInt32 OPTIONAL >+} >+ >+KRB-SAFE ::= [APPLICATION 20] SEQUENCE { >+ pvno [0] INTEGER (5), >+ msg-type [1] INTEGER (20), >+ safe-body [2] KRB-SAFE-BODY, >+ cksum [3] Checksum >+} >+ >+KRB-SAFE-BODY ::= SEQUENCE { >+ user-data [0] OCTET STRING, >+ timestamp [1] KerberosTime OPTIONAL, >+ usec [2] Microseconds OPTIONAL, >+ seq-number [3] UInt32 OPTIONAL, >+ s-address [4] HostAddress, >+ r-address [5] HostAddress OPTIONAL >+} >+ >+KRB-PRIV ::= [APPLICATION 21] SEQUENCE { >+ pvno [0] INTEGER (5), >+ msg-type [1] INTEGER (21), >+ -- NOTE: there is no [2] tag >+ enc-part [3] EncryptedData -- EncKrbPrivPart >+} >+ >+EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE { >+ user-data [0] OCTET STRING, >+ timestamp [1] KerberosTime OPTIONAL, >+ usec [2] Microseconds OPTIONAL, >+ seq-number [3] UInt32 OPTIONAL, >+ s-address [4] HostAddress -- sender's addr --, >+ r-address [5] HostAddress OPTIONAL -- recip's addr >+} >+ >+KRB-CRED ::= [APPLICATION 22] SEQUENCE { >+ pvno [0] INTEGER (5), >+ msg-type [1] INTEGER (22), >+ tickets [2] SEQUENCE OF Ticket, >+ enc-part [3] EncryptedData -- EncKrbCredPart >+} >+ >+EncKrbCredPart ::= [APPLICATION 29] SEQUENCE { >+ ticket-info [0] SEQUENCE OF KrbCredInfo, >+ nonce [1] UInt32 OPTIONAL, >+ timestamp [2] KerberosTime OPTIONAL, >+ usec [3] Microseconds OPTIONAL, >+ s-address [4] HostAddress OPTIONAL, >+ r-address [5] HostAddress OPTIONAL >+} >+ >+KrbCredInfo ::= SEQUENCE { >+ key [0] EncryptionKey, >+ prealm [1] Realm OPTIONAL, >+ pname [2] PrincipalName OPTIONAL, >+ flags [3] TicketFlags OPTIONAL, >+ authtime [4] KerberosTime OPTIONAL, >+ starttime [5] KerberosTime OPTIONAL, >+ endtime [6] KerberosTime OPTIONAL, >+ renew-till [7] KerberosTime OPTIONAL, >+ srealm [8] Realm OPTIONAL, >+ sname [9] PrincipalName OPTIONAL, >+ caddr [10] HostAddresses OPTIONAL >+} >+ >+KRB-ERROR ::= [APPLICATION 30] SEQUENCE { >+ pvno [0] INTEGER (5), >+ msg-type [1] INTEGER (30), >+ ctime [2] KerberosTime OPTIONAL, >+ cusec [3] Microseconds OPTIONAL, >+ stime [4] KerberosTime, >+ susec [5] Microseconds, >+ error-code [6] Int32, >+ crealm [7] Realm OPTIONAL, >+ cname [8] PrincipalName OPTIONAL, >+ realm [9] Realm -- service realm --, >+ sname [10] PrincipalName -- service name --, >+ e-text [11] KerberosString OPTIONAL, >+ e-data [12] OCTET STRING OPTIONAL >+} >+ >+METHOD-DATA ::= SEQUENCE OF PA-DATA >+ >+TYPED-DATA ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { >+ data-type [0] Int32, >+ data-value [1] OCTET STRING OPTIONAL >+} >+ >+-- preauth stuff follows >+ >+PA-ENC-TIMESTAMP ::= EncryptedData -- PA-ENC-TS-ENC >+ >+PA-ENC-TS-ENC ::= SEQUENCE { >+ patimestamp [0] KerberosTime -- client's time --, >+ pausec [1] Microseconds OPTIONAL >+} >+ >+ETYPE-INFO-ENTRY ::= SEQUENCE { >+ etype [0] Int32, >+ salt [1] OCTET STRING OPTIONAL >+} >+ >+ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY >+ >+ETYPE-INFO2-ENTRY ::= SEQUENCE { >+ etype [0] Int32, >+ salt [1] KerberosString OPTIONAL, >+ s2kparams [2] OCTET STRING OPTIONAL >+} >+ >+ETYPE-INFO2 ::= SEQUENCE SIZE (1..MAX) OF ETYPE-INFO2-ENTRY >+ >+AD-IF-RELEVANT ::= AuthorizationData >+ >+AD-KDCIssued ::= SEQUENCE { >+ ad-checksum [0] Checksum, >+ i-realm [1] Realm OPTIONAL, >+ i-sname [2] PrincipalName OPTIONAL, >+ elements [3] AuthorizationData >+} >+ >+AD-AND-OR ::= SEQUENCE { >+ condition-count [0] Int32, >+ elements [1] AuthorizationData >+} >+ >+AD-MANDATORY-FOR-KDC ::= AuthorizationData >+ >+END >-- >2.25.1 > > >From b7fac786dc5a7415075cb0fa589efe3099788429 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 13 Feb 2020 16:29:38 +0100 >Subject: [PATCH 024/686] python/tests/krb5: modify rfc4120.asn1 in order to > generate pyasn1 code > >The pyasn1 bindings are generated by pyasn1gen.py from >https://github.com/kimgr/asn1ate.git > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 94d068427f6cf23ab68c135ed9833db4b9155b65) >--- > python/samba/tests/krb5/rfc4120.asn1 | 293 +++++- > python/samba/tests/krb5/rfc4120_pyasn1.py | 914 ++++++++++++++++++ > .../samba/tests/krb5/rfc4120_pyasn1_regen.sh | 41 + > python/samba/tests/source.py | 6 + > 4 files changed, 1243 insertions(+), 11 deletions(-) > create mode 100644 python/samba/tests/krb5/rfc4120_pyasn1.py > create mode 100755 python/samba/tests/krb5/rfc4120_pyasn1_regen.sh > >diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 >index ec44557f45a..05b43106034 100644 >--- a/python/samba/tests/krb5/rfc4120.asn1 >+++ b/python/samba/tests/krb5/rfc4120.asn1 >@@ -25,15 +25,23 @@ UInt32 ::= INTEGER (0..4294967295) > Microseconds ::= INTEGER (0..999999) > -- microseconds > >-KerberosString ::= GeneralString (IA5String) >+-- >+-- asn1ate doesn't support 'GeneralString (IA5String)' >+-- only 'GeneralString' or 'IA5String', on the wire >+-- GeneralString is used. >+-- >+-- KerberosString ::= GeneralString (IA5String) >+KerberosString ::= GeneralString > > Realm ::= KerberosString > > PrincipalName ::= SEQUENCE { >- name-type [0] Int32, >+ name-type [0] NameType, -- Int32, > name-string [1] SEQUENCE OF KerberosString > } > >+NameType ::= Int32 >+ > KerberosTime ::= GeneralizedTime -- with no fractional seconds > > HostAddress ::= SEQUENCE { >@@ -50,36 +58,48 @@ HostAddresses -- NOTE: subtly different from rfc1510, > -- NOTE: AuthorizationData is always used as an OPTIONAL field and > -- should not be empty. > AuthorizationData ::= SEQUENCE OF SEQUENCE { >- ad-type [0] Int32, >+ ad-type [0] AuthDataType, -- Int32, > ad-data [1] OCTET STRING > } > >+AuthDataType ::= Int32 >+ > PA-DATA ::= SEQUENCE { > -- NOTE: first tag is [1], not [0] >- padata-type [1] Int32, >+ padata-type [1] PADataType, -- Int32 > padata-value [2] OCTET STRING -- might be encoded AP-REQ > } > >-KerberosFlags ::= BIT STRING (SIZE (32..MAX)) >+PADataType ::= Int32 >+ >+-- >+-- asn1ate doesn't support 'MAX' nor a lower range != 1. >+-- We'll use a custom enodeValue() hooks for BitString >+-- in order to encode them with at least 32-Bit. >+-- >+-- KerberosFlags ::= BIT STRING (SIZE (32..MAX)) >+KerberosFlags ::= BIT STRING (SIZE (1..32)) > -- minimum number of bits shall be sent, > -- but no fewer than 32 > > EncryptedData ::= SEQUENCE { >- etype [0] Int32 -- EncryptionType --, >+ etype [0] EncryptionType, --Int32 EncryptionType -- > kvno [1] UInt32 OPTIONAL, > cipher [2] OCTET STRING -- ciphertext > } > > EncryptionKey ::= SEQUENCE { >- keytype [0] Int32 -- actually encryption type --, >+ keytype [0] EncryptionType, -- Int32 actually encryption type -- > keyvalue [1] OCTET STRING > } > > Checksum ::= SEQUENCE { >- cksumtype [0] Int32, >+ cksumtype [0] ChecksumType, -- Int32, > checksum [1] OCTET STRING > } > >+ChecksumType ::= Int32 >+ > Ticket ::= [APPLICATION 1] SEQUENCE { > tkt-vno [0] INTEGER (5), > realm [1] Realm, >@@ -150,7 +170,7 @@ KDC-REQ-BODY ::= SEQUENCE { > till [5] KerberosTime, > rtime [6] KerberosTime OPTIONAL, > nonce [7] UInt32, >- etype [8] SEQUENCE OF Int32 -- EncryptionType >+ etype [8] SEQUENCE OF EncryptionType -- Int32 - EncryptionType > -- in preference order --, > addresses [9] HostAddresses OPTIONAL, > enc-authorization-data [10] EncryptedData OPTIONAL >@@ -159,6 +179,8 @@ KDC-REQ-BODY ::= SEQUENCE { > -- NOTE: not empty > } > >+EncryptionType ::= Int32 >+ > KDCOptions ::= KerberosFlags > -- reserved(0), > -- forwardable(1), >@@ -344,7 +366,11 @@ KRB-ERROR ::= [APPLICATION 30] SEQUENCE { > > METHOD-DATA ::= SEQUENCE OF PA-DATA > >-TYPED-DATA ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { >+-- >+-- asn1ate doesn't support 'MAX' >+-- >+-- TYPED-DATA ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { >+TYPED-DATA ::= SEQUENCE SIZE (1..256) OF SEQUENCE { > data-type [0] Int32, > data-value [1] OCTET STRING OPTIONAL > } >@@ -371,7 +397,7 @@ ETYPE-INFO2-ENTRY ::= SEQUENCE { > s2kparams [2] OCTET STRING OPTIONAL > } > >-ETYPE-INFO2 ::= SEQUENCE SIZE (1..MAX) OF ETYPE-INFO2-ENTRY >+ETYPE-INFO2 ::= SEQUENCE SIZE (1..256) OF ETYPE-INFO2-ENTRY > > AD-IF-RELEVANT ::= AuthorizationData > >@@ -389,4 +415,249 @@ AD-AND-OR ::= SEQUENCE { > > AD-MANDATORY-FOR-KDC ::= AuthorizationData > >+ >+ >+ >+ >+ >+-- >+-- >+-- prettyPrint values >+-- >+-- >+ >+NameTypeValues ::= INTEGER { -- Int32 >+ kRB5-NT-UNKNOWN(0), -- Name type not known >+ kRB5-NT-PRINCIPAL(1), -- Just the name of the principal as in >+ kRB5-NT-SRV-INST(2), -- Service and other unique instance (krbtgt) >+ kRB5-NT-SRV-HST(3), -- Service with host name as instance >+ kRB5-NT-SRV-XHST(4), -- Service with host as remaining components >+ kRB5-NT-UID(5), -- Unique ID >+ kRB5-NT-X500-PRINCIPAL(6), -- PKINIT >+ kRB5-NT-SMTP-NAME(7), -- Name in form of SMTP email name >+ kRB5-NT-ENTERPRISE-PRINCIPAL(10), -- Windows 2000 UPN >+ kRB5-NT-WELLKNOWN(11), -- Wellknown >+ kRB5-NT-ENT-PRINCIPAL-AND-ID(-130), -- Windows 2000 UPN and SID >+ kRB5-NT-MS-PRINCIPAL(-128), -- NT 4 style name >+ kRB5-NT-MS-PRINCIPAL-AND-ID(-129) -- NT style name and SID >+} >+NameTypeSequence ::= SEQUENCE { >+ dummy [0] NameTypeValues >+} >+ >+TicketFlagsValues ::= BIT STRING { -- KerberosFlags >+ reserved(0), >+ forwardable(1), >+ forwarded(2), >+ proxiable(3), >+ proxy(4), >+ may-postdate(5), >+ postdated(6), >+ invalid(7), >+ renewable(8), >+ initial(9), >+ pre-authent(10), >+ hw-authent(11), >+-- the following are new since 1510 >+ transited-policy-checked(12), >+ ok-as-delegate(13) >+} >+TicketFlagsSequence ::= SEQUENCE { >+ dummy [0] TicketFlagsValues >+} >+ >+KDCOptionsValues ::= BIT STRING { -- KerberosFlags >+ reserved(0), >+ forwardable(1), >+ forwarded(2), >+ proxiable(3), >+ proxy(4), >+ allow-postdate(5), >+ postdated(6), >+ unused7(7), >+ renewable(8), >+ unused9(9), >+ unused10(10), >+ opt-hardware-auth(11), >+ unused12(12), >+ unused13(13), >+-- 15 is reserved for canonicalize >+ unused15(15), >+-- 26 was unused in 1510 >+ disable-transited-check(26), >+-- >+ renewable-ok(27), >+ enc-tkt-in-skey(28), >+ renew(30), >+ validate(31) >+} >+KDCOptionsSequence ::= SEQUENCE { >+ dummy [0] KDCOptionsValues >+} >+ >+MessageTypeValues ::= INTEGER { >+ krb-as-req(10), -- Request for initial authentication >+ krb-as-rep(11), -- Response to KRB_AS_REQ request >+ krb-tgs-req(12), -- Request for authentication based on TGT >+ krb-tgs-rep(13), -- Response to KRB_TGS_REQ request >+ krb-ap-req(14), -- application request to server >+ krb-ap-rep(15), -- Response to KRB_AP_REQ_MUTUAL >+ krb-safe(20), -- Safe (checksummed) application message >+ krb-priv(21), -- Private (encrypted) application message >+ krb-cred(22), -- Private (encrypted) message to forward credentials >+ krb-error(30) -- Error response >+} >+MessageTypeSequence ::= SEQUENCE { >+ dummy [0] MessageTypeValues >+} >+ >+PADataTypeValues ::= INTEGER { >+ kRB5-PADATA-NONE(0), >+ -- kRB5-PADATA-TGS-REQ(1), >+ -- kRB5-PADATA-AP-REQ(1), >+ kRB5-PADATA-KDC-REQ(1), >+ kRB5-PADATA-ENC-TIMESTAMP(2), >+ kRB5-PADATA-PW-SALT(3), >+ kRB5-PADATA-ENC-UNIX-TIME(5), >+ kRB5-PADATA-SANDIA-SECUREID(6), >+ kRB5-PADATA-SESAME(7), >+ kRB5-PADATA-OSF-DCE(8), >+ kRB5-PADATA-CYBERSAFE-SECUREID(9), >+ kRB5-PADATA-AFS3-SALT(10), >+ kRB5-PADATA-ETYPE-INFO(11), >+ kRB5-PADATA-SAM-CHALLENGE(12), -- (sam/otp) >+ kRB5-PADATA-SAM-RESPONSE(13), -- (sam/otp) >+ kRB5-PADATA-PK-AS-REQ-19(14), -- (PKINIT-19) >+ kRB5-PADATA-PK-AS-REP-19(15), -- (PKINIT-19) >+ -- kRB5-PADATA-PK-AS-REQ-WIN(15), - (PKINIT - old number) >+ kRB5-PADATA-PK-AS-REQ(16), -- (PKINIT-25) >+ kRB5-PADATA-PK-AS-REP(17), -- (PKINIT-25) >+ kRB5-PADATA-PA-PK-OCSP-RESPONSE(18), >+ kRB5-PADATA-ETYPE-INFO2(19), >+ -- kRB5-PADATA-USE-SPECIFIED-KVNO(20), >+ kRB5-PADATA-SVR-REFERRAL-INFO(20), --- old ms referral number >+ kRB5-PADATA-SAM-REDIRECT(21), -- (sam/otp) >+ kRB5-PADATA-GET-FROM-TYPED-DATA(22), >+ kRB5-PADATA-SAM-ETYPE-INFO(23), >+ kRB5-PADATA-SERVER-REFERRAL(25), >+ kRB5-PADATA-ALT-PRINC(24), -- (crawdad@fnal.gov) >+ kRB5-PADATA-SAM-CHALLENGE2(30), -- (kenh@pobox.com) >+ kRB5-PADATA-SAM-RESPONSE2(31), -- (kenh@pobox.com) >+ kRB5-PA-EXTRA-TGT(41), -- Reserved extra TGT >+ kRB5-PADATA-TD-KRB-PRINCIPAL(102), -- PrincipalName >+ kRB5-PADATA-PK-TD-TRUSTED-CERTIFIERS(104), -- PKINIT >+ kRB5-PADATA-PK-TD-CERTIFICATE-INDEX(105), -- PKINIT >+ kRB5-PADATA-TD-APP-DEFINED-ERROR(106), -- application specific >+ kRB5-PADATA-TD-REQ-NONCE(107), -- INTEGER >+ kRB5-PADATA-TD-REQ-SEQ(108), -- INTEGER >+ kRB5-PADATA-PA-PAC-REQUEST(128), -- jbrezak@exchange.microsoft.com >+ kRB5-PADATA-FOR-USER(129), -- MS-KILE >+ kRB5-PADATA-FOR-X509-USER(130), -- MS-KILE >+ kRB5-PADATA-FOR-CHECK-DUPS(131), -- MS-KILE >+ kRB5-PADATA-AS-CHECKSUM(132), -- MS-KILE >+ -- kRB5-PADATA-PK-AS-09-BINDING(132), - client send this to >+ -- tell KDC that is supports >+ -- the asCheckSum in the >+ -- PK-AS-REP >+ kRB5-PADATA-FX-COOKIE(133), -- krb-wg-preauth-framework >+ kRB5-PADATA-AUTHENTICATION-SET(134), -- krb-wg-preauth-framework >+ kRB5-PADATA-AUTH-SET-SELECTED(135), -- krb-wg-preauth-framework >+ kRB5-PADATA-FX-FAST(136), -- krb-wg-preauth-framework >+ kRB5-PADATA-FX-ERROR(137), -- krb-wg-preauth-framework >+ kRB5-PADATA-ENCRYPTED-CHALLENGE(138), -- krb-wg-preauth-framework >+ kRB5-PADATA-OTP-CHALLENGE(141), -- (gareth.richards@rsa.com) >+ kRB5-PADATA-OTP-REQUEST(142), -- (gareth.richards@rsa.com) >+ kBB5-PADATA-OTP-CONFIRM(143), -- (gareth.richards@rsa.com) >+ kRB5-PADATA-OTP-PIN-CHANGE(144), -- (gareth.richards@rsa.com) >+ kRB5-PADATA-EPAK-AS-REQ(145), >+ kRB5-PADATA-EPAK-AS-REP(146), >+ kRB5-PADATA-PKINIT-KX(147), -- krb-wg-anon >+ kRB5-PADATA-PKU2U-NAME(148), -- zhu-pku2u >+ kRB5-PADATA-REQ-ENC-PA-REP(149), -- >+ kRB5-PADATA-SUPPORTED-ETYPES(165) -- MS-KILE >+} >+PADataTypeSequence ::= SEQUENCE { >+ dummy [0] PADataTypeValues >+} >+ >+AuthDataTypeValues ::= INTEGER { >+ kRB5-AUTHDATA-IF-RELEVANT(1), >+ kRB5-AUTHDATA-INTENDED-FOR-SERVER(2), >+ kRB5-AUTHDATA-INTENDED-FOR-APPLICATION-CLASS(3), >+ kRB5-AUTHDATA-KDC-ISSUED(4), >+ kRB5-AUTHDATA-AND-OR(5), >+ kRB5-AUTHDATA-MANDATORY-TICKET-EXTENSIONS(6), >+ kRB5-AUTHDATA-IN-TICKET-EXTENSIONS(7), >+ kRB5-AUTHDATA-MANDATORY-FOR-KDC(8), >+ kRB5-AUTHDATA-INITIAL-VERIFIED-CAS(9), >+ kRB5-AUTHDATA-OSF-DCE(64), >+ kRB5-AUTHDATA-SESAME(65), >+ kRB5-AUTHDATA-OSF-DCE-PKI-CERTID(66), >+ kRB5-AUTHDATA-WIN2K-PAC(128), >+ kRB5-AUTHDATA-GSS-API-ETYPE-NEGOTIATION(129), -- Authenticator only >+ kRB5-AUTHDATA-SIGNTICKET-OLDER(-17), >+ kRB5-AUTHDATA-SIGNTICKET-OLD(142), >+ kRB5-AUTHDATA-SIGNTICKET(512) >+} >+AuthDataTypeSequence ::= SEQUENCE { >+ dummy [0] AuthDataTypeValues >+} >+ >+ChecksumTypeValues ::= INTEGER { >+ kRB5-CKSUMTYPE-NONE(0), >+ kRB5-CKSUMTYPE-CRC32(1), >+ kRB5-CKSUMTYPE-RSA-MD4(2), >+ kRB5-CKSUMTYPE-RSA-MD4-DES(3), >+ kRB5-CKSUMTYPE-DES-MAC(4), >+ kRB5-CKSUMTYPE-DES-MAC-K(5), >+ kRB5-CKSUMTYPE-RSA-MD4-DES-K(6), >+ kRB5-CKSUMTYPE-RSA-MD5(7), >+ kRB5-CKSUMTYPE-RSA-MD5-DES(8), >+ kRB5-CKSUMTYPE-RSA-MD5-DES3(9), >+ kRB5-CKSUMTYPE-SHA1-OTHER(10), >+ kRB5-CKSUMTYPE-HMAC-SHA1-DES3(12), >+ kRB5-CKSUMTYPE-SHA1(14), >+ kRB5-CKSUMTYPE-HMAC-SHA1-96-AES-128(15), >+ kRB5-CKSUMTYPE-HMAC-SHA1-96-AES-256(16), >+ kRB5-CKSUMTYPE-GSSAPI(32771), -- 0x8003 >+ kRB5-CKSUMTYPE-HMAC-MD5(-138), -- unofficial microsoft number >+ kRB5-CKSUMTYPE-HMAC-MD5-ENC(-1138) -- even more unofficial >+} >+ChecksumTypeSequence ::= SEQUENCE { >+ dummy [0] ChecksumTypeValues >+} >+ >+EncryptionTypeValues ::= INTEGER { >+ kRB5-ENCTYPE-NULL(0), >+ kRB5-ENCTYPE-DES-CBC-CRC(1), >+ kRB5-ENCTYPE-DES-CBC-MD4(2), >+ kRB5-ENCTYPE-DES-CBC-MD5(3), >+ kRB5-ENCTYPE-DES3-CBC-MD5(5), >+ kRB5-ENCTYPE-OLD-DES3-CBC-SHA1(7), >+ kRB5-ENCTYPE-SIGN-DSA-GENERATE(8), >+ kRB5-ENCTYPE-ENCRYPT-RSA-PRIV(9), >+ kRB5-ENCTYPE-ENCRYPT-RSA-PUB(10), >+ kRB5-ENCTYPE-DES3-CBC-SHA1(16), -- with key derivation >+ kRB5-ENCTYPE-AES128-CTS-HMAC-SHA1-96(17), >+ kRB5-ENCTYPE-AES256-CTS-HMAC-SHA1-96(18), >+ kRB5-ENCTYPE-ARCFOUR-HMAC-MD5(23), >+ kRB5-ENCTYPE-ARCFOUR-HMAC-MD5-56(24), >+ kRB5-ENCTYPE-ENCTYPE-PK-CROSS(48), >+-- some "old" windows types >+ kRB5-ENCTYPE-ARCFOUR-MD4(-128), >+ kRB5-ENCTYPE-ARCFOUR-HMAC-OLD(-133), >+ kRB5-ENCTYPE-ARCFOUR-HMAC-OLD-EXP(-135), >+-- these are for Heimdal internal use >+-- kRB5-ENCTYPE-DES-CBC-NONE(-0x1000), >+-- kRB5-ENCTYPE-DES3-CBC-NONE(-0x1001), >+-- kRB5-ENCTYPE-DES-CFB64-NONE(-0x1002), >+-- kRB5-ENCTYPE-DES-PCBC-NONE(-0x1003), >+-- kRB5-ENCTYPE-DIGEST-MD5-NONE(-0x1004), - private use, lukeh@padl.com >+-- kRB5-ENCTYPE-CRAM-MD5-NONE(-0x1005) - private use, lukeh@padl.com >+ kRB5-ENCTYPE-DUMMY(-1111) >+} >+EncryptionTypeSequence ::= SEQUENCE { >+ dummy [0] EncryptionTypeValues >+} >+ > END >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1.py b/python/samba/tests/krb5/rfc4120_pyasn1.py >new file mode 100644 >index 00000000000..b2627aa3dcb >--- /dev/null >+++ b/python/samba/tests/krb5/rfc4120_pyasn1.py >@@ -0,0 +1,914 @@ >+# Auto-generated by asn1ate v.0.6.1.dev0 from rfc4120.asn1 >+# (last modified on 2020-03-26 10:28:24.346775) >+ >+# KerberosV5Spec2 >+from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful >+ >+ >+def _OID(*components): >+ output = [] >+ for x in tuple(components): >+ if isinstance(x, univ.ObjectIdentifier): >+ output.extend(list(x)) >+ else: >+ output.append(int(x)) >+ >+ return univ.ObjectIdentifier(output) >+ >+ >+class Int32(univ.Integer): >+ pass >+ >+ >+Int32.subtypeSpec = constraint.ValueRangeConstraint(-2147483648, 2147483647) >+ >+ >+class AuthDataType(Int32): >+ pass >+ >+ >+class AuthorizationData(univ.SequenceOf): >+ pass >+ >+ >+AuthorizationData.componentType = univ.Sequence(componentType=namedtype.NamedTypes( >+ namedtype.NamedType('ad-type', AuthDataType().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('ad-data', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+)) >+ >+ >+class AD_AND_OR(univ.Sequence): >+ pass >+ >+ >+AD_AND_OR.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('condition-count', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('elements', AuthorizationData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+) >+ >+ >+class AD_IF_RELEVANT(AuthorizationData): >+ pass >+ >+ >+class ChecksumType(Int32): >+ pass >+ >+ >+class Checksum(univ.Sequence): >+ pass >+ >+ >+Checksum.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('cksumtype', ChecksumType().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('checksum', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+) >+ >+ >+class KerberosString(char.GeneralString): >+ pass >+ >+ >+class NameType(Int32): >+ pass >+ >+ >+class PrincipalName(univ.Sequence): >+ pass >+ >+ >+PrincipalName.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('name-type', NameType().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('name-string', univ.SequenceOf(componentType=KerberosString()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+) >+ >+ >+class Realm(KerberosString): >+ pass >+ >+ >+class AD_KDCIssued(univ.Sequence): >+ pass >+ >+ >+AD_KDCIssued.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('ad-checksum', Checksum().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), >+ namedtype.OptionalNamedType('i-realm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('i-sname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), >+ namedtype.NamedType('elements', AuthorizationData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) >+) >+ >+ >+class AD_MANDATORY_FOR_KDC(AuthorizationData): >+ pass >+ >+ >+class EncryptionType(Int32): >+ pass >+ >+ >+class UInt32(univ.Integer): >+ pass >+ >+ >+UInt32.subtypeSpec = constraint.ValueRangeConstraint(0, 4294967295) >+ >+ >+class EncryptedData(univ.Sequence): >+ pass >+ >+ >+EncryptedData.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('etype', EncryptionType().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.OptionalNamedType('kvno', UInt32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('cipher', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) >+) >+ >+ >+class AP_REP(univ.Sequence): >+ pass >+ >+ >+AP_REP.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 15)) >+AP_REP.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('pvno', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(5)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('msg-type', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(15)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('enc-part', EncryptedData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))) >+) >+ >+ >+class KerberosFlags(univ.BitString): >+ pass >+ >+ >+KerberosFlags.subtypeSpec=constraint.ValueSizeConstraint(1, 32) >+ >+ >+class APOptions(KerberosFlags): >+ pass >+ >+ >+class Ticket(univ.Sequence): >+ pass >+ >+ >+Ticket.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 1)) >+Ticket.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('tkt-vno', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(5)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('realm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('sname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), >+ namedtype.NamedType('enc-part', EncryptedData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))) >+) >+ >+ >+class AP_REQ(univ.Sequence): >+ pass >+ >+ >+AP_REQ.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 14)) >+AP_REQ.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('pvno', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(5)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('msg-type', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(14)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('ap-options', APOptions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.NamedType('ticket', Ticket().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), >+ namedtype.NamedType('authenticator', EncryptedData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))) >+) >+ >+ >+class PADataType(Int32): >+ pass >+ >+ >+class PA_DATA(univ.Sequence): >+ pass >+ >+ >+PA_DATA.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('padata-type', PADataType().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('padata-value', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) >+) >+ >+ >+class KDC_REP(univ.Sequence): >+ pass >+ >+ >+KDC_REP.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('pvno', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(5)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('msg-type', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(11, 13)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('padata', univ.SequenceOf(componentType=PA_DATA()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.NamedType('crealm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), >+ namedtype.NamedType('cname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))), >+ namedtype.NamedType('ticket', Ticket().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))), >+ namedtype.NamedType('enc-part', EncryptedData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 6))) >+) >+ >+ >+class AS_REP(KDC_REP): >+ pass >+ >+ >+AS_REP.tagSet = KDC_REP.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 11)) >+ >+ >+class HostAddress(univ.Sequence): >+ pass >+ >+ >+HostAddress.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('addr-type', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('address', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+) >+ >+ >+class HostAddresses(univ.SequenceOf): >+ pass >+ >+ >+HostAddresses.componentType = HostAddress() >+ >+ >+class KDCOptions(KerberosFlags): >+ pass >+ >+ >+class KerberosTime(useful.GeneralizedTime): >+ pass >+ >+ >+class KDC_REQ_BODY(univ.Sequence): >+ pass >+ >+ >+KDC_REQ_BODY.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('kdc-options', KDCOptions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.OptionalNamedType('cname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), >+ namedtype.NamedType('realm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.OptionalNamedType('sname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))), >+ namedtype.OptionalNamedType('from', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), >+ namedtype.NamedType('till', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))), >+ namedtype.OptionalNamedType('rtime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))), >+ namedtype.NamedType('nonce', UInt32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))), >+ namedtype.NamedType('etype', univ.SequenceOf(componentType=EncryptionType()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8))), >+ namedtype.OptionalNamedType('addresses', HostAddresses().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 9))), >+ namedtype.OptionalNamedType('enc-authorization-data', EncryptedData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 10))), >+ namedtype.OptionalNamedType('additional-tickets', univ.SequenceOf(componentType=Ticket()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 11))) >+) >+ >+ >+class KDC_REQ(univ.Sequence): >+ pass >+ >+ >+KDC_REQ.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('pvno', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(5)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('msg-type', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(10, 12)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.OptionalNamedType('padata', univ.SequenceOf(componentType=PA_DATA()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), >+ namedtype.NamedType('req-body', KDC_REQ_BODY().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))) >+) >+ >+ >+class AS_REQ(KDC_REQ): >+ pass >+ >+ >+AS_REQ.tagSet = KDC_REQ.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 10)) >+ >+ >+class AuthDataTypeValues(univ.Integer): >+ pass >+ >+ >+AuthDataTypeValues.namedValues = namedval.NamedValues( >+ ('kRB5-AUTHDATA-IF-RELEVANT', 1), >+ ('kRB5-AUTHDATA-INTENDED-FOR-SERVER', 2), >+ ('kRB5-AUTHDATA-INTENDED-FOR-APPLICATION-CLASS', 3), >+ ('kRB5-AUTHDATA-KDC-ISSUED', 4), >+ ('kRB5-AUTHDATA-AND-OR', 5), >+ ('kRB5-AUTHDATA-MANDATORY-TICKET-EXTENSIONS', 6), >+ ('kRB5-AUTHDATA-IN-TICKET-EXTENSIONS', 7), >+ ('kRB5-AUTHDATA-MANDATORY-FOR-KDC', 8), >+ ('kRB5-AUTHDATA-INITIAL-VERIFIED-CAS', 9), >+ ('kRB5-AUTHDATA-OSF-DCE', 64), >+ ('kRB5-AUTHDATA-SESAME', 65), >+ ('kRB5-AUTHDATA-OSF-DCE-PKI-CERTID', 66), >+ ('kRB5-AUTHDATA-WIN2K-PAC', 128), >+ ('kRB5-AUTHDATA-GSS-API-ETYPE-NEGOTIATION', 129), >+ ('kRB5-AUTHDATA-SIGNTICKET-OLDER', -17), >+ ('kRB5-AUTHDATA-SIGNTICKET-OLD', 142), >+ ('kRB5-AUTHDATA-SIGNTICKET', 512) >+) >+ >+ >+class AuthDataTypeSequence(univ.Sequence): >+ pass >+ >+ >+AuthDataTypeSequence.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('dummy', AuthDataTypeValues().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ >+class EncryptionKey(univ.Sequence): >+ pass >+ >+ >+EncryptionKey.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('keytype', EncryptionType().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('keyvalue', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+) >+ >+ >+class Microseconds(univ.Integer): >+ pass >+ >+ >+Microseconds.subtypeSpec = constraint.ValueRangeConstraint(0, 999999) >+ >+ >+class Authenticator(univ.Sequence): >+ pass >+ >+ >+Authenticator.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 2)) >+Authenticator.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('authenticator-vno', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(5)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('crealm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('cname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), >+ namedtype.OptionalNamedType('cksum', Checksum().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))), >+ namedtype.NamedType('cusec', Microseconds().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), >+ namedtype.NamedType('ctime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))), >+ namedtype.OptionalNamedType('subkey', EncryptionKey().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 6))), >+ namedtype.OptionalNamedType('seq-number', UInt32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))), >+ namedtype.OptionalNamedType('authorization-data', AuthorizationData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8))) >+) >+ >+ >+class ChecksumTypeValues(univ.Integer): >+ pass >+ >+ >+ChecksumTypeValues.namedValues = namedval.NamedValues( >+ ('kRB5-CKSUMTYPE-NONE', 0), >+ ('kRB5-CKSUMTYPE-CRC32', 1), >+ ('kRB5-CKSUMTYPE-RSA-MD4', 2), >+ ('kRB5-CKSUMTYPE-RSA-MD4-DES', 3), >+ ('kRB5-CKSUMTYPE-DES-MAC', 4), >+ ('kRB5-CKSUMTYPE-DES-MAC-K', 5), >+ ('kRB5-CKSUMTYPE-RSA-MD4-DES-K', 6), >+ ('kRB5-CKSUMTYPE-RSA-MD5', 7), >+ ('kRB5-CKSUMTYPE-RSA-MD5-DES', 8), >+ ('kRB5-CKSUMTYPE-RSA-MD5-DES3', 9), >+ ('kRB5-CKSUMTYPE-SHA1-OTHER', 10), >+ ('kRB5-CKSUMTYPE-HMAC-SHA1-DES3', 12), >+ ('kRB5-CKSUMTYPE-SHA1', 14), >+ ('kRB5-CKSUMTYPE-HMAC-SHA1-96-AES-128', 15), >+ ('kRB5-CKSUMTYPE-HMAC-SHA1-96-AES-256', 16), >+ ('kRB5-CKSUMTYPE-GSSAPI', 32771), >+ ('kRB5-CKSUMTYPE-HMAC-MD5', -138), >+ ('kRB5-CKSUMTYPE-HMAC-MD5-ENC', -1138) >+) >+ >+ >+class ChecksumTypeSequence(univ.Sequence): >+ pass >+ >+ >+ChecksumTypeSequence.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('dummy', ChecksumTypeValues().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ >+class ETYPE_INFO_ENTRY(univ.Sequence): >+ pass >+ >+ >+ETYPE_INFO_ENTRY.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('etype', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.OptionalNamedType('salt', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+) >+ >+ >+class ETYPE_INFO(univ.SequenceOf): >+ pass >+ >+ >+ETYPE_INFO.componentType = ETYPE_INFO_ENTRY() >+ >+ >+class ETYPE_INFO2_ENTRY(univ.Sequence): >+ pass >+ >+ >+ETYPE_INFO2_ENTRY.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('etype', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.OptionalNamedType('salt', KerberosString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('s2kparams', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) >+) >+ >+ >+class ETYPE_INFO2(univ.SequenceOf): >+ pass >+ >+ >+ETYPE_INFO2.componentType = ETYPE_INFO2_ENTRY() >+ETYPE_INFO2.subtypeSpec=constraint.ValueSizeConstraint(1, 256) >+ >+ >+class EncAPRepPart(univ.Sequence): >+ pass >+ >+ >+EncAPRepPart.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 27)) >+EncAPRepPart.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('ctime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('cusec', Microseconds().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('subkey', EncryptionKey().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), >+ namedtype.OptionalNamedType('seq-number', UInt32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) >+) >+ >+ >+class LastReq(univ.SequenceOf): >+ pass >+ >+ >+LastReq.componentType = univ.Sequence(componentType=namedtype.NamedTypes( >+ namedtype.NamedType('lr-type', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('lr-value', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+)) >+ >+ >+class TicketFlags(KerberosFlags): >+ pass >+ >+ >+class EncKDCRepPart(univ.Sequence): >+ pass >+ >+ >+EncKDCRepPart.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('key', EncryptionKey().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), >+ namedtype.NamedType('last-req', LastReq().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('nonce', UInt32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.OptionalNamedType('key-expiration', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), >+ namedtype.NamedType('flags', TicketFlags().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), >+ namedtype.NamedType('authtime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))), >+ namedtype.OptionalNamedType('starttime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))), >+ namedtype.NamedType('endtime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))), >+ namedtype.OptionalNamedType('renew-till', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8))), >+ namedtype.NamedType('srealm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 9))), >+ namedtype.NamedType('sname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 10))), >+ namedtype.OptionalNamedType('caddr', HostAddresses().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 11))) >+) >+ >+ >+class EncASRepPart(EncKDCRepPart): >+ pass >+ >+ >+EncASRepPart.tagSet = EncKDCRepPart.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 25)) >+ >+ >+class KrbCredInfo(univ.Sequence): >+ pass >+ >+ >+KrbCredInfo.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('key', EncryptionKey().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), >+ namedtype.OptionalNamedType('prealm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('pname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), >+ namedtype.OptionalNamedType('flags', TicketFlags().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), >+ namedtype.OptionalNamedType('authtime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), >+ namedtype.OptionalNamedType('starttime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))), >+ namedtype.OptionalNamedType('endtime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))), >+ namedtype.OptionalNamedType('renew-till', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))), >+ namedtype.OptionalNamedType('srealm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8))), >+ namedtype.OptionalNamedType('sname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 9))), >+ namedtype.OptionalNamedType('caddr', HostAddresses().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10))) >+) >+ >+ >+class EncKrbCredPart(univ.Sequence): >+ pass >+ >+ >+EncKrbCredPart.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 29)) >+EncKrbCredPart.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('ticket-info', univ.SequenceOf(componentType=KrbCredInfo()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.OptionalNamedType('nonce', UInt32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('timestamp', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.OptionalNamedType('usec', Microseconds().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), >+ namedtype.OptionalNamedType('s-address', HostAddress().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))), >+ namedtype.OptionalNamedType('r-address', HostAddress().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 5))) >+) >+ >+ >+class EncKrbPrivPart(univ.Sequence): >+ pass >+ >+ >+EncKrbPrivPart.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 28)) >+EncKrbPrivPart.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('user-data', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.OptionalNamedType('timestamp', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('usec', Microseconds().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.OptionalNamedType('seq-number', UInt32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), >+ namedtype.NamedType('s-address', HostAddress().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))), >+ namedtype.OptionalNamedType('r-address', HostAddress().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 5))) >+) >+ >+ >+class EncTGSRepPart(EncKDCRepPart): >+ pass >+ >+ >+EncTGSRepPart.tagSet = EncKDCRepPart.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 26)) >+ >+ >+class TransitedEncoding(univ.Sequence): >+ pass >+ >+ >+TransitedEncoding.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('tr-type', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('contents', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+) >+ >+ >+class EncTicketPart(univ.Sequence): >+ pass >+ >+ >+EncTicketPart.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 3)) >+EncTicketPart.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('flags', TicketFlags().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('key', EncryptionKey().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), >+ namedtype.NamedType('crealm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.NamedType('cname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))), >+ namedtype.NamedType('transited', TransitedEncoding().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))), >+ namedtype.NamedType('authtime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))), >+ namedtype.OptionalNamedType('starttime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))), >+ namedtype.NamedType('endtime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))), >+ namedtype.OptionalNamedType('renew-till', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8))), >+ namedtype.OptionalNamedType('caddr', HostAddresses().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 9))), >+ namedtype.OptionalNamedType('authorization-data', AuthorizationData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10))) >+) >+ >+ >+class EncryptionTypeValues(univ.Integer): >+ pass >+ >+ >+EncryptionTypeValues.namedValues = namedval.NamedValues( >+ ('kRB5-ENCTYPE-NULL', 0), >+ ('kRB5-ENCTYPE-DES-CBC-CRC', 1), >+ ('kRB5-ENCTYPE-DES-CBC-MD4', 2), >+ ('kRB5-ENCTYPE-DES-CBC-MD5', 3), >+ ('kRB5-ENCTYPE-DES3-CBC-MD5', 5), >+ ('kRB5-ENCTYPE-OLD-DES3-CBC-SHA1', 7), >+ ('kRB5-ENCTYPE-SIGN-DSA-GENERATE', 8), >+ ('kRB5-ENCTYPE-ENCRYPT-RSA-PRIV', 9), >+ ('kRB5-ENCTYPE-ENCRYPT-RSA-PUB', 10), >+ ('kRB5-ENCTYPE-DES3-CBC-SHA1', 16), >+ ('kRB5-ENCTYPE-AES128-CTS-HMAC-SHA1-96', 17), >+ ('kRB5-ENCTYPE-AES256-CTS-HMAC-SHA1-96', 18), >+ ('kRB5-ENCTYPE-ARCFOUR-HMAC-MD5', 23), >+ ('kRB5-ENCTYPE-ARCFOUR-HMAC-MD5-56', 24), >+ ('kRB5-ENCTYPE-ENCTYPE-PK-CROSS', 48), >+ ('kRB5-ENCTYPE-ARCFOUR-MD4', -128), >+ ('kRB5-ENCTYPE-ARCFOUR-HMAC-OLD', -133), >+ ('kRB5-ENCTYPE-ARCFOUR-HMAC-OLD-EXP', -135), >+ ('kRB5-ENCTYPE-DUMMY', -1111) >+) >+ >+ >+class EncryptionTypeSequence(univ.Sequence): >+ pass >+ >+ >+EncryptionTypeSequence.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('dummy', EncryptionTypeValues().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ >+class KDCOptionsValues(univ.BitString): >+ pass >+ >+ >+KDCOptionsValues.namedValues = namedval.NamedValues( >+ ('reserved', 0), >+ ('forwardable', 1), >+ ('forwarded', 2), >+ ('proxiable', 3), >+ ('proxy', 4), >+ ('allow-postdate', 5), >+ ('postdated', 6), >+ ('unused7', 7), >+ ('renewable', 8), >+ ('unused9', 9), >+ ('unused10', 10), >+ ('opt-hardware-auth', 11), >+ ('unused12', 12), >+ ('unused13', 13), >+ ('unused15', 15), >+ ('disable-transited-check', 26), >+ ('renewable-ok', 27), >+ ('enc-tkt-in-skey', 28), >+ ('renew', 30), >+ ('validate', 31) >+) >+ >+ >+class KDCOptionsSequence(univ.Sequence): >+ pass >+ >+ >+KDCOptionsSequence.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('dummy', KDCOptionsValues().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ >+class KRB_CRED(univ.Sequence): >+ pass >+ >+ >+KRB_CRED.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 22)) >+KRB_CRED.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('pvno', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(5)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('msg-type', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(22)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('tickets', univ.SequenceOf(componentType=Ticket()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.NamedType('enc-part', EncryptedData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))) >+) >+ >+ >+class KRB_ERROR(univ.Sequence): >+ pass >+ >+ >+KRB_ERROR.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 30)) >+KRB_ERROR.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('pvno', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(5)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('msg-type', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(30)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('ctime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.OptionalNamedType('cusec', Microseconds().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), >+ namedtype.NamedType('stime', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), >+ namedtype.NamedType('susec', Microseconds().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))), >+ namedtype.NamedType('error-code', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))), >+ namedtype.OptionalNamedType('crealm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))), >+ namedtype.OptionalNamedType('cname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 8))), >+ namedtype.NamedType('realm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 9))), >+ namedtype.NamedType('sname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 10))), >+ namedtype.OptionalNamedType('e-text', KerberosString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 11))), >+ namedtype.OptionalNamedType('e-data', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 12))) >+) >+ >+ >+class KRB_PRIV(univ.Sequence): >+ pass >+ >+ >+KRB_PRIV.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 21)) >+KRB_PRIV.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('pvno', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(5)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('msg-type', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(21)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('enc-part', EncryptedData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))) >+) >+ >+ >+class KRB_SAFE_BODY(univ.Sequence): >+ pass >+ >+ >+KRB_SAFE_BODY.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('user-data', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.OptionalNamedType('timestamp', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('usec', Microseconds().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.OptionalNamedType('seq-number', UInt32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), >+ namedtype.NamedType('s-address', HostAddress().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))), >+ namedtype.OptionalNamedType('r-address', HostAddress().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 5))) >+) >+ >+ >+class KRB_SAFE(univ.Sequence): >+ pass >+ >+ >+KRB_SAFE.tagSet = univ.Sequence.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 20)) >+KRB_SAFE.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('pvno', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(5)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('msg-type', univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(20)).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('safe-body', KRB_SAFE_BODY().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), >+ namedtype.NamedType('cksum', Checksum().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))) >+) >+ >+ >+class METHOD_DATA(univ.SequenceOf): >+ pass >+ >+ >+METHOD_DATA.componentType = PA_DATA() >+ >+ >+class MessageTypeValues(univ.Integer): >+ pass >+ >+ >+MessageTypeValues.namedValues = namedval.NamedValues( >+ ('krb-as-req', 10), >+ ('krb-as-rep', 11), >+ ('krb-tgs-req', 12), >+ ('krb-tgs-rep', 13), >+ ('krb-ap-req', 14), >+ ('krb-ap-rep', 15), >+ ('krb-safe', 20), >+ ('krb-priv', 21), >+ ('krb-cred', 22), >+ ('krb-error', 30) >+) >+ >+ >+class MessageTypeSequence(univ.Sequence): >+ pass >+ >+ >+MessageTypeSequence.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('dummy', MessageTypeValues().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ >+class NameTypeValues(univ.Integer): >+ pass >+ >+ >+NameTypeValues.namedValues = namedval.NamedValues( >+ ('kRB5-NT-UNKNOWN', 0), >+ ('kRB5-NT-PRINCIPAL', 1), >+ ('kRB5-NT-SRV-INST', 2), >+ ('kRB5-NT-SRV-HST', 3), >+ ('kRB5-NT-SRV-XHST', 4), >+ ('kRB5-NT-UID', 5), >+ ('kRB5-NT-X500-PRINCIPAL', 6), >+ ('kRB5-NT-SMTP-NAME', 7), >+ ('kRB5-NT-ENTERPRISE-PRINCIPAL', 10), >+ ('kRB5-NT-WELLKNOWN', 11), >+ ('kRB5-NT-ENT-PRINCIPAL-AND-ID', -130), >+ ('kRB5-NT-MS-PRINCIPAL', -128), >+ ('kRB5-NT-MS-PRINCIPAL-AND-ID', -129) >+) >+ >+ >+class NameTypeSequence(univ.Sequence): >+ pass >+ >+ >+NameTypeSequence.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('dummy', NameTypeValues().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ >+class PA_ENC_TIMESTAMP(EncryptedData): >+ pass >+ >+ >+class PA_ENC_TS_ENC(univ.Sequence): >+ pass >+ >+ >+PA_ENC_TS_ENC.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('patimestamp', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.OptionalNamedType('pausec', Microseconds().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+) >+ >+ >+class PADataTypeValues(univ.Integer): >+ pass >+ >+ >+PADataTypeValues.namedValues = namedval.NamedValues( >+ ('kRB5-PADATA-NONE', 0), >+ ('kRB5-PADATA-KDC-REQ', 1), >+ ('kRB5-PADATA-ENC-TIMESTAMP', 2), >+ ('kRB5-PADATA-PW-SALT', 3), >+ ('kRB5-PADATA-ENC-UNIX-TIME', 5), >+ ('kRB5-PADATA-SANDIA-SECUREID', 6), >+ ('kRB5-PADATA-SESAME', 7), >+ ('kRB5-PADATA-OSF-DCE', 8), >+ ('kRB5-PADATA-CYBERSAFE-SECUREID', 9), >+ ('kRB5-PADATA-AFS3-SALT', 10), >+ ('kRB5-PADATA-ETYPE-INFO', 11), >+ ('kRB5-PADATA-SAM-CHALLENGE', 12), >+ ('kRB5-PADATA-SAM-RESPONSE', 13), >+ ('kRB5-PADATA-PK-AS-REQ-19', 14), >+ ('kRB5-PADATA-PK-AS-REP-19', 15), >+ ('kRB5-PADATA-PK-AS-REQ', 16), >+ ('kRB5-PADATA-PK-AS-REP', 17), >+ ('kRB5-PADATA-PA-PK-OCSP-RESPONSE', 18), >+ ('kRB5-PADATA-ETYPE-INFO2', 19), >+ ('kRB5-PADATA-SVR-REFERRAL-INFO', 20), >+ ('kRB5-PADATA-SAM-REDIRECT', 21), >+ ('kRB5-PADATA-GET-FROM-TYPED-DATA', 22), >+ ('kRB5-PADATA-SAM-ETYPE-INFO', 23), >+ ('kRB5-PADATA-SERVER-REFERRAL', 25), >+ ('kRB5-PADATA-ALT-PRINC', 24), >+ ('kRB5-PADATA-SAM-CHALLENGE2', 30), >+ ('kRB5-PADATA-SAM-RESPONSE2', 31), >+ ('kRB5-PA-EXTRA-TGT', 41), >+ ('kRB5-PADATA-TD-KRB-PRINCIPAL', 102), >+ ('kRB5-PADATA-PK-TD-TRUSTED-CERTIFIERS', 104), >+ ('kRB5-PADATA-PK-TD-CERTIFICATE-INDEX', 105), >+ ('kRB5-PADATA-TD-APP-DEFINED-ERROR', 106), >+ ('kRB5-PADATA-TD-REQ-NONCE', 107), >+ ('kRB5-PADATA-TD-REQ-SEQ', 108), >+ ('kRB5-PADATA-PA-PAC-REQUEST', 128), >+ ('kRB5-PADATA-FOR-USER', 129), >+ ('kRB5-PADATA-FOR-X509-USER', 130), >+ ('kRB5-PADATA-FOR-CHECK-DUPS', 131), >+ ('kRB5-PADATA-AS-CHECKSUM', 132), >+ ('kRB5-PADATA-FX-COOKIE', 133), >+ ('kRB5-PADATA-AUTHENTICATION-SET', 134), >+ ('kRB5-PADATA-AUTH-SET-SELECTED', 135), >+ ('kRB5-PADATA-FX-FAST', 136), >+ ('kRB5-PADATA-FX-ERROR', 137), >+ ('kRB5-PADATA-ENCRYPTED-CHALLENGE', 138), >+ ('kRB5-PADATA-OTP-CHALLENGE', 141), >+ ('kRB5-PADATA-OTP-REQUEST', 142), >+ ('kBB5-PADATA-OTP-CONFIRM', 143), >+ ('kRB5-PADATA-OTP-PIN-CHANGE', 144), >+ ('kRB5-PADATA-EPAK-AS-REQ', 145), >+ ('kRB5-PADATA-EPAK-AS-REP', 146), >+ ('kRB5-PADATA-PKINIT-KX', 147), >+ ('kRB5-PADATA-PKU2U-NAME', 148), >+ ('kRB5-PADATA-REQ-ENC-PA-REP', 149), >+ ('kRB5-PADATA-SUPPORTED-ETYPES', 165) >+) >+ >+ >+class PADataTypeSequence(univ.Sequence): >+ pass >+ >+ >+PADataTypeSequence.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('dummy', PADataTypeValues().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ >+class TGS_REP(KDC_REP): >+ pass >+ >+ >+TGS_REP.tagSet = KDC_REP.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 13)) >+ >+ >+class TGS_REQ(KDC_REQ): >+ pass >+ >+ >+TGS_REQ.tagSet = KDC_REQ.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 12)) >+ >+ >+class TYPED_DATA(univ.SequenceOf): >+ pass >+ >+ >+TYPED_DATA.componentType = univ.Sequence(componentType=namedtype.NamedTypes( >+ namedtype.NamedType('data-type', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.OptionalNamedType('data-value', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+)) >+ >+TYPED_DATA.subtypeSpec=constraint.ValueSizeConstraint(1, 256) >+ >+ >+class TicketFlagsValues(univ.BitString): >+ pass >+ >+ >+TicketFlagsValues.namedValues = namedval.NamedValues( >+ ('reserved', 0), >+ ('forwardable', 1), >+ ('forwarded', 2), >+ ('proxiable', 3), >+ ('proxy', 4), >+ ('may-postdate', 5), >+ ('postdated', 6), >+ ('invalid', 7), >+ ('renewable', 8), >+ ('initial', 9), >+ ('pre-authent', 10), >+ ('hw-authent', 11), >+ ('transited-policy-checked', 12), >+ ('ok-as-delegate', 13) >+) >+ >+ >+class TicketFlagsSequence(univ.Sequence): >+ pass >+ >+ >+TicketFlagsSequence.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('dummy', TicketFlagsValues().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ >+id_krb5 = _OID(1, 3, 6, 1, 5, 2) >+ >+ >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1_regen.sh b/python/samba/tests/krb5/rfc4120_pyasn1_regen.sh >new file mode 100755 >index 00000000000..2e3995688f2 >--- /dev/null >+++ b/python/samba/tests/krb5/rfc4120_pyasn1_regen.sh >@@ -0,0 +1,41 @@ >+#!/bin/bash >+# >+ >+# >+# I used https://github.com/kimgr/asn1ate.git >+# to generate pyasn1 bindings for rfc4120.asn1 >+# >+ >+PATH_TO_ASN1ATE_CHECKOUT=$1 >+PATH_TO_ASN1_INPUT_FILE=$2 >+ >+set -u >+set -e >+ >+usage() { >+ echo "usage: $0 PATH_TO_ASN1ATE_CHECKOUT PATH_TO_ASN1_INPUT_FILE > PATH_TO_PYASN1_OUTPUT_FILE" >+} >+ >+test -n "${PATH_TO_ASN1ATE_CHECKOUT}" || { >+ usage >+ exit 1 >+} >+test -n "${PATH_TO_ASN1_INPUT_FILE}" || { >+ usage >+ exit 1 >+} >+test -d "${PATH_TO_ASN1ATE_CHECKOUT}" || { >+ usage >+ exit 1 >+} >+test -f "${PATH_TO_ASN1_INPUT_FILE}" || { >+ usage >+ exit 1 >+} >+ >+PATH_TO_PYASN1GEN_PY="${PATH_TO_ASN1ATE_CHECKOUT}/asn1ate/pyasn1gen.py" >+ >+PYTHONPATH="${PATH_TO_ASN1ATE_CHECKOUT}:${PYTHONPATH-}" >+export PYTHONPATH >+ >+python3 "${PATH_TO_PYASN1GEN_PY}" "${PATH_TO_ASN1_INPUT_FILE}" >diff --git a/python/samba/tests/source.py b/python/samba/tests/source.py >index b7608b1bab3..cebfb9ae8fb 100644 >--- a/python/samba/tests/source.py >+++ b/python/samba/tests/source.py >@@ -93,6 +93,9 @@ class TestSource(TestCase): > if fname.endswith("python/samba/tests/krb5/kcrypto.py"): > # Imported from MIT testing repo > continue >+ if fname.endswith("python/samba/tests/krb5/rfc4120_pyasn1.py"): >+ # Autogenerated >+ continue > match = copyright_re.search(text) > if not match: > incorrect.append((fname, 'no copyright line found\n')) >@@ -138,6 +141,9 @@ class TestSource(TestCase): > if fname.endswith("python/samba/tests/krb5/kcrypto.py"): > # Imported from MIT testing repo > continue >+ if fname.endswith("python/samba/tests/krb5/rfc4120_pyasn1.py"): >+ # Autogenerated >+ continue > if not gpl_re.search(text): > incorrect.append(fname) > >-- >2.25.1 > > >From 3e737d4d89eb15186c245c714f636426b9fe6b2b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 13 Feb 2020 16:29:38 +0100 >Subject: [PATCH 025/686] python/tests/krb5: add raw_testcase.py as the base > for our Kerberos protocol testing > >Pair-Programmed-With: Isaac Boukris <iboukris@samba.org> > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Signed-off-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit fb7cba50ae3472b29aa806208badc1ded8979073) >--- > python/samba/tests/krb5/raw_testcase.py | 869 ++++++++++++++++++++++++ > 1 file changed, 869 insertions(+) > create mode 100644 python/samba/tests/krb5/raw_testcase.py > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >new file mode 100644 >index 00000000000..6c7bcd418a0 >--- /dev/null >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -0,0 +1,869 @@ >+# Unix SMB/CIFS implementation. >+# Copyright (C) Isaac Boukris 2020 >+# Copyright (C) Stefan Metzmacher 2020 >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import socket >+import struct >+import time >+import datetime >+import random >+ >+import samba.tests >+from samba.credentials import Credentials >+from samba.tests import TestCase >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+import samba.tests.krb5.kcrypto as kcrypto >+ >+from pyasn1.codec.der.decoder import decode as pyasn1_der_decode >+from pyasn1.codec.der.encoder import encode as pyasn1_der_encode >+from pyasn1.codec.native.decoder import decode as pyasn1_native_decode >+from pyasn1.codec.native.encoder import encode as pyasn1_native_encode >+ >+from pyasn1.codec.ber.encoder import BitStringEncoder as BitStringEncoder >+def BitStringEncoder_encodeValue32(self, value, asn1Spec, encodeFun, **options): >+ # >+ # BitStrings like KDCOptions or TicketFlags should at least >+ # be 32-Bit on the wire >+ # >+ if asn1Spec is not None: >+ # TODO: try to avoid ASN.1 schema instantiation >+ value = asn1Spec.clone(value) >+ >+ valueLength = len(value) >+ if valueLength % 8: >+ alignedValue = value << (8 - valueLength % 8) >+ else: >+ alignedValue = value >+ >+ substrate = alignedValue.asOctets() >+ length = len(substrate) >+ # We need at least 32-Bit / 4-Bytes >+ if length < 4: >+ padding = 4 - length >+ else: >+ padding = 0 >+ ret = b'\x00' + substrate + (b'\x00' * padding) >+ return ret, False, True >+BitStringEncoder.encodeValue = BitStringEncoder_encodeValue32 >+ >+def BitString_NamedValues_prettyPrint(self, scope=0): >+ ret = "%s" % self.asBinary() >+ bits = [] >+ highest_bit = 32 >+ for byte in self.asNumbers(): >+ for bit in [7,6,5,4,3,2,1,0]: >+ mask = 1 << bit >+ if byte & mask: >+ val = 1 >+ else: >+ val = 0 >+ bits.append(val) >+ if len(bits) < highest_bit: >+ for bitPosition in range(len(bits), highest_bit): >+ bits.append(0) >+ indent = " " * scope >+ delim = ": (\n%s " % indent >+ for bitPosition in range(highest_bit): >+ if bitPosition in self.prettyPrintNamedValues: >+ name = self.prettyPrintNamedValues[bitPosition] >+ elif bits[bitPosition] != 0: >+ name = "unknown-bit-%u" % bitPosition >+ else: >+ continue >+ ret += "%s%s:%u" % (delim, name, bits[bitPosition]) >+ delim = ",\n%s " % indent >+ ret += "\n%s)" % indent >+ return ret >+krb5_asn1.TicketFlags.prettyPrintNamedValues = krb5_asn1.TicketFlagsValues.namedValues >+krb5_asn1.TicketFlags.namedValues = krb5_asn1.TicketFlagsValues.namedValues >+krb5_asn1.TicketFlags.prettyPrint = BitString_NamedValues_prettyPrint >+krb5_asn1.KDCOptions.prettyPrintNamedValues = krb5_asn1.KDCOptionsValues.namedValues >+krb5_asn1.KDCOptions.namedValues = krb5_asn1.KDCOptionsValues.namedValues >+krb5_asn1.KDCOptions.prettyPrint = BitString_NamedValues_prettyPrint >+ >+def Integer_NamedValues_prettyPrint(self, scope=0): >+ intval = int(self) >+ if intval in self.prettyPrintNamedValues: >+ name = self.prettyPrintNamedValues[intval] >+ else: >+ name = "<__unknown__>" >+ ret = "%d (0x%x) %s" % (intval, intval, name) >+ return ret >+krb5_asn1.NameType.prettyPrintNamedValues = krb5_asn1.NameTypeValues.namedValues >+krb5_asn1.NameType.prettyPrint = Integer_NamedValues_prettyPrint >+krb5_asn1.AuthDataType.prettyPrintNamedValues = krb5_asn1.AuthDataTypeValues.namedValues >+krb5_asn1.AuthDataType.prettyPrint = Integer_NamedValues_prettyPrint >+krb5_asn1.PADataType.prettyPrintNamedValues = krb5_asn1.PADataTypeValues.namedValues >+krb5_asn1.PADataType.prettyPrint = Integer_NamedValues_prettyPrint >+krb5_asn1.EncryptionType.prettyPrintNamedValues = krb5_asn1.EncryptionTypeValues.namedValues >+krb5_asn1.EncryptionType.prettyPrint = Integer_NamedValues_prettyPrint >+krb5_asn1.ChecksumType.prettyPrintNamedValues = krb5_asn1.ChecksumTypeValues.namedValues >+krb5_asn1.ChecksumType.prettyPrint = Integer_NamedValues_prettyPrint >+ >+class Krb5EncryptionKey(object): >+ def __init__(self, key, kvno): >+ EncTypeChecksum = { >+ kcrypto.Enctype.AES256: kcrypto.Cksumtype.SHA1_AES256, >+ kcrypto.Enctype.AES128: kcrypto.Cksumtype.SHA1_AES128, >+ kcrypto.Enctype.RC4: kcrypto.Cksumtype.HMAC_MD5, >+ } >+ self.key = key >+ self.etype = key.enctype >+ self.ctype = EncTypeChecksum[self.etype] >+ self.kvno = kvno >+ return >+ >+ def encrypt(self, usage, plaintext): >+ ciphertext = kcrypto.encrypt(self.key, usage, plaintext) >+ return ciphertext >+ >+ def decrypt(self, usage, ciphertext): >+ plaintext = kcrypto.decrypt(self.key, usage, ciphertext) >+ return plaintext >+ >+ def make_checksum(self, usage, plaintext, ctype=None): >+ if ctype is None: >+ ctype = self.ctype >+ cksum = kcrypto.make_checksum(ctype, self.key, usage, plaintext) >+ return cksum >+ >+ def export_obj(self): >+ EncryptionKey_obj = { >+ 'keytype': self.etype, >+ 'keyvalue': self.key.contents, >+ }; >+ return EncryptionKey_obj >+ >+class RawKerberosTest(TestCase): >+ """A raw Kerberos Test case.""" >+ >+ def setUp(self): >+ super(RawKerberosTest, self).setUp() >+ self.do_asn1_print = False >+ self.do_hexdump = False >+ >+ self.host = samba.tests.env_get_var_value('SERVER') >+ >+ self.s = None >+ >+ def tearDown(self): >+ self._disconnect("tearDown") >+ super(TestCase, self).tearDown() >+ >+ def _disconnect(self, reason): >+ if self.s is None: >+ return >+ self.s.close() >+ self.s = None >+ if self.do_hexdump: >+ sys.stderr.write("disconnect[%s]\n" % reason) >+ >+ def _connect_tcp(self): >+ tcp_port = 88 >+ try: >+ self.a = socket.getaddrinfo(self.host, tcp_port, socket.AF_UNSPEC, >+ socket.SOCK_STREAM, socket.SOL_TCP, >+ 0) >+ self.s = socket.socket(self.a[0][0], self.a[0][1], self.a[0][2]) >+ self.s.settimeout(10) >+ self.s.connect(self.a[0][4]) >+ except socket.error as e: >+ self.s.close() >+ raise >+ except IOError as e: >+ self.s.close() >+ raise >+ except Exception as e: >+ raise >+ finally: >+ pass >+ >+ def connect(self): >+ self.assertNotConnected() >+ self._connect_tcp() >+ if self.do_hexdump: >+ sys.stderr.write("connected[%s]\n" % self.host) >+ return >+ >+ def get_user_creds(self): >+ c = Credentials() >+ c.guess() >+ domain = samba.tests.env_get_var_value('DOMAIN') >+ realm = samba.tests.env_get_var_value('REALM') >+ username = samba.tests.env_get_var_value('USERNAME') >+ password = samba.tests.env_get_var_value('PASSWORD') >+ c.set_domain(domain) >+ c.set_realm(realm) >+ c.set_username(username) >+ c.set_password(password) >+ return c >+ >+ def get_service_creds(self, allow_missing_password=False): >+ c = Credentials() >+ c.guess() >+ domain = samba.tests.env_get_var_value('DOMAIN') >+ realm = samba.tests.env_get_var_value('REALM') >+ username = samba.tests.env_get_var_value('SERVICE_USERNAME') >+ password = samba.tests.env_get_var_value('SERVICE_PASSWORD', >+ allow_missing=allow_missing_password) >+ c.set_domain(domain) >+ c.set_realm(realm) >+ c.set_username(username) >+ if password is not None: >+ c.set_password(password) >+ return c >+ >+ def get_anon_creds(self): >+ c = Credentials() >+ c.set_anonymous() >+ return c >+ >+ def asn1_dump(self, name, obj, asn1_print=None): >+ if asn1_print is None: >+ asn1_print = self.do_asn1_print >+ if asn1_print: >+ if name is not None: >+ sys.stderr.write("%s:\n%s" % (name, obj)) >+ else: >+ sys.stderr.write("%s" % (obj)) >+ >+ def hex_dump(self, name, blob, hexdump=None): >+ if hexdump is None: >+ hexdump = self.do_hexdump >+ if hexdump: >+ sys.stderr.write("%s: %d\n%s" % (name, len(blob), self.hexdump(blob))) >+ >+ def der_decode(self, blob, asn1Spec=None, native_encode=True, asn1_print=None, hexdump=None): >+ if asn1Spec is not None: >+ class_name = type(asn1Spec).__name__.split(':')[0] >+ else: >+ class_name = "<None-asn1Spec>" >+ self.hex_dump(class_name, blob, hexdump=hexdump) >+ obj,_ = pyasn1_der_decode(blob, asn1Spec=asn1Spec) >+ self.asn1_dump(None, obj, asn1_print=asn1_print) >+ if native_encode: >+ obj = pyasn1_native_encode(obj) >+ return obj >+ >+ def der_encode(self, obj, asn1Spec=None, native_decode=True, asn1_print=None, hexdump=None): >+ if native_decode: >+ obj = pyasn1_native_decode(obj, asn1Spec=asn1Spec) >+ class_name = type(obj).__name__.split(':')[0] >+ if class_name is not None: >+ self.asn1_dump(None, obj, asn1_print=asn1_print) >+ blob = pyasn1_der_encode(obj) >+ if class_name is not None: >+ self.hex_dump(class_name, blob, hexdump=hexdump) >+ return blob >+ >+ def send_pdu(self, req, asn1_print=None, hexdump=None): >+ try: >+ k5_pdu = self.der_encode(req, native_decode=False, asn1_print=asn1_print, hexdump=False) >+ header = struct.pack('>I', len(k5_pdu)) >+ req_pdu = header >+ req_pdu += k5_pdu >+ self.hex_dump("send_pdu", header, hexdump=hexdump) >+ self.hex_dump("send_pdu", k5_pdu, hexdump=hexdump) >+ while True: >+ sent = self.s.send(req_pdu, 0) >+ if sent == len(req_pdu): >+ break >+ req_pdu = req_pdu[sent:] >+ except socket.error as e: >+ self._disconnect("send_pdu: %s" % e) >+ raise >+ except IOError as e: >+ self._disconnect("send_pdu: %s" % e) >+ raise >+ finally: >+ pass >+ >+ def recv_raw(self, num_recv=0xffff, hexdump=None, timeout=None): >+ rep_pdu = None >+ try: >+ if timeout is not None: >+ self.s.settimeout(timeout) >+ rep_pdu = self.s.recv(num_recv, 0) >+ self.s.settimeout(10) >+ if len(rep_pdu) == 0: >+ self._disconnect("recv_raw: EOF") >+ return None >+ self.hex_dump("recv_raw", rep_pdu, hexdump=hexdump) >+ except socket.timeout as e: >+ self.s.settimeout(10) >+ sys.stderr.write("recv_raw: TIMEOUT\n") >+ pass >+ except socket.error as e: >+ self._disconnect("recv_raw: %s" % e) >+ raise >+ except IOError as e: >+ self._disconnect("recv_raw: %s" % e) >+ raise >+ finally: >+ pass >+ return rep_pdu >+ >+ def recv_pdu_raw(self, asn1_print=None, hexdump=None, timeout=None): >+ rep_pdu = None >+ rep = None >+ try: >+ raw_pdu = self.recv_raw(num_recv=4, hexdump=hexdump, timeout=timeout) >+ if raw_pdu is None: >+ return (None, None) >+ header = struct.unpack(">I", raw_pdu[0:4]) >+ k5_len = header[0] >+ if k5_len == 0: >+ return (None, "") >+ missing = k5_len >+ rep_pdu = b'' >+ while missing > 0: >+ raw_pdu = self.recv_raw(num_recv=missing, hexdump=hexdump, timeout=timeout) >+ self.assertGreaterEqual(len(raw_pdu), 1) >+ rep_pdu += raw_pdu >+ missing = k5_len - len(rep_pdu) >+ k5_raw = self.der_decode(rep_pdu, asn1Spec=None, native_encode=False, >+ asn1_print=False, hexdump=False) >+ pvno=k5_raw['field-0'] >+ self.assertEqual(pvno, 5) >+ msg_type=k5_raw['field-1'] >+ self.assertIn(msg_type, [11,13,30]) >+ if msg_type == 11: >+ asn1Spec=krb5_asn1.AS_REP() >+ elif msg_type == 13: >+ asn1Spec=krb5_asn1.TGS_REP() >+ elif msg_type == 30: >+ asn1Spec=krb5_asn1.KRB_ERROR() >+ rep = self.der_decode(rep_pdu, asn1Spec=asn1Spec, >+ asn1_print=asn1_print, hexdump=False) >+ finally: >+ pass >+ return (rep, rep_pdu) >+ >+ def recv_pdu(self, asn1_print=None, hexdump=None, timeout=None): >+ (rep, rep_pdu) = self.recv_pdu_raw(asn1_print=asn1_print, >+ hexdump=hexdump, >+ timeout=timeout) >+ return rep >+ >+ def assertIsConnected(self): >+ self.assertIsNotNone(self.s, msg="Not connected") >+ return >+ >+ def assertNotConnected(self): >+ self.assertIsNone(self.s, msg="Is connected") >+ return >+ >+ def send_recv_transaction(self, req, asn1_print=None, hexdump=None, timeout=None): >+ self.connect() >+ try: >+ self.send_pdu(req, asn1_print=asn1_print, hexdump=hexdump) >+ rep = self.recv_pdu(asn1_print=asn1_print, hexdump=hexdump, timeout=timeout) >+ except Exception: >+ self._disconnect("transaction failed") >+ raise >+ self._disconnect("transaction done") >+ return rep >+ >+ def assertNoValue(self, value): >+ self.assertTrue(value.isNoValue) >+ return >+ >+ def assertHasValue(self, value): >+ self.assertIsNotNone(value) >+ return >+ >+ def assertPrincipalEqual(self, princ1, princ2): >+ self.assertEqual(princ1['name-type'], princ2['name-type']) >+ self.assertEqual(len(princ1['name-string']), len(princ2['name-string']), >+ msg="princ1=%s != princ2=%s" % (princ1, princ2)) >+ for idx in range(len(princ1['name-string'])): >+ self.assertEqual(princ1['name-string'][idx], princ2['name-string'][idx], >+ msg="princ1=%s != princ2=%s" % (princ1, princ2)) >+ return >+ >+ def get_KerberosTimeWithUsec(self, epoch=None, offset=None): >+ if epoch is None: >+ epoch = time.time() >+ if offset is not None: >+ epoch = epoch + int(offset) >+ dt = datetime.datetime.fromtimestamp(epoch, tz=datetime.timezone.utc) >+ return (dt.strftime("%Y%m%d%H%M%SZ"), dt.microsecond) >+ >+ def get_KerberosTime(self, epoch=None, offset=None): >+ (s, _) = self.get_KerberosTimeWithUsec(epoch=epoch, offset=offset) >+ return s >+ >+ def SessionKey_create(self, etype, contents, kvno=None): >+ key = kcrypto.Key(etype, contents) >+ return Krb5EncryptionKey(key, kvno) >+ >+ def PasswordKey_create(self, etype=None, pwd=None, salt=None, kvno=None): >+ key = kcrypto.string_to_key(etype, pwd, salt) >+ return Krb5EncryptionKey(key, kvno) >+ >+ def PasswordKey_from_etype_info2(self, creds, etype_info2, kvno=None): >+ e = etype_info2['etype'] >+ salt = None >+ try: >+ salt = etype_info2['salt'] >+ except: >+ pass >+ >+ if e == kcrypto.Enctype.RC4: >+ self.assertIsNone(salt) >+ nthash = creds.get_nt_hash() >+ return self.SessionKey_create(etype=e, contents=nthash, kvno=kvno) >+ >+ password = creds.get_password() >+ return self.PasswordKey_create(etype=e, pwd=password, salt=salt, kvno=kvno) >+ >+ def RandomKey(self, etype): >+ e = kcrypto._get_enctype_profile(etype) >+ contents = samba.generate_random_bytes(e.keysize) >+ return self.SessionKey_create(etype=etype, contents=contents) >+ >+ def EncryptionKey_import(self, EncryptionKey_obj): >+ return self.SessionKey_create(EncryptionKey_obj['keytype'], >+ EncryptionKey_obj['keyvalue']) >+ >+ def EncryptedData_create(self, key, usage, plaintext): >+ # EncryptedData ::= SEQUENCE { >+ # etype [0] Int32 -- EncryptionType --, >+ # kvno [1] UInt32 OPTIONAL, >+ # cipher [2] OCTET STRING -- ciphertext >+ # } >+ ciphertext = key.encrypt(usage, plaintext) >+ EncryptedData_obj = { >+ 'etype': key.etype, >+ 'cipher': ciphertext >+ } >+ if key.kvno is not None: >+ EncryptedData_obj['kvno'] = key.kvno >+ return EncryptedData_obj >+ >+ def Checksum_create(self, key, usage, plaintext, ctype=None): >+ #Checksum ::= SEQUENCE { >+ # cksumtype [0] Int32, >+ # checksum [1] OCTET STRING >+ #} >+ if ctype is None: >+ ctype = key.ctype >+ checksum = key.make_checksum(usage, plaintext, ctype=ctype) >+ Checksum_obj = { >+ 'cksumtype': ctype, >+ 'checksum': checksum, >+ } >+ return Checksum_obj >+ >+ def PrincipalName_create(self, name_type, names): >+ # PrincipalName ::= SEQUENCE { >+ # name-type [0] Int32, >+ # name-string [1] SEQUENCE OF KerberosString >+ # } >+ PrincipalName_obj = { >+ 'name-type': name_type, >+ 'name-string': names, >+ } >+ return PrincipalName_obj >+ >+ def PA_DATA_create(self, padata_type, padata_value): >+ # PA-DATA ::= SEQUENCE { >+ # -- NOTE: first tag is [1], not [0] >+ # padata-type [1] Int32, >+ # padata-value [2] OCTET STRING -- might be encoded AP-REQ >+ # } >+ PA_DATA_obj = { >+ 'padata-type': padata_type, >+ 'padata-value': padata_value, >+ } >+ return PA_DATA_obj >+ >+ def PA_ENC_TS_ENC_create(self, ts, usec): >+ #PA-ENC-TS-ENC ::= SEQUENCE { >+ # patimestamp[0] KerberosTime, -- client's time >+ # pausec[1] krb5int32 OPTIONAL >+ #} >+ PA_ENC_TS_ENC_obj = { >+ 'patimestamp': ts, >+ 'pausec': usec, >+ } >+ return PA_ENC_TS_ENC_obj >+ >+ def KDC_REQ_BODY_create(self, >+ kdc_options, >+ cname, >+ realm, >+ sname, >+ from_time, >+ till_time, >+ renew_time, >+ nonce, >+ etypes, >+ addresses, >+ EncAuthorizationData, >+ EncAuthorizationData_key, >+ additional_tickets, >+ asn1_print=None, >+ hexdump=None): >+ #KDC-REQ-BODY ::= SEQUENCE { >+ # kdc-options [0] KDCOptions, >+ # cname [1] PrincipalName OPTIONAL >+ # -- Used only in AS-REQ --, >+ # realm [2] Realm >+ # -- Server's realm >+ # -- Also client's in AS-REQ --, >+ # sname [3] PrincipalName OPTIONAL, >+ # from [4] KerberosTime OPTIONAL, >+ # till [5] KerberosTime, >+ # rtime [6] KerberosTime OPTIONAL, >+ # nonce [7] UInt32, >+ # etype [8] SEQUENCE OF Int32 -- EncryptionType >+ # -- in preference order --, >+ # addresses [9] HostAddresses OPTIONAL, >+ # enc-authorization-data [10] EncryptedData OPTIONAL >+ # -- AuthorizationData --, >+ # additional-tickets [11] SEQUENCE OF Ticket OPTIONAL >+ # -- NOTE: not empty >+ #} >+ if EncAuthorizationData is not None: >+ enc_ad_plain = self.der_encode(EncAuthorizationData, >+ asn1Spec=krb5_asn1.AuthorizationData(), >+ asn1_print=asn1_print, >+ hexdump=hexdump) >+ enc_ad = self.EncryptedData_create(EncAuthorizationData_key, enc_ad_plain) >+ else: >+ enc_ad = None >+ KDC_REQ_BODY_obj = { >+ 'kdc-options': kdc_options, >+ 'realm': realm, >+ 'till': till_time, >+ 'nonce': nonce, >+ 'etype': etypes, >+ } >+ if cname is not None: >+ KDC_REQ_BODY_obj['cname'] = cname >+ if sname is not None: >+ KDC_REQ_BODY_obj['sname'] = sname >+ if from_time is not None: >+ KDC_REQ_BODY_obj['from'] = from_time >+ if renew_time is not None: >+ KDC_REQ_BODY_obj['rtime'] = renew_time >+ if addresses is not None: >+ KDC_REQ_BODY_obj['addresses'] = addresses >+ if enc_ad is not None: >+ KDC_REQ_BODY_obj['enc-authorization-data'] = enc_ad >+ if additional_tickets is not None: >+ KDC_REQ_BODY_obj['additional-tickets'] = additional_tickets >+ return KDC_REQ_BODY_obj >+ >+ def KDC_REQ_create(self, >+ msg_type, >+ padata, >+ kdc_options, >+ cname, >+ realm, >+ sname, >+ from_time, >+ till_time, >+ renew_time, >+ nonce, >+ etypes, >+ addresses, >+ EncAuthorizationData, >+ EncAuthorizationData_key, >+ additional_tickets, >+ asn1Spec=None, >+ asn1_print=None, >+ hexdump=None): >+ #KDC-REQ ::= SEQUENCE { >+ # -- NOTE: first tag is [1], not [0] >+ # pvno [1] INTEGER (5) , >+ # msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), >+ # padata [3] SEQUENCE OF PA-DATA OPTIONAL >+ # -- NOTE: not empty --, >+ # req-body [4] KDC-REQ-BODY >+ #} >+ # >+ KDC_REQ_BODY_obj = self.KDC_REQ_BODY_create(kdc_options, >+ cname, >+ realm, >+ sname, >+ from_time, >+ till_time, >+ renew_time, >+ nonce, >+ etypes, >+ addresses, >+ EncAuthorizationData, >+ EncAuthorizationData_key, >+ additional_tickets, >+ asn1_print=asn1_print, >+ hexdump=hexdump) >+ KDC_REQ_obj = { >+ 'pvno': 5, >+ 'msg-type': msg_type, >+ 'req-body': KDC_REQ_BODY_obj, >+ } >+ if padata is not None: >+ KDC_REQ_obj['padata'] = padata >+ if asn1Spec is not None: >+ KDC_REQ_decoded = pyasn1_native_decode(KDC_REQ_obj, asn1Spec=asn1Spec) >+ else: >+ KDC_REQ_decoded = None >+ return KDC_REQ_obj, KDC_REQ_decoded >+ >+ def AS_REQ_create(self, >+ padata, # optional >+ kdc_options, # required >+ cname, # optional >+ realm, # required >+ sname, # optional >+ from_time, # optional >+ till_time, # required >+ renew_time, # optional >+ nonce, # required >+ etypes, # required >+ addresses, # optional >+ EncAuthorizationData, >+ EncAuthorizationData_key, >+ additional_tickets, >+ native_decoded_only=True, >+ asn1_print=None, >+ hexdump=None): >+ #KDC-REQ ::= SEQUENCE { >+ # -- NOTE: first tag is [1], not [0] >+ # pvno [1] INTEGER (5) , >+ # msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), >+ # padata [3] SEQUENCE OF PA-DATA OPTIONAL >+ # -- NOTE: not empty --, >+ # req-body [4] KDC-REQ-BODY >+ #} >+ # >+ #KDC-REQ-BODY ::= SEQUENCE { >+ # kdc-options [0] KDCOptions, >+ # cname [1] PrincipalName OPTIONAL >+ # -- Used only in AS-REQ --, >+ # realm [2] Realm >+ # -- Server's realm >+ # -- Also client's in AS-REQ --, >+ # sname [3] PrincipalName OPTIONAL, >+ # from [4] KerberosTime OPTIONAL, >+ # till [5] KerberosTime, >+ # rtime [6] KerberosTime OPTIONAL, >+ # nonce [7] UInt32, >+ # etype [8] SEQUENCE OF Int32 -- EncryptionType >+ # -- in preference order --, >+ # addresses [9] HostAddresses OPTIONAL, >+ # enc-authorization-data [10] EncryptedData OPTIONAL >+ # -- AuthorizationData --, >+ # additional-tickets [11] SEQUENCE OF Ticket OPTIONAL >+ # -- NOTE: not empty >+ #} >+ obj,decoded = self.KDC_REQ_create(msg_type=10, >+ padata=padata, >+ kdc_options=kdc_options, >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=from_time, >+ till_time=till_time, >+ renew_time=renew_time, >+ nonce=nonce, >+ etypes=etypes, >+ addresses=addresses, >+ EncAuthorizationData=EncAuthorizationData, >+ EncAuthorizationData_key=EncAuthorizationData_key, >+ additional_tickets=additional_tickets, >+ asn1Spec=krb5_asn1.AS_REQ(), >+ asn1_print=asn1_print, >+ hexdump=hexdump) >+ if native_decoded_only: >+ return decoded >+ return decoded, obj >+ >+ def AP_REQ_create(self, ap_options, ticket, authenticator): >+ # AP-REQ ::= [APPLICATION 14] SEQUENCE { >+ # pvno [0] INTEGER (5), >+ # msg-type [1] INTEGER (14), >+ # ap-options [2] APOptions, >+ # ticket [3] Ticket, >+ # authenticator [4] EncryptedData -- Authenticator >+ #} >+ AP_REQ_obj = { >+ 'pvno': 5, >+ 'msg-type': 14, >+ 'ap-options': ap_options, >+ 'ticket': ticket, >+ 'authenticator': authenticator, >+ } >+ return AP_REQ_obj >+ >+ def Authenticator_create(self, crealm, cname, cksum, cusec, ctime, subkey, seq_number, >+ authorization_data): >+ # -- Unencrypted authenticator >+ # Authenticator ::= [APPLICATION 2] SEQUENCE { >+ # authenticator-vno [0] INTEGER (5), >+ # crealm [1] Realm, >+ # cname [2] PrincipalName, >+ # cksum [3] Checksum OPTIONAL, >+ # cusec [4] Microseconds, >+ # ctime [5] KerberosTime, >+ # subkey [6] EncryptionKey OPTIONAL, >+ # seq-number [7] UInt32 OPTIONAL, >+ # authorization-data [8] AuthorizationData OPTIONAL >+ #} >+ Authenticator_obj = { >+ 'authenticator-vno': 5, >+ 'crealm': crealm, >+ 'cname': cname, >+ 'cusec': cusec, >+ 'ctime': ctime, >+ } >+ if cksum is not None: >+ Authenticator_obj['cksum'] = cksum >+ if subkey is not None: >+ Authenticator_obj['subkey'] = subkey >+ if seq_number is not None: >+ Authenticator_obj['seq-number'] = seq_number >+ if authorization_data is not None: >+ Authenticator_obj['authorization-data'] = authorization_data >+ return Authenticator_obj >+ >+ def TGS_REQ_create(self, >+ padata, # optional >+ cusec, >+ ctime, >+ ticket, >+ kdc_options, # required >+ cname, # optional >+ realm, # required >+ sname, # optional >+ from_time, # optional >+ till_time, # required >+ renew_time, # optional >+ nonce, # required >+ etypes, # required >+ addresses, # optional >+ EncAuthorizationData, >+ EncAuthorizationData_key, >+ additional_tickets, >+ ticket_session_key, >+ authenticator_subkey=None, >+ body_checksum_type=None, >+ native_decoded_only=True, >+ asn1_print=None, >+ hexdump=None): >+ #KDC-REQ ::= SEQUENCE { >+ # -- NOTE: first tag is [1], not [0] >+ # pvno [1] INTEGER (5) , >+ # msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), >+ # padata [3] SEQUENCE OF PA-DATA OPTIONAL >+ # -- NOTE: not empty --, >+ # req-body [4] KDC-REQ-BODY >+ #} >+ # >+ #KDC-REQ-BODY ::= SEQUENCE { >+ # kdc-options [0] KDCOptions, >+ # cname [1] PrincipalName OPTIONAL >+ # -- Used only in AS-REQ --, >+ # realm [2] Realm >+ # -- Server's realm >+ # -- Also client's in AS-REQ --, >+ # sname [3] PrincipalName OPTIONAL, >+ # from [4] KerberosTime OPTIONAL, >+ # till [5] KerberosTime, >+ # rtime [6] KerberosTime OPTIONAL, >+ # nonce [7] UInt32, >+ # etype [8] SEQUENCE OF Int32 -- EncryptionType >+ # -- in preference order --, >+ # addresses [9] HostAddresses OPTIONAL, >+ # enc-authorization-data [10] EncryptedData OPTIONAL >+ # -- AuthorizationData --, >+ # additional-tickets [11] SEQUENCE OF Ticket OPTIONAL >+ # -- NOTE: not empty >+ #} >+ >+ req_body = self.KDC_REQ_BODY_create(kdc_options=kdc_options, >+ cname=None, >+ realm=realm, >+ sname=sname, >+ from_time=from_time, >+ till_time=till_time, >+ renew_time=renew_time, >+ nonce=nonce, >+ etypes=etypes, >+ addresses=addresses, >+ EncAuthorizationData=EncAuthorizationData, >+ EncAuthorizationData_key=EncAuthorizationData_key, >+ additional_tickets=additional_tickets) >+ req_body = self.der_encode(req_body, asn1Spec=krb5_asn1.KDC_REQ_BODY(), >+ asn1_print=asn1_print, hexdump=hexdump) >+ >+ req_body_checksum = self.Checksum_create(ticket_session_key, 6, req_body, >+ ctype=body_checksum_type) >+ >+ subkey_obj = None >+ if authenticator_subkey is not None: >+ subkey_obj = authenticator_subkey.export_obj() >+ seq_number = random.randint(0, 0xfffffffe) >+ authenticator = self.Authenticator_create(crealm=realm, >+ cname=cname, >+ cksum=req_body_checksum, >+ cusec=cusec, >+ ctime=ctime, >+ subkey=subkey_obj, >+ seq_number=seq_number, >+ authorization_data=None) >+ authenticator = self.der_encode(authenticator, asn1Spec=krb5_asn1.Authenticator(), >+ asn1_print=asn1_print, hexdump=hexdump) >+ >+ authenticator = self.EncryptedData_create(ticket_session_key, 7, authenticator) >+ >+ ap_options = krb5_asn1.APOptions('0') >+ ap_req = self.AP_REQ_create(ap_options=str(ap_options), >+ ticket=ticket, >+ authenticator=authenticator) >+ ap_req = self.der_encode(ap_req, asn1Spec=krb5_asn1.AP_REQ(), >+ asn1_print=asn1_print, hexdump=hexdump) >+ pa_tgs_req = self.PA_DATA_create(1, ap_req) >+ if padata is not None: >+ padata.append(pa_tgs_req) >+ else: >+ padata = [pa_tgs_req] >+ >+ obj,decoded = self.KDC_REQ_create(msg_type=12, >+ padata=padata, >+ kdc_options=kdc_options, >+ cname=None, >+ realm=realm, >+ sname=sname, >+ from_time=from_time, >+ till_time=till_time, >+ renew_time=renew_time, >+ nonce=nonce, >+ etypes=etypes, >+ addresses=addresses, >+ EncAuthorizationData=EncAuthorizationData, >+ EncAuthorizationData_key=EncAuthorizationData_key, >+ additional_tickets=additional_tickets, >+ asn1Spec=krb5_asn1.TGS_REQ(), >+ asn1_print=asn1_print, >+ hexdump=hexdump) >+ if native_decoded_only: >+ return decoded >+ return decoded, obj >-- >2.25.1 > > >From 975bfad2523ae33996864ec1b0be486778e2d162 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 13 Feb 2020 16:29:38 +0100 >Subject: [PATCH 026/686] python/tests/krb5: add simple_tests.py with the first > simple test > >This just demonstrates that the infrastructure works:-) > >I'm running this as: > > SERVER=172.31.9.188 DOMAIN=W2012R2-L6 REALM=W2012R2-L6.BASE \ > USERNAME=administrator PASSWORD=A1b2C3d4 SERVICE_USERNAME="w2012r2-188" \ > python/samba/tests/krb5/simple_tests.py > >Pair-Programmed-With: Isaac Boukris <iboukris@samba.org> > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Signed-off-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 4f6d26609a66a42df671a540677af15e67efc0df) >--- > python/samba/tests/krb5/simple_tests.py | 171 ++++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > 2 files changed, 172 insertions(+) > create mode 100755 python/samba/tests/krb5/simple_tests.py > >diff --git a/python/samba/tests/krb5/simple_tests.py b/python/samba/tests/krb5/simple_tests.py >new file mode 100755 >index 00000000000..c9998c4d2db >--- /dev/null >+++ b/python/samba/tests/krb5/simple_tests.py >@@ -0,0 +1,171 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+from samba.tests.krb5.raw_testcase import RawKerberosTest >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+ >+global_asn1_print = False >+global_hexdump = False >+ >+class SimpleKerberosTests(RawKerberosTest): >+ >+ def setUp(self): >+ super(SimpleKerberosTests, self).setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def test_simple(self): >+ user_creds = self.get_user_creds() >+ user = user_creds.get_username() >+ realm = user_creds.get_realm() >+ >+ cname = self.PrincipalName_create(name_type=1, names=[user]) >+ sname = self.PrincipalName_create(name_type=2, names=["krbtgt", realm]) >+ >+ till = self.get_KerberosTime(offset=36000) >+ >+ kdc_options = krb5_asn1.KDCOptions('forwardable') >+ padata = None >+ >+ etypes=(18,17,23) >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ self.assertEqual(rep['msg-type'], 30) >+ self.assertEqual(rep['error-code'], 25) >+ rep_padata = self.der_decode(rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) >+ >+ for pa in rep_padata: >+ if pa['padata-type'] == 19: >+ etype_info2 = pa['padata-value'] >+ break >+ >+ etype_info2 = self.der_decode(etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ >+ key = self.PasswordKey_from_etype_info2(user_creds, etype_info2[0]) >+ >+ (patime, pausec) = self.get_KerberosTimeWithUsec() >+ pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) >+ >+ enc_pa_ts_usage = 1 >+ pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) >+ >+ pa_ts = self.PA_DATA_create(2, pa_ts) >+ >+ kdc_options = krb5_asn1.KDCOptions('forwardable') >+ padata = [pa_ts] >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ msg_type = rep['msg-type'] >+ self.assertEqual(msg_type, 11) >+ >+ usage = 3 >+ enc_part2 = key.decrypt(usage, rep['enc-part']['cipher']) >+ enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ >+ # TGS Request >+ service_creds = self.get_service_creds(allow_missing_password=True) >+ service_name = service_creds.get_username() >+ >+ sname = self.PrincipalName_create(name_type=2, names=["host", service_name]) >+ kdc_options = krb5_asn1.KDCOptions('forwardable') >+ till = self.get_KerberosTime(offset=36000) >+ ticket = rep['ticket'] >+ ticket_session_key = self.EncryptionKey_import(enc_part2['key']) >+ padata = [] >+ >+ subkey = self.RandomKey(ticket_session_key.etype) >+ subkey_usage = 9 >+ >+ (ctime, cusec) = self.get_KerberosTimeWithUsec() >+ >+ req = self.TGS_REQ_create(padata=padata, >+ cusec=cusec, >+ ctime=ctime, >+ ticket=ticket, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7ffffffe, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None, >+ ticket_session_key=ticket_session_key, >+ authenticator_subkey=subkey) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ msg_type = rep['msg-type'] >+ self.assertEqual(msg_type, 13) >+ >+ enc_part2 = subkey.decrypt(subkey_usage, rep['enc-part']['cipher']) >+ enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ >+ return >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index cebc54461b9..de144f1d6a4 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -84,6 +84,7 @@ EXCLUDE_USAGE = { > 'bin/python/samba/subunit/run.py', > 'python/samba/tests/dcerpc/raw_protocol.py', > 'python/samba/tests/krb5/kcrypto.py', >+ 'python/samba/tests/krb5/simple_tests.py', > } > > >-- >2.25.1 > > >From c331bb7b7884c3cd8742c0e54516e568850bcd34 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 13 Feb 2020 16:29:38 +0100 >Subject: [PATCH 027/686] s4:selftest: run samba.tests.krb5.simple_tests > against ad_dc_default > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Fri Mar 27 19:54:25 UTC 2020 on sn-devel-184 > >(cherry picked from commit c4ccdf4b30de1b1e63d3fd99d33b924b816a5d37) >--- > source4/selftest/tests.py | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index e627158d2f9..06828a53dae 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -714,6 +714,8 @@ planoldpythontestsuite("ad_dc:local", "samba.tests.gpo", extra_args=['-U"$USERNA > planoldpythontestsuite("ad_dc:local", "samba.tests.dckeytab", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) > > planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") >+planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", >+ environ={'SERVICE_USERNAME':'$SERVER'}) > > for env in ["ad_dc", smbv1_disabled_testenv]: > planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) >-- >2.25.1 > > >From ab73e2eee23ad0adb0da4225391de98a9236c356 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Thu, 7 May 2020 17:17:12 +0200 >Subject: [PATCH 028/686] Revert "CVE-2018-16860 selftest: Add test for > S4U2Self with unkeyed checksum" > >This reverts commit 5639e973c1f6f1b28b122741763f1d05b47bc2d8. > >This is no longer needed as the next commit includes a Python >test for this, without the complexity of being inside krb5.kdc.canon. > >Signed-off-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 19875a37318a7cd5585572616cf12a775591193f) >--- > source4/torture/krb5/kdc-canon-heimdal.c | 105 +---------------------- > 1 file changed, 4 insertions(+), 101 deletions(-) > >diff --git a/source4/torture/krb5/kdc-canon-heimdal.c b/source4/torture/krb5/kdc-canon-heimdal.c >index ee3045181dc..30eca87cb52 100644 >--- a/source4/torture/krb5/kdc-canon-heimdal.c >+++ b/source4/torture/krb5/kdc-canon-heimdal.c >@@ -44,8 +44,7 @@ > #define TEST_S4U2SELF 0x0000080 > #define TEST_REMOVEDOLLAR 0x0000100 > #define TEST_AS_REQ_SPN 0x0000200 >-#define TEST_MITM_S4U2SELF 0x0000400 >-#define TEST_ALL 0x00007FF >+#define TEST_ALL 0x00003FF > > struct test_data { > const char *test_name; >@@ -63,7 +62,6 @@ struct test_data { > bool upn; > bool other_upn_suffix; > bool s4u2self; >- bool mitm_s4u2self; > bool removedollar; > bool as_req_spn; > bool spn_is_upn; >@@ -214,67 +212,6 @@ static bool test_accept_ticket(struct torture_context *tctx, > return true; > } > >-krb5_error_code >-_krb5_s4u2self_to_checksumdata(krb5_context context, >- const PA_S4U2Self *self, >- krb5_data *data); >- >-/* Helper function to modify the principal in PA_FOR_USER padata */ >-static bool change_for_user_principal(struct torture_krb5_context *test_context, >- krb5_data *modified_send_buf) >-{ >- PA_DATA *for_user; >- int i = 0; >- size_t used; >- krb5_error_code ret; >- PA_S4U2Self self, mod_self; >- krb5_data cksum_data; >- krb5_principal admin; >- heim_octet_string orig_padata_value; >- krb5_context k5_ctx = test_context->smb_krb5_context->krb5_context; >- >- for_user = krb5_find_padata(test_context->tgs_req.padata->val, >- test_context->tgs_req.padata->len, KRB5_PADATA_FOR_USER, &i); >- torture_assert(test_context->tctx, for_user != NULL, "No PA_FOR_USER in s4u2self request"); >- orig_padata_value = for_user->padata_value; >- >- torture_assert_int_equal(test_context->tctx, >- krb5_make_principal(k5_ctx, &admin, test_context->test_data->realm, >- "Administrator", NULL), >- 0, "krb5_make_principal() failed"); >- torture_assert_int_equal(test_context->tctx, >- decode_PA_S4U2Self(for_user->padata_value.data, >- for_user->padata_value.length, &self, NULL), >- 0, "decode_PA_S4U2Self() failed"); >- mod_self = self; >- mod_self.name = admin->name; >- >- torture_assert_int_equal(test_context->tctx, >- _krb5_s4u2self_to_checksumdata(k5_ctx, &mod_self, &cksum_data), >- 0, "_krb5_s4u2self_to_checksumdata() failed"); >- torture_assert_int_equal(test_context->tctx, >- krb5_create_checksum(k5_ctx, NULL, KRB5_KU_OTHER_CKSUM, >- CKSUMTYPE_CRC32, cksum_data.data, >- cksum_data.length, &mod_self.cksum), >- 0, "krb5_create_checksum() failed"); >- >- ASN1_MALLOC_ENCODE(PA_S4U2Self, for_user->padata_value.data, for_user->padata_value.length, >- &mod_self, &used, ret); >- torture_assert(test_context->tctx, ret == 0, "Failed to encode PA_S4U2Self ASN1 struct"); >- ASN1_MALLOC_ENCODE(TGS_REQ, modified_send_buf->data, modified_send_buf->length, >- &test_context->tgs_req, &used, ret); >- torture_assert(test_context->tctx, ret == 0, "Failed to encode TGS_REQ ASN1 struct"); >- >- free(for_user->padata_value.data); >- for_user->padata_value = orig_padata_value; >- >- free_PA_S4U2Self(&self); >- krb5_data_free(&cksum_data); >- free_Checksum(&mod_self.cksum); >- >- return true; >-} >- > /* > * TEST_AS_REQ and TEST_AS_REQ_SELF - SEND > * >@@ -694,12 +631,7 @@ static bool torture_krb5_pre_send_tgs_req_canon_test(struct torture_krb5_context > > } > >- if (test_context->test_data->mitm_s4u2self) { >- torture_assert(test_context->tctx, change_for_user_principal(test_context, modified_send_buf), >- "Failed to modify PA_FOR_USER principal name"); >- } else { >- *modified_send_buf = *send_buf; >- } >+ *modified_send_buf = *send_buf; > > return true; > } >@@ -718,7 +650,6 @@ static bool torture_krb5_post_recv_tgs_req_canon_test(struct torture_krb5_contex > { > KRB_ERROR error; > size_t used; >- krb5_error_code expected_error; > > /* > * If this account did not have a servicePrincipalName, then >@@ -729,13 +660,9 @@ static bool torture_krb5_post_recv_tgs_req_canon_test(struct torture_krb5_contex > torture_assert_int_equal(test_context->tctx, > error.pvno, 5, > "Got wrong error.pvno"); >- expected_error = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN - KRB5KDC_ERR_NONE; >- if (error.error_code != expected_error && test_context->test_data->mitm_s4u2self) { >- expected_error = KRB5KRB_AP_ERR_INAPP_CKSUM - KRB5KDC_ERR_NONE; >- } > torture_assert_int_equal(test_context->tctx, > error.error_code, >- expected_error, >+ KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN - KRB5KDC_ERR_NONE, > "Got wrong error.error_code"); > } else { > torture_assert_int_equal(test_context->tctx, >@@ -778,8 +705,6 @@ static bool torture_krb5_post_recv_tgs_req_canon_test(struct torture_krb5_contex > torture_assert_int_equal(test_context->tctx, > *test_context->tgs_rep.ticket.enc_part.kvno & 0xFFFF0000, > 0, "Unexpecedly got a RODC number in the KVNO, should just be principal KVNO"); >- torture_assert(test_context->tctx, test_context->test_data->mitm_s4u2self == false, >- "KDC accepted PA_S4U2Self with unkeyed checksum!"); > free_TGS_REP(&test_context->tgs_rep); > } > torture_assert(test_context->tctx, test_context->packet_count == 0, "too many packets"); >@@ -2081,23 +2006,7 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void * > && (test_data->enterprise > || test_data->spn_is_upn > || test_data->upn == false)) { >- >- if (test_data->mitm_s4u2self) { >- torture_assert_int_equal(tctx, k5ret, KRB5KRB_AP_ERR_INAPP_CKSUM, >- assertion_message); >- /* Done testing mitm-s4u2self */ >- return true; >- } >- > torture_assert_int_equal(tctx, k5ret, 0, assertion_message); >- >- /* Check that the impersonate principal is not being canonicalized by the KDC. */ >- if (test_data->s4u2self) { >- torture_assert(tctx, krb5_principal_compare(k5_context, server_creds->client, >- principal), >- "TGS-REP cname does not match requested client principal"); >- } >- > torture_assert_int_equal(tctx, krb5_cc_store_cred(k5_context, > ccache, server_creds), > 0, "krb5_cc_store_cred failed"); >@@ -2571,7 +2480,7 @@ struct torture_suite *torture_krb5_canon(TALLOC_CTX *mem_ctx) > (i & TEST_UPN) ? "upn" : > ((i & TEST_AS_REQ_SPN) ? "spn" : > ((i & TEST_REMOVEDOLLAR) ? "removedollar" : "samaccountname")), >- (i & TEST_S4U2SELF) ? (i & TEST_MITM_S4U2SELF) ? "mitm-s4u2self" : "s4u2self" : "normal"); >+ (i & TEST_S4U2SELF) ? "s4u2self" : "normal"); > struct torture_suite *sub_suite = torture_suite_create(mem_ctx, name); > > struct test_data *test_data = talloc_zero(suite, struct test_data); >@@ -2585,11 +2494,6 @@ struct torture_suite *torture_krb5_canon(TALLOC_CTX *mem_ctx) > continue; > } > } >- if (i & TEST_MITM_S4U2SELF) { >- if (!(i & TEST_S4U2SELF)) { >- continue; >- } >- } > > test_data->test_name = name; > test_data->real_realm >@@ -2610,7 +2514,6 @@ struct torture_suite *torture_krb5_canon(TALLOC_CTX *mem_ctx) > test_data->win2k = (i & TEST_WIN2K) != 0; > test_data->upn = (i & TEST_UPN) != 0; > test_data->s4u2self = (i & TEST_S4U2SELF) != 0; >- test_data->mitm_s4u2self = (i & TEST_MITM_S4U2SELF) != 0; > test_data->removedollar = (i & TEST_REMOVEDOLLAR) != 0; > test_data->as_req_spn = (i & TEST_AS_REQ_SPN) != 0; > torture_suite_add_simple_tcase_const(sub_suite, name, torture_krb5_as_req_canon, >-- >2.25.1 > > >From b711e6b0180ac628bb1e1aa89c77e6434b088066 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Mon, 4 May 2020 18:09:53 +0200 >Subject: [PATCH 029/686] selftest: add python S4U2Self tests including unkeyed > checksums > >To test the CRC32 I reverted the unkeyed-checksum fix (43958af1) >and the weak-crypto fix (389d1b97). Note that the unkeyed-md5 >still worked even with weak-crypto disabled, and that the >unkeyed-sha1 never worked but I left it anyway. > >Signed-off-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Fri May 15 12:25:40 UTC 2020 on sn-devel-184 > >(cherry picked from commit 8b5e7644130146bcc4e5a0dd05da6458a6025dd8) >--- > python/samba/tests/krb5/kcrypto.py | 85 ++++++++++ > python/samba/tests/krb5/raw_testcase.py | 23 +++ > python/samba/tests/krb5/rfc4120.asn1 | 8 + > python/samba/tests/krb5/rfc4120_pyasn1.py | 14 +- > python/samba/tests/krb5/s4u_tests.py | 197 ++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > selftest/knownfail | 2 + > selftest/skip_mit_kdc | 1 + > selftest/target/Samba4.pm | 23 +++ > source4/selftest/tests.py | 4 + > 10 files changed, 357 insertions(+), 1 deletion(-) > create mode 100755 python/samba/tests/krb5/s4u_tests.py > >diff --git a/python/samba/tests/krb5/kcrypto.py b/python/samba/tests/krb5/kcrypto.py >index ed3c84fa186..2572fa5bab3 100755 >--- a/python/samba/tests/krb5/kcrypto.py >+++ b/python/samba/tests/krb5/kcrypto.py >@@ -51,6 +51,7 @@ os.environ["PYTHONUNBUFFERED"] = "1" > from math import gcd > from functools import reduce > from struct import pack, unpack >+from binascii import crc32 > from cryptography.hazmat.primitives import hashes > from cryptography.hazmat.primitives import hmac > from cryptography.hazmat.primitives.ciphers import algorithms as ciphers >@@ -533,6 +534,21 @@ class _MD5(_ChecksumProfile): > return SIMPLE_HASH(text, hashes.MD5) > > >+class _SHA1(_ChecksumProfile): >+ @classmethod >+ def checksum(cls, key, keyusage, text): >+ # This is unkeyed! >+ return SIMPLE_HASH(text, hashes.SHA1) >+ >+ >+class _CRC32(_ChecksumProfile): >+ @classmethod >+ def checksum(cls, key, keyusage, text): >+ # This is unkeyed! >+ cksum = (~crc32(text, 0xffffffff)) & 0xffffffff >+ return pack('<I', cksum) >+ >+ > _enctype_table = { > Enctype.DES3: _DES3CBC, > Enctype.AES128: _AES128CTS, >@@ -547,6 +563,8 @@ _checksum_table = { > Cksumtype.SHA1_AES256: _SHA1AES256, > Cksumtype.HMAC_MD5: _HMACMD5, > Cksumtype.MD5: _MD5, >+ Cksumtype.SHA1: _SHA1, >+ Cksumtype.CRC32: _CRC32, > } > > >@@ -835,6 +853,73 @@ class KcrytoTest(TestCase): > def test_md5_unkeyed_checksum_aes256_usage_50(self): > return self._test_md5_unkeyed_checksum(Enctype.AES256, 50) > >+ def _test_sha1_unkeyed_checksum(self, etype, usage): >+ # SHA1 unkeyed checksum >+ pw = b'password' >+ salt = b'salt' >+ key = string_to_key(etype, pw, salt) >+ plain = b'twenty nineteen eighteen seventeen' >+ cksum = h('381c870d8875d1913555de19af5c885fd27b7da9') >+ verify_checksum(Cksumtype.SHA1, key, usage, plain, cksum) >+ >+ def test_sha1_unkeyed_checksum_des3_usage_40(self): >+ return self._test_sha1_unkeyed_checksum(Enctype.DES3, 40) >+ >+ def test_sha1_unkeyed_checksum_des3_usage_50(self): >+ return self._test_sha1_unkeyed_checksum(Enctype.DES3, 50) >+ >+ def test_sha1_unkeyed_checksum_rc4_usage_40(self): >+ return self._test_sha1_unkeyed_checksum(Enctype.RC4, 40) >+ >+ def test_sha1_unkeyed_checksum_rc4_usage_50(self): >+ return self._test_sha1_unkeyed_checksum(Enctype.RC4, 50) >+ >+ def test_sha1_unkeyed_checksum_aes128_usage_40(self): >+ return self._test_sha1_unkeyed_checksum(Enctype.AES128, 40) >+ >+ def test_sha1_unkeyed_checksum_aes128_usage_50(self): >+ return self._test_sha1_unkeyed_checksum(Enctype.AES128, 50) >+ >+ def test_sha1_unkeyed_checksum_aes256_usage_40(self): >+ return self._test_sha1_unkeyed_checksum(Enctype.AES256, 40) >+ >+ def test_sha1_unkeyed_checksum_aes256_usage_50(self): >+ return self._test_sha1_unkeyed_checksum(Enctype.AES256, 50) >+ >+ def _test_crc32_unkeyed_checksum(self, etype, usage): >+ # CRC32 unkeyed checksum >+ pw = b'password' >+ salt = b'salt' >+ key = string_to_key(etype, pw, salt) >+ plain = b'africa america asia australia europe' >+ cksum = h('ce595a53') >+ verify_checksum(Cksumtype.CRC32, key, usage, plain, cksum) >+ >+ def test_crc32_unkeyed_checksum_des3_usage_40(self): >+ return self._test_crc32_unkeyed_checksum(Enctype.DES3, 40) >+ >+ def test_crc32_unkeyed_checksum_des3_usage_50(self): >+ return self._test_crc32_unkeyed_checksum(Enctype.DES3, 50) >+ >+ def test_crc32_unkeyed_checksum_rc4_usage_40(self): >+ return self._test_crc32_unkeyed_checksum(Enctype.RC4, 40) >+ >+ def test_crc32_unkeyed_checksum_rc4_usage_50(self): >+ return self._test_crc32_unkeyed_checksum(Enctype.RC4, 50) >+ >+ def test_crc32_unkeyed_checksum_aes128_usage_40(self): >+ return self._test_crc32_unkeyed_checksum(Enctype.AES128, 40) >+ >+ def test_crc32_unkeyed_checksum_aes128_usage_50(self): >+ return self._test_crc32_unkeyed_checksum(Enctype.AES128, 50) >+ >+ def test_crc32_unkeyed_checksum_aes256_usage_40(self): >+ return self._test_crc32_unkeyed_checksum(Enctype.AES256, 40) >+ >+ def test_crc32_unkeyed_checksum_aes256_usage_50(self): >+ return self._test_crc32_unkeyed_checksum(Enctype.AES256, 50) >+ >+ > if __name__ == "__main__": > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 6c7bcd418a0..f43ce9cbc3c 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -867,3 +867,26 @@ class RawKerberosTest(TestCase): > if native_decoded_only: > return decoded > return decoded, obj >+ >+ def PA_S4U2Self_create(self, name, realm, tgt_session_key, ctype=None): >+ # PA-S4U2Self ::= SEQUENCE { >+ # name [0] PrincipalName, >+ # realm [1] Realm, >+ # cksum [2] Checksum, >+ # auth [3] GeneralString >+ # } >+ cksum_data = name['name-type'].to_bytes(4, byteorder='little') >+ for n in name['name-string']: >+ cksum_data += n.encode() >+ cksum_data += realm.encode() >+ cksum_data += "Kerberos".encode() >+ cksum = self.Checksum_create(tgt_session_key, 17, cksum_data, ctype) >+ >+ PA_S4U2Self_obj = { >+ 'name': name, >+ 'realm': realm, >+ 'cksum': cksum, >+ 'auth': "Kerberos", >+ } >+ pa_s4u2self = self.der_encode(PA_S4U2Self_obj, asn1Spec=krb5_asn1.PA_S4U2Self()) >+ return self.PA_DATA_create(129, pa_s4u2self) >diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 >index 05b43106034..98ba887729d 100644 >--- a/python/samba/tests/krb5/rfc4120.asn1 >+++ b/python/samba/tests/krb5/rfc4120.asn1 >@@ -415,6 +415,14 @@ AD-AND-OR ::= SEQUENCE { > > AD-MANDATORY-FOR-KDC ::= AuthorizationData > >+-- S4U >+ >+PA-S4U2Self ::= SEQUENCE { >+ name [0] PrincipalName, >+ realm [1] Realm, >+ cksum [2] Checksum, >+ auth [3] KerberosString >+} > > > >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1.py b/python/samba/tests/krb5/rfc4120_pyasn1.py >index b2627aa3dcb..05304a8a099 100644 >--- a/python/samba/tests/krb5/rfc4120_pyasn1.py >+++ b/python/samba/tests/krb5/rfc4120_pyasn1.py >@@ -1,5 +1,5 @@ > # Auto-generated by asn1ate v.0.6.1.dev0 from rfc4120.asn1 >-# (last modified on 2020-03-26 10:28:24.346775) >+# (last modified on 2020-05-06 17:51:00.323318) > > # KerberosV5Spec2 > from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful >@@ -780,6 +780,18 @@ PA_ENC_TS_ENC.componentType = namedtype.NamedTypes( > ) > > >+class PA_S4U2Self(univ.Sequence): >+ pass >+ >+ >+PA_S4U2Self.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('name', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), >+ namedtype.NamedType('realm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('cksum', Checksum().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), >+ namedtype.NamedType('auth', KerberosString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) >+) >+ >+ > class PADataTypeValues(univ.Integer): > pass > >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >new file mode 100755 >index 00000000000..ae38635c53b >--- /dev/null >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -0,0 +1,197 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+from samba.tests import env_get_var_value >+from samba.tests.krb5.kcrypto import Cksumtype >+from samba.tests.krb5.raw_testcase import RawKerberosTest >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+ >+global_asn1_print = False >+global_hexdump = False >+ >+class S4UKerberosTests(RawKerberosTest): >+ >+ def setUp(self): >+ super(S4UKerberosTests, self).setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def _test_s4u2self(self, pa_s4u2self_ctype=None): >+ service_creds = self.get_service_creds() >+ service = service_creds.get_username() >+ realm = service_creds.get_realm() >+ >+ cname = self.PrincipalName_create(name_type=1, names=[service]) >+ sname = self.PrincipalName_create(name_type=2, names=["krbtgt", realm]) >+ >+ till = self.get_KerberosTime(offset=36000) >+ >+ kdc_options = krb5_asn1.KDCOptions('forwardable') >+ padata = None >+ >+ etypes=(18,17,23) >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ self.assertEqual(rep['msg-type'], 30) >+ self.assertEqual(rep['error-code'], 25) >+ rep_padata = self.der_decode(rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) >+ >+ for pa in rep_padata: >+ if pa['padata-type'] == 19: >+ etype_info2 = pa['padata-value'] >+ break >+ >+ etype_info2 = self.der_decode(etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ >+ key = self.PasswordKey_from_etype_info2(service_creds, etype_info2[0]) >+ >+ (patime, pausec) = self.get_KerberosTimeWithUsec() >+ pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) >+ >+ enc_pa_ts_usage = 1 >+ pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) >+ >+ pa_ts = self.PA_DATA_create(2, pa_ts) >+ >+ kdc_options = krb5_asn1.KDCOptions('forwardable') >+ padata = [pa_ts] >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ msg_type = rep['msg-type'] >+ self.assertEqual(msg_type, 11) >+ >+ usage = 3 >+ enc_part2 = key.decrypt(usage, rep['enc-part']['cipher']) >+ enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ >+ # S4U2Self Request >+ sname = cname >+ >+ for_user_name = env_get_var_value('FOR_USER') >+ uname = self.PrincipalName_create(name_type=1, names=[for_user_name]) >+ >+ kdc_options = krb5_asn1.KDCOptions('forwardable') >+ till = self.get_KerberosTime(offset=36000) >+ ticket = rep['ticket'] >+ ticket_session_key = self.EncryptionKey_import(enc_part2['key']) >+ pa_s4u = self.PA_S4U2Self_create(name=uname, realm=realm, >+ tgt_session_key=ticket_session_key, >+ ctype=pa_s4u2self_ctype) >+ padata = [pa_s4u] >+ >+ subkey = self.RandomKey(ticket_session_key.etype) >+ subkey_usage = 9 >+ >+ (ctime, cusec) = self.get_KerberosTimeWithUsec() >+ >+ req = self.TGS_REQ_create(padata=padata, >+ cusec=cusec, >+ ctime=ctime, >+ ticket=ticket, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7ffffffe, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None, >+ ticket_session_key=ticket_session_key, >+ authenticator_subkey=subkey) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ msg_type = rep['msg-type'] >+ if msg_type == 13: >+ enc_part2 = subkey.decrypt(subkey_usage, rep['enc-part']['cipher']) >+ enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ >+ return msg_type >+ >+ # Using the checksum type from the tgt_session_key happens to work everywhere >+ def test_s4u2self(self): >+ msg_type = self._test_s4u2self() >+ self.assertEqual(msg_type, 13) >+ >+ # Per spec, the checksum of PA-FOR-USER is HMAC_MD5, see [MS-SFU] 2.2.1 >+ def test_s4u2self_hmac_md5_checksum(self): >+ msg_type = self._test_s4u2self(pa_s4u2self_ctype=Cksumtype.HMAC_MD5) >+ self.assertEqual(msg_type, 13) >+ >+ def test_s4u2self_md5_unkeyed_checksum(self): >+ msg_type = self._test_s4u2self(pa_s4u2self_ctype=Cksumtype.MD5) >+ self.assertEqual(msg_type, 30) >+ >+ def test_s4u2self_sha1_unkeyed_checksum(self): >+ msg_type = self._test_s4u2self(pa_s4u2self_ctype=Cksumtype.SHA1) >+ self.assertEqual(msg_type, 30) >+ >+ def test_s4u2self_crc32_unkeyed_checksum(self): >+ msg_type = self._test_s4u2self(pa_s4u2self_ctype=Cksumtype.CRC32) >+ self.assertEqual(msg_type, 30) >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index de144f1d6a4..8af43bc8299 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -85,6 +85,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/dcerpc/raw_protocol.py', > 'python/samba/tests/krb5/kcrypto.py', > 'python/samba/tests/krb5/simple_tests.py', >+ 'python/samba/tests/krb5/s4u_tests.py', > } > > >diff --git a/selftest/knownfail b/selftest/knownfail >index 1817db384e0..3a851b06e8e 100644 >--- a/selftest/knownfail >+++ b/selftest/knownfail >@@ -361,3 +361,5 @@ > ^samba.tests.ntlmdisabled.python\(ktest\).python2.ntlmdisabled.NtlmDisabledTests.test_samr_change_password\(ktest\) > ^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).python3.ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\) > ^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).python2.ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\) >+# Fixed upstream heimdal in PR #439 >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_hmac_md5_checksum >diff --git a/selftest/skip_mit_kdc b/selftest/skip_mit_kdc >index 4a51c98ea0b..ea644638c9f 100644 >--- a/selftest/skip_mit_kdc >+++ b/selftest/skip_mit_kdc >@@ -3,3 +3,4 @@ > .*RODC > ^samba4.ntvfs.cifs.ntlm.base.unlink > ^samba4.ntvfs.cifs.krb5.base.unlink >+^samba.tests.krb5.s4u_tests >diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm >index 2fbd5e24928..aa12e823ae5 100755 >--- a/selftest/target/Samba4.pm >+++ b/selftest/target/Samba4.pm >@@ -954,6 +954,29 @@ sub provision_raw_step2($$$) > return undef; > } > >+ my $srv_account = "srv_account"; >+ $samba_tool_cmd = ""; >+ $samba_tool_cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" "; >+ $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" "; >+ $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" "; >+ $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool") >+ . " user create --configfile=$ctx->{smb_conf} $srv_account $ctx->{password}"; >+ unless (system($samba_tool_cmd) == 0) { >+ warn("Unable to add $srv_account user: \n$samba_tool_cmd\n"); >+ return undef; >+ } >+ >+ $samba_tool_cmd = ""; >+ $samba_tool_cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" "; >+ $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" "; >+ $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" "; >+ $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool") >+ . " spn add HOST/$srv_account --configfile=$ctx->{smb_conf} $srv_account"; >+ unless (system($samba_tool_cmd) == 0) { >+ warn("Unable to add spn for $srv_account: \n$samba_tool_cmd\n"); >+ return undef; >+ } >+ > my $ldbmodify = ""; > $ldbmodify .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" "; > $ldbmodify .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" "; >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 06828a53dae..dd3b894203b 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -716,6 +716,10 @@ planoldpythontestsuite("ad_dc:local", "samba.tests.dckeytab", extra_args=['-U"$U > planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", > environ={'SERVICE_USERNAME':'$SERVER'}) >+planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", >+ environ={'SERVICE_USERNAME':'srv_account', >+ 'SERVICE_PASSWORD':'$PASSWORD', >+ 'FOR_USER':'$USERNAME'}) > > for env in ["ad_dc", smbv1_disabled_testenv]: > planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) >-- >2.25.1 > > >From fa598b44e786421f8cb94cff5aec762871256629 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Sun, 19 Jan 2020 16:24:24 +0100 >Subject: [PATCH 030/686] selftest: add test for disallowed-forwardable server > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14233 > >Signed-off-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 197f97bc13c513ae6ae2b4129b23489081f63c64) >--- > selftest/knownfail.d/disallowed_forwardable_server | 1 + > testprogs/blackbox/test_s4u_heimdal.sh | 13 +++++++++++-- > 2 files changed, 12 insertions(+), 2 deletions(-) > create mode 100644 selftest/knownfail.d/disallowed_forwardable_server > >diff --git a/selftest/knownfail.d/disallowed_forwardable_server b/selftest/knownfail.d/disallowed_forwardable_server >new file mode 100644 >index 00000000000..2e05909ab89 >--- /dev/null >+++ b/selftest/knownfail.d/disallowed_forwardable_server >@@ -0,0 +1 @@ >+^samba4.blackbox.krb5.s4u.test S4U2Proxy using received ticket >diff --git a/testprogs/blackbox/test_s4u_heimdal.sh b/testprogs/blackbox/test_s4u_heimdal.sh >index 0e12c7ec096..c6ada54e85b 100755 >--- a/testprogs/blackbox/test_s4u_heimdal.sh >+++ b/testprogs/blackbox/test_s4u_heimdal.sh >@@ -54,7 +54,7 @@ testit "set not-delegated flag" $samba_tool user sensitive $princ on || failed=` > > > echo $PASSWORD > $PREFIX/tmppassfile >-testit "kinit with password" $samba4kinit -f --password-file=$PREFIX/tmppassfile $impersonator || failed=`expr $failed + 1` >+testit "kinit impersonator" $samba4kinit -f --password-file=$PREFIX/tmppassfile $impersonator || failed=`expr $failed + 1` > > testit "test S4U2Self with normal user" $samba4kgetcred --out-cache=$ocache --forwardable --impersonate=${USERNAME} $impersonator || failed=`expr $failed + 1` > testit "test S4U2Proxy with normal user" $samba4kgetcred --out-cache=$ocache --delegation-credential-cache=${ocache} $target || failed=`expr $failed + 1` >@@ -68,6 +68,15 @@ testit "unset not-delegated flag" $samba_tool user sensitive $princ off || faile > testit "test S4U2Self after unsetting ND flag" $samba4kgetcred --out-cache=$ocache --forwardable --impersonate=$princ $impersonator || failed=`expr $failed + 1` > testit "test S4U2Proxy after unsetting ND flag" $samba4kgetcred --out-cache=$ocache --delegation-credential-cache=${ocache} $target || failed=`expr $failed + 1` > >+testit "kinit user cache" $samba4kinit -c $ocache -f --password-file=$PREFIX/tmppassfile $USERNAME || failed=`expr $failed + 1` >+testit "get a ticket to impersonator" $samba4kgetcred -c $ocache --forwardable $impersonator || failed=`expr $failed + 1` >+testit "test S4U2Proxy evidence ticket obtained by TGS" $samba4kgetcred --out-cache=$ocache --delegation-credential-cache=${ocache} $target || failed=`expr $failed + 1` > >-rm -f $ocache $PREFIX/tmpccache tmppassfile >+testit "set not-delegated on impersonator" $samba_tool user sensitive $impersonator on || failed=`expr $failed + 1` >+testit "kinit user cache again" $samba4kinit -c $ocache -f --password-file=$PREFIX/tmppassfile $USERNAME || failed=`expr $failed + 1` >+testit "get a ticket to sensitive impersonator" $samba4kgetcred -c $ocache --forwardable $impersonator || failed=`expr $failed + 1` >+testit_expect_failure "test S4U2Proxy using received ticket" $samba4kgetcred --out-cache=$ocache --delegation-credential-cache=${ocache} $target || failed=`expr $failed + 1` >+ >+ >+rm -f $ocache $PREFIX/tmpccache $PREFIX/tmppassfile > exit $failed >-- >2.25.1 > > >From 8fbf70bcbcc7ec56c55949e03dd1e35f462b6701 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Mon, 13 Jan 2020 23:42:54 +0100 >Subject: [PATCH 031/686] heimdal: apply disallow-forwardable on server in TGS > request > >upstream commit: 839b073facd2aecda6740224d73e560bc79965dc > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14233 > >Signed-off-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 8fdff19c5461315556014d25d237a958edeed1a2) >--- > selftest/knownfail.d/disallowed_forwardable_server | 1 - > source4/heimdal/kdc/krb5tgs.c | 6 ++++++ > 2 files changed, 6 insertions(+), 1 deletion(-) > delete mode 100644 selftest/knownfail.d/disallowed_forwardable_server > >diff --git a/selftest/knownfail.d/disallowed_forwardable_server b/selftest/knownfail.d/disallowed_forwardable_server >deleted file mode 100644 >index 2e05909ab89..00000000000 >--- a/selftest/knownfail.d/disallowed_forwardable_server >+++ /dev/null >@@ -1 +0,0 @@ >-^samba4.blackbox.krb5.s4u.test S4U2Proxy using received ticket >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index ee3ac3d8f53..efbdd6ed77f 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -866,6 +866,12 @@ tgs_make_reply(krb5_context context, > et.flags.anonymous = tgt->flags.anonymous; > et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate; > >+ /* See MS-KILE 3.3.5.1 */ >+ if (!server->entry.flags.forwardable) >+ et.flags.forwardable = 0; >+ if (!server->entry.flags.proxiable) >+ et.flags.proxiable = 0; >+ > if(rspac->length) { > /* > * No not need to filter out the any PAC from the >-- >2.25.1 > > >From da9081c347de5f13f3875ef6ec9b39a57ff95fd0 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Thu, 7 May 2020 01:25:36 +0200 >Subject: [PATCH 032/686] selftest: allow EncASRepPart to be encoded as > EncTGSRepPart > >that's how MIT kdc encodes it, clients accept both. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14233 > >Signed-off-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a823cc1e8bc9a68a7e662022705039397a5df7e1) >--- > python/samba/tests/krb5/simple_tests.py | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/simple_tests.py b/python/samba/tests/krb5/simple_tests.py >index c9998c4d2db..236fbda1cd5 100755 >--- a/python/samba/tests/krb5/simple_tests.py >+++ b/python/samba/tests/krb5/simple_tests.py >@@ -115,7 +115,12 @@ class SimpleKerberosTests(RawKerberosTest): > > usage = 3 > enc_part2 = key.decrypt(usage, rep['enc-part']['cipher']) >- enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ >+ # MIT KDC encodes both EncASRepPart and EncTGSRepPart with application tag 26 >+ try: >+ enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ except Exception: >+ enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) > > # TGS Request > service_creds = self.get_service_creds(allow_missing_password=True) >-- >2.25.1 > > >From 474664fad2d1b99d1c13f7b35066038612bc0953 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Wed, 6 May 2020 15:54:55 +0200 >Subject: [PATCH 033/686] selftest: test forwardable flag in cross-realm tgt > tickets > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14233 > >Signed-off-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 9b302a57ff0d4c3a373f762f2ad4daf736b0853b) >--- > python/samba/tests/krb5/xrealm_tests.py | 180 ++++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > selftest/knownfail.d/xrealm | 1 + > source4/selftest/tests.py | 2 + > 4 files changed, 184 insertions(+) > create mode 100755 python/samba/tests/krb5/xrealm_tests.py > create mode 100644 selftest/knownfail.d/xrealm > >diff --git a/python/samba/tests/krb5/xrealm_tests.py b/python/samba/tests/krb5/xrealm_tests.py >new file mode 100755 >index 00000000000..64064b8a670 >--- /dev/null >+++ b/python/samba/tests/krb5/xrealm_tests.py >@@ -0,0 +1,180 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+from samba.tests.krb5.raw_testcase import RawKerberosTest >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+import samba.tests >+ >+global_asn1_print = False >+global_hexdump = False >+ >+class XrealmKerberosTests(RawKerberosTest): >+ >+ def setUp(self): >+ super(XrealmKerberosTests, self).setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def test_xrealm(self): >+ user_creds = self.get_user_creds() >+ user = user_creds.get_username() >+ realm = user_creds.get_realm() >+ >+ cname = self.PrincipalName_create(name_type=1, names=[user]) >+ sname = self.PrincipalName_create(name_type=2, names=["krbtgt", realm]) >+ >+ till = self.get_KerberosTime(offset=36000) >+ >+ kdc_options = krb5_asn1.KDCOptions('forwardable') >+ padata = None >+ >+ etypes=(18,17,23) >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ self.assertEqual(rep['msg-type'], 30) >+ self.assertEqual(rep['error-code'], 25) >+ rep_padata = self.der_decode(rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) >+ >+ for pa in rep_padata: >+ if pa['padata-type'] == 19: >+ etype_info2 = pa['padata-value'] >+ break >+ >+ etype_info2 = self.der_decode(etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ >+ key = self.PasswordKey_from_etype_info2(user_creds, etype_info2[0]) >+ >+ (patime, pausec) = self.get_KerberosTimeWithUsec() >+ pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) >+ >+ enc_pa_ts_usage = 1 >+ pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) >+ >+ pa_ts = self.PA_DATA_create(2, pa_ts) >+ >+ kdc_options = krb5_asn1.KDCOptions('forwardable') >+ padata = [pa_ts] >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ msg_type = rep['msg-type'] >+ self.assertEqual(msg_type, 11) >+ >+ usage = 3 >+ enc_part2 = key.decrypt(usage, rep['enc-part']['cipher']) >+ >+ # MIT KDC encodes both EncASRepPart and EncTGSRepPart with application tag 26 >+ try: >+ enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ except Exception: >+ enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ >+ # TGS Request (for cross-realm TGT) >+ trust_realm = samba.tests.env_get_var_value('TRUST_REALM') >+ sname = self.PrincipalName_create(name_type=2, names=["krbtgt", trust_realm]) >+ >+ kdc_options = krb5_asn1.KDCOptions('forwardable') >+ till = self.get_KerberosTime(offset=36000) >+ ticket = rep['ticket'] >+ ticket_session_key = self.EncryptionKey_import(enc_part2['key']) >+ padata = [] >+ >+ subkey = self.RandomKey(ticket_session_key.etype) >+ subkey_usage = 9 >+ >+ (ctime, cusec) = self.get_KerberosTimeWithUsec() >+ >+ req = self.TGS_REQ_create(padata=padata, >+ cusec=cusec, >+ ctime=ctime, >+ ticket=ticket, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7ffffffe, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None, >+ ticket_session_key=ticket_session_key, >+ authenticator_subkey=subkey) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ msg_type = rep['msg-type'] >+ self.assertEqual(msg_type, 13) >+ >+ enc_part2 = subkey.decrypt(subkey_usage, rep['enc-part']['cipher']) >+ enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ >+ # Check the forwardable flag >+ fwd_pos = len(tuple(krb5_asn1.TicketFlags('forwardable'))) -1 >+ assert(krb5_asn1.TicketFlags(enc_part2['flags'])[fwd_pos]) >+ >+ return >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 8af43bc8299..27cdb4c0cb3 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -86,6 +86,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/kcrypto.py', > 'python/samba/tests/krb5/simple_tests.py', > 'python/samba/tests/krb5/s4u_tests.py', >+ 'python/samba/tests/krb5/xrealm_tests.py', > } > > >diff --git a/selftest/knownfail.d/xrealm b/selftest/knownfail.d/xrealm >new file mode 100644 >index 00000000000..2e09644b1d8 >--- /dev/null >+++ b/selftest/knownfail.d/xrealm >@@ -0,0 +1 @@ >+^samba.tests.krb5.xrealm_tests.samba.tests.krb5.xrealm_tests.XrealmKerberosTests.test_xrealm >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index dd3b894203b..4aed6e1af91 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -721,6 +721,8 @@ planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", > 'SERVICE_PASSWORD':'$PASSWORD', > 'FOR_USER':'$USERNAME'}) > >+planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests") >+ > for env in ["ad_dc", smbv1_disabled_testenv]: > planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) > planoldpythontestsuite(env + ":local", "samba.tests.ntacls_backup", >-- >2.25.1 > > >From 12273e330ea1ad3063d24c397354ed6a50369611 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Sat, 9 May 2020 16:26:45 +0200 >Subject: [PATCH 034/686] selftest: test forwardable flag in cross-realm with > s4u2proxy > >Signed-off-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit fb7dfdbe8f94f7f053d67832e7f28a751136d733) > >[jsutton@samba.org Backported to fix conflicts] >--- > selftest/knownfail.d/s4u2p_fwd | 2 ++ > source4/selftest/tests.py | 2 +- > testprogs/blackbox/test_s4u_heimdal.sh | 17 ++++++++++++++--- > 3 files changed, 17 insertions(+), 4 deletions(-) > create mode 100644 selftest/knownfail.d/s4u2p_fwd > >diff --git a/selftest/knownfail.d/s4u2p_fwd b/selftest/knownfail.d/s4u2p_fwd >new file mode 100644 >index 00000000000..63ade3eece0 >--- /dev/null >+++ b/selftest/knownfail.d/s4u2p_fwd >@@ -0,0 +1,2 @@ >+^samba4.blackbox.krb5.s4u.get a ticket to impersonator for trust user >+^samba4.blackbox.krb5.s4u.test S4U2Proxy evidence ticket obtained by TGS of trust user >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 4aed6e1af91..91c25cfb978 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -460,7 +460,7 @@ if have_heimdal_support: > plantestsuite("samba4.blackbox.kinit_trust(fl2003dc:local)", "fl2003dc:local", [os.path.join(bbdir, "test_kinit_trusts_heimdal.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "external", "arcfour-hmac-md5"]) > plantestsuite("samba4.blackbox.export.keytab(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_export_keytab_heimdal.sh"), '$SERVER', '$USERNAME', '$REALM', '$DOMAIN', "$PREFIX", smbclient4]) > plantestsuite("samba4.blackbox.kpasswd(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_kpasswd_heimdal.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', "$PREFIX/ad_dc_ntvfs"]) >- plantestsuite("samba4.blackbox.krb5.s4u", "fl2008r2dc:local", [os.path.join(bbdir, "test_s4u_heimdal.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$PREFIX', configuration]) >+ plantestsuite("samba4.blackbox.krb5.s4u", "fl2008r2dc:local", [os.path.join(bbdir, "test_s4u_heimdal.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', configuration]) > else: > plantestsuite("samba4.blackbox.kinit(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_kinit_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$PREFIX', smbclient4, configuration]) > plantestsuite("samba4.blackbox.kinit(fl2000dc:local)", "fl2000dc:local", [os.path.join(bbdir, "test_kinit_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$PREFIX', smbclient4, configuration]) >diff --git a/testprogs/blackbox/test_s4u_heimdal.sh b/testprogs/blackbox/test_s4u_heimdal.sh >index c6ada54e85b..c63eeaa2e30 100755 >--- a/testprogs/blackbox/test_s4u_heimdal.sh >+++ b/testprogs/blackbox/test_s4u_heimdal.sh >@@ -12,8 +12,13 @@ USERNAME=$2 > PASSWORD=$3 > REALM=$4 > DOMAIN=$5 >-PREFIX=$6 >-shift 6 >+TRUST_SERVER=$6 >+TRUST_USERNAME=$7 >+TRUST_PASSWORD=$8 >+TRUST_REALM=$9 >+TRUST_DOMAIN=${10} >+PREFIX=${11} >+shift 11 > failed=0 > > >@@ -39,7 +44,7 @@ export KRB5CCNAME > rm -rf $KRB5CCNAME_PATH > > princ=test_impersonate_princ >-impersonator=test_impersonator >+impersonator=test_impersonator.$REALM > target="CIFS/$SERVER.$REALM" > > >@@ -72,6 +77,12 @@ testit "kinit user cache" $samba4kinit -c $ocache -f --password-file=$PREFIX/tmp > testit "get a ticket to impersonator" $samba4kgetcred -c $ocache --forwardable $impersonator || failed=`expr $failed + 1` > testit "test S4U2Proxy evidence ticket obtained by TGS" $samba4kgetcred --out-cache=$ocache --delegation-credential-cache=${ocache} $target || failed=`expr $failed + 1` > >+echo $TRUST_PASSWORD > $PREFIX/tmppassfile >+testit "kinit trust user cache" $samba4kinit -c $ocache -f --password-file=$PREFIX/tmppassfile $TRUST_USERNAME@$TRUST_REALM || failed=`expr $failed + 1` >+testit "get a ticket to impersonator for trust user" $samba4kgetcred -c $ocache --forwardable $impersonator || failed=`expr $failed + 1` >+testit "test S4U2Proxy evidence ticket obtained by TGS of trust user" $samba4kgetcred --out-cache=$ocache --delegation-credential-cache=${ocache} $target || failed=`expr $failed + 1` >+ >+echo $PASSWORD > $PREFIX/tmppassfile > testit "set not-delegated on impersonator" $samba_tool user sensitive $impersonator on || failed=`expr $failed + 1` > testit "kinit user cache again" $samba4kinit -c $ocache -f --password-file=$PREFIX/tmppassfile $USERNAME || failed=`expr $failed + 1` > testit "get a ticket to sensitive impersonator" $samba4kgetcred -c $ocache --forwardable $impersonator || failed=`expr $failed + 1` >-- >2.25.1 > > >From afe2d6ee8ece7f143d44e636719c39e8e4d56602 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Tue, 14 Jan 2020 13:16:02 +0100 >Subject: [PATCH 035/686] db-glue.c: set forwardable flag on cross-realm tgt > tickets > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14233 > >Match Windows behavior and allow the forwardable flag to be >set in cross-realm tickets. We used to allow forwardable to >any server, but now that we apply disallow-forwardable policy >in heimdal we need to explicitly allow in the corss-realm case >(and remove the workaround we have for it the MIT plugin). > >Signed-off-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Fri Jun 12 22:10:34 UTC 2020 on sn-devel-184 > >(cherry picked from commit 7655a0298e5f55582bf48ec776d8cd8b79fb5dd9) >--- > selftest/knownfail.d/s4u2p_fwd | 2 -- > selftest/knownfail.d/xrealm | 1 - > source4/kdc/db-glue.c | 3 +++ > source4/kdc/mit_samba.c | 5 ----- > 4 files changed, 3 insertions(+), 8 deletions(-) > delete mode 100644 selftest/knownfail.d/s4u2p_fwd > delete mode 100644 selftest/knownfail.d/xrealm > >diff --git a/selftest/knownfail.d/s4u2p_fwd b/selftest/knownfail.d/s4u2p_fwd >deleted file mode 100644 >index 63ade3eece0..00000000000 >--- a/selftest/knownfail.d/s4u2p_fwd >+++ /dev/null >@@ -1,2 +0,0 @@ >-^samba4.blackbox.krb5.s4u.get a ticket to impersonator for trust user >-^samba4.blackbox.krb5.s4u.test S4U2Proxy evidence ticket obtained by TGS of trust user >diff --git a/selftest/knownfail.d/xrealm b/selftest/knownfail.d/xrealm >deleted file mode 100644 >index 2e09644b1d8..00000000000 >--- a/selftest/knownfail.d/xrealm >+++ /dev/null >@@ -1 +0,0 @@ >-^samba.tests.krb5.xrealm_tests.samba.tests.krb5.xrealm_tests.XrealmKerberosTests.test_xrealm >diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c >index f62a633c6c7..63d910eccb4 100644 >--- a/source4/kdc/db-glue.c >+++ b/source4/kdc/db-glue.c >@@ -1556,6 +1556,9 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context, > > entry_ex->entry.max_renew = NULL; > >+ /* Match Windows behavior and allow forwardable flag in cross-realm. */ >+ entry_ex->entry.flags.forwardable = 1; >+ > ret = samba_kdc_sort_encryption_keys(entry_ex); > if (ret != 0) { > krb5_clear_error_message(context); >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index 5a4f6e73e97..54dcd545ea1 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -304,11 +304,6 @@ fetch_referral_principal: > > sdb_free_entry(&sentry); > >- if ((kflags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) == 0) { >- kentry->attributes &= ~KRB5_KDB_DISALLOW_FORWARDABLE; >- kentry->attributes &= ~KRB5_KDB_DISALLOW_PROXIABLE; >- } >- > done: > krb5_free_principal(ctx->context, referral_principal); > referral_principal = NULL; >-- >2.25.1 > > >From cf9e1dc2218ef88aa0e28690d336473adb2af5c2 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 3 Nov 2020 09:25:48 +1300 >Subject: [PATCH 036/686] selftest: add mit kdc specific known fail > >Add a MIT kerberos specific known fail, will be needed by subsequent >commits. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 04248f5e868d38498bdc8f9705c9a60fcfe79c09) >--- > selftest/knownfail_mit_kdc | 0 > selftest/wscript | 2 ++ > 2 files changed, 2 insertions(+) > create mode 100644 selftest/knownfail_mit_kdc > >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >new file mode 100644 >index 00000000000..e69de29bb2d >diff --git a/selftest/wscript b/selftest/wscript >index b7eec2c2605..80e0f1feabd 100644 >--- a/selftest/wscript >+++ b/selftest/wscript >@@ -268,6 +268,8 @@ def cmd_testonly(opt): > > if CONFIG_GET(opt, 'USING_SYSTEM_KRB5') and CONFIG_GET(opt, 'MIT_KDC_PATH'): > env.OPTIONS += " --mitkrb5 --exclude=${srcdir}/selftest/skip_mit_kdc" >+ env.FILTER_XFAIL += " --expected-failures=${srcdir}/selftest/"\ >+ "knownfail_mit_kdc" > > if not CONFIG_GET(opt, 'HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X'): > # older MIT krb5 libraries (< 1.14) don't have >-- >2.25.1 > > >From 9cc79dc5fdb638cf0c9955a7438b3362c3468031 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 27 Oct 2020 09:29:56 +1300 >Subject: [PATCH 037/686] tests python krb5: Make PrincipalName_create a class > method > >Make PrincipalName_create a class method, so it can be used in helper >classes. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit b14dca7c1c063e069517ff01b33c63a000d398c3) >--- > python/samba/tests/krb5/raw_testcase.py | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index f43ce9cbc3c..45e46e0b7ba 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -470,6 +470,7 @@ class RawKerberosTest(TestCase): > } > return Checksum_obj > >+ @classmethod > def PrincipalName_create(self, name_type, names): > # PrincipalName ::= SEQUENCE { > # name-type [0] Int32, >-- >2.25.1 > > >From 04724db90987f96f7717fe6e36794743d6e56c99 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 27 Oct 2020 09:31:24 +1300 >Subject: [PATCH 038/686] tests python krb5: Add canonicalize flag to ASN1 > >Add the canonicalize flag to KerberosFlags, so that it can be used in >python based canonicalization tests. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 41c8aa4b991aad306d731b08d068c480eb5c7fed) >--- > python/samba/tests/krb5/rfc4120.asn1 | 8 ++++---- > python/samba/tests/krb5/rfc4120_pyasn1.py | 4 ++-- > 2 files changed, 6 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 >index 98ba887729d..58e0c1636a1 100644 >--- a/python/samba/tests/krb5/rfc4120.asn1 >+++ b/python/samba/tests/krb5/rfc4120.asn1 >@@ -196,8 +196,8 @@ KDCOptions ::= KerberosFlags > -- opt-hardware-auth(11), > -- unused12(12), > -- unused13(13), >--- 15 is reserved for canonicalize >- -- unused15(15), >+-- Canonicalize is used in RFC 6806 >+ -- canonicalize(15), > -- 26 was unused in 1510 > -- disable-transited-check(26), > -- >@@ -489,8 +489,8 @@ KDCOptionsValues ::= BIT STRING { -- KerberosFlags > opt-hardware-auth(11), > unused12(12), > unused13(13), >--- 15 is reserved for canonicalize >- unused15(15), >+-- Canonicalize is used by RFC 6806 >+ canonicalize(15), > -- 26 was unused in 1510 > disable-transited-check(26), > -- >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1.py b/python/samba/tests/krb5/rfc4120_pyasn1.py >index 05304a8a099..b4ea678afd8 100644 >--- a/python/samba/tests/krb5/rfc4120_pyasn1.py >+++ b/python/samba/tests/krb5/rfc4120_pyasn1.py >@@ -1,5 +1,5 @@ > # Auto-generated by asn1ate v.0.6.1.dev0 from rfc4120.asn1 >-# (last modified on 2020-05-06 17:51:00.323318) >+# (last modified on 2020-11-03 14:07:15.270009) > > # KerberosV5Spec2 > from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful >@@ -610,7 +610,7 @@ KDCOptionsValues.namedValues = namedval.NamedValues( > ('opt-hardware-auth', 11), > ('unused12', 12), > ('unused13', 13), >- ('unused15', 15), >+ ('canonicalize', 15), > ('disable-transited-check', 26), > ('renewable-ok', 27), > ('enc-tkt-in-skey', 28), >-- >2.25.1 > > >From f5eebcb5bd6cf92e1553ee58f0b2a249edb20b53 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 27 Oct 2020 09:32:21 +1300 >Subject: [PATCH 039/686] tests python krb5: Add python kerberos > canonicalization tests > >Add python canonicalization tests, loosely based on the code in >source4/torture/krb5/kdc-canon-heimdal.c. The long term goal is to move >the integration level tests out of kdc-canon-heimdal, leaving it as a >heimdal library unit test. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 005435dc4d7de9d442c7513edec8c782fe20fda3) >--- > .../tests/krb5/as_canonicalization_tests.py | 499 ++++++++++++++++++ > python/samba/tests/usage.py | 1 + > selftest/knownfail_mit_kdc | 144 +++++ > source4/selftest/tests.py | 1 + > 4 files changed, 645 insertions(+) > create mode 100755 python/samba/tests/krb5/as_canonicalization_tests.py > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >new file mode 100755 >index 00000000000..7b599ad6e44 >--- /dev/null >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -0,0 +1,499 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# >+# Copyright (C) Catalyst IT Ltd. 2020 >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+from enum import Enum, unique >+import pyasn1 >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+from samba.tests.krb5.raw_testcase import RawKerberosTest >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+import samba >+from samba.auth import system_session >+from samba.credentials import ( >+ Credentials, >+ CLI_CRED_NTLMv2_AUTH, >+ CLI_CRED_NTLM_AUTH, >+ DONT_USE_KERBEROS) >+from samba.dcerpc.misc import SEC_CHAN_WKSTA >+from samba.dsdb import ( >+ UF_WORKSTATION_TRUST_ACCOUNT, >+ UF_PASSWD_NOTREQD, >+ UF_NORMAL_ACCOUNT) >+from samba.samdb import SamDB >+from samba.tests import delete_force, DynamicTestCase >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+@unique >+class TestOptions(Enum): >+ Canonicalize = 1 >+ Enterprise = 2 >+ UpperRealm = 4 >+ UpperUserName = 8 >+ NetbiosRealm = 16 >+ UPN = 32 >+ RemoveDollar = 64 >+ Last = 128 >+ >+ def is_set(self, x): >+ return self.value & x >+ >+ >+@unique >+class CredentialsType(Enum): >+ User = 1 >+ Machine = 2 >+ >+ def is_set(self, x): >+ return self.value & x >+ >+ >+class TestData: >+ >+ def __init__(self, options, creds): >+ self.options = options >+ self.user_creds = creds >+ self.user_name = self.get_username(options, creds) >+ self.realm = self.get_realm(options, creds) >+ self.cname = RawKerberosTest.PrincipalName_create( >+ name_type=1, names=[self.user_name]) >+ self.sname = RawKerberosTest.PrincipalName_create( >+ name_type=2, names=["krbtgt", self.realm]) >+ self.canonicalize = TestOptions.Canonicalize.is_set(options) >+ >+ def get_realm(self, options, creds): >+ realm = creds.get_realm() >+ if TestOptions.NetbiosRealm.is_set(options): >+ realm = creds.get_domain() >+ if TestOptions.UpperRealm.is_set(options): >+ realm = realm.upper() >+ else: >+ realm = realm.lower() >+ return realm >+ >+ def get_username(self, options, creds): >+ name = creds.get_username() >+ if TestOptions.RemoveDollar.is_set(options) and name.endswith("$"): >+ name = name[:-1] >+ if TestOptions.Enterprise.is_set(options): >+ realm = creds.get_realm() >+ name = "{0}@{1}".format(name, realm) >+ if TestOptions.UpperUserName.is_set(options): >+ name = name.upper() >+ return name >+ >+ def __repr__(self): >+ rep = "Test Data: " >+ rep += "options = '" + "{:08b}".format(self.options) + "'" >+ rep += "user name = '" + self.user_name + "'" >+ rep += ", realm = '" + self.realm + "'" >+ rep += ", cname = '" + str(self.cname) + "'" >+ rep += ", sname = '" + str(self.sname) + "'" >+ return rep >+ >+ >+MACHINE_NAME = "tstkrb5cnnusr" >+USER_NAME = "tstkrb5cnnmch" >+ >+# Encryption types >+AES256_CTS_HMAC_SHA1_96 = int( >+ krb5_asn1.EncryptionTypeValues('kRB5-ENCTYPE-AES256-CTS-HMAC-SHA1-96')) >+AES128_CTS_HMAC_SHA1_96 = int( >+ krb5_asn1.EncryptionTypeValues('kRB5-ENCTYPE-AES128-CTS-HMAC-SHA1-96')) >+ARCFOUR_HMAC_MD5 = int( >+ krb5_asn1.EncryptionTypeValues('kRB5-ENCTYPE-ARCFOUR-HMAC-MD5')) >+ >+# Message types >+KRB_ERROR = int(krb5_asn1.MessageTypeValues('krb-error')) >+KRB_AS_REP = int(krb5_asn1.MessageTypeValues('krb-as-rep')) >+ >+# PAData types >+PADATA_ENC_TIMESTAMP = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-ENC-TIMESTAMP')) >+PADATA_ETYPE_INFO2 = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-ETYPE-INFO2')) >+ >+# Error codes >+KDC_ERR_C_PRINCIPAL_UNKNOWN = 6 >+KDC_ERR_PREAUTH_REQUIRED = 25 >+ >+# Name types >+NT_UNKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-UNKNOWN')) >+NT_PRINCIPAL = int(krb5_asn1.NameTypeValues('kRB5-NT-PRINCIPAL')) >+NT_SRV_INST = int(krb5_asn1.NameTypeValues('kRB5-NT-SRV-INST')) >+ >+ >+@DynamicTestCase >+class KerberosASCanonicalizationTests(RawKerberosTest): >+ >+ @classmethod >+ def setUpDynamicTestCases(cls): >+ >+ def skip(ct, options): >+ ''' Filter out any mutually exclusive test options ''' >+ if ct != CredentialsType.Machine and\ >+ TestOptions.RemoveDollar.is_set(options): >+ return True >+ return False >+ >+ def build_test_name(ct, options): >+ name = "%sCredentials" % ct.name >+ for opt in TestOptions: >+ if opt.is_set(options): >+ name += ("_%s" % opt.name) >+ return name >+ >+ for ct in CredentialsType: >+ for x in range(TestOptions.Last.value): >+ if skip(ct, x): >+ continue >+ name = build_test_name(ct, x) >+ cls.generate_dynamic_test("test", name, x, ct) >+ >+ @classmethod >+ def setUpClass(cls): >+ cls.lp = cls.get_loadparm(cls) >+ cls.username = os.environ["USERNAME"] >+ cls.password = os.environ["PASSWORD"] >+ cls.domain = os.environ["DOMAIN"] >+ cls.realm = os.environ["REALM"] >+ cls.host = os.environ["SERVER"] >+ >+ c = Credentials() >+ c.set_username(cls.username) >+ c.set_password(cls.password) >+ c.set_domain(cls.domain) >+ c.set_realm(cls.realm) >+ cls.credentials = c >+ >+ cls.session = system_session() >+ cls.ldb = SamDB(url="ldap://%s" % cls.host, >+ session_info=cls.session, >+ credentials=cls.credentials, >+ lp=cls.lp) >+ cls.create_machine_account() >+ cls.create_user_account() >+ >+ @classmethod >+ def tearDownClass(cls): >+ super(KerberosASCanonicalizationTests, cls).tearDownClass() >+ delete_force(cls.ldb, cls.machine_dn) >+ delete_force(cls.ldb, cls.user_dn) >+ >+ def setUp(self): >+ super(KerberosASCanonicalizationTests, self).setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ # >+ # Create a test user account >+ @classmethod >+ def create_user_account(cls): >+ cls.user_pass = samba.generate_random_password(32, 32) >+ cls.user_name = USER_NAME >+ cls.user_dn = "cn=%s,%s" % (cls.user_name, cls.ldb.domain_dn()) >+ >+ # remove the account if it exists, this will happen if a previous test >+ # run failed >+ delete_force(cls.ldb, cls.user_dn) >+ >+ utf16pw = ('"%s"' % cls.user_pass).encode('utf-16-le') >+ cls.ldb.add({ >+ "dn": cls.user_dn, >+ "objectclass": "user", >+ "sAMAccountName": "%s" % cls.user_name, >+ "userAccountControl": str(UF_NORMAL_ACCOUNT), >+ "unicodePwd": utf16pw}) >+ >+ cls.user_creds = Credentials() >+ cls.user_creds.guess(cls.lp) >+ cls.user_creds.set_password(cls.user_pass) >+ cls.user_creds.set_username(cls.user_name) >+ cls.user_creds.set_workstation(cls.machine_name) >+ >+ # >+ # Create the machine account >+ @classmethod >+ def create_machine_account(cls): >+ cls.machine_pass = samba.generate_random_password(32, 32) >+ cls.machine_name = MACHINE_NAME >+ cls.machine_dn = "cn=%s,%s" % (cls.machine_name, cls.ldb.domain_dn()) >+ >+ # remove the account if it exists, this will happen if a previous test >+ # run failed >+ delete_force(cls.ldb, cls.machine_dn) >+ >+ utf16pw = ('"%s"' % cls.machine_pass).encode('utf-16-le') >+ cls.ldb.add({ >+ "dn": cls.machine_dn, >+ "objectclass": "computer", >+ "sAMAccountName": "%s$" % cls.machine_name, >+ "userAccountControl": >+ str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), >+ "unicodePwd": utf16pw}) >+ >+ cls.machine_creds = Credentials() >+ cls.machine_creds.guess(cls.lp) >+ cls.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) >+ cls.machine_creds.set_kerberos_state(DONT_USE_KERBEROS) >+ cls.machine_creds.set_password(cls.machine_pass) >+ cls.machine_creds.set_username(cls.machine_name + "$") >+ cls.machine_creds.set_workstation(cls.machine_name) >+ >+ def _test_with_args(self, x, ct): >+ if ct == CredentialsType.User: >+ creds = self.user_creds >+ elif ct == CredentialsType.Machine: >+ creds = self.machine_creds >+ else: >+ raise Exception("Unexpected credential type") >+ data = TestData(x, creds) >+ >+ try: >+ (rep, as_rep) = self.as_req(data) >+ except pyasn1.error.PyAsn1Error as e: >+ import traceback >+ self.fail("ASN1 Error, Options {0:08b}:{1} {2}".format( >+ traceback.format_exc(), >+ data.options, >+ e)) >+ # If as_req triggered an expected server error response >+ # No need to test the response data. >+ if rep is not None: >+ # The kvno is optional, heimdal includes it >+ # MIT does not. >+ if 'kvno' in rep['enc-part']: >+ kvno = rep['enc-part']['kvno'] >+ self.check_kvno(kvno, data) >+ >+ cname = rep['cname'] >+ self.check_cname(cname, data) >+ >+ crealm = rep['crealm'].decode('ascii') >+ self.check_crealm(crealm, data) >+ >+ sname = as_rep['sname'] >+ self.check_sname(sname, data) >+ >+ srealm = as_rep['srealm'].decode('ascii') >+ self.check_srealm(srealm, data) >+ >+ def as_req(self, data): >+ user_creds = data.user_creds >+ realm = data.realm >+ >+ cname = data.cname >+ sname = data.sname >+ >+ till = self.get_KerberosTime(offset=36000) >+ >+ kdc_options = "0" >+ if data.canonicalize: >+ kdc_options = str(krb5_asn1.KDCOptions('canonicalize')) >+ >+ padata = None >+ >+ # Set the allowable encryption types >+ etypes = ( >+ AES256_CTS_HMAC_SHA1_96, >+ AES128_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5) >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=kdc_options, >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ # >+ # Check the protocol version, should be 5 >+ self.assertEqual( >+ rep['pvno'], 5, "Data {0}".format(str(data))) >+ >+ self.assertEqual( >+ rep['msg-type'], KRB_ERROR, "Data {0}".format(str(data))) >+ >+ # We should get KDC_ERR_PREAUTH_REQUIRED >+ # unless the RemoveDollar and Enterprise options are set >+ # then we should get a KDC_ERR_C_PRINCIPAL_UNKNOWN >+ if TestOptions.RemoveDollar.is_set(data.options) and\ >+ TestOptions.Enterprise.is_set(data.options): >+ self.assertEqual( >+ rep['error-code'], >+ KDC_ERR_C_PRINCIPAL_UNKNOWN, >+ "Error code {0}, Data {1}".format(rep['error-code'], str(data))) >+ return (None, None) >+ >+ self.assertEqual( >+ rep['error-code'], >+ KDC_ERR_PREAUTH_REQUIRED, >+ "Error code {0}, Data {1}".format(rep['error-code'], str(data))) >+ >+ rep_padata = self.der_decode( >+ rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) >+ >+ for pa in rep_padata: >+ if pa['padata-type'] == 19: >+ etype_info2 = pa['padata-value'] >+ break >+ >+ etype_info2 = self.der_decode( >+ etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ >+ key = self.PasswordKey_from_etype_info2(user_creds, etype_info2[0]) >+ >+ (patime, pausec) = self.get_KerberosTimeWithUsec() >+ pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) >+ >+ enc_pa_ts_usage = 1 >+ pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) >+ >+ pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts) >+ >+ kdc_options = "0" >+ if data.canonicalize: >+ kdc_options = str(krb5_asn1.KDCOptions('canonicalize')) >+ padata = [pa_ts] >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=kdc_options, >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ # >+ # Check the protocol version, should be 5 >+ self.assertEqual( >+ rep['pvno'], 5, "Data {0}".format(str(data))) >+ >+ msg_type = rep['msg-type'] >+ # Should not have got an error. >+ # If we did, fail and print the error code to help debugging >+ self.assertNotEqual( >+ msg_type, >+ KRB_ERROR, >+ "Error code {0}, Data {1}".format( >+ rep.get('error-code', ''), >+ str(data))) >+ >+ self.assertEqual(msg_type, KRB_AS_REP, "Data {0}".format(str(data))) >+ >+ # Decrypt and decode the EncKdcRepPart >+ enc = key.decrypt(3, rep['enc-part']['cipher']) >+ if enc[0] == 0x7A: >+ # MIT Kerberos Tags the EncASRepPart as a EncKDCRepPart >+ # i.e. tag number 26 instead of tag number 25 >+ as_rep = self.der_decode(enc, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ else: >+ as_rep = self.der_decode(enc, asn1Spec=krb5_asn1.EncASRepPart()) >+ >+ return (rep, as_rep) >+ >+ def check_cname(self, cname, data): >+ nt = cname['name-type'] >+ self.assertEqual( >+ NT_PRINCIPAL, >+ nt, >+ "cname name-type, Options {0:08b}".format(data.options)) >+ >+ ns = cname['name-string'] >+ name = ns[0].decode('ascii') >+ >+ expected = data.user_name >+ if TestOptions.Canonicalize.is_set(data.options): >+ expected = data.user_creds.get_username() >+ self.assertEqual( >+ expected, >+ name, >+ "cname principal, Options {0:08b}".format(data.options)) >+ >+ def check_crealm(self, crealm, data): >+ realm = data.user_creds.get_realm() >+ self.assertEqual( >+ realm, crealm, "crealm, Options {0:08b}".format(data.options)) >+ >+ def check_sname(self, sname, data): >+ nt = sname['name-type'] >+ self.assertEqual( >+ NT_SRV_INST, >+ nt, >+ "sname name-type, Options {0:08b}".format(data.options)) >+ >+ ns = sname['name-string'] >+ name = ns[0].decode('ascii') >+ self.assertEqual( >+ 'krbtgt', >+ name, >+ "sname principal, Options {0:08b}".format(data.options)) >+ >+ realm = ns[1].decode('ascii') >+ expected = data.realm >+ if TestOptions.Canonicalize.is_set(data.options): >+ expected = data.user_creds.get_realm().upper() >+ self.assertEqual( >+ expected, >+ realm, >+ "sname realm, Options {0:08b}".format(data.options)) >+ >+ def check_srealm(self, srealm, data): >+ realm = data.user_creds.get_realm() >+ self.assertEqual( >+ realm, srealm, "srealm, Options {0:08b}".format(data.options)) >+ >+ def check_kvno(self, kvno, data): >+ self.assertEqual( >+ 1, kvno, "kvno, Options {0:08b}".format(data.options)) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 27cdb4c0cb3..dc86f4808ae 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -87,6 +87,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/simple_tests.py', > 'python/samba/tests/krb5/s4u_tests.py', > 'python/samba/tests/krb5/xrealm_tests.py', >+ 'python/samba/tests/krb5/as_canonicalization_tests.py', > } > > >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index e69de29bb2d..96d3e51da5c 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -0,0 +1,144 @@ >+# >+# Currently MOST but not quite all the Canonicalization tests fail on the >+# MIT KDC >+# >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_Enterprise_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperRealm_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperRealm_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperRealm_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperRealm_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperRealm_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperRealm_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Canonicalize_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UpperRealm_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UpperRealm_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UpperRealm_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UpperRealm_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UpperUserName_UPN\( >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 91c25cfb978..d56226bf561 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1228,6 +1228,7 @@ for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: > '--option=torture:expect_machine_account=true'] + extra_options, > "samba4.krb5.kdc with machine account") > >+planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests") > > for env in [ > 'vampire_dc', >-- >2.25.1 > > >From 8d58ba078a1582ce44664baaeddb161922fdfb63 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 10 Nov 2020 11:09:13 +1300 >Subject: [PATCH 040/686] selftest: Send enterprise principals tagged as such > >This test passed against Samba but failed against Windows when >an enterprise principal (user@domain.com@REALM) was encoded as >NT_PRINCIPAL. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d7f731ed3577b407370d8fe7a62b4c3ee2dd9c75) >--- > .../tests/krb5/as_canonicalization_tests.py | 24 ++++++-- > selftest/knownfail.d/kdc-enterprise | 57 +++++++++++++++++++ > selftest/knownfail_mit_kdc | 8 +++ > 3 files changed, 84 insertions(+), 5 deletions(-) > create mode 100644 selftest/knownfail.d/kdc-enterprise > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index 7b599ad6e44..3f8ed5c5a11 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -77,10 +77,16 @@ class TestData: > self.user_creds = creds > self.user_name = self.get_username(options, creds) > self.realm = self.get_realm(options, creds) >+ >+ if TestOptions.Enterprise.is_set(options): >+ client_name_type = NT_ENTERPRISE_PRINCIPAL >+ else: >+ client_name_type = NT_PRINCIPAL >+ > self.cname = RawKerberosTest.PrincipalName_create( >- name_type=1, names=[self.user_name]) >+ name_type=client_name_type, names=[self.user_name]) > self.sname = RawKerberosTest.PrincipalName_create( >- name_type=2, names=["krbtgt", self.realm]) >+ name_type=NT_SRV_INST, names=["krbtgt", self.realm]) > self.canonicalize = TestOptions.Canonicalize.is_set(options) > > def get_realm(self, options, creds): >@@ -143,6 +149,7 @@ KDC_ERR_PREAUTH_REQUIRED = 25 > NT_UNKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-UNKNOWN')) > NT_PRINCIPAL = int(krb5_asn1.NameTypeValues('kRB5-NT-PRINCIPAL')) > NT_SRV_INST = int(krb5_asn1.NameTypeValues('kRB5-NT-SRV-INST')) >+NT_ENTERPRISE_PRINCIPAL = int(krb5_asn1.NameTypeValues('kRB5-NT-ENTERPRISE-PRINCIPAL')) > > > @DynamicTestCase >@@ -436,10 +443,17 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > return (rep, as_rep) > > def check_cname(self, cname, data): >- nt = cname['name-type'] >+ if TestOptions.Canonicalize.is_set(data.options): >+ expected_name_type = NT_PRINCIPAL >+ elif TestOptions.Enterprise.is_set(data.options): >+ expected_name_type = NT_ENTERPRISE_PRINCIPAL >+ else: >+ expected_name_type = NT_PRINCIPAL >+ >+ name_type = cname['name-type'] > self.assertEqual( >- NT_PRINCIPAL, >- nt, >+ expected_name_type, >+ name_type, > "cname name-type, Options {0:08b}".format(data.options)) > > ns = cname['name-string'] >diff --git a/selftest/knownfail.d/kdc-enterprise b/selftest/knownfail.d/kdc-enterprise >new file mode 100644 >index 00000000000..4e4f8a93e03 >--- /dev/null >+++ b/selftest/knownfail.d/kdc-enterprise >@@ -0,0 +1,57 @@ >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName_NetbiosRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName_UPN\( >+ >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 96d3e51da5c..9bac4737591 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -142,3 +142,11 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UpperUserName_NetbiosRealm\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UpperUserName_NetbiosRealm_UPN\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UpperUserName\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UpperUserName_UPN\( >-- >2.25.1 > > >From 553a0c6cd516990d057a6373537227edbd15c4aa Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 10 Nov 2020 11:09:59 +1300 >Subject: [PATCH 041/686] selftest: Fix flipped machine and user constants > >This naturally does not change the test, but reduces developer >confusion. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 579a3c641c72b65f6ba39141a55c765b517bd7f8) >--- > python/samba/tests/krb5/as_canonicalization_tests.py | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index 3f8ed5c5a11..7cdf614482e 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -120,8 +120,8 @@ class TestData: > return rep > > >-MACHINE_NAME = "tstkrb5cnnusr" >-USER_NAME = "tstkrb5cnnmch" >+MACHINE_NAME = "tstkrb5cnnmch" >+USER_NAME = "tstkrb5cnnusr" > > # Encryption types > AES256_CTS_HMAC_SHA1_96 = int( >-- >2.25.1 > > >From 55496b2d9456c00e1a82865e36ed5876e5f7ecac Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 10 Nov 2020 11:12:13 +1300 >Subject: [PATCH 042/686] selftest: Make as_canonicalization_tests.py easier to > run outside "make test" > >This takes the realm from the LDAP base DN and so avoids one >easy mistake to make. So far the NT4 domain name is not >auto-detected, so much be read from the smb.conf. > >By using .guess() the smb.conf is read for the unspecified >parts (eg workstation for an NTLM login to the LDAP server if >the target server is an IP address). > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d85e71f449037fa035fa2fae6b64caf695c53cb3) >--- > python/samba/tests/krb5/as_canonicalization_tests.py | 12 ++++++++++-- > 1 file changed, 10 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index 7cdf614482e..c0c3208d216 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -185,14 +185,20 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > cls.username = os.environ["USERNAME"] > cls.password = os.environ["PASSWORD"] > cls.domain = os.environ["DOMAIN"] >- cls.realm = os.environ["REALM"] > cls.host = os.environ["SERVER"] > > c = Credentials() > c.set_username(cls.username) > c.set_password(cls.password) > c.set_domain(cls.domain) >- c.set_realm(cls.realm) >+ try: >+ realm = os.environ["REALM"] >+ c.set_realm(realm) >+ except KeyError: >+ pass >+ >+ c.guess() >+ > cls.credentials = c > > cls.session = system_session() >@@ -236,6 +242,7 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > > cls.user_creds = Credentials() > cls.user_creds.guess(cls.lp) >+ cls.user_creds.set_realm(cls.ldb.domain_dns_name().upper()) > cls.user_creds.set_password(cls.user_pass) > cls.user_creds.set_username(cls.user_name) > cls.user_creds.set_workstation(cls.machine_name) >@@ -263,6 +270,7 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > > cls.machine_creds = Credentials() > cls.machine_creds.guess(cls.lp) >+ cls.machine_creds.set_realm(cls.ldb.domain_dns_name().upper()) > cls.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) > cls.machine_creds.set_kerberos_state(DONT_USE_KERBEROS) > cls.machine_creds.set_password(cls.machine_pass) >-- >2.25.1 > > >From bd2bcbe856e89b2404068d0859d52176d031cf5b Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 10 Nov 2020 13:46:28 +1300 >Subject: [PATCH 043/686] samdb: Add samdb.domain_netbios_name() > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >[abartlet@samba.org: Backported from commit >d79218dbba3d0f26d6a0e22b3c91b0731bf641dd as this backport >to Samba 4.13 does not include 07ce48088824bba2054e029edfa6fbae972c1921 >(samba-tool: Create unix user with modified template homedir)] > >[jsutton@samba.org Backported to fix conflicts in selftests/tests.py and > remove changes in python/samba/netcmd/user.py] >--- > python/samba/samdb.py | 15 +++++++++++++++ > python/samba/tests/samdb.py | 13 ++++++++++--- > selftest/tests.py | 1 + > 3 files changed, 26 insertions(+), 3 deletions(-) > >diff --git a/python/samba/samdb.py b/python/samba/samdb.py >index 308b5f96a7b..0d76d98783e 100644 >--- a/python/samba/samdb.py >+++ b/python/samba/samdb.py >@@ -751,6 +751,21 @@ accountExpires: %u > domain_dn = self.get_default_basedn() > return domain_dn.canonical_str().split('/')[0] > >+ def domain_netbios_name(self): >+ """return the NetBIOS name of the domain root""" >+ domain_dn = self.get_default_basedn() >+ dns_name = self.domain_dns_name() >+ filter = "(&(objectClass=crossRef)(nETBIOSName=*)(ncName=%s)(dnsroot=%s))" % (domain_dn, dns_name) >+ partitions_dn = self.get_partitions_dn() >+ res = self.search(partitions_dn, >+ scope=ldb.SCOPE_ONELEVEL, >+ expression=filter) >+ try: >+ netbios_domain = res[0]["nETBIOSName"][0].decode() >+ except IndexError: >+ return None >+ return netbios_domain >+ > def forest_dns_name(self): > """return the DNS name of the forest root""" > forest_dn = self.get_root_basedn() >diff --git a/python/samba/tests/samdb.py b/python/samba/tests/samdb.py >index a185a1566e3..834c5a204a6 100644 >--- a/python/samba/tests/samdb.py >+++ b/python/samba/tests/samdb.py >@@ -38,13 +38,13 @@ class SamDBTestCase(TestCaseInTempDir): > super(SamDBTestCase, self).setUp() > self.session = system_session() > logger = logging.getLogger("selftest") >- domain = "dsdb" >- realm = "dsdb.samba.example.com" >+ self.domain = "dsdb" >+ self.realm = "dsdb.samba.example.com" > host_name = "test" > server_role = "active directory domain controller" > self.result = provision(logger, > self.session, targetdir=self.tempdir, >- realm=realm, domain=domain, >+ realm=self.realm, domain=self.domain, > hostname=host_name, > use_ntvfs=True, > serverrole=server_role, >@@ -61,3 +61,10 @@ class SamDBTestCase(TestCaseInTempDir): > shutil.rmtree(os.path.join(self.tempdir, d)) > > super(SamDBTestCase, self).tearDown() >+ >+ >+class SamDBTests(SamDBTestCase): >+ >+ def test_get_domain(self): >+ self.assertEqual(self.samdb.domain_dns_name(), self.realm.lower()) >+ self.assertEqual(self.samdb.domain_netbios_name(), self.domain.upper()) >diff --git a/selftest/tests.py b/selftest/tests.py >index e7639c4da27..1748feeefb4 100644 >--- a/selftest/tests.py >+++ b/selftest/tests.py >@@ -163,6 +163,7 @@ planpythontestsuite("none", "samba.tests.graph", py3_compatible=True) > plantestsuite("wafsamba.duplicate_symbols", "none", [os.path.join(srcdir(), "buildtools/wafsamba/test_duplicate_symbol.sh")]) > planpythontestsuite("none", "samba.tests.glue", py3_compatible=True) > planpythontestsuite("none", "samba.tests.tdb_util", py3_compatible=True) >+planpythontestsuite("none", "samba.tests.samdb", py3_compatible=True) > planpythontestsuite("none", "samba.tests.samdb_api", py3_compatible=True) > > if with_pam: >-- >2.25.1 > > >From 63654ae298faeca069fc0c7d8ed2740a0ade29f2 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 10 Nov 2020 13:47:30 +1300 >Subject: [PATCH 044/686] selftest: Make as_canonicalization_tests.py > auto-detect the NT4 domain name > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 2693f12fbe321e0f4932b1f74d7006dbac140e8e) >--- > python/samba/tests/krb5/as_canonicalization_tests.py | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index c0c3208d216..221ff486fd8 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -184,18 +184,21 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > cls.lp = cls.get_loadparm(cls) > cls.username = os.environ["USERNAME"] > cls.password = os.environ["PASSWORD"] >- cls.domain = os.environ["DOMAIN"] > cls.host = os.environ["SERVER"] > > c = Credentials() > c.set_username(cls.username) > c.set_password(cls.password) >- c.set_domain(cls.domain) > try: > realm = os.environ["REALM"] > c.set_realm(realm) > except KeyError: > pass >+ try: >+ domain = os.environ["DOMAIN"] >+ c.set_domain(domain) >+ except KeyError: >+ pass > > c.guess() > >@@ -243,6 +246,7 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > cls.user_creds = Credentials() > cls.user_creds.guess(cls.lp) > cls.user_creds.set_realm(cls.ldb.domain_dns_name().upper()) >+ cls.user_creds.set_domain(cls.ldb.domain_netbios_name().upper()) > cls.user_creds.set_password(cls.user_pass) > cls.user_creds.set_username(cls.user_name) > cls.user_creds.set_workstation(cls.machine_name) >@@ -271,6 +275,7 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > cls.machine_creds = Credentials() > cls.machine_creds.guess(cls.lp) > cls.machine_creds.set_realm(cls.ldb.domain_dns_name().upper()) >+ cls.machine_creds.set_domain(cls.ldb.domain_netbios_name().upper()) > cls.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) > cls.machine_creds.set_kerberos_state(DONT_USE_KERBEROS) > cls.machine_creds.set_password(cls.machine_pass) >-- >2.25.1 > > >From 9671d8e817d867bec9f5d9e05dcb040a957ce061 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 10 Nov 2020 11:21:24 +1300 >Subject: [PATCH 045/686] selftest: Fix formatting of failure (traceback and > options swapped in format string) > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit ab8c0a181bebe17a597af49790f6e7b17e13c29b) >--- > python/samba/tests/krb5/as_canonicalization_tests.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index 221ff486fd8..f0e9f6307f6 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -296,8 +296,8 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > except pyasn1.error.PyAsn1Error as e: > import traceback > self.fail("ASN1 Error, Options {0:08b}:{1} {2}".format( >- traceback.format_exc(), > data.options, >+ traceback.format_exc(), > e)) > # If as_req triggered an expected server error response > # No need to test the response data. >-- >2.25.1 > > >From 1881eb17c7c775f162f971deec36c33756960740 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 10 Nov 2020 11:27:06 +1300 >Subject: [PATCH 046/686] selftest: Add in encrypted-pa-data from RFC 6806 > >This comes from Windows 2019 which supports FAST. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit fc77ece0e2b5fd324809e17a9b208cc7854cee4b) >--- > python/samba/tests/krb5/rfc4120.asn1 | 3 ++- > python/samba/tests/krb5/rfc4120_pyasn1.py | 19 ++++++++++--------- > 2 files changed, 12 insertions(+), 10 deletions(-) > >diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 >index 58e0c1636a1..654f9788ca7 100644 >--- a/python/samba/tests/krb5/rfc4120.asn1 >+++ b/python/samba/tests/krb5/rfc4120.asn1 >@@ -239,7 +239,8 @@ EncKDCRepPart ::= SEQUENCE { > renew-till [8] KerberosTime OPTIONAL, > srealm [9] Realm, > sname [10] PrincipalName, >- caddr [11] HostAddresses OPTIONAL >+ caddr [11] HostAddresses OPTIONAL, >+ encrypted-pa-data[12] METHOD-DATA OPTIONAL > } > > LastReq ::= SEQUENCE OF SEQUENCE { >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1.py b/python/samba/tests/krb5/rfc4120_pyasn1.py >index b4ea678afd8..1d89f94adf1 100644 >--- a/python/samba/tests/krb5/rfc4120_pyasn1.py >+++ b/python/samba/tests/krb5/rfc4120_pyasn1.py >@@ -1,5 +1,5 @@ > # Auto-generated by asn1ate v.0.6.1.dev0 from rfc4120.asn1 >-# (last modified on 2020-11-03 14:07:15.270009) >+# (last modified on 2020-11-06 11:30:42.476808) > > # KerberosV5Spec2 > from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful >@@ -438,6 +438,13 @@ LastReq.componentType = univ.Sequence(componentType=namedtype.NamedTypes( > )) > > >+class METHOD_DATA(univ.SequenceOf): >+ pass >+ >+ >+METHOD_DATA.componentType = PA_DATA() >+ >+ > class TicketFlags(KerberosFlags): > pass > >@@ -458,7 +465,8 @@ EncKDCRepPart.componentType = namedtype.NamedTypes( > namedtype.OptionalNamedType('renew-till', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8))), > namedtype.NamedType('srealm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 9))), > namedtype.NamedType('sname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 10))), >- namedtype.OptionalNamedType('caddr', HostAddresses().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 11))) >+ namedtype.OptionalNamedType('caddr', HostAddresses().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 11))), >+ namedtype.OptionalNamedType('encrypted-pa-data', METHOD_DATA().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 12))) > ) > > >@@ -702,13 +710,6 @@ KRB_SAFE.componentType = namedtype.NamedTypes( > ) > > >-class METHOD_DATA(univ.SequenceOf): >- pass >- >- >-METHOD_DATA.componentType = PA_DATA() >- >- > class MessageTypeValues(univ.Integer): > pass > >-- >2.25.1 > > >From 9b88ad620b67cb10072e24c4b8c8331555923201 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 10 Nov 2020 13:50:37 +1300 >Subject: [PATCH 047/686] selftest: Windows 2019 implements the RemoveDollar > behaviour for Enterprise principals > >This is documented in MS-KILE. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Autobuild-User(master): Gary Lockyer <gary@samba.org> >Autobuild-Date(master): Wed Nov 11 02:38:46 UTC 2020 on sn-devel-184 > >(cherry picked from commit f214a3ba5a3e9f129f10062392ae03edd62d8186) >--- > .../tests/krb5/as_canonicalization_tests.py | 11 ---------- > selftest/knownfail.d/kdc-enterprise | 20 ------------------- > selftest/knownfail_mit_kdc | 20 +++++++++++++++++++ > 3 files changed, 20 insertions(+), 31 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index f0e9f6307f6..caa186bed41 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -366,17 +366,6 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > self.assertEqual( > rep['msg-type'], KRB_ERROR, "Data {0}".format(str(data))) > >- # We should get KDC_ERR_PREAUTH_REQUIRED >- # unless the RemoveDollar and Enterprise options are set >- # then we should get a KDC_ERR_C_PRINCIPAL_UNKNOWN >- if TestOptions.RemoveDollar.is_set(data.options) and\ >- TestOptions.Enterprise.is_set(data.options): >- self.assertEqual( >- rep['error-code'], >- KDC_ERR_C_PRINCIPAL_UNKNOWN, >- "Error code {0}, Data {1}".format(rep['error-code'], str(data))) >- return (None, None) >- > self.assertEqual( > rep['error-code'], > KDC_ERR_PREAUTH_REQUIRED, >diff --git a/selftest/knownfail.d/kdc-enterprise b/selftest/knownfail.d/kdc-enterprise >index 4e4f8a93e03..d15d67c8af6 100644 >--- a/selftest/knownfail.d/kdc-enterprise >+++ b/selftest/knownfail.d/kdc-enterprise >@@ -1,19 +1,3 @@ >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm_UPN_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UPN_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_UPN_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UPN_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_UPN_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_UPN_RemoveDollar\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_RemoveDollar\( >@@ -26,14 +10,10 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_RemoveDollar\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UPN_RemoveDollar\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_RemoveDollar\( >-samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_UPN_RemoveDollar\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_RemoveDollar\( >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 9bac4737591..00edbc0c34d 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -150,3 +150,23 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UPN\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UpperUserName\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UpperUserName_UPN\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UPN_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_RemoveDollar\( >+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_UPN_RemoveDollar\( >-- >2.25.1 > > >From 2c77435119d3577110f9eb8bbdbb3028634373a7 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Wed, 4 Nov 2020 13:54:46 +1300 >Subject: [PATCH 048/686] selftest: add heimdal kdc specific known fail > >Add a heimdal kerberos specific known fail, will be needed by subsequent >commits. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 5cb5134377f099353e0f91c44cc11e45d548d40f) >--- > selftest/knownfail_heimdal_kdc | 0 > selftest/wscript | 3 +++ > 2 files changed, 3 insertions(+) > create mode 100644 selftest/knownfail_heimdal_kdc > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >new file mode 100644 >index 00000000000..e69de29bb2d >diff --git a/selftest/wscript b/selftest/wscript >index 80e0f1feabd..257dae04156 100644 >--- a/selftest/wscript >+++ b/selftest/wscript >@@ -270,6 +270,9 @@ def cmd_testonly(opt): > env.OPTIONS += " --mitkrb5 --exclude=${srcdir}/selftest/skip_mit_kdc" > env.FILTER_XFAIL += " --expected-failures=${srcdir}/selftest/"\ > "knownfail_mit_kdc" >+ else: >+ env.FILTER_XFAIL += " --expected-failures=${srcdir}/selftest/"\ >+ "knownfail_heimdal_kdc" > > if not CONFIG_GET(opt, 'HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X'): > # older MIT krb5 libraries (< 1.14) don't have >-- >2.25.1 > > >From b5e9b33136e1bc3319358ed128b5a969b9078aab Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Wed, 4 Nov 2020 13:58:24 +1300 >Subject: [PATCH 049/686] tests python krb5: Add python kerberos compatability > tests > >Add new python test to document the differences between the MIT and >Heimdal Kerberos implementations. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 1e1d8b9c83f32c06ecab31214a20b77529ee038e) >--- > .../samba/tests/krb5/compatability_tests.py | 174 ++++++++++++++++++ > python/samba/tests/usage.py | 1 + > selftest/knownfail_heimdal_kdc | 4 + > selftest/knownfail_mit_kdc | 4 + > source4/selftest/tests.py | 1 + > 5 files changed, 184 insertions(+) > create mode 100755 python/samba/tests/krb5/compatability_tests.py > >diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py >new file mode 100755 >index 00000000000..63bd5269c2b >--- /dev/null >+++ b/python/samba/tests/krb5/compatability_tests.py >@@ -0,0 +1,174 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) Catalyst.Net Ltd 2020 >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+from samba.tests.krb5.raw_testcase import RawKerberosTest >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class SimpleKerberosTests(RawKerberosTest): >+ >+ def setUp(self): >+ super(SimpleKerberosTests, self).setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def test_mit_EncASRepPart_tag(self): >+ creds = self.get_user_creds() >+ (enc, _) = self.as_req(creds) >+ self.assertEqual(0x7a, enc[0]) >+ >+ def test_heimdal_EncASRepPart_tag(self): >+ creds = self.get_user_creds() >+ (enc, _) = self.as_req(creds) >+ self.assertEqual(0x79, enc[0]) >+ >+ def test_mit_EncryptedData_kvno(self): >+ creds = self.get_user_creds() >+ (_, enc) = self.as_req(creds) >+ if 'kvno' in enc: >+ self.fail("kvno present in EncryptedData") >+ >+ def test_heimdal_EncryptedData_kvno(self): >+ creds = self.get_user_creds() >+ (_, enc) = self.as_req(creds) >+ if 'kvno' not in enc: >+ self.fail("kvno absent in EncryptedData") >+ >+ def test_mit_EncASRepPart_FAST_support(self): >+ creds = self.get_user_creds() >+ (enc, _) = self.as_req(creds) >+ self.assertEqual(0x7A, enc[0]) >+ as_rep = self.der_decode(enc, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ flags = int(as_rep['flags'], base=2) >+ # MIT sets enc-pa-rep, flag bit 15 >+ # RFC 6806 11. Negotiation of FAST and Detecting Modified Requests >+ self.assertTrue(0x00010000 & flags) >+ >+ def test_heimdal_EncASRepPart_FAST_support(self): >+ creds = self.get_user_creds() >+ (enc, _) = self.as_req(creds) >+ self.assertEqual(0x79, enc[0]) >+ as_rep = self.der_decode(enc, asn1Spec=krb5_asn1.EncASRepPart()) >+ flags = as_rep['flags'] >+ flags = int(as_rep['flags'], base=2) >+ # Heimdal does not set enc-pa-rep, flag bit 15 >+ # RFC 6806 11. Negotiation of FAST and Detecting Modified Requests >+ self.assertFalse(0x00010000 & flags) >+ >+ def as_req(self, creds): >+ user = creds.get_username() >+ realm = creds.get_realm() >+ >+ cname = self.PrincipalName_create(name_type=1, names=[user]) >+ sname = self.PrincipalName_create(name_type=2, names=["krbtgt", realm]) >+ >+ till = self.get_KerberosTime(offset=36000) >+ >+ kdc_options = krb5_asn1.KDCOptions('forwardable') >+ padata = None >+ >+ etypes = (18, 17, 23) >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ self.assertEqual(rep['msg-type'], 30) >+ self.assertEqual(rep['error-code'], 25) >+ rep_padata = self.der_decode( >+ rep['e-data'], >+ asn1Spec=krb5_asn1.METHOD_DATA()) >+ >+ for pa in rep_padata: >+ if pa['padata-type'] == 19: >+ etype_info2 = pa['padata-value'] >+ break >+ >+ etype_info2 = self.der_decode( >+ etype_info2, >+ asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ >+ key = self.PasswordKey_from_etype_info2(creds, etype_info2[0]) >+ >+ (patime, pausec) = self.get_KerberosTimeWithUsec() >+ pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) >+ >+ enc_pa_ts_usage = 1 >+ pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) >+ >+ pa_ts = self.PA_DATA_create(2, pa_ts) >+ >+ kdc_options = krb5_asn1.KDCOptions('forwardable') >+ padata = [pa_ts] >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ msg_type = rep['msg-type'] >+ self.assertEqual(msg_type, 11) >+ >+ usage = 3 >+ enc_part = rep['enc-part'] >+ enc_as_rep_part = key.decrypt(usage, rep['enc-part']['cipher']) >+ return (enc_as_rep_part, enc_part) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index dc86f4808ae..cf1314ac9c6 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -88,6 +88,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/s4u_tests.py', > 'python/samba/tests/krb5/xrealm_tests.py', > 'python/samba/tests/krb5/as_canonicalization_tests.py', >+ 'python/samba/tests/krb5/compatability_tests.py', > } > > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index e69de29bb2d..7ab56b6721b 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -0,0 +1,4 @@ >+# >+# We expect all the MIT specific compatability tests to fail on heimdal >+# kerberos >+^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_mit_ >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 00edbc0c34d..9953d51f21d 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -1,4 +1,8 @@ > # >+# We expect all the heimdal specific compatability tests to fail on MIT >+# kerberos >+^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_heimdal_ >+# > # Currently MOST but not quite all the Canonicalization tests fail on the > # MIT KDC > # >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index d56226bf561..c37b9050c2b 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1229,6 +1229,7 @@ for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: > "samba4.krb5.kdc with machine account") > > planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests") >+planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests") > > for env in [ > 'vampire_dc', >-- >2.25.1 > > >From 169891ce134e0bfb6ec289b2170af86273288e19 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 10 Nov 2020 11:19:02 +1300 >Subject: [PATCH 050/686] tests python krb5: Add constants module > >Extract the constants used in the tests into a separate module. >To reduce code duplication > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 532c941fbb8fc5fc5da4aa2d0e170229076e9aa7) >--- > python/samba/tests/krb5/rfc4120_constants.py | 49 ++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > 2 files changed, 50 insertions(+) > create mode 100644 python/samba/tests/krb5/rfc4120_constants.py > >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >new file mode 100644 >index 00000000000..e939bb75e82 >--- /dev/null >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -0,0 +1,49 @@ >+# Unix SMB/CIFS implementation. >+# Copyright (C) 2020 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+ >+# Encryption types >+AES256_CTS_HMAC_SHA1_96 = int( >+ krb5_asn1.EncryptionTypeValues('kRB5-ENCTYPE-AES256-CTS-HMAC-SHA1-96')) >+AES128_CTS_HMAC_SHA1_96 = int( >+ krb5_asn1.EncryptionTypeValues('kRB5-ENCTYPE-AES128-CTS-HMAC-SHA1-96')) >+ARCFOUR_HMAC_MD5 = int( >+ krb5_asn1.EncryptionTypeValues('kRB5-ENCTYPE-ARCFOUR-HMAC-MD5')) >+ >+# Message types >+KRB_ERROR = int(krb5_asn1.MessageTypeValues('krb-error')) >+KRB_AS_REP = int(krb5_asn1.MessageTypeValues('krb-as-rep')) >+ >+# PAData types >+PADATA_ENC_TIMESTAMP = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-ENC-TIMESTAMP')) >+PADATA_ETYPE_INFO2 = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-ETYPE-INFO2')) >+ >+# Error codes >+KDC_ERR_C_PRINCIPAL_UNKNOWN = 6 >+KDC_ERR_PREAUTH_FAILED = 24 >+KDC_ERR_PREAUTH_REQUIRED = 25 >+KDC_ERR_SKEW = 37 >+ >+# Name types >+NT_UNKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-UNKNOWN')) >+NT_PRINCIPAL = int(krb5_asn1.NameTypeValues('kRB5-NT-PRINCIPAL')) >+NT_SRV_INST = int(krb5_asn1.NameTypeValues('kRB5-NT-SRV-INST')) >+NT_ENTERPRISE_PRINCIPAL = int(krb5_asn1.NameTypeValues( >+ 'kRB5-NT-ENTERPRISE-PRINCIPAL')) >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index cf1314ac9c6..a642940570d 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -89,6 +89,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/xrealm_tests.py', > 'python/samba/tests/krb5/as_canonicalization_tests.py', > 'python/samba/tests/krb5/compatability_tests.py', >+ 'python/samba/tests/krb5/rfc4120_constants.py', > } > > >-- >2.25.1 > > >From 502ac974c027ecc654076fb5474e0ddc848e21f1 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 10 Nov 2020 11:20:03 +1300 >Subject: [PATCH 051/686] tests python krb5: Refactor canonicalization test > constants > >Modify tests to use the constants defined in rfc4120_constants.py > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 97b830cbcac53fcf49bbcd272812d1ba019bac51) >--- > .../tests/krb5/as_canonicalization_tests.py | 30 +------------------ > 1 file changed, 1 insertion(+), 29 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index caa186bed41..303788b672e 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -41,6 +41,7 @@ from samba.dsdb import ( > UF_NORMAL_ACCOUNT) > from samba.samdb import SamDB > from samba.tests import delete_force, DynamicTestCase >+from samba.tests.krb5.rfc4120_constants import * > > global_asn1_print = False > global_hexdump = False >@@ -123,35 +124,6 @@ class TestData: > MACHINE_NAME = "tstkrb5cnnmch" > USER_NAME = "tstkrb5cnnusr" > >-# Encryption types >-AES256_CTS_HMAC_SHA1_96 = int( >- krb5_asn1.EncryptionTypeValues('kRB5-ENCTYPE-AES256-CTS-HMAC-SHA1-96')) >-AES128_CTS_HMAC_SHA1_96 = int( >- krb5_asn1.EncryptionTypeValues('kRB5-ENCTYPE-AES128-CTS-HMAC-SHA1-96')) >-ARCFOUR_HMAC_MD5 = int( >- krb5_asn1.EncryptionTypeValues('kRB5-ENCTYPE-ARCFOUR-HMAC-MD5')) >- >-# Message types >-KRB_ERROR = int(krb5_asn1.MessageTypeValues('krb-error')) >-KRB_AS_REP = int(krb5_asn1.MessageTypeValues('krb-as-rep')) >- >-# PAData types >-PADATA_ENC_TIMESTAMP = int( >- krb5_asn1.PADataTypeValues('kRB5-PADATA-ENC-TIMESTAMP')) >-PADATA_ETYPE_INFO2 = int( >- krb5_asn1.PADataTypeValues('kRB5-PADATA-ETYPE-INFO2')) >- >-# Error codes >-KDC_ERR_C_PRINCIPAL_UNKNOWN = 6 >-KDC_ERR_PREAUTH_REQUIRED = 25 >- >-# Name types >-NT_UNKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-UNKNOWN')) >-NT_PRINCIPAL = int(krb5_asn1.NameTypeValues('kRB5-NT-PRINCIPAL')) >-NT_SRV_INST = int(krb5_asn1.NameTypeValues('kRB5-NT-SRV-INST')) >-NT_ENTERPRISE_PRINCIPAL = int(krb5_asn1.NameTypeValues('kRB5-NT-ENTERPRISE-PRINCIPAL')) >- >- > @DynamicTestCase > class KerberosASCanonicalizationTests(RawKerberosTest): > >-- >2.25.1 > > >From 831593578f5fd987c6eb5ec2f45b0e968e57b868 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 10 Nov 2020 11:20:58 +1300 >Subject: [PATCH 052/686] tests python krb5: Refactor compatability test > constants > >Modify tests to use the constants defined in rfc4120_constants.py > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 82a413f48b7ef71feb68fc34f7ca753d45eb8974) >--- > .../samba/tests/krb5/compatability_tests.py | 42 ++++++++++++------- > 1 file changed, 28 insertions(+), 14 deletions(-) > >diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py >index 63bd5269c2b..bf561346ab3 100755 >--- a/python/samba/tests/krb5/compatability_tests.py >+++ b/python/samba/tests/krb5/compatability_tests.py >@@ -25,10 +25,17 @@ os.environ["PYTHONUNBUFFERED"] = "1" > > from samba.tests.krb5.raw_testcase import RawKerberosTest > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+from samba.tests.krb5.rfc4120_constants import * > > global_asn1_print = False > global_hexdump = False > >+HIEMDAL_ENC_AS_REP_PART_TYPE_TAG = 0x79 >+# MIT uses the EncTGSRepPart tag for the EncASRepPart >+MIT_ENC_AS_REP_PART_TYPE_TAG = 0x7A >+ >+ENC_PA_REP_FLAG = 0x00010000 >+ > > class SimpleKerberosTests(RawKerberosTest): > >@@ -40,12 +47,12 @@ class SimpleKerberosTests(RawKerberosTest): > def test_mit_EncASRepPart_tag(self): > creds = self.get_user_creds() > (enc, _) = self.as_req(creds) >- self.assertEqual(0x7a, enc[0]) >+ self.assertEqual(MIT_ENC_AS_REP_PART_TYPE_TAG, enc[0]) > > def test_heimdal_EncASRepPart_tag(self): > creds = self.get_user_creds() > (enc, _) = self.as_req(creds) >- self.assertEqual(0x79, enc[0]) >+ self.assertEqual(HIEMDAL_ENC_AS_REP_PART_TYPE_TAG, enc[0]) > > def test_mit_EncryptedData_kvno(self): > creds = self.get_user_creds() >@@ -62,37 +69,44 @@ class SimpleKerberosTests(RawKerberosTest): > def test_mit_EncASRepPart_FAST_support(self): > creds = self.get_user_creds() > (enc, _) = self.as_req(creds) >- self.assertEqual(0x7A, enc[0]) >+ self.assertEqual(MIT_ENC_AS_REP_PART_TYPE_TAG, enc[0]) > as_rep = self.der_decode(enc, asn1Spec=krb5_asn1.EncTGSRepPart()) > flags = int(as_rep['flags'], base=2) > # MIT sets enc-pa-rep, flag bit 15 > # RFC 6806 11. Negotiation of FAST and Detecting Modified Requests >- self.assertTrue(0x00010000 & flags) >+ self.assertTrue(ENC_PA_REP_FLAG & flags) > > def test_heimdal_EncASRepPart_FAST_support(self): > creds = self.get_user_creds() > (enc, _) = self.as_req(creds) >- self.assertEqual(0x79, enc[0]) >+ self.assertEqual(HIEMDAL_ENC_AS_REP_PART_TYPE_TAG, enc[0]) > as_rep = self.der_decode(enc, asn1Spec=krb5_asn1.EncASRepPart()) > flags = as_rep['flags'] > flags = int(as_rep['flags'], base=2) > # Heimdal does not set enc-pa-rep, flag bit 15 > # RFC 6806 11. Negotiation of FAST and Detecting Modified Requests >- self.assertFalse(0x00010000 & flags) >+ self.assertFalse(ENC_PA_REP_FLAG & flags) > > def as_req(self, creds): > user = creds.get_username() > realm = creds.get_realm() > >- cname = self.PrincipalName_create(name_type=1, names=[user]) >- sname = self.PrincipalName_create(name_type=2, names=["krbtgt", realm]) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[user]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, >+ names=["krbtgt", realm]) > > till = self.get_KerberosTime(offset=36000) > > kdc_options = krb5_asn1.KDCOptions('forwardable') > padata = None > >- etypes = (18, 17, 23) >+ etypes = ( >+ AES256_CTS_HMAC_SHA1_96, >+ AES128_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5) > > req = self.AS_REQ_create(padata=padata, > kdc_options=str(kdc_options), >@@ -111,14 +125,14 @@ class SimpleKerberosTests(RawKerberosTest): > rep = self.send_recv_transaction(req) > self.assertIsNotNone(rep) > >- self.assertEqual(rep['msg-type'], 30) >- self.assertEqual(rep['error-code'], 25) >+ self.assertEqual(rep['msg-type'], KRB_ERROR) >+ self.assertEqual(rep['error-code'], KDC_ERR_PREAUTH_REQUIRED) > rep_padata = self.der_decode( > rep['e-data'], > asn1Spec=krb5_asn1.METHOD_DATA()) > > for pa in rep_padata: >- if pa['padata-type'] == 19: >+ if pa['padata-type'] == PADATA_ETYPE_INFO2: > etype_info2 = pa['padata-value'] > break > >@@ -136,7 +150,7 @@ class SimpleKerberosTests(RawKerberosTest): > pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) > >- pa_ts = self.PA_DATA_create(2, pa_ts) >+ pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts) > > kdc_options = krb5_asn1.KDCOptions('forwardable') > padata = [pa_ts] >@@ -159,7 +173,7 @@ class SimpleKerberosTests(RawKerberosTest): > self.assertIsNotNone(rep) > > msg_type = rep['msg-type'] >- self.assertEqual(msg_type, 11) >+ self.assertEqual(msg_type, KRB_AS_REP) > > usage = 3 > enc_part = rep['enc-part'] >-- >2.25.1 > > >From 7c5000863307f55157dec2f38dd61eeae7072757 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 10 Nov 2020 13:51:39 +1300 >Subject: [PATCH 053/686] tests python krb5: raw_testcase permit RC4 salts > >MIT kerberos returns a salt when ARCFOUR_HMAC_MD5, this commit removes >the check that a salt is not returned. A test for the difference >between MIT and Heimdal will be added in the subsequent commits. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 1bab87c50baf0fecb5d4cd09e1a9896730c6377e) >--- > python/samba/tests/krb5/raw_testcase.py | 1 - > 1 file changed, 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 45e46e0b7ba..e67f5464e59 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -425,7 +425,6 @@ class RawKerberosTest(TestCase): > pass > > if e == kcrypto.Enctype.RC4: >- self.assertIsNone(salt) > nthash = creds.get_nt_hash() > return self.SessionKey_create(etype=e, contents=nthash, kvno=kvno) > >-- >2.25.1 > > >From 077a1a0428e5ba924f3692ef7f6789573b946f29 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Fri, 6 Nov 2020 09:07:04 +1300 >Subject: [PATCH 054/686] tests python krb5: Convert kdc-heimdal to python > >Implement the tests in source4/torture/krb5/kdc-heimdal.c in python. >The following tests were not re-implemented as they are client side >tests for the "Orpheus Lyre" attack: > TORTURE_KRB5_TEST_CHANGE_SERVER_OUT > TORTURE_KRB5_TEST_CHANGE_SERVER_IN > TORTURE_KRB5_TEST_CHANGE_SERVER_BOTH > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit a00a1c9745033dae05eee17cfa4e2c5354a81e68) >--- > python/samba/tests/krb5/kdc_tests.py | 219 +++++++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > source4/selftest/tests.py | 1 + > 3 files changed, 221 insertions(+) > create mode 100755 python/samba/tests/krb5/kdc_tests.py > >diff --git a/python/samba/tests/krb5/kdc_tests.py b/python/samba/tests/krb5/kdc_tests.py >new file mode 100755 >index 00000000000..57a25448965 >--- /dev/null >+++ b/python/samba/tests/krb5/kdc_tests.py >@@ -0,0 +1,219 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) 2020 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+from samba.tests.krb5.raw_testcase import RawKerberosTest >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+from samba.tests.krb5.rfc4120_constants import * >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class KdcTests(RawKerberosTest): >+ """ Port of the tests in source4/torture/krb5/kdc-heimdal.c >+ To python. >+ """ >+ >+ def setUp(self): >+ super(KdcTests, self).setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def as_req(self, creds, etypes, padata=None): >+ user = creds.get_username() >+ realm = creds.get_realm() >+ >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[user]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, >+ names=["krbtgt", realm]) >+ till = self.get_KerberosTime(offset=36000) >+ >+ kdc_options = 0 >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ return rep >+ >+ def get_pa_data(self, creds, rep, skew=0): >+ rep_padata = self.der_decode( >+ rep['e-data'], >+ asn1Spec=krb5_asn1.METHOD_DATA()) >+ >+ for pa in rep_padata: >+ if pa['padata-type'] == PADATA_ETYPE_INFO2: >+ etype_info2 = pa['padata-value'] >+ break >+ >+ etype_info2 = self.der_decode( >+ etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ >+ key = self.PasswordKey_from_etype_info2(creds, etype_info2[0]) >+ >+ (patime, pausec) = self.get_KerberosTimeWithUsec(offset=skew) >+ pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) >+ >+ enc_pa_ts_usage = 1 >+ pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) >+ >+ pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts) >+ >+ padata = [pa_ts] >+ return padata >+ >+ def check_pre_authenication(self, rep): >+ """ Check that the kdc response was pre-authentication required >+ """ >+ self.check_error_rep(rep, KDC_ERR_PREAUTH_REQUIRED) >+ >+ def check_as_reply(self, rep): >+ """ Check that the kdc response is an AS-REP and that the >+ values for: >+ msg-type >+ pvno >+ tkt-pvno >+ kvno >+ match the expected values >+ """ >+ >+ # Should have a reply, and it should an AS-REP message. >+ self.assertIsNotNone(rep) >+ self.assertEqual(rep['msg-type'], KRB_AS_REP) >+ >+ # Protocol version number should be 5 >+ pvno = int(rep['pvno']) >+ self.assertEqual(5, pvno) >+ >+ # The ticket version number should be 5 >+ tkt_vno = int(rep['ticket']['tkt-vno']) >+ self.assertEqual(5, tkt_vno) >+ >+ # Check that the kvno is not an RODC kvno >+ # MIT kerberos does not provide the kvno, so we treat it as optional. >+ # This is tested in compatability_test.py >+ if 'kvno' in rep['enc-part']: >+ kvno = int(rep['enc-part']['kvno']) >+ # If the high order bits are set this is an RODC kvno. >+ self.assertEqual(0, kvno & 0xFFFF0000) >+ >+ def check_error_rep(self, rep, expected): >+ """ Check that the reply is an error message, with the expected >+ error-code specified. >+ """ >+ self.assertIsNotNone(rep) >+ self.assertEqual(rep['msg-type'], KRB_ERROR) >+ self.assertEqual(rep['error-code'], expected) >+ >+ def test_aes256_cts_hmac_sha1_96(self): >+ creds = self.get_user_creds() >+ etype = (AES256_CTS_HMAC_SHA1_96,) >+ >+ rep = self.as_req(creds, etype) >+ self.check_pre_authenication(rep) >+ >+ padata = self.get_pa_data(creds, rep) >+ rep = self.as_req(creds, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ etype = rep['enc-part']['etype'] >+ self.assertEquals(AES256_CTS_HMAC_SHA1_96, etype) >+ >+ def test_arc4_hmac_md5(self): >+ creds = self.get_user_creds() >+ etype = (ARCFOUR_HMAC_MD5,) >+ >+ rep = self.as_req(creds, etype) >+ self.check_pre_authenication(rep) >+ >+ padata = self.get_pa_data(creds, rep) >+ rep = self.as_req(creds, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ etype = rep['enc-part']['etype'] >+ self.assertEquals(ARCFOUR_HMAC_MD5, etype) >+ >+ def test_aes_rc4(self): >+ creds = self.get_user_creds() >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ >+ rep = self.as_req(creds, etype) >+ self.check_pre_authenication(rep) >+ >+ padata = self.get_pa_data(creds, rep) >+ rep = self.as_req(creds, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ etype = rep['enc-part']['etype'] >+ self.assertEquals(AES256_CTS_HMAC_SHA1_96, etype) >+ >+ def test_clock_skew(self): >+ creds = self.get_user_creds() >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ >+ rep = self.as_req(creds, etype) >+ self.check_pre_authenication(rep) >+ >+ padata = self.get_pa_data(creds, rep, skew=3600) >+ rep = self.as_req(creds, etype, padata=padata) >+ >+ self.check_error_rep(rep, KDC_ERR_SKEW) >+ >+ def test_invalid_password(self): >+ creds = self.insta_creds(template=self.get_user_creds()) >+ creds.set_password("Not the correct password") >+ >+ etype = (AES256_CTS_HMAC_SHA1_96,) >+ >+ rep = self.as_req(creds, etype) >+ self.check_pre_authenication(rep) >+ >+ padata = self.get_pa_data(creds, rep) >+ rep = self.as_req(creds, etype, padata=padata) >+ >+ self.check_error_rep(rep, KDC_ERR_PREAUTH_FAILED) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index a642940570d..11cd405deea 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -90,6 +90,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/as_canonicalization_tests.py', > 'python/samba/tests/krb5/compatability_tests.py', > 'python/samba/tests/krb5/rfc4120_constants.py', >+ 'python/samba/tests/krb5/kdc_tests.py', > } > > >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index c37b9050c2b..f2cdae9342c 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1230,6 +1230,7 @@ for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: > > planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests") > planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests") >+planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests") > > for env in [ > 'vampire_dc', >-- >2.25.1 > > >From 0ab271f36f48d560bac41058bcb34a7bb60aa57e Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 10 Nov 2020 16:56:46 +1300 >Subject: [PATCH 055/686] tests python krb5: refactor compatability tests > >Refactor to aid the adding of tests for the inclusion of a salt when >ARCFOUR_HMAC_MD5 encryption selected > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d492355f293e2da400318665035b056dfaba852c) >--- > .../samba/tests/krb5/compatability_tests.py | 24 ++++++++++++++----- > 1 file changed, 18 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py >index bf561346ab3..5990d2ce8df 100755 >--- a/python/samba/tests/krb5/compatability_tests.py >+++ b/python/samba/tests/krb5/compatability_tests.py >@@ -87,7 +87,7 @@ class SimpleKerberosTests(RawKerberosTest): > # RFC 6806 11. Negotiation of FAST and Detecting Modified Requests > self.assertFalse(ENC_PA_REP_FLAG & flags) > >- def as_req(self, creds): >+ def as_pre_auth_req(self, creds, etypes): > user = creds.get_username() > realm = creds.get_realm() > >@@ -103,10 +103,6 @@ class SimpleKerberosTests(RawKerberosTest): > kdc_options = krb5_asn1.KDCOptions('forwardable') > padata = None > >- etypes = ( >- AES256_CTS_HMAC_SHA1_96, >- AES128_CTS_HMAC_SHA1_96, >- ARCFOUR_HMAC_MD5) > > req = self.AS_REQ_create(padata=padata, > kdc_options=str(kdc_options), >@@ -123,10 +119,16 @@ class SimpleKerberosTests(RawKerberosTest): > EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) >- self.assertIsNotNone(rep) > >+ return (rep, cname, sname, realm, till) >+ >+ def check_preauth_rep(self, rep): >+ self.assertIsNotNone(rep) > self.assertEqual(rep['msg-type'], KRB_ERROR) > self.assertEqual(rep['error-code'], KDC_ERR_PREAUTH_REQUIRED) >+ >+ def get_etype_info2(self, rep): >+ > rep_padata = self.der_decode( > rep['e-data'], > asn1Spec=krb5_asn1.METHOD_DATA()) >@@ -139,7 +141,17 @@ class SimpleKerberosTests(RawKerberosTest): > etype_info2 = self.der_decode( > etype_info2, > asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ return etype_info2 >+ >+ def as_req(self, creds): >+ etypes = ( >+ AES256_CTS_HMAC_SHA1_96, >+ AES128_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5) >+ (rep, cname, sname, realm, till) = self.as_pre_auth_req(creds, etypes) >+ self.check_preauth_rep(rep) > >+ etype_info2 = self.get_etype_info2(rep) > key = self.PasswordKey_from_etype_info2(creds, etype_info2[0]) > > (patime, pausec) = self.get_KerberosTimeWithUsec() >-- >2.25.1 > > >From 4ca40699c28f42ead5f735df243d7ec2d0b215f1 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 10 Nov 2020 16:57:11 +1300 >Subject: [PATCH 056/686] tests python krb5: add arcfour salt tests > >MIT kerberos returns a salt when ARCFOUR_HMAC_MD5 encryption selected, >Heimdal does not. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Thu Nov 12 22:54:22 UTC 2020 on sn-devel-184 > >(cherry picked from commit 2ba6d596ff0a3580eca9285fd83569bcb147ce77) >--- > .../samba/tests/krb5/compatability_tests.py | 20 +++++++++++++++++++ > 1 file changed, 20 insertions(+) > >diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py >index 5990d2ce8df..e4b1453e712 100755 >--- a/python/samba/tests/krb5/compatability_tests.py >+++ b/python/samba/tests/krb5/compatability_tests.py >@@ -87,6 +87,26 @@ class SimpleKerberosTests(RawKerberosTest): > # RFC 6806 11. Negotiation of FAST and Detecting Modified Requests > self.assertFalse(ENC_PA_REP_FLAG & flags) > >+ def test_mit_arcfour_salt(self): >+ creds = self.get_user_creds() >+ etypes = (ARCFOUR_HMAC_MD5,) >+ (rep, *_) = self.as_pre_auth_req(creds, etypes) >+ self.check_preauth_rep(rep) >+ etype_info2 = self.get_etype_info2(rep) >+ if 'salt' not in etype_info2[0]: >+ self.fail( >+ "(MIT) Salt not populated for ARCFOUR_HMAC_MD5 encryption") >+ >+ def test_heimdal_arcfour_salt(self): >+ creds = self.get_user_creds() >+ etypes = (ARCFOUR_HMAC_MD5,) >+ (rep, *_) = self.as_pre_auth_req(creds, etypes) >+ self.check_preauth_rep(rep) >+ etype_info2 = self.get_etype_info2(rep) >+ if 'salt' in etype_info2[0]: >+ self.fail( >+ "(Heimdal) Salt populated for ARCFOUR_HMAC_MD5 encryption") >+ > def as_pre_auth_req(self, creds, etypes): > user = creds.get_username() > realm = creds.get_realm() >-- >2.25.1 > > >From 65822aeaf3015ec94f371054227f4d5516d364af Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Wed, 18 Nov 2020 14:49:28 +1300 >Subject: [PATCH 057/686] tests python krb5: Extra canonicalization tests > >Add tests that set the server name to the client name for the machine >account in the kerberos AS_REQ. This replicates the TEST_AS_REQ_SELF >test phase in source4/torture/krb5/kdc-canon-heimdal.c. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Mon Nov 30 05:21:42 UTC 2020 on sn-devel-184 > >(cherry picked from commit 7f7e2b0e1e17321d800de787098bb2b2c8259ecd) >--- > .../tests/krb5/as_canonicalization_tests.py | 74 +++++++++----- > selftest/knownfail.d/kdc-enterprise | 26 +++++ > selftest/knownfail_mit_kdc | 96 +++++++++++++++++++ > 3 files changed, 172 insertions(+), 24 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index 303788b672e..6ea3ff0491e 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -56,7 +56,8 @@ class TestOptions(Enum): > NetbiosRealm = 16 > UPN = 32 > RemoveDollar = 64 >- Last = 128 >+ AsReqSelf = 128 >+ Last = 256 > > def is_set(self, x): > return self.value & x >@@ -76,8 +77,8 @@ class TestData: > def __init__(self, options, creds): > self.options = options > self.user_creds = creds >- self.user_name = self.get_username(options, creds) >- self.realm = self.get_realm(options, creds) >+ self.user_name = self._get_username(options, creds) >+ self.realm = self._get_realm(options, creds) > > if TestOptions.Enterprise.is_set(options): > client_name_type = NT_ENTERPRISE_PRINCIPAL >@@ -86,11 +87,14 @@ class TestData: > > self.cname = RawKerberosTest.PrincipalName_create( > name_type=client_name_type, names=[self.user_name]) >- self.sname = RawKerberosTest.PrincipalName_create( >- name_type=NT_SRV_INST, names=["krbtgt", self.realm]) >+ if TestOptions.AsReqSelf.is_set(options): >+ self.sname = self.cname >+ else: >+ self.sname = RawKerberosTest.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", self.realm]) > self.canonicalize = TestOptions.Canonicalize.is_set(options) > >- def get_realm(self, options, creds): >+ def _get_realm(self, options, creds): > realm = creds.get_realm() > if TestOptions.NetbiosRealm.is_set(options): > realm = creds.get_domain() >@@ -100,7 +104,7 @@ class TestData: > realm = realm.lower() > return realm > >- def get_username(self, options, creds): >+ def _get_username(self, options, creds): > name = creds.get_username() > if TestOptions.RemoveDollar.is_set(options) and name.endswith("$"): > name = name[:-1] >@@ -135,6 +139,9 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > if ct != CredentialsType.Machine and\ > TestOptions.RemoveDollar.is_set(options): > return True >+ if ct != CredentialsType.Machine and\ >+ TestOptions.AsReqSelf.is_set(options): >+ return True > return False > > def build_test_name(ct, options): >@@ -448,26 +455,45 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > > def check_sname(self, sname, data): > nt = sname['name-type'] >- self.assertEqual( >- NT_SRV_INST, >- nt, >- "sname name-type, Options {0:08b}".format(data.options)) >- > ns = sname['name-string'] > name = ns[0].decode('ascii') >- self.assertEqual( >- 'krbtgt', >- name, >- "sname principal, Options {0:08b}".format(data.options)) > >- realm = ns[1].decode('ascii') >- expected = data.realm >- if TestOptions.Canonicalize.is_set(data.options): >- expected = data.user_creds.get_realm().upper() >- self.assertEqual( >- expected, >- realm, >- "sname realm, Options {0:08b}".format(data.options)) >+ if TestOptions.AsReqSelf.is_set(data.options): >+ expected_name_type = NT_PRINCIPAL >+ if not TestOptions.Canonicalize.is_set(data.options)\ >+ and TestOptions.Enterprise.is_set(data.options): >+ >+ expected_name_type = NT_ENTERPRISE_PRINCIPAL >+ >+ self.assertEqual( >+ expected_name_type, >+ nt, >+ "sname name-type, Options {0:08b}".format(data.options)) >+ expected = data.user_name >+ if TestOptions.Canonicalize.is_set(data.options): >+ expected = data.user_creds.get_username() >+ self.assertEqual( >+ expected, >+ name, >+ "sname principal, Options {0:08b}".format(data.options)) >+ else: >+ self.assertEqual( >+ NT_SRV_INST, >+ nt, >+ "sname name-type, Options {0:08b}".format(data.options)) >+ self.assertEqual( >+ 'krbtgt', >+ name, >+ "sname principal, Options {0:08b}".format(data.options)) >+ >+ realm = ns[1].decode('ascii') >+ expected = data.realm >+ if TestOptions.Canonicalize.is_set(data.options): >+ expected = data.user_creds.get_realm().upper() >+ self.assertEqual( >+ expected, >+ realm, >+ "sname realm, Options {0:08b}".format(data.options)) > > def check_srealm(self, srealm, data): > realm = data.user_creds.get_realm() >diff --git a/selftest/knownfail.d/kdc-enterprise b/selftest/knownfail.d/kdc-enterprise >index d15d67c8af6..c9b6c98a2ee 100644 >--- a/selftest/knownfail.d/kdc-enterprise >+++ b/selftest/knownfail.d/kdc-enterprise >@@ -35,3 +35,29 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName_UPN\( > >+ >+ >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN_RemoveDollar_AsReqSelf\( >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 9953d51f21d..f1a4971430e 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -174,3 +174,99 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UPN_RemoveDollar\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_RemoveDollar\( > samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_UPN_RemoveDollar\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperRealm_UpperUserName_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\(ad_dc >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_Enterprise_UpperUserName_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperRealm_UpperUserName_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_UpperUserName_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_NetbiosRealm_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_RemoveDollar_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_UPN_AsReqSelf\( >+^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_UPN_RemoveDollar_AsReqSelf\( >-- >2.25.1 > > >From 60e333bae9e29c23ff076b95c18e28fc7c9cc3f4 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Thu, 10 Dec 2020 10:15:28 +1300 >Subject: [PATCH 058/686] tests python krb5: Add Authorization data ad-type > constants > >Add constants for the Authorization Data Type values. >RFC 4120 7.5.4. Authorization Data Types > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d74c9dcf3aaa613abfac49288f427484468bf6e1) >--- > python/samba/tests/krb5/rfc4120_constants.py | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index e939bb75e82..e1d0c5baa68 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -47,3 +47,17 @@ NT_PRINCIPAL = int(krb5_asn1.NameTypeValues('kRB5-NT-PRINCIPAL')) > NT_SRV_INST = int(krb5_asn1.NameTypeValues('kRB5-NT-SRV-INST')) > NT_ENTERPRISE_PRINCIPAL = int(krb5_asn1.NameTypeValues( > 'kRB5-NT-ENTERPRISE-PRINCIPAL')) >+ >+# Authorization data ad-type values >+ >+AD_IF_RELEVANT = 1 >+AD_INTENDED_FOR_SERVER = 2 >+AD_INTENDED_FOR_APPLICATION_CLASS = 3 >+AD_KDC_ISSUED = 4 >+AD_AND_OR = 5 >+AD_MANDATORY_TICKET_EXTENSIONS = 6 >+AD_IN_TICKET_EXTENSIONS = 7 >+AD_MANDATORY_FOR_KDC = 8 >+AD_INITIAL_VERIFIED_CAS = 9 >+AD_WIN2K_PAC = 128 >+AD_SIGNTICKET = 512 >-- >2.25.1 > > >From 49178797b6b65eaf020e7096ff5c0c0b8b3692b9 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Mon, 30 Nov 2020 14:16:28 +1300 >Subject: [PATCH 059/686] tests python krb5: add test base class > >Add a base class for the KDC tests to reduce the amount of code >duplication in the tests. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 0f232ed42fb2671d025643cafb19891373562e4a) >--- > python/samba/tests/krb5/kdc_base_test.py | 419 +++++++++++++++++++++++ > 1 file changed, 419 insertions(+) > create mode 100755 python/samba/tests/krb5/kdc_base_test.py > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >new file mode 100755 >index 00000000000..4fc7ee85ba9 >--- /dev/null >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -0,0 +1,419 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) 2020 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+from collections import namedtuple >+from ldb import SCOPE_BASE >+from samba import generate_random_password >+from samba.auth import system_session >+from samba.credentials import Credentials >+from samba.dcerpc import krb5pac >+from samba.dsdb import UF_WORKSTATION_TRUST_ACCOUNT, UF_NORMAL_ACCOUNT >+from samba.ndr import ndr_unpack >+from samba.samdb import SamDB >+ >+from samba.tests import delete_force >+from samba.tests.krb5.raw_testcase import RawKerberosTest >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+from samba.tests.krb5.rfc4120_constants import ( >+ AD_IF_RELEVANT, >+ AD_WIN2K_PAC, >+ KDC_ERR_PREAUTH_REQUIRED, >+ KRB_AS_REP, >+ KRB_TGS_REP, >+ KRB_ERROR, >+ PADATA_ENC_TIMESTAMP, >+ PADATA_ETYPE_INFO2, >+) >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class KDCBaseTest(RawKerberosTest): >+ """ Base class for KDC tests. >+ """ >+ >+ @classmethod >+ def setUpClass(cls): >+ cls.lp = cls.get_loadparm(cls) >+ cls.username = os.environ["USERNAME"] >+ cls.password = os.environ["PASSWORD"] >+ cls.host = os.environ["SERVER"] >+ >+ c = Credentials() >+ c.set_username(cls.username) >+ c.set_password(cls.password) >+ try: >+ realm = os.environ["REALM"] >+ c.set_realm(realm) >+ except KeyError: >+ pass >+ try: >+ domain = os.environ["DOMAIN"] >+ c.set_domain(domain) >+ except KeyError: >+ pass >+ >+ c.guess() >+ >+ cls.credentials = c >+ >+ cls.session = system_session() >+ cls.ldb = SamDB(url="ldap://%s" % cls.host, >+ session_info=cls.session, >+ credentials=cls.credentials, >+ lp=cls.lp) >+ # fetch the dnsHostName from the RootDse >+ res = cls.ldb.search( >+ base="", expression="", scope=SCOPE_BASE, attrs=["dnsHostName"]) >+ cls.dns_host_name = str(res[0]['dnsHostName']) >+ >+ def setUp(self): >+ super().setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ self.accounts = [] >+ >+ def tearDown(self): >+ # Clean up any accounts created by create_account >+ for dn in self.accounts: >+ delete_force(self.ldb, dn) >+ >+ def create_account(self, name, machine_account=False, spn=None): >+ '''Create an account for testing. >+ The dn of the created account is added to self.accounts, >+ which is used by tearDown to clean up the created accounts. >+ ''' >+ dn = "cn=%s,%s" % (name, self.ldb.domain_dn()) >+ >+ # remove the account if it exists, this will happen if a previous test >+ # run failed >+ delete_force(self.ldb, dn) >+ if machine_account: >+ object_class = "computer" >+ account_name = "%s$" % name >+ account_control = str(UF_WORKSTATION_TRUST_ACCOUNT) >+ else: >+ object_class = "user" >+ account_name = name >+ account_control = str(UF_NORMAL_ACCOUNT) >+ >+ password = generate_random_password(32, 32) >+ utf16pw = ('"%s"' % password).encode('utf-16-le') >+ >+ details = { >+ "dn": dn, >+ "objectclass": object_class, >+ "sAMAccountName": account_name, >+ "userAccountControl": account_control, >+ "unicodePwd": utf16pw} >+ if spn is not None: >+ details["servicePrincipalName"] = spn >+ self.ldb.add(details) >+ >+ creds = Credentials() >+ creds.guess(self.lp) >+ creds.set_realm(self.ldb.domain_dns_name().upper()) >+ creds.set_domain(self.ldb.domain_netbios_name().upper()) >+ creds.set_password(password) >+ creds.set_username(account_name) >+ if machine_account: >+ creds.set_workstation(name) >+ # >+ # Save the account name so it can be deleted in the tearDown >+ self.accounts.append(dn) >+ >+ return (creds, dn) >+ >+ def as_req(self, cname, sname, realm, etypes, padata=None): >+ '''Send a Kerberos AS_REQ, returns the undecoded response >+ ''' >+ >+ till = self.get_KerberosTime(offset=36000) >+ kdc_options = 0 >+ >+ req = self.AS_REQ_create(padata=padata, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7fffffff, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None) >+ rep = self.send_recv_transaction(req) >+ return rep >+ >+ def get_as_rep_key(self, creds, rep): >+ '''Extract the session key from an AS-REP >+ ''' >+ rep_padata = self.der_decode( >+ rep['e-data'], >+ asn1Spec=krb5_asn1.METHOD_DATA()) >+ >+ for pa in rep_padata: >+ if pa['padata-type'] == PADATA_ETYPE_INFO2: >+ padata_value = pa['padata-value'] >+ break >+ >+ etype_info2 = self.der_decode( >+ padata_value, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ >+ key = self.PasswordKey_from_etype_info2(creds, etype_info2[0]) >+ return key >+ >+ def get_pa_data(self, creds, rep, skew=0): >+ '''generate the pa_data data element for an AS-REQ >+ ''' >+ key = self.get_as_rep_key(creds, rep) >+ >+ (patime, pausec) = self.get_KerberosTimeWithUsec(offset=skew) >+ padata = self.PA_ENC_TS_ENC_create(patime, pausec) >+ padata = self.der_encode(padata, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) >+ >+ usage = 1 >+ padata = self.EncryptedData_create(key, usage, padata) >+ padata = self.der_encode(padata, asn1Spec=krb5_asn1.EncryptedData()) >+ >+ padata = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, padata) >+ >+ return [padata] >+ >+ def get_as_rep_enc_data(self, key, rep): >+ ''' Decrypt and Decode the encrypted data in an AS-REP >+ ''' >+ usage = 3 >+ enc_part = key.decrypt(usage, rep['enc-part']['cipher']) >+ # MIT KDC encodes both EncASRepPart and EncTGSRepPart with >+ # application tag 26 >+ try: >+ enc_part = self.der_decode( >+ enc_part, asn1Spec=krb5_asn1.EncASRepPart()) >+ except Exception: >+ enc_part = self.der_decode( >+ enc_part, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ >+ return enc_part >+ >+ def check_pre_authenication(self, rep): >+ """ Check that the kdc response was pre-authentication required >+ """ >+ self.check_error_rep(rep, KDC_ERR_PREAUTH_REQUIRED) >+ >+ def check_as_reply(self, rep): >+ """ Check that the kdc response is an AS-REP and that the >+ values for: >+ msg-type >+ pvno >+ tkt-pvno >+ kvno >+ match the expected values >+ """ >+ >+ # Should have a reply, and it should an AS-REP message. >+ self.assertIsNotNone(rep) >+ self.assertEqual(rep['msg-type'], KRB_AS_REP, "rep = {%s}" % rep) >+ >+ # Protocol version number should be 5 >+ pvno = int(rep['pvno']) >+ self.assertEqual(5, pvno, "rep = {%s}" % rep) >+ >+ # The ticket version number should be 5 >+ tkt_vno = int(rep['ticket']['tkt-vno']) >+ self.assertEqual(5, tkt_vno, "rep = {%s}" % rep) >+ >+ # Check that the kvno is not an RODC kvno >+ # MIT kerberos does not provide the kvno, so we treat it as optional. >+ # This is tested in compatability_test.py >+ if 'kvno' in rep['enc-part']: >+ kvno = int(rep['enc-part']['kvno']) >+ # If the high order bits are set this is an RODC kvno. >+ self.assertEqual(0, kvno & 0xFFFF0000, "rep = {%s}" % rep) >+ >+ def check_tgs_reply(self, rep): >+ """ Check that the kdc response is an TGS-REP and that the >+ values for: >+ msg-type >+ pvno >+ tkt-pvno >+ kvno >+ match the expected values >+ """ >+ >+ # Should have a reply, and it should an TGS-REP message. >+ self.assertIsNotNone(rep) >+ self.assertEqual(rep['msg-type'], KRB_TGS_REP, "rep = {%s}" % rep) >+ >+ # Protocol version number should be 5 >+ pvno = int(rep['pvno']) >+ self.assertEqual(5, pvno, "rep = {%s}" % rep) >+ >+ # The ticket version number should be 5 >+ tkt_vno = int(rep['ticket']['tkt-vno']) >+ self.assertEqual(5, tkt_vno, "rep = {%s}" % rep) >+ >+ # Check that the kvno is not an RODC kvno >+ # MIT kerberos does not provide the kvno, so we treat it as optional. >+ # This is tested in compatability_test.py >+ if 'kvno' in rep['enc-part']: >+ kvno = int(rep['enc-part']['kvno']) >+ # If the high order bits are set this is an RODC kvno. >+ self.assertEqual(0, kvno & 0xFFFF0000, "rep = {%s}" % rep) >+ >+ def check_error_rep(self, rep, expected): >+ """ Check that the reply is an error message, with the expected >+ error-code specified. >+ """ >+ self.assertIsNotNone(rep) >+ self.assertEqual(rep['msg-type'], KRB_ERROR, "rep = {%s}" % rep) >+ self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep) >+ >+ def tgs_req(self, cname, sname, realm, ticket, key, etypes): >+ '''Send a TGS-REQ, returns the response and the decrypted and >+ decoded enc-part >+ ''' >+ >+ kdc_options = "0" >+ till = self.get_KerberosTime(offset=36000) >+ padata = [] >+ >+ subkey = self.RandomKey(key.etype) >+ subkey_usage = 9 >+ >+ (ctime, cusec) = self.get_KerberosTimeWithUsec() >+ >+ req = self.TGS_REQ_create(padata=padata, >+ cusec=cusec, >+ ctime=ctime, >+ ticket=ticket, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=None, >+ till_time=till, >+ renew_time=None, >+ nonce=0x7ffffffe, >+ etypes=etypes, >+ addresses=None, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ additional_tickets=None, >+ ticket_session_key=key, >+ authenticator_subkey=subkey) >+ rep = self.send_recv_transaction(req) >+ self.assertIsNotNone(rep) >+ >+ msg_type = rep['msg-type'] >+ enc_part = None >+ if msg_type == KRB_TGS_REP: >+ enc_part = subkey.decrypt(subkey_usage, rep['enc-part']['cipher']) >+ enc_part = self.der_decode( >+ enc_part, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ return (rep, enc_part) >+ >+ # Named tuple to contain values of interest when the PAC is decoded. >+ PacData = namedtuple( >+ "PacData", >+ "account_name account_sid logon_name upn domain_name") >+ PAC_LOGON_INFO = 1 >+ PAC_CREDENTIAL_INFO = 2 >+ PAC_SRV_CHECKSUM = 6 >+ PAC_KDC_CHECKSUM = 7 >+ PAC_LOGON_NAME = 10 >+ PAC_CONSTRAINED_DELEGATION = 11 >+ PAC_UPN_DNS_INFO = 12 >+ >+ def get_pac_data(self, authorization_data): >+ '''Decode the PAC element contained in the authorization-data element >+ ''' >+ account_name = None >+ user_sid = None >+ logon_name = None >+ upn = None >+ domain_name = None >+ >+ # The PAC data will be wrapped in an AD_IF_RELEVANT element >+ ad_if_relevant_elements = ( >+ x for x in authorization_data if x['ad-type'] == AD_IF_RELEVANT) >+ for dt in ad_if_relevant_elements: >+ buf = self.der_decode( >+ dt['ad-data'], asn1Spec=krb5_asn1.AD_IF_RELEVANT()) >+ # The PAC data is further wrapped in a AD_WIN2K_PAC element >+ for ad in (x for x in buf if x['ad-type'] == AD_WIN2K_PAC): >+ pb = ndr_unpack(krb5pac.PAC_DATA, ad['ad-data']) >+ for pac in pb.buffers: >+ if pac.type == self.PAC_LOGON_INFO: >+ account_name = ( >+ pac.info.info.info3.base.account_name) >+ user_sid = ( >+ str(pac.info.info.info3.base.domain_sid) + >+ "-" + str(pac.info.info.info3.base.rid)) >+ elif pac.type == self.PAC_LOGON_NAME: >+ logon_name = pac.info.account_name >+ elif pac.type == self.PAC_UPN_DNS_INFO: >+ upn = pac.info.upn_name >+ domain_name = pac.info.dns_domain_name >+ >+ return self.PacData( >+ account_name, >+ user_sid, >+ logon_name, >+ upn, >+ domain_name) >+ >+ def decode_service_ticket(self, creds, ticket): >+ '''Decrypt and decode a service ticket >+ ''' >+ >+ name = creds.get_username() >+ if name.endswith('$'): >+ name = name[:-1] >+ realm = creds.get_realm() >+ salt = "%s.%s@%s" % (name, realm.lower(), realm.upper()) >+ >+ key = self.PasswordKey_create( >+ ticket['enc-part']['etype'], >+ creds.get_password(), >+ salt, >+ ticket['enc-part']['kvno']) >+ >+ enc_part = key.decrypt(2, ticket['enc-part']['cipher']) >+ enc_ticket_part = self.der_decode( >+ enc_part, asn1Spec=krb5_asn1.EncTicketPart()) >+ return enc_ticket_part >+ >+ def get_objectSid(self, dn): >+ ''' Get the objectSID for a DN >+ Note: performs an Ldb query. >+ ''' >+ res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=["objectSID"]) >+ self.assertTrue(len(res) == 1, "did not get objectSid for %s" % dn) >+ sid = self.ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) >+ return sid.decode('utf8') >-- >2.25.1 > > >From 469948dd013eaff517680f59453e38c3bf8f851e Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Mon, 30 Nov 2020 14:19:15 +1300 >Subject: [PATCH 060/686] tests python krb5: initial TGS tests > >Initial tests on the KDC TGS > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 1ed461a142f68f5de5e21b873ebddfcf5ae0ca1e) >--- > python/samba/tests/krb5/kdc_base_test.py | 1 - > python/samba/tests/krb5/kdc_tgs_tests.py | 210 +++++++++++++++++++ > python/samba/tests/krb5/rfc4120_constants.py | 2 + > python/samba/tests/usage.py | 2 + > selftest/knownfail_mit_kdc | 5 + > source4/selftest/tests.py | 3 + > 6 files changed, 222 insertions(+), 1 deletion(-) > mode change 100755 => 100644 python/samba/tests/krb5/kdc_base_test.py > create mode 100755 python/samba/tests/krb5/kdc_tgs_tests.py > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >old mode 100755 >new mode 100644 >index 4fc7ee85ba9..1a823d173e3 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1,4 +1,3 @@ >-#!/usr/bin/env python3 > # Unix SMB/CIFS implementation. > # Copyright (C) Stefan Metzmacher 2020 > # Copyright (C) 2020 Catalyst.Net Ltd >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >new file mode 100755 >index 00000000000..23a1d868a79 >--- /dev/null >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -0,0 +1,210 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) 2020 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+from samba.tests.krb5.rfc4120_constants import ( >+ AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5, >+ KRB_ERROR, >+ KDC_ERR_BADMATCH, >+ NT_PRINCIPAL, >+ NT_SRV_INST, >+) >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class KdcTgsTests(KDCBaseTest): >+ >+ def setUp(self): >+ super().setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def test_tgs_req_cname_does_not_not_match_authenticator_cname(self): >+ ''' Try and obtain a ticket from the TGS, but supply a cname >+ that differs from that provided to the krbtgt >+ ''' >+ # Create the user account >+ user_name = "tsttktusr" >+ (uc, _) = self.create_account(user_name) >+ realm = uc.get_realm().lower() >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96,) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(uc, rep) >+ key = self.get_as_rep_key(uc, rep) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ # Request a service ticket, but use a cname that does not match >+ # that in the original AS-REQ >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ ticket = rep['ticket'] >+ >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=["Administrator"]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=["host", self.dns_host_name]) >+ >+ (rep, enc_part) = self.tgs_req(cname, sname, realm, ticket, key, etype) >+ >+ self.assertIsNone( >+ enc_part, >+ "rep = {%s}, enc_part = {%s}" % (rep, enc_part)) >+ self.assertEqual(KRB_ERROR, rep['msg-type'], "rep = {%s}" % rep) >+ self.assertEqual( >+ KDC_ERR_BADMATCH, >+ rep['error-code'], >+ "rep = {%s}" % rep) >+ >+ def test_ldap_service_ticket(self): >+ '''Get a ticket to the ldap service >+ ''' >+ # Create the user account >+ user_name = "tsttktusr" >+ (uc, _) = self.create_account(user_name) >+ realm = uc.get_realm().lower() >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96,) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(uc, rep) >+ key = self.get_as_rep_key(uc, rep) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ ticket = rep['ticket'] >+ >+ # Request a ticket to the ldap service >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, >+ names=["ldap", self.dns_host_name]) >+ >+ (rep, _) = self.tgs_req( >+ cname, sname, uc.get_realm(), ticket, key, etype) >+ >+ self.check_tgs_reply(rep) >+ >+ def test_get_ticket_for_host_service_of_machine_account(self): >+ >+ # Create a user and machine account for the test. >+ # >+ user_name = "tsttktusr" >+ (uc, dn) = self.create_account(user_name) >+ (mc, _) = self.create_account("tsttktmac", machine_account=True) >+ realm = uc.get_realm().lower() >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(uc, rep) >+ key = self.get_as_rep_key(uc, rep) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[mc.get_username()]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, uc.get_realm(), ticket, key, etype) >+ self.check_tgs_reply(rep) >+ >+ # Check the contents of the service ticket >+ ticket = rep['ticket'] >+ enc_part = self.decode_service_ticket(mc, ticket) >+ >+ pac_data = self.get_pac_data(enc_part['authorization-data']) >+ sid = self.get_objectSid(dn) >+ upn = "%s@%s" % (uc.get_username(), realm) >+ self.assertEqual( >+ uc.get_username(), >+ str(pac_data.account_name), >+ "rep = {%s},%s" % (rep, pac_data)) >+ self.assertEqual( >+ uc.get_username(), >+ pac_data.logon_name, >+ "rep = {%s},%s" % (rep, pac_data)) >+ self.assertEqual( >+ uc.get_realm(), >+ pac_data.domain_name, >+ "rep = {%s},%s" % (rep, pac_data)) >+ self.assertEqual( >+ upn, >+ pac_data.upn, >+ "rep = {%s},%s" % (rep, pac_data)) >+ self.assertEqual( >+ sid, >+ pac_data.account_sid, >+ "rep = {%s},%s" % (rep, pac_data)) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index e1d0c5baa68..19bb6691d43 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -28,6 +28,7 @@ ARCFOUR_HMAC_MD5 = int( > # Message types > KRB_ERROR = int(krb5_asn1.MessageTypeValues('krb-error')) > KRB_AS_REP = int(krb5_asn1.MessageTypeValues('krb-as-rep')) >+KRB_TGS_REP = int(krb5_asn1.MessageTypeValues('krb-tgs-rep')) > > # PAData types > PADATA_ENC_TIMESTAMP = int( >@@ -39,6 +40,7 @@ PADATA_ETYPE_INFO2 = int( > KDC_ERR_C_PRINCIPAL_UNKNOWN = 6 > KDC_ERR_PREAUTH_FAILED = 24 > KDC_ERR_PREAUTH_REQUIRED = 25 >+KDC_ERR_BADMATCH = 36 > KDC_ERR_SKEW = 37 > > # Name types >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 11cd405deea..838a3148d8e 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -91,6 +91,8 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/compatability_tests.py', > 'python/samba/tests/krb5/rfc4120_constants.py', > 'python/samba/tests/krb5/kdc_tests.py', >+ 'python/samba/tests/krb5/kdc_base_test.py', >+ 'python/samba/tests/krb5/kdc_tgs_tests.py', > } > > >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index f1a4971430e..e64303c6b0f 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -270,3 +270,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_RemoveDollar_AsReqSelf\( > ^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_UPN_AsReqSelf\( > ^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_UpperUserName_UPN_RemoveDollar_AsReqSelf\( >+# >+# MIT currently returns an error code of 12 KRB5KDC_ERR_POLICY: KDC policy rejects request, to the >+# following tests >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_ldap_service_ticket\(ad_dc\) >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_get_ticket_for_host_service_of_machine_account\(ad_dc\) >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index f2cdae9342c..4ce9602b53f 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1231,6 +1231,9 @@ for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: > planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests") > planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests") > planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests") >+planpythontestsuite( >+ "ad_dc", >+ "samba.tests.krb5.kdc_tgs_tests") > > for env in [ > 'vampire_dc', >-- >2.25.1 > > >From c9a58373964088c637985626dd55743b69e2a712 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Thu, 10 Dec 2020 16:26:06 +1300 >Subject: [PATCH 061/686] tests python krb5: Add key usage constants > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d8ed73b75ad67da99be392b2db18fe2e1ffed87f) >--- > python/samba/tests/krb5/rfc4120_constants.py | 50 ++++++++++++++++++++ > 1 file changed, 50 insertions(+) > >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index 19bb6691d43..9de56578c99 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -63,3 +63,53 @@ AD_MANDATORY_FOR_KDC = 8 > AD_INITIAL_VERIFIED_CAS = 9 > AD_WIN2K_PAC = 128 > AD_SIGNTICKET = 512 >+ >+# Key usage numbers >+# RFC 4120 Section 7.5.1. Key Usage Numbers >+KU_PA_ENC_TIMESTAMP = 1 >+''' AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the >+ client key (section 5.2.7.2) ''' >+KU_TICKET = 2 >+''' AS-REP Ticket and TGS-REP Ticket (includes tgs session key or >+ application session key), encrypted with the service key >+ (section 5.3) ''' >+KU_AS_REP_ENC_PART = 3 >+''' AS-REP encrypted part (includes tgs session key or application >+ session key), encrypted with the client key (section 5.4.2) ''' >+KU_TGS_REQ_AUTH_DAT_SESSION = 4 >+''' TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs >+ session key (section 5.4.1) ''' >+KU_TGS_REQ_AUTH_DAT_SUBKEY = 5 >+''' TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs >+ authenticator subkey (section 5.4.1) ''' >+KU_TGS_REQ_AUTH_CKSUM = 6 >+''' TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed >+ with the tgs session key (section 5.5.1) ''' >+KU_TGS_REQ_AUTH = 7 >+''' TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes tgs >+ authenticator subkey), encrypted with the tgs session key >+ (section 5.5.1) ''' >+KU_TGS_REP_ENC_PART_SESSION = 8 >+''' TGS-REP encrypted part (includes application session key), >+ encrypted with the tgs session key (section 5.4.2) ''' >+KU_TGS_REP_ENC_PART_SUB_KEY = 9 >+''' TGS-REP encrypted part (includes application session key), >+ encrypted with the tgs authenticator subkey (section 5.4.2) ''' >+KU_AP_REQ_AUTH_CKSUM = 10 >+''' AP-REQ Authenticator cksum, keyed with the application session >+ key (section 5.5.1) ''' >+KU_AP_REQ_AUTH = 11 >+''' AP-REQ Authenticator (includes application authenticator >+ subkey), encrypted with the application session key (section 5.5.1) ''' >+KU_AP_REQ_ENC_PART = 12 >+''' AP-REP encrypted part (includes application session subkey), >+ encrypted with the application session key (section 5.5.2) ''' >+KU_KRB_PRIV = 13 >+''' KRB-PRIV encrypted part, encrypted with a key chosen by the >+ application (section 5.7.1) ''' >+KU_KRB_CRED = 14 >+''' KRB-CRED encrypted part, encrypted with a key chosen by the >+ application (section 5.8.1) ''' >+KU_KRB_SAFE_CKSUM = 15 >+''' KRB-SAFE cksum, keyed with a key chosen by the application >+ (section 5.6.1) ''' >-- >2.25.1 > > >From 1ed4be2f2e77fbc5ce25d7dd88fba3b09f733b49 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Thu, 10 Dec 2020 16:27:17 +1300 >Subject: [PATCH 062/686] tests python krb5: use key usage constants > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 03676a4a5c55ab5f4958a86cbd4d7be0f0a8a294) >--- > .../tests/krb5/as_canonicalization_tests.py | 5 ++--- > python/samba/tests/krb5/compatability_tests.py | 7 +++---- > python/samba/tests/krb5/kdc_base_test.py | 16 +++++++++------- > python/samba/tests/krb5/kdc_tests.py | 3 +-- > python/samba/tests/krb5/s4u_tests.py | 15 +++++++++------ > python/samba/tests/krb5/simple_tests.py | 15 +++++++++------ > python/samba/tests/krb5/xrealm_tests.py | 15 +++++++++------ > 7 files changed, 42 insertions(+), 34 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index 6ea3ff0491e..e89b40eab8f 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -367,8 +367,7 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) > >- enc_pa_ts_usage = 1 >- pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.EncryptedData_create(key, KU_PA_ENC_TIMESTAMP, pa_ts) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) > > pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts) >@@ -413,7 +412,7 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > self.assertEqual(msg_type, KRB_AS_REP, "Data {0}".format(str(data))) > > # Decrypt and decode the EncKdcRepPart >- enc = key.decrypt(3, rep['enc-part']['cipher']) >+ enc = key.decrypt(KU_AS_REP_ENC_PART, rep['enc-part']['cipher']) > if enc[0] == 0x7A: > # MIT Kerberos Tags the EncASRepPart as a EncKDCRepPart > # i.e. tag number 26 instead of tag number 25 >diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py >index e4b1453e712..0b3701cd60d 100755 >--- a/python/samba/tests/krb5/compatability_tests.py >+++ b/python/samba/tests/krb5/compatability_tests.py >@@ -178,8 +178,7 @@ class SimpleKerberosTests(RawKerberosTest): > pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) > >- enc_pa_ts_usage = 1 >- pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.EncryptedData_create(key, KU_PA_ENC_TIMESTAMP, pa_ts) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) > > pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts) >@@ -207,9 +206,9 @@ class SimpleKerberosTests(RawKerberosTest): > msg_type = rep['msg-type'] > self.assertEqual(msg_type, KRB_AS_REP) > >- usage = 3 > enc_part = rep['enc-part'] >- enc_as_rep_part = key.decrypt(usage, rep['enc-part']['cipher']) >+ enc_as_rep_part = key.decrypt( >+ KU_AS_REP_ENC_PART, rep['enc-part']['cipher']) > return (enc_as_rep_part, enc_part) > > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 1a823d173e3..e835d389f1c 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -41,6 +41,10 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_AS_REP, > KRB_TGS_REP, > KRB_ERROR, >+ KU_AS_REP_ENC_PART, >+ KU_PA_ENC_TIMESTAMP, >+ KU_TGS_REP_ENC_PART_SUB_KEY, >+ KU_TICKET, > PADATA_ENC_TIMESTAMP, > PADATA_ETYPE_INFO2, > ) >@@ -196,8 +200,7 @@ class KDCBaseTest(RawKerberosTest): > padata = self.PA_ENC_TS_ENC_create(patime, pausec) > padata = self.der_encode(padata, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) > >- usage = 1 >- padata = self.EncryptedData_create(key, usage, padata) >+ padata = self.EncryptedData_create(key, KU_PA_ENC_TIMESTAMP, padata) > padata = self.der_encode(padata, asn1Spec=krb5_asn1.EncryptedData()) > > padata = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, padata) >@@ -207,8 +210,7 @@ class KDCBaseTest(RawKerberosTest): > def get_as_rep_enc_data(self, key, rep): > ''' Decrypt and Decode the encrypted data in an AS-REP > ''' >- usage = 3 >- enc_part = key.decrypt(usage, rep['enc-part']['cipher']) >+ enc_part = key.decrypt(KU_AS_REP_ENC_PART, rep['enc-part']['cipher']) > # MIT KDC encodes both EncASRepPart and EncTGSRepPart with > # application tag 26 > try: >@@ -303,7 +305,6 @@ class KDCBaseTest(RawKerberosTest): > padata = [] > > subkey = self.RandomKey(key.etype) >- subkey_usage = 9 > > (ctime, cusec) = self.get_KerberosTimeWithUsec() > >@@ -332,7 +333,8 @@ class KDCBaseTest(RawKerberosTest): > msg_type = rep['msg-type'] > enc_part = None > if msg_type == KRB_TGS_REP: >- enc_part = subkey.decrypt(subkey_usage, rep['enc-part']['cipher']) >+ enc_part = subkey.decrypt( >+ KU_TGS_REP_ENC_PART_SUB_KEY, rep['enc-part']['cipher']) > enc_part = self.der_decode( > enc_part, asn1Spec=krb5_asn1.EncTGSRepPart()) > return (rep, enc_part) >@@ -403,7 +405,7 @@ class KDCBaseTest(RawKerberosTest): > salt, > ticket['enc-part']['kvno']) > >- enc_part = key.decrypt(2, ticket['enc-part']['cipher']) >+ enc_part = key.decrypt(KU_TICKET, ticket['enc-part']['cipher']) > enc_ticket_part = self.der_decode( > enc_part, asn1Spec=krb5_asn1.EncTicketPart()) > return enc_ticket_part >diff --git a/python/samba/tests/krb5/kdc_tests.py b/python/samba/tests/krb5/kdc_tests.py >index 57a25448965..17b9d154bd9 100755 >--- a/python/samba/tests/krb5/kdc_tests.py >+++ b/python/samba/tests/krb5/kdc_tests.py >@@ -91,8 +91,7 @@ class KdcTests(RawKerberosTest): > pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) > >- enc_pa_ts_usage = 1 >- pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.EncryptedData_create(key, KU_PA_ENC_TIMESTAMP, pa_ts) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) > > pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts) >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index ae38635c53b..2e1bd3fbe1f 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -25,6 +25,11 @@ os.environ["PYTHONUNBUFFERED"] = "1" > from samba.tests import env_get_var_value > from samba.tests.krb5.kcrypto import Cksumtype > from samba.tests.krb5.raw_testcase import RawKerberosTest >+from samba.tests.krb5.rfc4120_constants import ( >+ KU_PA_ENC_TIMESTAMP, >+ KU_AS_REP_ENC_PART, >+ KU_TGS_REP_ENC_PART_SUB_KEY, >+) > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > > global_asn1_print = False >@@ -86,8 +91,7 @@ class S4UKerberosTests(RawKerberosTest): > pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) > >- enc_pa_ts_usage = 1 >- pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.EncryptedData_create(key, KU_PA_ENC_TIMESTAMP, pa_ts) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) > > pa_ts = self.PA_DATA_create(2, pa_ts) >@@ -115,8 +119,7 @@ class S4UKerberosTests(RawKerberosTest): > msg_type = rep['msg-type'] > self.assertEqual(msg_type, 11) > >- usage = 3 >- enc_part2 = key.decrypt(usage, rep['enc-part']['cipher']) >+ enc_part2 = key.decrypt(KU_AS_REP_ENC_PART, rep['enc-part']['cipher']) > enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) > > # S4U2Self Request >@@ -135,7 +138,6 @@ class S4UKerberosTests(RawKerberosTest): > padata = [pa_s4u] > > subkey = self.RandomKey(ticket_session_key.etype) >- subkey_usage = 9 > > (ctime, cusec) = self.get_KerberosTimeWithUsec() > >@@ -163,7 +165,8 @@ class S4UKerberosTests(RawKerberosTest): > > msg_type = rep['msg-type'] > if msg_type == 13: >- enc_part2 = subkey.decrypt(subkey_usage, rep['enc-part']['cipher']) >+ enc_part2 = subkey.decrypt( >+ KU_TGS_REP_ENC_PART_SUB_KEY, rep['enc-part']['cipher']) > enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) > > return msg_type >diff --git a/python/samba/tests/krb5/simple_tests.py b/python/samba/tests/krb5/simple_tests.py >index 236fbda1cd5..6c090af3d46 100755 >--- a/python/samba/tests/krb5/simple_tests.py >+++ b/python/samba/tests/krb5/simple_tests.py >@@ -23,6 +23,11 @@ sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > > from samba.tests.krb5.raw_testcase import RawKerberosTest >+from samba.tests.krb5.rfc4120_constants import ( >+ KU_AS_REP_ENC_PART, >+ KU_PA_ENC_TIMESTAMP, >+ KU_TGS_REP_ENC_PART_SUB_KEY, >+) > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > > global_asn1_print = False >@@ -84,8 +89,7 @@ class SimpleKerberosTests(RawKerberosTest): > pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) > >- enc_pa_ts_usage = 1 >- pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.EncryptedData_create(key, KU_PA_ENC_TIMESTAMP, pa_ts) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) > > pa_ts = self.PA_DATA_create(2, pa_ts) >@@ -113,8 +117,7 @@ class SimpleKerberosTests(RawKerberosTest): > msg_type = rep['msg-type'] > self.assertEqual(msg_type, 11) > >- usage = 3 >- enc_part2 = key.decrypt(usage, rep['enc-part']['cipher']) >+ enc_part2 = key.decrypt(KU_AS_REP_ENC_PART, rep['enc-part']['cipher']) > > # MIT KDC encodes both EncASRepPart and EncTGSRepPart with application tag 26 > try: >@@ -134,7 +137,6 @@ class SimpleKerberosTests(RawKerberosTest): > padata = [] > > subkey = self.RandomKey(ticket_session_key.etype) >- subkey_usage = 9 > > (ctime, cusec) = self.get_KerberosTimeWithUsec() > >@@ -163,7 +165,8 @@ class SimpleKerberosTests(RawKerberosTest): > msg_type = rep['msg-type'] > self.assertEqual(msg_type, 13) > >- enc_part2 = subkey.decrypt(subkey_usage, rep['enc-part']['cipher']) >+ enc_part2 = subkey.decrypt( >+ KU_TGS_REP_ENC_PART_SUB_KEY, rep['enc-part']['cipher']) > enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) > > return >diff --git a/python/samba/tests/krb5/xrealm_tests.py b/python/samba/tests/krb5/xrealm_tests.py >index 64064b8a670..b4a02bff33a 100755 >--- a/python/samba/tests/krb5/xrealm_tests.py >+++ b/python/samba/tests/krb5/xrealm_tests.py >@@ -23,6 +23,11 @@ sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > > from samba.tests.krb5.raw_testcase import RawKerberosTest >+from samba.tests.krb5.rfc4120_constants import ( >+ KU_PA_ENC_TIMESTAMP, >+ KU_AS_REP_ENC_PART, >+ KU_TGS_REP_ENC_PART_SUB_KEY, >+) > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > import samba.tests > >@@ -85,8 +90,7 @@ class XrealmKerberosTests(RawKerberosTest): > pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) > >- enc_pa_ts_usage = 1 >- pa_ts = self.EncryptedData_create(key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.EncryptedData_create(key, KU_PA_ENC_TIMESTAMP, pa_ts) > pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) > > pa_ts = self.PA_DATA_create(2, pa_ts) >@@ -114,8 +118,7 @@ class XrealmKerberosTests(RawKerberosTest): > msg_type = rep['msg-type'] > self.assertEqual(msg_type, 11) > >- usage = 3 >- enc_part2 = key.decrypt(usage, rep['enc-part']['cipher']) >+ enc_part2 = key.decrypt(KU_AS_REP_ENC_PART, rep['enc-part']['cipher']) > > # MIT KDC encodes both EncASRepPart and EncTGSRepPart with application tag 26 > try: >@@ -134,7 +137,6 @@ class XrealmKerberosTests(RawKerberosTest): > padata = [] > > subkey = self.RandomKey(ticket_session_key.etype) >- subkey_usage = 9 > > (ctime, cusec) = self.get_KerberosTimeWithUsec() > >@@ -163,7 +165,8 @@ class XrealmKerberosTests(RawKerberosTest): > msg_type = rep['msg-type'] > self.assertEqual(msg_type, 13) > >- enc_part2 = subkey.decrypt(subkey_usage, rep['enc-part']['cipher']) >+ enc_part2 = subkey.decrypt( >+ KU_TGS_REP_ENC_PART_SUB_KEY, rep['enc-part']['cipher']) > enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) > > # Check the forwardable flag >-- >2.25.1 > > >From f1b7f4fff235e8d790da62546edb7daf6978818c Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Fri, 11 Dec 2020 11:55:01 +1300 >Subject: [PATCH 063/686] tests python krb5: PEP8 cleanups > >Fix all the PEP8 warnings in samba/tests/krb5. With the exception of >rfc4120_pyasn1.py, which is generated from rfc4120.asn1. > >As these tests are new, it makes sense to ensure that they conform to >PEP8. And set an aspirational goal for the rest of our python code. > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Autobuild-User(master): Gary Lockyer <gary@samba.org> >Autobuild-Date(master): Mon Dec 21 21:29:28 UTC 2020 on sn-devel-184 > >(cherry picked from commit c00d537526ca881c540ff66e703ad9c96dd1face) >--- > .../tests/krb5/as_canonicalization_tests.py | 54 ++- > .../samba/tests/krb5/compatability_tests.py | 24 +- > python/samba/tests/krb5/kcrypto.py | 67 +-- > python/samba/tests/krb5/kdc_base_test.py | 4 +- > python/samba/tests/krb5/kdc_tests.py | 17 +- > python/samba/tests/krb5/raw_testcase.py | 409 +++++++++++------- > python/samba/tests/krb5/rfc4120_constants.py | 32 +- > python/samba/tests/krb5/s4u_tests.py | 19 +- > python/samba/tests/krb5/simple_tests.py | 24 +- > python/samba/tests/krb5/xrealm_tests.py | 26 +- > 10 files changed, 413 insertions(+), 263 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index e89b40eab8f..43f532dc483 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -31,8 +31,6 @@ import samba > from samba.auth import system_session > from samba.credentials import ( > Credentials, >- CLI_CRED_NTLMv2_AUTH, >- CLI_CRED_NTLM_AUTH, > DONT_USE_KERBEROS) > from samba.dcerpc.misc import SEC_CHAN_WKSTA > from samba.dsdb import ( >@@ -41,7 +39,20 @@ from samba.dsdb import ( > UF_NORMAL_ACCOUNT) > from samba.samdb import SamDB > from samba.tests import delete_force, DynamicTestCase >-from samba.tests.krb5.rfc4120_constants import * >+from samba.tests.krb5.rfc4120_constants import ( >+ AES256_CTS_HMAC_SHA1_96, >+ AES128_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5, >+ KDC_ERR_PREAUTH_REQUIRED, >+ KRB_AS_REP, >+ KU_AS_REP_ENC_PART, >+ KRB_ERROR, >+ KU_PA_ENC_TIMESTAMP, >+ PADATA_ENC_TIMESTAMP, >+ NT_ENTERPRISE_PRINCIPAL, >+ NT_PRINCIPAL, >+ NT_SRV_INST, >+) > > global_asn1_print = False > global_hexdump = False >@@ -49,15 +60,15 @@ global_hexdump = False > > @unique > class TestOptions(Enum): >- Canonicalize = 1 >- Enterprise = 2 >- UpperRealm = 4 >- UpperUserName = 8 >- NetbiosRealm = 16 >- UPN = 32 >- RemoveDollar = 64 >- AsReqSelf = 128 >- Last = 256 >+ Canonicalize = 1 >+ Enterprise = 2 >+ UpperRealm = 4 >+ UpperUserName = 8 >+ NetbiosRealm = 16 >+ UPN = 32 >+ RemoveDollar = 64 >+ AsReqSelf = 128 >+ Last = 256 > > def is_set(self, x): > return self.value & x >@@ -65,7 +76,7 @@ class TestOptions(Enum): > > @unique > class CredentialsType(Enum): >- User = 1 >+ User = 1 > Machine = 2 > > def is_set(self, x): >@@ -126,7 +137,8 @@ class TestData: > > > MACHINE_NAME = "tstkrb5cnnmch" >-USER_NAME = "tstkrb5cnnusr" >+USER_NAME = "tstkrb5cnnusr" >+ > > @DynamicTestCase > class KerberosASCanonicalizationTests(RawKerberosTest): >@@ -160,21 +172,21 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > > @classmethod > def setUpClass(cls): >- cls.lp = cls.get_loadparm(cls) >+ cls.lp = cls.get_loadparm(cls) > cls.username = os.environ["USERNAME"] > cls.password = os.environ["PASSWORD"] >- cls.host = os.environ["SERVER"] >+ cls.host = os.environ["SERVER"] > > c = Credentials() > c.set_username(cls.username) > c.set_password(cls.password) > try: >- realm = os.environ["REALM"] >+ realm = os.environ["REALM"] > c.set_realm(realm) > except KeyError: > pass > try: >- domain = os.environ["DOMAIN"] >+ domain = os.environ["DOMAIN"] > c.set_domain(domain) > except KeyError: > pass >@@ -200,7 +212,7 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > def setUp(self): > super(KerberosASCanonicalizationTests, self).setUp() > self.do_asn1_print = global_asn1_print >- self.do_hexdump = global_hexdump >+ self.do_hexdump = global_hexdump > > # > # Create a test user account >@@ -340,7 +352,7 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > # > # Check the protocol version, should be 5 > self.assertEqual( >- rep['pvno'], 5, "Data {0}".format(str(data))) >+ rep['pvno'], 5, "Data {0}".format(str(data))) > > self.assertEqual( > rep['msg-type'], KRB_ERROR, "Data {0}".format(str(data))) >@@ -397,7 +409,7 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > # > # Check the protocol version, should be 5 > self.assertEqual( >- rep['pvno'], 5, "Data {0}".format(str(data))) >+ rep['pvno'], 5, "Data {0}".format(str(data))) > > msg_type = rep['msg-type'] > # Should not have got an error. >diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py >index 0b3701cd60d..5a1ef02ef80 100755 >--- a/python/samba/tests/krb5/compatability_tests.py >+++ b/python/samba/tests/krb5/compatability_tests.py >@@ -25,7 +25,20 @@ os.environ["PYTHONUNBUFFERED"] = "1" > > from samba.tests.krb5.raw_testcase import RawKerberosTest > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >-from samba.tests.krb5.rfc4120_constants import * >+from samba.tests.krb5.rfc4120_constants import ( >+ AES128_CTS_HMAC_SHA1_96, >+ AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5, >+ KDC_ERR_PREAUTH_REQUIRED, >+ KRB_AS_REP, >+ KRB_ERROR, >+ KU_AS_REP_ENC_PART, >+ KU_PA_ENC_TIMESTAMP, >+ PADATA_ENC_TIMESTAMP, >+ PADATA_ETYPE_INFO2, >+ NT_PRINCIPAL, >+ NT_SRV_INST, >+) > > global_asn1_print = False > global_hexdump = False >@@ -112,18 +125,17 @@ class SimpleKerberosTests(RawKerberosTest): > realm = creds.get_realm() > > cname = self.PrincipalName_create( >- name_type=NT_PRINCIPAL, >- names=[user]) >+ name_type=NT_PRINCIPAL, >+ names=[user]) > sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, >- names=["krbtgt", realm]) >+ name_type=NT_SRV_INST, >+ names=["krbtgt", realm]) > > till = self.get_KerberosTime(offset=36000) > > kdc_options = krb5_asn1.KDCOptions('forwardable') > padata = None > >- > req = self.AS_REQ_create(padata=padata, > kdc_options=str(kdc_options), > cname=cname, >diff --git a/python/samba/tests/krb5/kcrypto.py b/python/samba/tests/krb5/kcrypto.py >index 2572fa5bab3..23502d7bb62 100755 >--- a/python/samba/tests/krb5/kcrypto.py >+++ b/python/samba/tests/krb5/kcrypto.py >@@ -64,6 +64,7 @@ from samba.credentials import Credentials > from samba import generate_random_bytes as get_random_bytes > from samba.compat import get_string, get_bytes > >+ > class Enctype(object): > DES_CRC = 1 > DES_MD4 = 2 >@@ -112,26 +113,30 @@ def _mac_equal(mac1, mac2): > res |= x ^ y > return res == 0 > >+ > def SIMPLE_HASH(string, algo_cls): > hash_ctx = hashes.Hash(algo_cls(), default_backend()) > hash_ctx.update(string) > return hash_ctx.finalize() > >+ > def HMAC_HASH(key, string, algo_cls): > hmac_ctx = hmac.HMAC(key, algo_cls(), default_backend()) > hmac_ctx.update(string) > return hmac_ctx.finalize() > >+ > def _nfold(str, nbytes): > # Convert str to a string of length nbytes using the RFC 3961 nfold > # operation. > > # Rotate the bytes in str to the right by nbits bits. > def rotate_right(str, nbits): >- nbytes, remain = (nbits//8) % len(str), nbits % 8 >- return bytes([(str[i-nbytes] >> remain) | >- (str[i-nbytes-1] << (8-remain) & 0xff) >- for i in range(len(str))]) >+ nbytes, remain = (nbits // 8) % len(str), nbits % 8 >+ return bytes([ >+ (str[i - nbytes] >> remain) >+ | (str[i - nbytes - 1] << (8 - remain) & 0xff) >+ for i in range(len(str))]) > > # Add equal-length strings together with end-around carry. > def add_ones_complement(str1, str2): >@@ -139,7 +144,7 @@ def _nfold(str, nbytes): > v = [a + b for a, b in zip(str1, str2)] > # Propagate carry bits to the left until there aren't any left. > while any(x & ~0xff for x in v): >- v = [(v[i-n+1]>>8) + (v[i]&0xff) for i in range(n)] >+ v = [(v[i - n + 1] >> 8) + (v[i] & 0xff) for i in range(n)] > return bytes([x for x in v]) > > # Concatenate copies of str to produce the least common multiple >@@ -150,7 +155,7 @@ def _nfold(str, nbytes): > slen = len(str) > lcm = nbytes * slen // gcd(nbytes, slen) > bigstr = b''.join((rotate_right(str, 13 * i) for i in range(lcm // slen))) >- slices = (bigstr[p:p+nbytes] for p in range(0, lcm, nbytes)) >+ slices = (bigstr[p:p + nbytes] for p in range(0, lcm, nbytes)) > return reduce(add_ones_complement, slices) > > >@@ -275,7 +280,7 @@ class _DES3CBC(_SimplifiedEnctype): > return b if bin(b & ~1).count('1') % 2 else b | 1 > assert len(seed) == 7 > firstbytes = [parity(b & ~1) for b in seed] >- lastbyte = parity(sum((seed[i]&1) << i+1 for i in range(7))) >+ lastbyte = parity(sum((seed[i] & 1) << i + 1 for i in range(7))) > keybytes = bytes([b for b in firstbytes + [lastbyte]]) > if _is_weak_des_key(keybytes): > keybytes[7] = bytes([keybytes[7] ^ 0xF0]) >@@ -369,7 +374,7 @@ class _AESEnctype(_SimplifiedEnctype): > if len(ciphertext) == 16: > return aes_decrypt(ciphertext) > # Split the ciphertext into blocks. The last block may be partial. >- cblocks = [ciphertext[p:p+16] for p in range(0, len(ciphertext), 16)] >+ cblocks = [ciphertext[p:p + 16] for p in range(0, len(ciphertext), 16)] > lastlen = len(cblocks[-1]) > # CBC-decrypt all but the last two blocks. > prev_cblock = bytes(16) >@@ -383,7 +388,7 @@ class _AESEnctype(_SimplifiedEnctype): > # will be the omitted bytes of ciphertext from the final > # block. > b = aes_decrypt(cblocks[-2]) >- lastplaintext =_xorbytes(b[:lastlen], cblocks[-1]) >+ lastplaintext = _xorbytes(b[:lastlen], cblocks[-1]) > omitted = b[lastlen:] > # Decrypt the final cipher block plus the omitted bytes to get > # the second-to-last plaintext block. >@@ -433,7 +438,8 @@ class _RC4(_EnctypeProfile): > cksum = HMAC_HASH(ki, confounder + plaintext, hashes.MD5) > ke = HMAC_HASH(ki, cksum, hashes.MD5) > >- encryptor = Cipher(ciphers.ARC4(ke), None, default_backend()).encryptor() >+ encryptor = Cipher( >+ ciphers.ARC4(ke), None, default_backend()).encryptor() > ctext = encryptor.update(confounder + plaintext) > > return cksum + ctext >@@ -446,7 +452,8 @@ class _RC4(_EnctypeProfile): > ki = HMAC_HASH(key.contents, cls.usage_str(keyusage), hashes.MD5) > ke = HMAC_HASH(ki, cksum, hashes.MD5) > >- decryptor = Cipher(ciphers.ARC4(ke), None, default_backend()).decryptor() >+ decryptor = Cipher( >+ ciphers.ARC4(ke), None, default_backend()).decryptor() > basic_plaintext = decryptor.update(basic_ctext) > > exp_cksum = HMAC_HASH(ki, basic_plaintext, hashes.MD5) >@@ -636,14 +643,14 @@ def verify_checksum(cksumtype, key, keyusage, text, cksum): > c.verify(key, keyusage, text, cksum) > > >-def prfplus(key, pepper, l): >- # Produce l bytes of output using the RFC 6113 PRF+ function. >+def prfplus(key, pepper, ln): >+ # Produce ln bytes of output using the RFC 6113 PRF+ function. > out = b'' > count = 1 >- while len(out) < l: >+ while len(out) < ln: > out += prf(key, bytes([count]) + pepper) > count += 1 >- return out[:l] >+ return out[:ln] > > > def cf2(enctype, key1, key2, pepper1, pepper2): >@@ -653,9 +660,11 @@ def cf2(enctype, key1, key2, pepper1, pepper2): > return e.random_to_key(_xorbytes(prfplus(key1, pepper1, e.seedsize), > prfplus(key2, pepper2, e.seedsize))) > >+ > def h(hexstr): > return bytes.fromhex(hexstr) > >+ > class KcrytoTest(TestCase): > """kcrypto Test case.""" > >@@ -665,20 +674,21 @@ class KcrytoTest(TestCase): > conf = h('94B491F481485B9A0678CD3C4EA386AD') > keyusage = 2 > plain = b'9 bytesss' >- ctxt = h('68FB9679601F45C78857B2BF820FD6E53ECA8D42FD4B1D7024A09205ABB7CD2E' >- 'C26C355D2F') >+ ctxt = h('68FB9679601F45C78857B2BF820FD6E53ECA8D42FD4B1D7024A09205ABB7' >+ 'CD2EC26C355D2F') > k = Key(Enctype.AES128, kb) > self.assertEqual(encrypt(k, keyusage, plain, conf), ctxt) > self.assertEqual(decrypt(k, keyusage, ctxt), plain) > > def test_aes256_crypt(self): > # AES256 encrypt and decrypt >- kb = h('F1C795E9248A09338D82C3F8D5B567040B0110736845041347235B1404231398') >+ kb = h('F1C795E9248A09338D82C3F8D5B567040B0110736845041347235B14042313' >+ '98') > conf = h('E45CA518B42E266AD98E165E706FFB60') > keyusage = 4 > plain = b'30 bytes bytes bytes bytes byt' >- ctxt = h('D1137A4D634CFECE924DBC3BF6790648BD5CFF7DE0E7B99460211D0DAEF3D79A' >- '295C688858F3B34B9CBD6EEBAE81DAF6B734D4D498B6714F1C1D') >+ ctxt = h('D1137A4D634CFECE924DBC3BF6790648BD5CFF7DE0E7B99460211D0DAEF3' >+ 'D79A295C688858F3B34B9CBD6EEBAE81DAF6B734D4D498B6714F1C1D') > k = Key(Enctype.AES256, kb) > self.assertEqual(encrypt(k, keyusage, plain, conf), ctxt) > self.assertEqual(decrypt(k, keyusage, ctxt), plain) >@@ -694,7 +704,8 @@ class KcrytoTest(TestCase): > > def test_aes256_checksum(self): > # AES256 checksum >- kb = h('B1AE4CD8462AFF1677053CC9279AAC30B796FB81CE21474DD3DDBCFEA4EC76D7') >+ kb = h('B1AE4CD8462AFF1677053CC9279AAC30B796FB81CE21474DD3DDBC' >+ 'FEA4EC76D7') > keyusage = 4 > plain = b'fourteen' > cksum = h('E08739E3279E2903EC8E3836') >@@ -715,7 +726,8 @@ class KcrytoTest(TestCase): > string = b'X' * 64 > salt = b'pass phrase equals block size' > params = h('000004B0') >- kb = h('89ADEE3608DB8BC71F1BFBFE459486B05618B70CBAE22092534E56C553BA4B34') >+ kb = h('89ADEE3608DB8BC71F1BFBFE459486B05618B70CBAE22092534E56' >+ 'C553BA4B34') > k = string_to_key(Enctype.AES256, string, salt, params) > self.assertEqual(k.contents, kb) > >@@ -741,7 +753,8 @@ class KcrytoTest(TestCase): > > def test_aes256_cf2(self): > # AES256 cf2 >- kb = h('4D6CA4E629785C1F01BAF55E2E548566B9617AE3A96868C337CB93B5E72B1C7B') >+ kb = h('4D6CA4E629785C1F01BAF55E2E548566B9617AE3A96868C337CB93B5' >+ 'E72B1C7B') > k1 = string_to_key(Enctype.AES256, b'key1', b'key1') > k2 = string_to_key(Enctype.AES256, b'key2', b'key2') > k = cf2(Enctype.AES256, k1, k2, b'a', b'b') >@@ -753,8 +766,8 @@ class KcrytoTest(TestCase): > conf = h('94690A17B2DA3C9B') > keyusage = 3 > plain = b'13 bytes byte' >- ctxt = h('839A17081ECBAFBCDC91B88C6955DD3C4514023CF177B77BF0D0177A16F705E8' >- '49CB7781D76A316B193F8D30') >+ ctxt = h('839A17081ECBAFBCDC91B88C6955DD3C4514023CF177B77BF0D0177A16F7' >+ '05E849CB7781D76A316B193F8D30') > k = Key(Enctype.DES3, kb) > self.assertEqual(encrypt(k, keyusage, plain, conf), ctxt) > self.assertEqual(decrypt(k, keyusage, ctxt), _zeropad(plain, 8)) >@@ -790,8 +803,8 @@ class KcrytoTest(TestCase): > conf = h('37245E73A45FBF72') > keyusage = 4 > plain = b'30 bytes bytes bytes bytes byt' >- ctxt = h('95F9047C3AD75891C2E9B04B16566DC8B6EB9CE4231AFB2542EF87A7B5A0F260' >- 'A99F0460508DE0CECC632D07C354124E46C5D2234EB8') >+ ctxt = h('95F9047C3AD75891C2E9B04B16566DC8B6EB9CE4231AFB2542EF87A7B5A0' >+ 'F260A99F0460508DE0CECC632D07C354124E46C5D2234EB8') > k = Key(Enctype.RC4, kb) > self.assertEqual(encrypt(k, keyusage, plain, conf), ctxt) > self.assertEqual(decrypt(k, keyusage, ctxt), plain) >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index e835d389f1c..bef5458c881 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -374,8 +374,8 @@ class KDCBaseTest(RawKerberosTest): > account_name = ( > pac.info.info.info3.base.account_name) > user_sid = ( >- str(pac.info.info.info3.base.domain_sid) + >- "-" + str(pac.info.info.info3.base.rid)) >+ str(pac.info.info.info3.base.domain_sid) >+ + "-" + str(pac.info.info.info3.base.rid)) > elif pac.type == self.PAC_LOGON_NAME: > logon_name = pac.info.account_name > elif pac.type == self.PAC_UPN_DNS_INFO: >diff --git a/python/samba/tests/krb5/kdc_tests.py b/python/samba/tests/krb5/kdc_tests.py >index 17b9d154bd9..c7c53953a86 100755 >--- a/python/samba/tests/krb5/kdc_tests.py >+++ b/python/samba/tests/krb5/kdc_tests.py >@@ -25,7 +25,20 @@ os.environ["PYTHONUNBUFFERED"] = "1" > > from samba.tests.krb5.raw_testcase import RawKerberosTest > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >-from samba.tests.krb5.rfc4120_constants import * >+from samba.tests.krb5.rfc4120_constants import ( >+ AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5, >+ KDC_ERR_PREAUTH_FAILED, >+ KDC_ERR_PREAUTH_REQUIRED, >+ KDC_ERR_SKEW, >+ KRB_AS_REP, >+ KRB_ERROR, >+ KU_PA_ENC_TIMESTAMP, >+ PADATA_ENC_TIMESTAMP, >+ PADATA_ETYPE_INFO2, >+ NT_PRINCIPAL, >+ NT_SRV_INST, >+) > > global_asn1_print = False > global_hexdump = False >@@ -83,7 +96,7 @@ class KdcTests(RawKerberosTest): > break > > etype_info2 = self.der_decode( >- etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) > > key = self.PasswordKey_from_etype_info2(creds, etype_info2[0]) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e67f5464e59..82e68ee7019 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -35,7 +35,10 @@ from pyasn1.codec.native.decoder import decode as pyasn1_native_decode > from pyasn1.codec.native.encoder import encode as pyasn1_native_encode > > from pyasn1.codec.ber.encoder import BitStringEncoder as BitStringEncoder >-def BitStringEncoder_encodeValue32(self, value, asn1Spec, encodeFun, **options): >+ >+ >+def BitStringEncoder_encodeValue32( >+ self, value, asn1Spec, encodeFun, **options): > # > # BitStrings like KDCOptions or TicketFlags should at least > # be 32-Bit on the wire >@@ -59,14 +62,17 @@ def BitStringEncoder_encodeValue32(self, value, asn1Spec, encodeFun, **options): > padding = 0 > ret = b'\x00' + substrate + (b'\x00' * padding) > return ret, False, True >+ >+ > BitStringEncoder.encodeValue = BitStringEncoder_encodeValue32 > >+ > def BitString_NamedValues_prettyPrint(self, scope=0): > ret = "%s" % self.asBinary() > bits = [] > highest_bit = 32 > for byte in self.asNumbers(): >- for bit in [7,6,5,4,3,2,1,0]: >+ for bit in [7, 6, 5, 4, 3, 2, 1, 0]: > mask = 1 << bit > if byte & mask: > val = 1 >@@ -89,12 +95,21 @@ def BitString_NamedValues_prettyPrint(self, scope=0): > delim = ",\n%s " % indent > ret += "\n%s)" % indent > return ret >-krb5_asn1.TicketFlags.prettyPrintNamedValues = krb5_asn1.TicketFlagsValues.namedValues >-krb5_asn1.TicketFlags.namedValues = krb5_asn1.TicketFlagsValues.namedValues >-krb5_asn1.TicketFlags.prettyPrint = BitString_NamedValues_prettyPrint >-krb5_asn1.KDCOptions.prettyPrintNamedValues = krb5_asn1.KDCOptionsValues.namedValues >-krb5_asn1.KDCOptions.namedValues = krb5_asn1.KDCOptionsValues.namedValues >-krb5_asn1.KDCOptions.prettyPrint = BitString_NamedValues_prettyPrint >+ >+ >+krb5_asn1.TicketFlags.prettyPrintNamedValues =\ >+ krb5_asn1.TicketFlagsValues.namedValues >+krb5_asn1.TicketFlags.namedValues =\ >+ krb5_asn1.TicketFlagsValues.namedValues >+krb5_asn1.TicketFlags.prettyPrint =\ >+ BitString_NamedValues_prettyPrint >+krb5_asn1.KDCOptions.prettyPrintNamedValues =\ >+ krb5_asn1.KDCOptionsValues.namedValues >+krb5_asn1.KDCOptions.namedValues =\ >+ krb5_asn1.KDCOptionsValues.namedValues >+krb5_asn1.KDCOptions.prettyPrint =\ >+ BitString_NamedValues_prettyPrint >+ > > def Integer_NamedValues_prettyPrint(self, scope=0): > intval = int(self) >@@ -104,16 +119,29 @@ def Integer_NamedValues_prettyPrint(self, scope=0): > name = "<__unknown__>" > ret = "%d (0x%x) %s" % (intval, intval, name) > return ret >-krb5_asn1.NameType.prettyPrintNamedValues = krb5_asn1.NameTypeValues.namedValues >-krb5_asn1.NameType.prettyPrint = Integer_NamedValues_prettyPrint >-krb5_asn1.AuthDataType.prettyPrintNamedValues = krb5_asn1.AuthDataTypeValues.namedValues >-krb5_asn1.AuthDataType.prettyPrint = Integer_NamedValues_prettyPrint >-krb5_asn1.PADataType.prettyPrintNamedValues = krb5_asn1.PADataTypeValues.namedValues >-krb5_asn1.PADataType.prettyPrint = Integer_NamedValues_prettyPrint >-krb5_asn1.EncryptionType.prettyPrintNamedValues = krb5_asn1.EncryptionTypeValues.namedValues >-krb5_asn1.EncryptionType.prettyPrint = Integer_NamedValues_prettyPrint >-krb5_asn1.ChecksumType.prettyPrintNamedValues = krb5_asn1.ChecksumTypeValues.namedValues >-krb5_asn1.ChecksumType.prettyPrint = Integer_NamedValues_prettyPrint >+ >+ >+krb5_asn1.NameType.prettyPrintNamedValues =\ >+ krb5_asn1.NameTypeValues.namedValues >+krb5_asn1.NameType.prettyPrint =\ >+ Integer_NamedValues_prettyPrint >+krb5_asn1.AuthDataType.prettyPrintNamedValues =\ >+ krb5_asn1.AuthDataTypeValues.namedValues >+krb5_asn1.AuthDataType.prettyPrint =\ >+ Integer_NamedValues_prettyPrint >+krb5_asn1.PADataType.prettyPrintNamedValues =\ >+ krb5_asn1.PADataTypeValues.namedValues >+krb5_asn1.PADataType.prettyPrint =\ >+ Integer_NamedValues_prettyPrint >+krb5_asn1.EncryptionType.prettyPrintNamedValues =\ >+ krb5_asn1.EncryptionTypeValues.namedValues >+krb5_asn1.EncryptionType.prettyPrint =\ >+ Integer_NamedValues_prettyPrint >+krb5_asn1.ChecksumType.prettyPrintNamedValues =\ >+ krb5_asn1.ChecksumTypeValues.namedValues >+krb5_asn1.ChecksumType.prettyPrint =\ >+ Integer_NamedValues_prettyPrint >+ > > class Krb5EncryptionKey(object): > def __init__(self, key, kvno): >@@ -146,9 +174,10 @@ class Krb5EncryptionKey(object): > EncryptionKey_obj = { > 'keytype': self.etype, > 'keyvalue': self.key.contents, >- }; >+ } > return EncryptionKey_obj > >+ > class RawKerberosTest(TestCase): > """A raw Kerberos Test case.""" > >@@ -182,13 +211,13 @@ class RawKerberosTest(TestCase): > self.s = socket.socket(self.a[0][0], self.a[0][1], self.a[0][2]) > self.s.settimeout(10) > self.s.connect(self.a[0][4]) >- except socket.error as e: >+ except socket.error: > self.s.close() > raise >- except IOError as e: >+ except IOError: > self.s.close() > raise >- except Exception as e: >+ except Exception: > raise > finally: > pass >@@ -219,8 +248,9 @@ class RawKerberosTest(TestCase): > domain = samba.tests.env_get_var_value('DOMAIN') > realm = samba.tests.env_get_var_value('REALM') > username = samba.tests.env_get_var_value('SERVICE_USERNAME') >- password = samba.tests.env_get_var_value('SERVICE_PASSWORD', >- allow_missing=allow_missing_password) >+ password = samba.tests.env_get_var_value( >+ 'SERVICE_PASSWORD', >+ allow_missing=allow_missing_password) > c.set_domain(domain) > c.set_realm(realm) > c.set_username(username) >@@ -246,21 +276,34 @@ class RawKerberosTest(TestCase): > if hexdump is None: > hexdump = self.do_hexdump > if hexdump: >- sys.stderr.write("%s: %d\n%s" % (name, len(blob), self.hexdump(blob))) >- >- def der_decode(self, blob, asn1Spec=None, native_encode=True, asn1_print=None, hexdump=None): >+ sys.stderr.write( >+ "%s: %d\n%s" % (name, len(blob), self.hexdump(blob))) >+ >+ def der_decode( >+ self, >+ blob, >+ asn1Spec=None, >+ native_encode=True, >+ asn1_print=None, >+ hexdump=None): > if asn1Spec is not None: > class_name = type(asn1Spec).__name__.split(':')[0] > else: > class_name = "<None-asn1Spec>" > self.hex_dump(class_name, blob, hexdump=hexdump) >- obj,_ = pyasn1_der_decode(blob, asn1Spec=asn1Spec) >+ obj, _ = pyasn1_der_decode(blob, asn1Spec=asn1Spec) > self.asn1_dump(None, obj, asn1_print=asn1_print) > if native_encode: > obj = pyasn1_native_encode(obj) > return obj > >- def der_encode(self, obj, asn1Spec=None, native_decode=True, asn1_print=None, hexdump=None): >+ def der_encode( >+ self, >+ obj, >+ asn1Spec=None, >+ native_decode=True, >+ asn1_print=None, >+ hexdump=None): > if native_decode: > obj = pyasn1_native_decode(obj, asn1Spec=asn1Spec) > class_name = type(obj).__name__.split(':')[0] >@@ -273,7 +316,8 @@ class RawKerberosTest(TestCase): > > def send_pdu(self, req, asn1_print=None, hexdump=None): > try: >- k5_pdu = self.der_encode(req, native_decode=False, asn1_print=asn1_print, hexdump=False) >+ k5_pdu = self.der_encode( >+ req, native_decode=False, asn1_print=asn1_print, hexdump=False) > header = struct.pack('>I', len(k5_pdu)) > req_pdu = header > req_pdu += k5_pdu >@@ -304,7 +348,7 @@ class RawKerberosTest(TestCase): > self._disconnect("recv_raw: EOF") > return None > self.hex_dump("recv_raw", rep_pdu, hexdump=hexdump) >- except socket.timeout as e: >+ except socket.timeout: > self.s.settimeout(10) > sys.stderr.write("recv_raw: TIMEOUT\n") > pass >@@ -322,7 +366,8 @@ class RawKerberosTest(TestCase): > rep_pdu = None > rep = None > try: >- raw_pdu = self.recv_raw(num_recv=4, hexdump=hexdump, timeout=timeout) >+ raw_pdu = self.recv_raw( >+ num_recv=4, hexdump=hexdump, timeout=timeout) > if raw_pdu is None: > return (None, None) > header = struct.unpack(">I", raw_pdu[0:4]) >@@ -332,22 +377,27 @@ class RawKerberosTest(TestCase): > missing = k5_len > rep_pdu = b'' > while missing > 0: >- raw_pdu = self.recv_raw(num_recv=missing, hexdump=hexdump, timeout=timeout) >+ raw_pdu = self.recv_raw( >+ num_recv=missing, hexdump=hexdump, timeout=timeout) > self.assertGreaterEqual(len(raw_pdu), 1) > rep_pdu += raw_pdu > missing = k5_len - len(rep_pdu) >- k5_raw = self.der_decode(rep_pdu, asn1Spec=None, native_encode=False, >- asn1_print=False, hexdump=False) >- pvno=k5_raw['field-0'] >+ k5_raw = self.der_decode( >+ rep_pdu, >+ asn1Spec=None, >+ native_encode=False, >+ asn1_print=False, >+ hexdump=False) >+ pvno = k5_raw['field-0'] > self.assertEqual(pvno, 5) >- msg_type=k5_raw['field-1'] >- self.assertIn(msg_type, [11,13,30]) >+ msg_type = k5_raw['field-1'] >+ self.assertIn(msg_type, [11, 13, 30]) > if msg_type == 11: >- asn1Spec=krb5_asn1.AS_REP() >+ asn1Spec = krb5_asn1.AS_REP() > elif msg_type == 13: >- asn1Spec=krb5_asn1.TGS_REP() >+ asn1Spec = krb5_asn1.TGS_REP() > elif msg_type == 30: >- asn1Spec=krb5_asn1.KRB_ERROR() >+ asn1Spec = krb5_asn1.KRB_ERROR() > rep = self.der_decode(rep_pdu, asn1Spec=asn1Spec, > asn1_print=asn1_print, hexdump=False) > finally: >@@ -368,11 +418,17 @@ class RawKerberosTest(TestCase): > self.assertIsNone(self.s, msg="Is connected") > return > >- def send_recv_transaction(self, req, asn1_print=None, hexdump=None, timeout=None): >+ def send_recv_transaction( >+ self, >+ req, >+ asn1_print=None, >+ hexdump=None, >+ timeout=None): > self.connect() > try: > self.send_pdu(req, asn1_print=asn1_print, hexdump=hexdump) >- rep = self.recv_pdu(asn1_print=asn1_print, hexdump=hexdump, timeout=timeout) >+ rep = self.recv_pdu( >+ asn1_print=asn1_print, hexdump=hexdump, timeout=timeout) > except Exception: > self._disconnect("transaction failed") > raise >@@ -389,11 +445,15 @@ class RawKerberosTest(TestCase): > > def assertPrincipalEqual(self, princ1, princ2): > self.assertEqual(princ1['name-type'], princ2['name-type']) >- self.assertEqual(len(princ1['name-string']), len(princ2['name-string']), >- msg="princ1=%s != princ2=%s" % (princ1, princ2)) >+ self.assertEqual( >+ len(princ1['name-string']), >+ len(princ2['name-string']), >+ msg="princ1=%s != princ2=%s" % (princ1, princ2)) > for idx in range(len(princ1['name-string'])): >- self.assertEqual(princ1['name-string'][idx], princ2['name-string'][idx], >- msg="princ1=%s != princ2=%s" % (princ1, princ2)) >+ self.assertEqual( >+ princ1['name-string'][idx], >+ princ2['name-string'][idx], >+ msg="princ1=%s != princ2=%s" % (princ1, princ2)) > return > > def get_KerberosTimeWithUsec(self, epoch=None, offset=None): >@@ -421,7 +481,7 @@ class RawKerberosTest(TestCase): > salt = None > try: > salt = etype_info2['salt'] >- except: >+ except Exception: > pass > > if e == kcrypto.Enctype.RC4: >@@ -429,7 +489,8 @@ class RawKerberosTest(TestCase): > return self.SessionKey_create(etype=e, contents=nthash, kvno=kvno) > > password = creds.get_password() >- return self.PasswordKey_create(etype=e, pwd=password, salt=salt, kvno=kvno) >+ return self.PasswordKey_create( >+ etype=e, pwd=password, salt=salt, kvno=kvno) > > def RandomKey(self, etype): > e = kcrypto._get_enctype_profile(etype) >@@ -452,14 +513,14 @@ class RawKerberosTest(TestCase): > 'cipher': ciphertext > } > if key.kvno is not None: >- EncryptedData_obj['kvno'] = key.kvno >+ EncryptedData_obj['kvno'] = key.kvno > return EncryptedData_obj > > def Checksum_create(self, key, usage, plaintext, ctype=None): >- #Checksum ::= SEQUENCE { >+ # Checksum ::= SEQUENCE { > # cksumtype [0] Int32, > # checksum [1] OCTET STRING >- #} >+ # } > if ctype is None: > ctype = key.ctype > checksum = key.make_checksum(usage, plaintext, ctype=ctype) >@@ -494,10 +555,10 @@ class RawKerberosTest(TestCase): > return PA_DATA_obj > > def PA_ENC_TS_ENC_create(self, ts, usec): >- #PA-ENC-TS-ENC ::= SEQUENCE { >+ # PA-ENC-TS-ENC ::= SEQUENCE { > # patimestamp[0] KerberosTime, -- client's time > # pausec[1] krb5int32 OPTIONAL >- #} >+ # } > PA_ENC_TS_ENC_obj = { > 'patimestamp': ts, > 'pausec': usec, >@@ -520,7 +581,7 @@ class RawKerberosTest(TestCase): > additional_tickets, > asn1_print=None, > hexdump=None): >- #KDC-REQ-BODY ::= SEQUENCE { >+ # KDC-REQ-BODY ::= SEQUENCE { > # kdc-options [0] KDCOptions, > # cname [1] PrincipalName OPTIONAL > # -- Used only in AS-REQ --, >@@ -532,20 +593,23 @@ class RawKerberosTest(TestCase): > # till [5] KerberosTime, > # rtime [6] KerberosTime OPTIONAL, > # nonce [7] UInt32, >- # etype [8] SEQUENCE OF Int32 -- EncryptionType >+ # etype [8] SEQUENCE OF Int32 >+ # -- EncryptionType > # -- in preference order --, > # addresses [9] HostAddresses OPTIONAL, > # enc-authorization-data [10] EncryptedData OPTIONAL > # -- AuthorizationData --, > # additional-tickets [11] SEQUENCE OF Ticket OPTIONAL > # -- NOTE: not empty >- #} >+ # } > if EncAuthorizationData is not None: >- enc_ad_plain = self.der_encode(EncAuthorizationData, >- asn1Spec=krb5_asn1.AuthorizationData(), >- asn1_print=asn1_print, >- hexdump=hexdump) >- enc_ad = self.EncryptedData_create(EncAuthorizationData_key, enc_ad_plain) >+ enc_ad_plain = self.der_encode( >+ EncAuthorizationData, >+ asn1Spec=krb5_asn1.AuthorizationData(), >+ asn1_print=asn1_print, >+ hexdump=hexdump) >+ enc_ad = self.EncryptedData_create( >+ EncAuthorizationData_key, enc_ad_plain) > else: > enc_ad = None > KDC_REQ_BODY_obj = { >@@ -590,14 +654,14 @@ class RawKerberosTest(TestCase): > asn1Spec=None, > asn1_print=None, > hexdump=None): >- #KDC-REQ ::= SEQUENCE { >+ # KDC-REQ ::= SEQUENCE { > # -- NOTE: first tag is [1], not [0] > # pvno [1] INTEGER (5) , > # msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), > # padata [3] SEQUENCE OF PA-DATA OPTIONAL > # -- NOTE: not empty --, > # req-body [4] KDC-REQ-BODY >- #} >+ # } > # > KDC_REQ_BODY_obj = self.KDC_REQ_BODY_create(kdc_options, > cname, >@@ -622,39 +686,40 @@ class RawKerberosTest(TestCase): > if padata is not None: > KDC_REQ_obj['padata'] = padata > if asn1Spec is not None: >- KDC_REQ_decoded = pyasn1_native_decode(KDC_REQ_obj, asn1Spec=asn1Spec) >+ KDC_REQ_decoded = pyasn1_native_decode( >+ KDC_REQ_obj, asn1Spec=asn1Spec) > else: > KDC_REQ_decoded = None > return KDC_REQ_obj, KDC_REQ_decoded > > def AS_REQ_create(self, >- padata, # optional >- kdc_options, # required >- cname, # optional >- realm, # required >- sname, # optional >- from_time, # optional >- till_time, # required >- renew_time, # optional >- nonce, # required >- etypes, # required >- addresses, # optional >+ padata, # optional >+ kdc_options, # required >+ cname, # optional >+ realm, # required >+ sname, # optional >+ from_time, # optional >+ till_time, # required >+ renew_time, # optional >+ nonce, # required >+ etypes, # required >+ addresses, # optional > EncAuthorizationData, > EncAuthorizationData_key, > additional_tickets, > native_decoded_only=True, > asn1_print=None, > hexdump=None): >- #KDC-REQ ::= SEQUENCE { >+ # KDC-REQ ::= SEQUENCE { > # -- NOTE: first tag is [1], not [0] > # pvno [1] INTEGER (5) , > # msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), > # padata [3] SEQUENCE OF PA-DATA OPTIONAL > # -- NOTE: not empty --, > # req-body [4] KDC-REQ-BODY >- #} >+ # } > # >- #KDC-REQ-BODY ::= SEQUENCE { >+ # KDC-REQ-BODY ::= SEQUENCE { > # kdc-options [0] KDCOptions, > # cname [1] PrincipalName OPTIONAL > # -- Used only in AS-REQ --, >@@ -666,32 +731,34 @@ class RawKerberosTest(TestCase): > # till [5] KerberosTime, > # rtime [6] KerberosTime OPTIONAL, > # nonce [7] UInt32, >- # etype [8] SEQUENCE OF Int32 -- EncryptionType >+ # etype [8] SEQUENCE OF Int32 >+ # -- EncryptionType > # -- in preference order --, > # addresses [9] HostAddresses OPTIONAL, > # enc-authorization-data [10] EncryptedData OPTIONAL > # -- AuthorizationData --, > # additional-tickets [11] SEQUENCE OF Ticket OPTIONAL > # -- NOTE: not empty >- #} >- obj,decoded = self.KDC_REQ_create(msg_type=10, >- padata=padata, >- kdc_options=kdc_options, >- cname=cname, >- realm=realm, >- sname=sname, >- from_time=from_time, >- till_time=till_time, >- renew_time=renew_time, >- nonce=nonce, >- etypes=etypes, >- addresses=addresses, >- EncAuthorizationData=EncAuthorizationData, >- EncAuthorizationData_key=EncAuthorizationData_key, >- additional_tickets=additional_tickets, >- asn1Spec=krb5_asn1.AS_REQ(), >- asn1_print=asn1_print, >- hexdump=hexdump) >+ # } >+ obj, decoded = self.KDC_REQ_create( >+ msg_type=10, >+ padata=padata, >+ kdc_options=kdc_options, >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=from_time, >+ till_time=till_time, >+ renew_time=renew_time, >+ nonce=nonce, >+ etypes=etypes, >+ addresses=addresses, >+ EncAuthorizationData=EncAuthorizationData, >+ EncAuthorizationData_key=EncAuthorizationData_key, >+ additional_tickets=additional_tickets, >+ asn1Spec=krb5_asn1.AS_REQ(), >+ asn1_print=asn1_print, >+ hexdump=hexdump) > if native_decoded_only: > return decoded > return decoded, obj >@@ -703,7 +770,7 @@ class RawKerberosTest(TestCase): > # ap-options [2] APOptions, > # ticket [3] Ticket, > # authenticator [4] EncryptedData -- Authenticator >- #} >+ # } > AP_REQ_obj = { > 'pvno': 5, > 'msg-type': 14, >@@ -713,8 +780,9 @@ class RawKerberosTest(TestCase): > } > return AP_REQ_obj > >- def Authenticator_create(self, crealm, cname, cksum, cusec, ctime, subkey, seq_number, >- authorization_data): >+ def Authenticator_create( >+ self, crealm, cname, cksum, cusec, ctime, subkey, seq_number, >+ authorization_data): > # -- Unencrypted authenticator > # Authenticator ::= [APPLICATION 2] SEQUENCE { > # authenticator-vno [0] INTEGER (5), >@@ -726,7 +794,7 @@ class RawKerberosTest(TestCase): > # subkey [6] EncryptionKey OPTIONAL, > # seq-number [7] UInt32 OPTIONAL, > # authorization-data [8] AuthorizationData OPTIONAL >- #} >+ # } > Authenticator_obj = { > 'authenticator-vno': 5, > 'crealm': crealm, >@@ -745,20 +813,20 @@ class RawKerberosTest(TestCase): > return Authenticator_obj > > def TGS_REQ_create(self, >- padata, # optional >+ padata, # optional > cusec, > ctime, > ticket, >- kdc_options, # required >- cname, # optional >- realm, # required >- sname, # optional >- from_time, # optional >- till_time, # required >- renew_time, # optional >- nonce, # required >- etypes, # required >- addresses, # optional >+ kdc_options, # required >+ cname, # optional >+ realm, # required >+ sname, # optional >+ from_time, # optional >+ till_time, # required >+ renew_time, # optional >+ nonce, # required >+ etypes, # required >+ addresses, # optional > EncAuthorizationData, > EncAuthorizationData_key, > additional_tickets, >@@ -768,16 +836,16 @@ class RawKerberosTest(TestCase): > native_decoded_only=True, > asn1_print=None, > hexdump=None): >- #KDC-REQ ::= SEQUENCE { >+ # KDC-REQ ::= SEQUENCE { > # -- NOTE: first tag is [1], not [0] > # pvno [1] INTEGER (5) , > # msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), > # padata [3] SEQUENCE OF PA-DATA OPTIONAL > # -- NOTE: not empty --, > # req-body [4] KDC-REQ-BODY >- #} >+ # } > # >- #KDC-REQ-BODY ::= SEQUENCE { >+ # KDC-REQ-BODY ::= SEQUENCE { > # kdc-options [0] KDCOptions, > # cname [1] PrincipalName OPTIONAL > # -- Used only in AS-REQ --, >@@ -789,50 +857,57 @@ class RawKerberosTest(TestCase): > # till [5] KerberosTime, > # rtime [6] KerberosTime OPTIONAL, > # nonce [7] UInt32, >- # etype [8] SEQUENCE OF Int32 -- EncryptionType >+ # etype [8] SEQUENCE OF Int32 >+ # -- EncryptionType > # -- in preference order --, > # addresses [9] HostAddresses OPTIONAL, > # enc-authorization-data [10] EncryptedData OPTIONAL > # -- AuthorizationData --, > # additional-tickets [11] SEQUENCE OF Ticket OPTIONAL > # -- NOTE: not empty >- #} >- >- req_body = self.KDC_REQ_BODY_create(kdc_options=kdc_options, >- cname=None, >- realm=realm, >- sname=sname, >- from_time=from_time, >- till_time=till_time, >- renew_time=renew_time, >- nonce=nonce, >- etypes=etypes, >- addresses=addresses, >- EncAuthorizationData=EncAuthorizationData, >- EncAuthorizationData_key=EncAuthorizationData_key, >- additional_tickets=additional_tickets) >+ # } >+ >+ req_body = self.KDC_REQ_BODY_create( >+ kdc_options=kdc_options, >+ cname=None, >+ realm=realm, >+ sname=sname, >+ from_time=from_time, >+ till_time=till_time, >+ renew_time=renew_time, >+ nonce=nonce, >+ etypes=etypes, >+ addresses=addresses, >+ EncAuthorizationData=EncAuthorizationData, >+ EncAuthorizationData_key=EncAuthorizationData_key, >+ additional_tickets=additional_tickets) > req_body = self.der_encode(req_body, asn1Spec=krb5_asn1.KDC_REQ_BODY(), > asn1_print=asn1_print, hexdump=hexdump) > >- req_body_checksum = self.Checksum_create(ticket_session_key, 6, req_body, >- ctype=body_checksum_type) >+ req_body_checksum = self.Checksum_create( >+ ticket_session_key, 6, req_body, ctype=body_checksum_type) > > subkey_obj = None > if authenticator_subkey is not None: > subkey_obj = authenticator_subkey.export_obj() > seq_number = random.randint(0, 0xfffffffe) >- authenticator = self.Authenticator_create(crealm=realm, >- cname=cname, >- cksum=req_body_checksum, >- cusec=cusec, >- ctime=ctime, >- subkey=subkey_obj, >- seq_number=seq_number, >- authorization_data=None) >- authenticator = self.der_encode(authenticator, asn1Spec=krb5_asn1.Authenticator(), >- asn1_print=asn1_print, hexdump=hexdump) >- >- authenticator = self.EncryptedData_create(ticket_session_key, 7, authenticator) >+ authenticator = self.Authenticator_create( >+ crealm=realm, >+ cname=cname, >+ cksum=req_body_checksum, >+ cusec=cusec, >+ ctime=ctime, >+ subkey=subkey_obj, >+ seq_number=seq_number, >+ authorization_data=None) >+ authenticator = self.der_encode( >+ authenticator, >+ asn1Spec=krb5_asn1.Authenticator(), >+ asn1_print=asn1_print, >+ hexdump=hexdump) >+ >+ authenticator = self.EncryptedData_create( >+ ticket_session_key, 7, authenticator) > > ap_options = krb5_asn1.APOptions('0') > ap_req = self.AP_REQ_create(ap_options=str(ap_options), >@@ -846,24 +921,25 @@ class RawKerberosTest(TestCase): > else: > padata = [pa_tgs_req] > >- obj,decoded = self.KDC_REQ_create(msg_type=12, >- padata=padata, >- kdc_options=kdc_options, >- cname=None, >- realm=realm, >- sname=sname, >- from_time=from_time, >- till_time=till_time, >- renew_time=renew_time, >- nonce=nonce, >- etypes=etypes, >- addresses=addresses, >- EncAuthorizationData=EncAuthorizationData, >- EncAuthorizationData_key=EncAuthorizationData_key, >- additional_tickets=additional_tickets, >- asn1Spec=krb5_asn1.TGS_REQ(), >- asn1_print=asn1_print, >- hexdump=hexdump) >+ obj, decoded = self.KDC_REQ_create( >+ msg_type=12, >+ padata=padata, >+ kdc_options=kdc_options, >+ cname=None, >+ realm=realm, >+ sname=sname, >+ from_time=from_time, >+ till_time=till_time, >+ renew_time=renew_time, >+ nonce=nonce, >+ etypes=etypes, >+ addresses=addresses, >+ EncAuthorizationData=EncAuthorizationData, >+ EncAuthorizationData_key=EncAuthorizationData_key, >+ additional_tickets=additional_tickets, >+ asn1Spec=krb5_asn1.TGS_REQ(), >+ asn1_print=asn1_print, >+ hexdump=hexdump) > if native_decoded_only: > return decoded > return decoded, obj >@@ -888,5 +964,6 @@ class RawKerberosTest(TestCase): > 'cksum': cksum, > 'auth': "Kerberos", > } >- pa_s4u2self = self.der_encode(PA_S4U2Self_obj, asn1Spec=krb5_asn1.PA_S4U2Self()) >+ pa_s4u2self = self.der_encode( >+ PA_S4U2Self_obj, asn1Spec=krb5_asn1.PA_S4U2Self()) > return self.PA_DATA_create(129, pa_s4u2self) >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index 9de56578c99..5bbf1229d09 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -38,31 +38,31 @@ PADATA_ETYPE_INFO2 = int( > > # Error codes > KDC_ERR_C_PRINCIPAL_UNKNOWN = 6 >-KDC_ERR_PREAUTH_FAILED = 24 >-KDC_ERR_PREAUTH_REQUIRED = 25 >-KDC_ERR_BADMATCH = 36 >-KDC_ERR_SKEW = 37 >+KDC_ERR_PREAUTH_FAILED = 24 >+KDC_ERR_PREAUTH_REQUIRED = 25 >+KDC_ERR_BADMATCH = 36 >+KDC_ERR_SKEW = 37 > > # Name types >-NT_UNKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-UNKNOWN')) >+NT_UNKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-UNKNOWN')) > NT_PRINCIPAL = int(krb5_asn1.NameTypeValues('kRB5-NT-PRINCIPAL')) >-NT_SRV_INST = int(krb5_asn1.NameTypeValues('kRB5-NT-SRV-INST')) >+NT_SRV_INST = int(krb5_asn1.NameTypeValues('kRB5-NT-SRV-INST')) > NT_ENTERPRISE_PRINCIPAL = int(krb5_asn1.NameTypeValues( > 'kRB5-NT-ENTERPRISE-PRINCIPAL')) > > # Authorization data ad-type values > >-AD_IF_RELEVANT = 1 >-AD_INTENDED_FOR_SERVER = 2 >+AD_IF_RELEVANT = 1 >+AD_INTENDED_FOR_SERVER = 2 > AD_INTENDED_FOR_APPLICATION_CLASS = 3 >-AD_KDC_ISSUED = 4 >-AD_AND_OR = 5 >-AD_MANDATORY_TICKET_EXTENSIONS = 6 >-AD_IN_TICKET_EXTENSIONS = 7 >-AD_MANDATORY_FOR_KDC = 8 >-AD_INITIAL_VERIFIED_CAS = 9 >-AD_WIN2K_PAC = 128 >-AD_SIGNTICKET = 512 >+AD_KDC_ISSUED = 4 >+AD_AND_OR = 5 >+AD_MANDATORY_TICKET_EXTENSIONS = 6 >+AD_IN_TICKET_EXTENSIONS = 7 >+AD_MANDATORY_FOR_KDC = 8 >+AD_INITIAL_VERIFIED_CAS = 9 >+AD_WIN2K_PAC = 128 >+AD_SIGNTICKET = 512 > > # Key usage numbers > # RFC 4120 Section 7.5.1. Key Usage Numbers >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index 2e1bd3fbe1f..30a58d6345a 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -35,6 +35,7 @@ import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > global_asn1_print = False > global_hexdump = False > >+ > class S4UKerberosTests(RawKerberosTest): > > def setUp(self): >@@ -55,7 +56,7 @@ class S4UKerberosTests(RawKerberosTest): > kdc_options = krb5_asn1.KDCOptions('forwardable') > padata = None > >- etypes=(18,17,23) >+ etypes = (18, 17, 23) > > req = self.AS_REQ_create(padata=padata, > kdc_options=str(kdc_options), >@@ -76,14 +77,16 @@ class S4UKerberosTests(RawKerberosTest): > > self.assertEqual(rep['msg-type'], 30) > self.assertEqual(rep['error-code'], 25) >- rep_padata = self.der_decode(rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) >+ rep_padata = self.der_decode( >+ rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) > > for pa in rep_padata: > if pa['padata-type'] == 19: > etype_info2 = pa['padata-value'] > break > >- etype_info2 = self.der_decode(etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ etype_info2 = self.der_decode( >+ etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) > > key = self.PasswordKey_from_etype_info2(service_creds, etype_info2[0]) > >@@ -120,7 +123,8 @@ class S4UKerberosTests(RawKerberosTest): > self.assertEqual(msg_type, 11) > > enc_part2 = key.decrypt(KU_AS_REP_ENC_PART, rep['enc-part']['cipher']) >- enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) > > # S4U2Self Request > sname = cname >@@ -167,11 +171,13 @@ class S4UKerberosTests(RawKerberosTest): > if msg_type == 13: > enc_part2 = subkey.decrypt( > KU_TGS_REP_ENC_PART_SUB_KEY, rep['enc-part']['cipher']) >- enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) > > return msg_type > >- # Using the checksum type from the tgt_session_key happens to work everywhere >+ # Using the checksum type from the tgt_session_key happens to work >+ # everywhere > def test_s4u2self(self): > msg_type = self._test_s4u2self() > self.assertEqual(msg_type, 13) >@@ -193,6 +199,7 @@ class S4UKerberosTests(RawKerberosTest): > msg_type = self._test_s4u2self(pa_s4u2self_ctype=Cksumtype.CRC32) > self.assertEqual(msg_type, 30) > >+ > if __name__ == "__main__": > global_asn1_print = True > global_hexdump = True >diff --git a/python/samba/tests/krb5/simple_tests.py b/python/samba/tests/krb5/simple_tests.py >index 6c090af3d46..889b91a9bf0 100755 >--- a/python/samba/tests/krb5/simple_tests.py >+++ b/python/samba/tests/krb5/simple_tests.py >@@ -33,6 +33,7 @@ import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > global_asn1_print = False > global_hexdump = False > >+ > class SimpleKerberosTests(RawKerberosTest): > > def setUp(self): >@@ -53,7 +54,7 @@ class SimpleKerberosTests(RawKerberosTest): > kdc_options = krb5_asn1.KDCOptions('forwardable') > padata = None > >- etypes=(18,17,23) >+ etypes = (18, 17, 23) > > req = self.AS_REQ_create(padata=padata, > kdc_options=str(kdc_options), >@@ -74,14 +75,16 @@ class SimpleKerberosTests(RawKerberosTest): > > self.assertEqual(rep['msg-type'], 30) > self.assertEqual(rep['error-code'], 25) >- rep_padata = self.der_decode(rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) >+ rep_padata = self.der_decode( >+ rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) > > for pa in rep_padata: > if pa['padata-type'] == 19: > etype_info2 = pa['padata-value'] > break > >- etype_info2 = self.der_decode(etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ etype_info2 = self.der_decode( >+ etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) > > key = self.PasswordKey_from_etype_info2(user_creds, etype_info2[0]) > >@@ -119,17 +122,21 @@ class SimpleKerberosTests(RawKerberosTest): > > enc_part2 = key.decrypt(KU_AS_REP_ENC_PART, rep['enc-part']['cipher']) > >- # MIT KDC encodes both EncASRepPart and EncTGSRepPart with application tag 26 >+ # MIT KDC encodes both EncASRepPart and EncTGSRepPart with >+ # application tag 26 > try: >- enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) > except Exception: >- enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) > > # TGS Request > service_creds = self.get_service_creds(allow_missing_password=True) > service_name = service_creds.get_username() > >- sname = self.PrincipalName_create(name_type=2, names=["host", service_name]) >+ sname = self.PrincipalName_create( >+ name_type=2, names=["host", service_name]) > kdc_options = krb5_asn1.KDCOptions('forwardable') > till = self.get_KerberosTime(offset=36000) > ticket = rep['ticket'] >@@ -167,7 +174,8 @@ class SimpleKerberosTests(RawKerberosTest): > > enc_part2 = subkey.decrypt( > KU_TGS_REP_ENC_PART_SUB_KEY, rep['enc-part']['cipher']) >- enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) > > return > >diff --git a/python/samba/tests/krb5/xrealm_tests.py b/python/samba/tests/krb5/xrealm_tests.py >index b4a02bff33a..efb953bdf7e 100755 >--- a/python/samba/tests/krb5/xrealm_tests.py >+++ b/python/samba/tests/krb5/xrealm_tests.py >@@ -34,6 +34,7 @@ import samba.tests > global_asn1_print = False > global_hexdump = False > >+ > class XrealmKerberosTests(RawKerberosTest): > > def setUp(self): >@@ -54,7 +55,7 @@ class XrealmKerberosTests(RawKerberosTest): > kdc_options = krb5_asn1.KDCOptions('forwardable') > padata = None > >- etypes=(18,17,23) >+ etypes = (18, 17, 23) > > req = self.AS_REQ_create(padata=padata, > kdc_options=str(kdc_options), >@@ -75,14 +76,16 @@ class XrealmKerberosTests(RawKerberosTest): > > self.assertEqual(rep['msg-type'], 30) > self.assertEqual(rep['error-code'], 25) >- rep_padata = self.der_decode(rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) >+ rep_padata = self.der_decode( >+ rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) > > for pa in rep_padata: > if pa['padata-type'] == 19: > etype_info2 = pa['padata-value'] > break > >- etype_info2 = self.der_decode(etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ etype_info2 = self.der_decode( >+ etype_info2, asn1Spec=krb5_asn1.ETYPE_INFO2()) > > key = self.PasswordKey_from_etype_info2(user_creds, etype_info2[0]) > >@@ -120,15 +123,19 @@ class XrealmKerberosTests(RawKerberosTest): > > enc_part2 = key.decrypt(KU_AS_REP_ENC_PART, rep['enc-part']['cipher']) > >- # MIT KDC encodes both EncASRepPart and EncTGSRepPart with application tag 26 >+ # MIT KDC encodes both EncASRepPart and EncTGSRepPart with >+ # application tag 26 > try: >- enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) > except Exception: >- enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) > > # TGS Request (for cross-realm TGT) > trust_realm = samba.tests.env_get_var_value('TRUST_REALM') >- sname = self.PrincipalName_create(name_type=2, names=["krbtgt", trust_realm]) >+ sname = self.PrincipalName_create( >+ name_type=2, names=["krbtgt", trust_realm]) > > kdc_options = krb5_asn1.KDCOptions('forwardable') > till = self.get_KerberosTime(offset=36000) >@@ -167,10 +174,11 @@ class XrealmKerberosTests(RawKerberosTest): > > enc_part2 = subkey.decrypt( > KU_TGS_REP_ENC_PART_SUB_KEY, rep['enc-part']['cipher']) >- enc_part2 = self.der_decode(enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) > > # Check the forwardable flag >- fwd_pos = len(tuple(krb5_asn1.TicketFlags('forwardable'))) -1 >+ fwd_pos = len(tuple(krb5_asn1.TicketFlags('forwardable'))) - 1 > assert(krb5_asn1.TicketFlags(enc_part2['flags'])[fwd_pos]) > > return >-- >2.25.1 > > >From c31294fe7f32899afc6ab845b5f204e9f39e6ce8 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 16 Apr 2021 17:22:12 +0200 >Subject: [PATCH 064/686] librpc: Add py_descriptor_richcmp() equality function > >Only a python3 version. Do we still need the python2 flavor? > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 439b7ccdc1b1c91c66c1a7c83e340fa044c26377) >--- > source4/librpc/ndr/py_security.c | 37 ++++++++++++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > >diff --git a/source4/librpc/ndr/py_security.c b/source4/librpc/ndr/py_security.c >index eb5224dc243..79a9fa5ac11 100644 >--- a/source4/librpc/ndr/py_security.c >+++ b/source4/librpc/ndr/py_security.c >@@ -308,9 +308,46 @@ static PyMethodDef py_descriptor_extra_methods[] = { > { NULL } > }; > >+static PyObject *py_descriptor_richcmp( >+ PyObject *py_self, PyObject *py_other, int op) >+{ >+ struct security_descriptor *self = pytalloc_get_ptr(py_self); >+ struct security_descriptor *other = pytalloc_get_ptr(py_other); >+ bool eq; >+ >+ if (other == NULL) { >+ Py_INCREF(Py_NotImplemented); >+ return Py_NotImplemented; >+ } >+ >+ eq = security_descriptor_equal(self, other); >+ >+ switch(op) { >+ case Py_EQ: >+ if (eq) { >+ Py_RETURN_TRUE; >+ } else { >+ Py_RETURN_FALSE; >+ } >+ break; >+ case Py_NE: >+ if (eq) { >+ Py_RETURN_FALSE; >+ } else { >+ Py_RETURN_TRUE; >+ } >+ break; >+ default: >+ break; >+ } >+ >+ return Py_NotImplemented; >+} >+ > static void py_descriptor_patch(PyTypeObject *type) > { > type->tp_new = py_descriptor_new; >+ type->tp_richcompare = py_descriptor_richcmp; > PyType_AddMethods(type, py_descriptor_extra_methods); > } > >-- >2.25.1 > > >From 78ac20a33aee9e4f6e0f25b077917e49ec6133eb Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Wed, 17 Feb 2021 12:15:50 +1300 >Subject: [PATCH 065/686] tests python krb5: MS-KILE client principal look-up > >Tests of [MS-KILE]: Kerberos Protocol Extensions > section 3.3.5.6.1 Client Principal Lookup > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Mon Apr 12 00:38:26 UTC 2021 on sn-devel-184 > >(cherry picked from commit 768d48fca9f8c7527c0d12e7acc8942b5fd36ac2) >--- > python/samba/tests/krb5/kdc_base_test.py | 29 +- > .../ms_kile_client_principal_lookup_tests.py | 814 ++++++++++++++++++ > python/samba/tests/usage.py | 1 + > selftest/knownfail_heimdal_kdc | 12 + > selftest/knownfail_mit_kdc | 16 + > source4/selftest/tests.py | 3 + > 6 files changed, 874 insertions(+), 1 deletion(-) > create mode 100755 python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index bef5458c881..1c7f05dda6d 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -22,6 +22,7 @@ import os > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > from collections import namedtuple >+import ldb > from ldb import SCOPE_BASE > from samba import generate_random_password > from samba.auth import system_session >@@ -103,7 +104,7 @@ class KDCBaseTest(RawKerberosTest): > for dn in self.accounts: > delete_force(self.ldb, dn) > >- def create_account(self, name, machine_account=False, spn=None): >+ def create_account(self, name, machine_account=False, spn=None, upn=None): > '''Create an account for testing. > The dn of the created account is added to self.accounts, > which is used by tearDown to clean up the created accounts. >@@ -133,6 +134,8 @@ class KDCBaseTest(RawKerberosTest): > "unicodePwd": utf16pw} > if spn is not None: > details["servicePrincipalName"] = spn >+ if upn is not None: >+ details["userPrincipalName"] = upn > self.ldb.add(details) > > creds = Credentials() >@@ -418,3 +421,27 @@ class KDCBaseTest(RawKerberosTest): > self.assertTrue(len(res) == 1, "did not get objectSid for %s" % dn) > sid = self.ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) > return sid.decode('utf8') >+ >+ def add_attribute(self, dn_str, name, value): >+ if isinstance(value, list): >+ values = value >+ else: >+ values = [value] >+ flag = ldb.FLAG_MOD_ADD >+ >+ dn = ldb.Dn(self.ldb, dn_str) >+ msg = ldb.Message(dn) >+ msg[name] = ldb.MessageElement(values, flag, name) >+ self.ldb.modify(msg) >+ >+ def modify_attribute(self, dn_str, name, value): >+ if isinstance(value, list): >+ values = value >+ else: >+ values = [value] >+ flag = ldb.FLAG_MOD_REPLACE >+ >+ dn = ldb.Dn(self.ldb, dn_str) >+ msg = ldb.Message(dn) >+ msg[name] = ldb.MessageElement(values, flag, name) >+ self.ldb.modify(msg) >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >new file mode 100755 >index 00000000000..356a25f8e18 >--- /dev/null >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -0,0 +1,814 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) 2020 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+from samba.dsdb import UF_NORMAL_ACCOUNT, UF_DONT_REQUIRE_PREAUTH >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+from samba.tests.krb5.rfc4120_constants import ( >+ AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5, >+ NT_ENTERPRISE_PRINCIPAL, >+ NT_PRINCIPAL, >+ NT_SRV_INST, >+ KDC_ERR_C_PRINCIPAL_UNKNOWN, >+) >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): >+ ''' Tests for MS-KILE client principal look-up >+ See [MS-KILE]: Kerberos Protocol Extensions >+ secion 3.3.5.6.1 Client Principal Lookup >+ ''' >+ >+ def setUp(self): >+ super().setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def check_pac(self, auth_data, dn, uc, name, upn=None): >+ >+ pac_data = self.get_pac_data(auth_data) >+ sid = self.get_objectSid(dn) >+ if upn is None: >+ upn = "%s@%s" % (name, uc.get_realm().lower()) >+ if name.endswith('$'): >+ name = name[:-1] >+ >+ self.assertEqual( >+ uc.get_username(), >+ str(pac_data.account_name), >+ "pac_data = {%s}" % str(pac_data)) >+ self.assertEqual( >+ name, >+ pac_data.logon_name, >+ "pac_data = {%s}" % str(pac_data)) >+ self.assertEqual( >+ uc.get_realm(), >+ pac_data.domain_name, >+ "pac_data = {%s}" % str(pac_data)) >+ self.assertEqual( >+ upn, >+ pac_data.upn, >+ "pac_data = {%s}" % str(pac_data)) >+ self.assertEqual( >+ sid, >+ pac_data.account_sid, >+ "pac_data = {%s}" % str(pac_data)) >+ >+ def test_nt_principal_step_1(self): >+ ''' Step 1 >+ For an NT_PRINCIPAL cname with no realm or the realm matches the >+ DC's domain >+ search for an account with the >+ sAMAccountName matching the cname. >+ ''' >+ >+ # Create user and machine accounts for the test. >+ # >+ user_name = "mskileusr" >+ (uc, dn) = self.create_account(user_name) >+ realm = uc.get_realm().lower() >+ >+ mach_name = "mskilemac" >+ (mc, _) = self.create_account(mach_name, machine_account=True) >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(uc, rep) >+ key = self.get_as_rep_key(uc, rep) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[mc.get_username()]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, uc.get_realm(), ticket, key, etype) >+ self.check_tgs_reply(rep) >+ >+ # Check the contents of the pac, and the ticket >+ ticket = rep['ticket'] >+ enc_part = self.decode_service_ticket(mc, ticket) >+ self.check_pac(enc_part['authorization-data'], dn, uc, user_name) >+ # check the crealm and cname >+ cname = enc_part['cname'] >+ self.assertEqual(NT_PRINCIPAL, cname['name-type']) >+ self.assertEqual(user_name.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(realm.upper().encode('UTF8'), enc_part['crealm']) >+ >+ def test_nt_principal_step_2(self): >+ ''' Step 2 >+ If not found >+ search for sAMAccountName equal to the cname + "$" >+ >+ ''' >+ >+ # Create a machine account for the test. >+ # >+ user_name = "mskilemac" >+ (mc, dn) = self.create_account(user_name, machine_account=True) >+ realm = mc.get_realm().lower() >+ >+ mach_name = "mskilemac" >+ (mc, _) = self.create_account(mach_name, machine_account=True) >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(mc, rep) >+ key = self.get_as_rep_key(mc, rep) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[mc.get_username()]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, mc.get_realm(), ticket, key, etype) >+ self.check_tgs_reply(rep) >+ >+ # Check the contents of the pac, and the ticket >+ ticket = rep['ticket'] >+ enc_part = self.decode_service_ticket(mc, ticket) >+ self.check_pac(enc_part['authorization-data'], dn, mc, mach_name + '$') >+ # check the crealm and cname >+ cname = enc_part['cname'] >+ self.assertEqual(NT_PRINCIPAL, cname['name-type']) >+ self.assertEqual(user_name.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(realm.upper().encode('UTF8'), enc_part['crealm']) >+ >+ def test_nt_principal_step_3(self): >+ ''' Step 3 >+ >+ If not found >+ search for a matching UPN name where the UPN is set to >+ cname@realm or cname@DC's domain name >+ >+ ''' >+ # Create a user account for the test. >+ # >+ user_name = "mskileusr" >+ upn_name = "mskileupn" >+ upn = upn_name + "@" + self.credentials.get_realm().lower() >+ (uc, dn) = self.create_account(user_name, upn=upn) >+ realm = uc.get_realm().lower() >+ >+ mach_name = "mskilemac" >+ (mc, _) = self.create_account(mach_name, machine_account=True) >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[upn_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(uc, rep) >+ key = self.get_as_rep_key(uc, rep) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[upn_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[mc.get_username()]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, uc.get_realm(), ticket, key, etype) >+ self.check_tgs_reply(rep) >+ >+ # Check the contents of the service ticket >+ ticket = rep['ticket'] >+ enc_part = self.decode_service_ticket(mc, ticket) >+ self.check_pac(enc_part['authorization-data'], dn, uc, upn_name) >+ # check the crealm and cname >+ cname = enc_part['cname'] >+ self.assertEqual(NT_PRINCIPAL, cname['name-type']) >+ self.assertEqual(upn_name.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(realm.upper().encode('UTF8'), enc_part['crealm']) >+ >+ def test_nt_principal_step_4_a(self): >+ ''' Step 4, no pre-authentication >+ If not found and no pre-authentication >+ search for a matching altSecurityIdentity >+ ''' >+ # Create a user account for the test. >+ # with an altSecurityIdentity, and with UF_DONT_REQUIRE_PREAUTH >+ # set. >+ # >+ # note that in this case IDL_DRSCrackNames is called with >+ # pmsgIn.formatOffered set to >+ # DS_USER_PRINCIPAL_NAME_AND_ALTSECID >+ # >+ # setting UF_DONT_REQUIRE_PREAUTH seems to be the only way >+ # to trigger the no pre-auth step >+ >+ user_name = "mskileusr" >+ alt_name = "mskilealtsec" >+ (uc, dn) = self.create_account(user_name) >+ realm = uc.get_realm().lower() >+ alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >+ self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ self.modify_attribute( >+ dn, >+ "userAccountControl", >+ str(UF_NORMAL_ACCOUNT | UF_DONT_REQUIRE_PREAUTH)) >+ >+ mach_name = "mskilemac" >+ (mc, _) = self.create_account(mach_name, machine_account=True) >+ >+ # Do the initial AS-REQ, as we've set UF_DONT_REQUIRE_PREAUTH >+ # we should get a valid AS-RESP >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[alt_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_as_reply(rep) >+ salt = "%s%s" % (realm.upper(), user_name) >+ key = self.PasswordKey_create( >+ rep['enc-part']['etype'], >+ uc.get_password(), >+ salt.encode('UTF8'), >+ rep['enc-part']['kvno']) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[alt_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[mc.get_username()]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, uc.get_realm(), ticket, key, etype) >+ self.check_tgs_reply(rep) >+ >+ # Check the contents of the service ticket >+ ticket = rep['ticket'] >+ enc_part = self.decode_service_ticket(mc, ticket) >+ # >+ # We get an empty authorization-data element in the ticket. >+ # i.e. no PAC >+ self.assertEqual([], enc_part['authorization-data']) >+ # check the crealm and cname >+ cname = enc_part['cname'] >+ self.assertEqual(NT_PRINCIPAL, cname['name-type']) >+ self.assertEqual(alt_name.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(realm.upper().encode('UTF8'), enc_part['crealm']) >+ >+ def test_nt_principal_step_4_b(self): >+ ''' Step 4, pre-authentication >+ If not found and pre-authentication >+ search for a matching user principal name >+ ''' >+ >+ # Create user and machine accounts for the test. >+ # >+ user_name = "mskileusr" >+ alt_name = "mskilealtsec" >+ (uc, dn) = self.create_account(user_name) >+ realm = uc.get_realm().lower() >+ alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >+ self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ >+ mach_name = "mskilemac" >+ (mc, _) = self.create_account(mach_name, machine_account=True) >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[alt_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(uc, rep) >+ key = self.get_as_rep_key(uc, rep) >+ # Note: although we used the alt security id for the pre-auth >+ # we need to use the username for the auth >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[user_name]) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[mc.get_username()]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, uc.get_realm(), ticket, key, etype) >+ self.check_tgs_reply(rep) >+ >+ # Check the contents of the pac, and the ticket >+ ticket = rep['ticket'] >+ enc_part = self.decode_service_ticket(mc, ticket) >+ self.check_pac(enc_part['authorization-data'], dn, uc, user_name) >+ # check the crealm and cname >+ cname = enc_part['cname'] >+ self.assertEqual(NT_PRINCIPAL, cname['name-type']) >+ self.assertEqual(user_name.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(realm.upper().encode('UTF8'), enc_part['crealm']) >+ >+ def test_nt_principal_step_4_c(self): >+ ''' Step 4, pre-authentication >+ If not found and pre-authentication >+ search for a matching user principal name >+ >+ This test uses the altsecid, so the AS-REQ should fail. >+ ''' >+ >+ # Create user and machine accounts for the test. >+ # >+ user_name = "mskileusr" >+ alt_name = "mskilealtsec" >+ (uc, dn) = self.create_account(user_name) >+ realm = uc.get_realm().lower() >+ alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >+ self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ >+ mach_name = "mskilemac" >+ (mc, _) = self.create_account(mach_name, machine_account=True) >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[alt_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(uc, rep) >+ # Use the alternate security identifier >+ # this should fail >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[alt_sec]) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN) >+ >+ def test_enterprise_principal_step_1_3(self): >+ ''' Steps 1-3 >+ For an NT_ENTERPRISE_PRINCIPAL cname >+ search for a user principal name matching the cname >+ >+ ''' >+ >+ # Create a user account for the test. >+ # >+ user_name = "mskileusr" >+ upn_name = "mskileupn" >+ upn = upn_name + "@" + self.credentials.get_realm().lower() >+ (uc, dn) = self.create_account(user_name, upn=upn) >+ realm = uc.get_realm().lower() >+ >+ mach_name = "mskilemac" >+ (mc, _) = self.create_account(mach_name, machine_account=True) >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[upn]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(uc, rep) >+ key = self.get_as_rep_key(uc, rep) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[upn]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[mc.get_username()]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, uc.get_realm(), ticket, key, etype) >+ self.check_tgs_reply(rep) >+ >+ # Check the contents of the pac, and the ticket >+ ticket = rep['ticket'] >+ enc_part = self.decode_service_ticket(mc, ticket) >+ self.check_pac( >+ enc_part['authorization-data'], dn, uc, upn, upn=upn) >+ # check the crealm and cname >+ cname = enc_part['cname'] >+ crealm = enc_part['crealm'] >+ self.assertEqual(NT_ENTERPRISE_PRINCIPAL, cname['name-type']) >+ self.assertEqual(upn.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(realm.upper().encode('UTF8'), crealm) >+ >+ def test_enterprise_principal_step_4(self): >+ ''' Step 4 >+ >+ If that fails >+ search for an account where the sAMAccountName matches >+ the name before the @ >+ >+ ''' >+ >+ # Create a user account for the test. >+ # >+ user_name = "mskileusr" >+ (uc, dn) = self.create_account(user_name) >+ realm = uc.get_realm().lower() >+ ename = user_name + "@" + realm >+ >+ mach_name = "mskilemac" >+ (mc, _) = self.create_account(mach_name, machine_account=True) >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[ename]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(uc, rep) >+ key = self.get_as_rep_key(uc, rep) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[ename]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[mc.get_username()]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, uc.get_realm(), ticket, key, etype) >+ self.check_tgs_reply(rep) >+ >+ # Check the contents of the pac, and the ticket >+ ticket = rep['ticket'] >+ enc_part = self.decode_service_ticket(mc, ticket) >+ self.check_pac( >+ enc_part['authorization-data'], dn, uc, ename, upn=ename) >+ # check the crealm and cname >+ cname = enc_part['cname'] >+ crealm = enc_part['crealm'] >+ self.assertEqual(NT_ENTERPRISE_PRINCIPAL, cname['name-type']) >+ self.assertEqual(ename.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(realm.upper().encode('UTF8'), crealm) >+ >+ def test_enterprise_principal_step_5(self): >+ ''' Step 5 >+ >+ If that fails >+ search for an account where the sAMAccountName matches >+ the name before the @ with a $ appended. >+ >+ ''' >+ >+ # Create a user account for the test. >+ # >+ user_name = "mskileusr" >+ (uc, _) = self.create_account(user_name) >+ realm = uc.get_realm().lower() >+ >+ mach_name = "mskilemac" >+ (mc, dn) = self.create_account(mach_name, machine_account=True) >+ ename = mach_name + "@" + realm >+ uname = mach_name + "$@" + realm >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[ename]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(mc, rep) >+ key = self.get_as_rep_key(mc, rep) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[ename]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[mc.get_username()]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, uc.get_realm(), ticket, key, etype) >+ self.check_tgs_reply(rep) >+ >+ # Check the contents of the pac, and the ticket >+ ticket = rep['ticket'] >+ enc_part = self.decode_service_ticket(mc, ticket) >+ self.check_pac( >+ enc_part['authorization-data'], dn, mc, ename, upn=uname) >+ # check the crealm and cname >+ cname = enc_part['cname'] >+ crealm = enc_part['crealm'] >+ self.assertEqual(NT_ENTERPRISE_PRINCIPAL, cname['name-type']) >+ self.assertEqual(ename.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(realm.upper().encode('UTF8'), crealm) >+ >+ def test_enterprise_principal_step_6_a(self): >+ ''' Step 6, no pre-authentication >+ If not found and no pre-authentication >+ search for a matching altSecurityIdentity >+ ''' >+ # Create a user account for the test. >+ # with an altSecurityIdentity, and with UF_DONT_REQUIRE_PREAUTH >+ # set. >+ # >+ # note that in this case IDL_DRSCrackNames is called with >+ # pmsgIn.formatOffered set to >+ # DS_USER_PRINCIPAL_NAME_AND_ALTSECID >+ # >+ # setting UF_DONT_REQUIRE_PREAUTH seems to be the only way >+ # to trigger the no pre-auth step >+ >+ user_name = "mskileusr" >+ alt_name = "mskilealtsec" >+ (uc, dn) = self.create_account(user_name) >+ realm = uc.get_realm().lower() >+ alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >+ self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ self.modify_attribute( >+ dn, >+ "userAccountControl", >+ str(UF_NORMAL_ACCOUNT | UF_DONT_REQUIRE_PREAUTH)) >+ ename = alt_name + "@" + realm >+ >+ mach_name = "mskilemac" >+ (mc, _) = self.create_account(mach_name, machine_account=True) >+ >+ # Do the initial AS-REQ, as we've set UF_DONT_REQUIRE_PREAUTH >+ # we should get a valid AS-RESP >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[ename]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_as_reply(rep) >+ salt = "%s%s" % (realm.upper(), user_name) >+ key = self.PasswordKey_create( >+ rep['enc-part']['etype'], >+ uc.get_password(), >+ salt.encode('UTF8'), >+ rep['enc-part']['kvno']) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[ename]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[mc.get_username()]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, uc.get_realm(), ticket, key, etype) >+ self.check_tgs_reply(rep) >+ >+ # Check the contents of the service ticket >+ ticket = rep['ticket'] >+ enc_part = self.decode_service_ticket(mc, ticket) >+ # >+ # We get an empty authorization-data element in the ticket. >+ # i.e. no PAC >+ self.assertEqual([], enc_part['authorization-data']) >+ # check the crealm and cname >+ cname = enc_part['cname'] >+ self.assertEqual(NT_ENTERPRISE_PRINCIPAL, cname['name-type']) >+ self.assertEqual(ename.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(realm.upper().encode('UTF8'), enc_part['crealm']) >+ >+ def test_nt_enterprise_principal_step_6_b(self): >+ ''' Step 4, pre-authentication >+ If not found and pre-authentication >+ search for a matching user principal name >+ ''' >+ >+ # Create user and machine accounts for the test. >+ # >+ user_name = "mskileusr" >+ alt_name = "mskilealtsec" >+ (uc, dn) = self.create_account(user_name) >+ realm = uc.get_realm().lower() >+ alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >+ self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ ename = alt_name + "@" + realm >+ uname = user_name + "@" + realm >+ >+ mach_name = "mskilemac" >+ (mc, _) = self.create_account(mach_name, machine_account=True) >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[ename]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(uc, rep) >+ key = self.get_as_rep_key(uc, rep) >+ # Note: although we used the alt security id for the pre-auth >+ # we need to use the username for the auth >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[uname]) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part2 = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part2['key']) >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, >+ names=[uname]) >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=[mc.get_username()]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, uc.get_realm(), ticket, key, etype) >+ self.check_tgs_reply(rep) >+ >+ # Check the contents of the pac, and the ticket >+ ticket = rep['ticket'] >+ enc_part = self.decode_service_ticket(mc, ticket) >+ self.check_pac( >+ enc_part['authorization-data'], dn, uc, uname, upn=uname) >+ # check the crealm and cname >+ cname = enc_part['cname'] >+ self.assertEqual(NT_ENTERPRISE_PRINCIPAL, cname['name-type']) >+ self.assertEqual(uname.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(realm.upper().encode('UTF8'), enc_part['crealm']) >+ >+ def test_nt_principal_step_6_c(self): >+ ''' Step 4, pre-authentication >+ If not found and pre-authentication >+ search for a matching user principal name >+ >+ This test uses the altsecid, so the AS-REQ should fail. >+ ''' >+ >+ # Create user and machine accounts for the test. >+ # >+ user_name = "mskileusr" >+ alt_name = "mskilealtsec" >+ (uc, dn) = self.create_account(user_name) >+ realm = uc.get_realm().lower() >+ alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >+ self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ ename = alt_name + "@" + realm >+ >+ mach_name = "mskilemac" >+ (mc, _) = self.create_account(mach_name, machine_account=True) >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[ename]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(uc, rep) >+ # Use the alternate security identifier >+ # this should fail >+ cname = self.PrincipalName_create( >+ name_type=NT_ENTERPRISE_PRINCIPAL, names=[ename]) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = False >+ global_hexdump = False >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 838a3148d8e..14f7cbfd7cd 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -93,6 +93,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/kdc_tests.py', > 'python/samba/tests/krb5/kdc_base_test.py', > 'python/samba/tests/krb5/kdc_tgs_tests.py', >+ 'python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py', > } > > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 7ab56b6721b..4e6ee93ce96 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -2,3 +2,15 @@ > # We expect all the MIT specific compatability tests to fail on heimdal > # kerberos > ^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_mit_ >+# >+# Heimdal currently fails the following MS-KILE client principal lookup >+# tests >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_1_3 >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_4 >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_5 >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_6_a >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_enterprise_principal_step_6_b >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_a >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_b >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index e64303c6b0f..2c2a643944c 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -275,3 +275,19 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > # following tests > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_ldap_service_ticket\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_get_ticket_for_host_service_of_machine_account\(ad_dc\) >+# >+# MIT currently fails the following MS-KILE tests. >+# >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_1_3 >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_4 >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_5 >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_6_a >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_enterprise_principal_step_6_b >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_1 >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_2 >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_3 >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_a >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_b >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c >+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c >+ >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 4ce9602b53f..3310d47f167 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1234,6 +1234,9 @@ planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests") > planpythontestsuite( > "ad_dc", > "samba.tests.krb5.kdc_tgs_tests") >+planpythontestsuite( >+ "ad_dc", >+ "samba.tests.krb5.ms_kile_client_principal_lookup_tests") > > for env in [ > 'vampire_dc', >-- >2.25.1 > > >From 63297ac692bc0c010ccf6cad704febaeabbbfe50 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Apr 2021 10:54:05 +1200 >Subject: [PATCH 066/686] auth:creds: Remove unused variable > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 1ea2de561839ad948efab5112fbe4c1eae44d9ee) > >[jsutton@samba.org Backported to fix conflict] >--- > auth/credentials/pycredentials.c | 3 --- > 1 file changed, 3 deletions(-) > >diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c >index 6fb2c807ed6..ae096e36302 100644 >--- a/auth/credentials/pycredentials.c >+++ b/auth/credentials/pycredentials.c >@@ -446,13 +446,10 @@ static PyObject *py_creds_get_forced_sasl_mech(PyObject *self, PyObject *unused) > static PyObject *py_creds_set_forced_sasl_mech(PyObject *self, PyObject *args) > { > char *newval; >- enum credentials_obtained obt = CRED_SPECIFIED; >- int _obt = obt; > > if (!PyArg_ParseTuple(args, "s", &newval)) { > return NULL; > } >- obt = _obt; > > cli_credentials_set_forced_sasl_mech(PyCredentials_AsCliCredentials(self), newval); > Py_RETURN_NONE; >-- >2.25.1 > > >From 2c44d208b6f2b630d350f22f1427cd1edb2bbafe Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Apr 2021 10:55:13 +1200 >Subject: [PATCH 067/686] auth:creds: Fix parameter in creds.set_named_ccache() > >Use the passed-in value for 'obtained' rather than always using >CRED_SPECIFIED. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 2d05268aa0904221c452fc650fcdfb680efc20bb) >--- > auth/credentials/pycredentials.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c >index ae096e36302..a58859a70d8 100644 >--- a/auth/credentials/pycredentials.c >+++ b/auth/credentials/pycredentials.c >@@ -584,6 +584,7 @@ static PyObject *py_creds_set_named_ccache(PyObject *self, PyObject *args) > > if (!PyArg_ParseTuple(args, "s|iO", &newval, &_obt, &py_lp_ctx)) > return NULL; >+ obt = _obt; > > mem_ctx = talloc_new(NULL); > if (mem_ctx == NULL) { >@@ -599,7 +600,7 @@ static PyObject *py_creds_set_named_ccache(PyObject *self, PyObject *args) > > ret = cli_credentials_set_ccache(PyCredentials_AsCliCredentials(self), > lp_ctx, >- newval, CRED_SPECIFIED, >+ newval, obt, > &error_string); > > if (ret != 0) { >-- >2.25.1 > > >From 3542e733ada773f186050fde39b5339d0c5b4f44 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Apr 2021 11:07:22 +1200 >Subject: [PATCH 068/686] pygensec: Fix method documentation > >This changes the docstrings to use the correct method names. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 50ade4cadc766a196316fd5c5a57f8c502f0ea22) >--- > source4/auth/gensec/pygensec.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > >diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c >index c9f3fd3b489..ca60d3bdc5e 100644 >--- a/source4/auth/gensec/pygensec.c >+++ b/source4/auth/gensec/pygensec.c >@@ -634,13 +634,13 @@ static PyMethodDef py_gensec_security_methods[] = { > { "start_server", (PyCFunction)py_gensec_start_server, METH_VARARGS|METH_KEYWORDS|METH_CLASS, > "S.start_server(auth_ctx, settings) -> gensec" }, > { "set_credentials", (PyCFunction)py_gensec_set_credentials, METH_VARARGS, >- "S.start_client(credentials)" }, >+ "S.set_credentials(credentials)" }, > { "set_target_hostname", (PyCFunction)py_gensec_set_target_hostname, METH_VARARGS, >- "S.start_target_hostname(target_hostname) \n This sets the Kerberos target hostname to obtain a ticket for." }, >+ "S.set_target_hostname(target_hostname) \n This sets the Kerberos target hostname to obtain a ticket for." }, > { "set_target_service", (PyCFunction)py_gensec_set_target_service, METH_VARARGS, >- "S.start_target_service(target_service) \n This sets the Kerberos target service to obtain a ticket for. The default value is 'host'" }, >+ "S.set_target_service(target_service) \n This sets the Kerberos target service to obtain a ticket for. The default value is 'host'" }, > { "set_target_service_description", (PyCFunction)py_gensec_set_target_service_description, METH_VARARGS, >- "S.start_target_service_description(target_service_description) \n This description is set server-side and used in authentication and authorization logs. The default value is that provided to set_target_service() or None."}, >+ "S.set_target_service_description(target_service_description) \n This description is set server-side and used in authentication and authorization logs. The default value is that provided to set_target_service() or None."}, > { "session_info", (PyCFunction)py_gensec_session_info, METH_NOARGS, > "S.session_info() -> info" }, > { "session_key", (PyCFunction)py_gensec_session_key, METH_NOARGS, >-- >2.25.1 > > >From f0d5396de4fbcbda214199e2336d18d1541b2136 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 15 Apr 2021 10:32:41 +1200 >Subject: [PATCH 069/686] Revert "s4-test: fixed ndrdump test for top level > build" > >This essentially reverts commit >b84c0a9ed6d556eb2d3797d606edcd03f9766606, but the datapath is now in the >source4 directory. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 6f144d49b5281a08bf7be550b949f4d91e8fe19b) > >[jsutton@samba.org Backported to fix conflict from formatting > differences] >--- > python/samba/tests/blackbox/ndrdump.py | 7 +------ > 1 file changed, 1 insertion(+), 6 deletions(-) > >diff --git a/python/samba/tests/blackbox/ndrdump.py b/python/samba/tests/blackbox/ndrdump.py >index 7ca7b93f559..c42f64f35a1 100644 >--- a/python/samba/tests/blackbox/ndrdump.py >+++ b/python/samba/tests/blackbox/ndrdump.py >@@ -24,12 +24,7 @@ from __future__ import print_function > import os > from samba.tests import BlackboxTestCase, BlackboxProcessError > >-for p in ["../../../../../source4/librpc/tests", "../../../../../librpc/tests"]: >- data_path_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), p)) >- print(data_path_dir) >- if os.path.exists(data_path_dir): >- break >- >+data_path_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../../source4/librpc/tests")) > > class NdrDumpTests(BlackboxTestCase): > """Blackbox tests for ndrdump.""" >-- >2.25.1 > > >From 8c506ed00e43d16ab1b6e269faf33bf85fc0a523 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Apr 2021 10:57:00 +1200 >Subject: [PATCH 070/686] krb5ccache.idl: Add definition for a Kerberos > credentials cache > >Based on specifications found at >https://web.mit.edu/kerberos/krb5-devel/doc/formats/ccache_file_format.html > >This is primarily designed for parsing and storing a single Kerberos >ticket, due to the limitations of PIDL. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 74fb2cc473cea0eebf641fc4d32d706bac8aa6f2) > >[jsutton@samba.org Backported to fix conflicts, and added dummy function > decode_ccache so that tables are properly generated] >--- > librpc/idl/krb5ccache.idl | 119 +++++++++++++++++++++++++++++++++++ > librpc/idl/wscript_build | 2 +- > librpc/wscript_build | 8 ++- > source4/librpc/wscript_build | 7 +++ > 4 files changed, 134 insertions(+), 2 deletions(-) > create mode 100644 librpc/idl/krb5ccache.idl > >diff --git a/librpc/idl/krb5ccache.idl b/librpc/idl/krb5ccache.idl >new file mode 100644 >index 00000000000..15f1beb9aab >--- /dev/null >+++ b/librpc/idl/krb5ccache.idl >@@ -0,0 +1,119 @@ >+/* >+ krb5 credentials cache (version 3 or 4) >+ specification: https://web.mit.edu/kerberos/krb5-devel/doc/formats/ccache_file_format.html >+*/ >+ >+#include "idl_types.h" >+ >+[ >+ uuid("1702b695-99ca-4f32-93e4-1e1c4d5ddb53"), >+ version(0.0), >+ pointer_default(unique), >+ helpstring("KRB5 credentials cache") >+] >+interface krb5ccache >+{ >+ typedef struct { >+ uint32 name_type; >+ uint32 component_count; >+ [flag(STR_SIZE4|STR_NOTERM|STR_UTF8)] string realm; >+ [flag(STR_SIZE4|STR_NOTERM|STR_UTF8)] string components[component_count]; >+ } PRINCIPAL; >+ >+ typedef struct { >+ uint16 enctype; >+ DATA_BLOB data; >+ } KEYBLOCK; >+ >+ typedef struct { >+ uint16 addrtype; >+ DATA_BLOB data; >+ } ADDRESS; >+ >+ typedef struct { >+ uint32 count; >+ ADDRESS data[count]; >+ } ADDRESSES; >+ >+ typedef struct { >+ uint16 ad_type; >+ DATA_BLOB data; >+ } AUTHDATUM; >+ >+ typedef struct { >+ uint32 count; >+ AUTHDATUM data[count]; >+ } AUTHDATA; >+ >+ typedef struct { >+ PRINCIPAL client; >+ PRINCIPAL server; >+ KEYBLOCK keyblock; >+ uint32 authtime; >+ uint32 starttime; >+ uint32 endtime; >+ uint32 renew_till; >+ uint8 is_skey; >+ uint32 ticket_flags; >+ ADDRESSES addresses; >+ AUTHDATA authdata; >+ DATA_BLOB ticket; >+ DATA_BLOB second_ticket; >+ } CREDENTIAL; >+ >+ typedef struct { >+ [value(0)] int32 kdc_sec_offset; >+ [value(0)] int32 kdc_usec_offset; >+ } DELTATIME_TAG; >+ >+ typedef [nodiscriminant] union { >+ [case(1)] DELTATIME_TAG deltatime_tag; >+ } FIELD; >+ >+ typedef struct { >+ [value(1)] uint16 tag; >+ [subcontext(2),switch_is(tag)] FIELD field; >+ } V4TAG; >+ >+ typedef struct { >+ V4TAG tag; >+ /* >+ * We should allow for more than one tag to be properly parsed, but that >+ * would require manual parsing. >+ */ >+ [flag(NDR_REMAINING)] DATA_BLOB further_tags; >+ } V4TAGS; >+ >+ typedef struct { >+ [subcontext(2)] V4TAGS v4tags; >+ } V4HEADER; >+ >+ typedef [nodiscriminant] union { >+ /* >+ * We don't attempt to support file format versions 1 and 2 as they >+ * assume native CPU byte order, which makes no sense in PIDL. >+ */ >+ [case(3)] ; >+ [case(4)] V4HEADER v4header; >+ } OPTIONAL_HEADER; >+ >+ /* Public structures. */ >+ >+ typedef [flag(NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX),public] struct { >+ [value(5)] uint8 pvno; >+ [value(4)] uint8 version; >+ [switch_is(version)] OPTIONAL_HEADER optional_header; >+ PRINCIPAL principal; >+ CREDENTIAL cred; >+ [flag(NDR_REMAINING)] DATA_BLOB further_creds; >+ } CCACHE; >+ >+ typedef [flag(NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX),public] struct { >+ CREDENTIAL cred; >+ [flag(NDR_REMAINING)] DATA_BLOB further_creds; >+ } MULTIPLE_CREDENTIALS; >+ >+ [nopython] void decode_ccache( >+ [in] CCACHE ccache >+ ); >+} >diff --git a/librpc/idl/wscript_build b/librpc/idl/wscript_build >index aa058e87133..f20558899fb 100644 >--- a/librpc/idl/wscript_build >+++ b/librpc/idl/wscript_build >@@ -5,7 +5,7 @@ bld.SAMBA_PIDL_LIST('PIDL', > misc.idl ntlmssp.idl negoex.idl schannel.idl trkwks.idl > audiosrv.idl dfsblobs.idl dsbackup.idl eventlog.idl file_id.idl keysvc.idl > msgsvc.idl ntsvcs.idl remact.idl security.idl smb_acl.idl unixinfo.idl wzcsvc.idl >- browser.idl dfs.idl dssetup.idl frsapi.idl krb5pac.idl >+ browser.idl dfs.idl dssetup.idl frsapi.idl krb5pac.idl krb5ccache.idl > named_pipe_auth.idl orpc.idl rot.idl spoolss.idl w32time.idl > dbgidl.idl dnsserver.idl echo.idl frsrpc.idl lsa.idl nbt.idl dns.idl > oxidresolver.idl samr.idl server_id.idl srvsvc.idl winreg.idl dcerpc.idl >diff --git a/librpc/wscript_build b/librpc/wscript_build >index b560a08a7e2..4c0c5a09988 100644 >--- a/librpc/wscript_build >+++ b/librpc/wscript_build >@@ -375,6 +375,11 @@ bld.SAMBA_LIBRARY('ndr-krb5pac', > vnum='0.0.1' > ) > >+bld.SAMBA_SUBSYSTEM('NDR_KRB5CCACHE', >+ source='gen_ndr/ndr_krb5ccache.c', >+ deps='ndr NDR_COMPRESSION NDR_SECURITY ndr-standard asn1util' >+ ) >+ > bld.SAMBA_LIBRARY('ndr-standard', > source='gen_ndr/ndr_eventlog6.c', > vnum='0.0.1', >@@ -702,7 +707,8 @@ bld.SAMBA_LIBRARY('ndr-samba', > source=[], > deps='''NDR_DRSBLOBS NDR_DRSUAPI NDR_IDMAP NDR_NTLMSSP NDR_NEGOEX NDR_SCHANNEL NDR_MGMT > NDR_DNSSERVER NDR_EPMAPPER NDR_XATTR NDR_UNIXINFO NDR_NAMED_PIPE_AUTH NDR_DCOM >- NDR_NTPRINTING NDR_FSRVP NDR_WITNESS NDR_MDSSVC NDR_OPEN_FILES NDR_SMBXSRV''', >+ NDR_NTPRINTING NDR_FSRVP NDR_WITNESS NDR_MDSSVC NDR_OPEN_FILES NDR_SMBXSRV >+ NDR_KRB5CCACHE''', > private_library=True, > grouping_library=True > ) >diff --git a/source4/librpc/wscript_build b/source4/librpc/wscript_build >index d9b7743c9d1..d452e7012dc 100644 >--- a/source4/librpc/wscript_build >+++ b/source4/librpc/wscript_build >@@ -230,6 +230,13 @@ for env in bld.gen_python_environments(): > cflags_end=gen_cflags > ) > >+ bld.SAMBA_PYTHON('python_krb5ccache', >+ source='../../librpc/gen_ndr/py_krb5ccache.c', >+ deps='NDR_KRB5CCACHE %s %s' % (pytalloc_util, pyrpc_util), >+ realname='samba/dcerpc/krb5ccache.so', >+ cflags_end=gen_cflags >+ ) >+ > bld.SAMBA_PYTHON('python_netlogon', > source='../../librpc/gen_ndr/py_netlogon.c', > deps='RPC_NDR_NETLOGON %s %s' % (pytalloc_util, pyrpc_util), >-- >2.25.1 > > >From 000cb58d6c95d82a77249d329c8fce95c984de41 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Apr 2021 10:58:48 +1200 >Subject: [PATCH 071/686] librpc: Test parsing a Kerberos 5 credentials cache > with ndrdump > >This is the format used by the FILE: credentials cache type. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 1f17b1edca9c1638ef404fadce3ca7a4d176de12) > >[jsutton@samba.org Backported to fix conflicts] >--- > python/samba/tests/blackbox/ndrdump.py | 37 + > source3/selftest/ktest-krb5_ccache-2.txt | 1574 ++++++++++++++++++++++ > source3/selftest/ktest-krb5_ccache-3.txt | 832 ++++++++++++ > 3 files changed, 2443 insertions(+) > create mode 100644 source3/selftest/ktest-krb5_ccache-2.txt > create mode 100644 source3/selftest/ktest-krb5_ccache-3.txt > >diff --git a/python/samba/tests/blackbox/ndrdump.py b/python/samba/tests/blackbox/ndrdump.py >index c42f64f35a1..5cc3eceb353 100644 >--- a/python/samba/tests/blackbox/ndrdump.py >+++ b/python/samba/tests/blackbox/ndrdump.py >@@ -55,3 +55,40 @@ class NdrDumpTests(BlackboxTestCase): > self.data_path("dns-decode_dns_name_packet-hex.dat")) > except BlackboxProcessError as e: > self.fail(e) >+ >+ def test_ndrdump_Krb5ccache(self): >+ expected = open(self.data_path("../../../source3/selftest/" >+ "ktest-krb5_ccache-2.txt")).read() >+ try: >+ # Specify -d1 to match the generated output file, because ndrdump >+ # only outputs some additional info if this parameter is specified, >+ # and the --configfile parameter gives us an empty smb.conf to avoid >+ # extraneous output. >+ actual = self.check_output( >+ "ndrdump krb5ccache CCACHE struct " >+ "--configfile /dev/null -d1 --validate " + >+ self.data_path("../../../source3/selftest/" >+ "ktest-krb5_ccache-2")) >+ except BlackboxProcessError as e: >+ self.fail(e) >+ # check_output will return bytes >+ # convert expected to bytes for python 3 >+ self.assertEqual(actual, expected.encode('utf-8')) >+ >+ expected = open(self.data_path("../../../source3/selftest/" >+ "ktest-krb5_ccache-3.txt")).read() >+ try: >+ # Specify -d1 to match the generated output file, because ndrdump >+ # only outputs some additional info if this parameter is specified, >+ # and the --configfile parameter gives us an empty smb.conf to avoid >+ # extraneous output. >+ actual = self.check_output( >+ "ndrdump krb5ccache CCACHE struct " >+ "--configfile /dev/null -d1 --validate " + >+ self.data_path("../../../source3/selftest/" >+ "ktest-krb5_ccache-3")) >+ except BlackboxProcessError as e: >+ self.fail(e) >+ # check_output will return bytes >+ # convert expected to bytes for python 3 >+ self.assertEqual(actual, expected.encode('utf-8')) >diff --git a/source3/selftest/ktest-krb5_ccache-2.txt b/source3/selftest/ktest-krb5_ccache-2.txt >new file mode 100644 >index 00000000000..c86750ae585 >--- /dev/null >+++ b/source3/selftest/ktest-krb5_ccache-2.txt >@@ -0,0 +1,1574 @@ >+pull returned Success >+ CCACHE: struct CCACHE >+ pvno : 0x05 (5) >+ version : 0x04 (4) >+ optional_header : union OPTIONAL_HEADER(case 0x4) >+ v4header: struct V4HEADER >+ v4tags: struct V4TAGS >+ tag: struct V4TAG >+ tag : 0x0001 (1) >+ field : union FIELD(case 0x1) >+ deltatime_tag: struct DELTATIME_TAG >+ kdc_sec_offset : 0 >+ kdc_usec_offset : 0 >+ further_tags : DATA_BLOB length=0 >+ principal: struct PRINCIPAL >+ name_type : 0x00000001 (1) >+ component_count : 0x00000001 (1) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(1) >+ components : 'administrator' >+ cred: struct CREDENTIAL >+ client: struct PRINCIPAL >+ name_type : 0x00000001 (1) >+ component_count : 0x00000001 (1) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(1) >+ components : 'administrator' >+ server: struct PRINCIPAL >+ name_type : 0x00000000 (0) >+ component_count : 0x00000002 (2) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(2) >+ components : 'krbtgt' >+ components : 'KTEST.SAMBA.EXAMPLE.COM' >+ keyblock: struct KEYBLOCK >+ enctype : 0x0017 (23) >+ data : DATA_BLOB length=16 >+[0000] 8B 94 0B 31 51 5B F7 A7 15 E9 EE D7 D7 0C 8C 90 ...1Q[.. ........ >+ authtime : 0x4d994f6a (1301892970) >+ starttime : 0x4d994f6a (1301892970) >+ endtime : 0x7d440b68 (2101611368) >+ renew_till : 0x7d440b68 (2101611368) >+ is_skey : 0x00 (0) >+ ticket_flags : 0x40e00000 (1088421888) >+ addresses: struct ADDRESSES >+ count : 0x00000000 (0) >+ data: ARRAY(0) >+ authdata: struct AUTHDATA >+ count : 0x00000000 (0) >+ data: ARRAY(0) >+ ticket : DATA_BLOB length=1032 >+[0000] 61 82 04 04 30 82 04 00 A0 03 02 01 05 A1 19 1B a...0... ........ >+[0010] 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 .KTEST.S AMBA.EXA >+[0020] 4D 50 4C 45 2E 43 4F 4D A2 2C 30 2A A0 03 02 01 MPLE.COM .,0*.... >+[0030] 00 A1 23 30 21 1B 06 6B 72 62 74 67 74 1B 17 4B ..#0!..k rbtgt..K >+[0040] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[0050] 4C 45 2E 43 4F 4D A3 82 03 AE 30 82 03 AA A0 03 LE.COM.. ..0..... >+[0060] 02 01 17 A1 03 02 01 01 A2 82 03 9C 04 82 03 98 ........ ........ >+[0070] 80 66 8F CF AB 24 9D C8 76 E4 28 F5 25 6B 73 B2 .f...$.. v.(.%ks. >+[0080] 4B 94 ED 09 10 29 05 C4 C0 B8 B9 33 FA C4 46 AB K....).. ...3..F. >+[0090] F4 B5 9E 5B 07 54 D6 58 1D B8 CA 04 41 A6 33 A6 ...[.T.X ....A.3. >+[00A0] 67 9D EB 83 70 65 A9 2D 65 A5 19 8C 55 2A 0F FC g...pe.- e...U*.. >+[00B0] 1B BB 7A BD 86 C0 32 06 F2 2F 0A A5 93 E7 D1 1E ..z...2. ./...... >+[00C0] 16 C4 27 DD 1F A7 61 03 FF 05 81 EF 49 B7 25 A3 ..'...a. ....I.%. >+[00D0] 6E EA E6 E8 15 E3 10 AF A3 F1 21 B3 D9 C0 67 2F n....... ..!...g/ >+[00E0] 0C 0C B7 42 D6 9A 34 8E D4 5E 55 C2 FE 62 03 37 ...B..4. .^U..b.7 >+[00F0] A5 58 9B 43 E7 26 E3 71 B2 E5 F1 91 B4 23 8F AC .X.C.&.q .....#.. >+[0100] 7A 31 3C 4E B4 94 E4 81 36 98 71 3B 98 7B B7 AB z1<N.... 6.q;.{.. >+[0110] D5 AA D3 34 2A 3B C8 D7 61 EE 60 F9 68 9C A0 56 ...4*;.. a.`.h..V >+[0120] 51 E7 85 81 DE EF B9 9F 8B 4A 07 E1 05 93 08 5A Q....... .J.....Z >+[0130] AE B3 92 A5 17 40 B1 1C 42 A9 E4 AD 3C B4 4E D3 .....@.. B...<.N. >+[0140] BE 68 C4 0C 81 C0 AB 2D 3E 81 09 BD 16 82 EB C5 .h.....- >....... >+[0150] 1A 69 EE 8C 4E A4 D8 55 A5 0B 23 0F D0 89 48 C4 .i..N..U ..#...H. >+[0160] 51 FE 32 FD CC F6 71 E1 95 2D CC 1D 0A 0C 8A A2 Q.2...q. .-...... >+[0170] 69 58 3B 65 88 53 EC D0 2E E1 C6 CC 6B BC 09 E5 iX;e.S.. ....k... >+[0180] B9 15 27 8B E4 B2 24 18 61 42 BB 8B 09 1B 8A 7B ..'...$. aB.....{ >+[0190] 13 D8 51 E1 0B 79 12 48 DE A9 54 04 00 6D DD E6 ..Q..y.H ..T..m.. >+[01A0] 5E 03 91 FF C7 6D 0B 7C 91 44 E1 0F C0 7E 32 34 ^....m.| .D...~24 >+[01B0] 82 86 94 F7 CD 53 EC 52 38 18 AA ED FF FC 5C 01 .....S.R 8.....\. >+[01C0] D2 EE 99 45 8E 5B E6 B3 46 B0 F6 3B 22 29 EC 11 ...E.[.. F..;").. >+[01D0] 30 6A F6 A1 1F 9E AE 71 E3 A6 E7 3F F3 7D 2B 75 0j.....q ...?.}+u >+[01E0] 70 4D 63 47 5C 18 2C 8B B1 1A 69 B6 C5 46 01 17 pMcG\.,. ..i..F.. >+[01F0] 8E 64 3D 47 88 20 1C AA D7 60 32 28 11 60 EA 28 .d=G. .. .`2(.`.( >+[0200] 66 99 4C B1 2A 28 96 BF 18 2A 3E F4 D6 84 E5 A0 f.L.*(.. .*>..... >+[0210] F4 4E E7 F9 54 95 22 96 2A 87 01 CC 3E A7 FF 42 .N..T.". *...>..B >+[0220] 6A A4 4A 3A B9 24 10 65 99 53 58 2A 4E 72 E7 1F j.J:.$.e .SX*Nr.. >+[0230] 82 BC BD 3C 6C 9D 33 3A CE C6 6E 72 A2 81 B3 84 ...<l.3: ..nr.... >+[0240] 82 DF 3C 1F 76 E5 B8 08 AD 0A 6C 7D 7B D5 0C 46 ..<.v... ..l}{..F >+[0250] 69 A4 F4 E9 9E 3D D7 2D E1 43 D1 7A 52 16 75 56 i....=.- .C.zR.uV >+[0260] 54 83 D5 2A 2F A7 D2 CB 48 FE FF DB AE 46 F2 5B T..*/... H....F.[ >+[0270] F4 52 BE C8 5E B1 04 95 52 35 3E 92 E0 02 F7 85 .R..^... R5>..... >+[0280] AB F0 D0 93 08 42 E5 37 19 24 4E C1 AF FC 92 A9 .....B.7 .$N..... >+[0290] B1 27 B1 9A 2A 62 34 F1 DC C0 6B 83 AE C3 74 E8 .'..*b4. ..k...t. >+[02A0] A3 05 DD 82 DD A3 D7 90 A8 E3 9C EB 64 16 23 06 ........ ....d.#. >+[02B0] 5D FB E4 35 7C 22 29 78 E3 3B 75 92 91 0C 9D A1 ]..5|")x .;u..... >+[02C0] 87 7C 2E 82 AE 49 9D 4A 50 A9 C2 D5 85 B0 16 5D .|...I.J P......] >+[02D0] A2 CD B0 DD 29 3F 6F 66 C9 C1 9F 5C F0 B6 FC D2 ....)?of ...\.... >+[02E0] 52 BE 7B F0 1F 26 AF 8A FC C3 A6 24 8C C0 10 06 R.{..&.. ...$.... >+[02F0] 73 1E 17 9E 6E 6F 32 44 6A DF 82 5D D0 6B 74 CE s...no2D j..].kt. >+[0300] 58 0B 4C 7B EB A1 13 44 B1 3E D8 F8 BA F4 4E 55 X.L{...D .>....NU >+[0310] 71 3D C1 09 D9 E7 97 9A 14 5C 54 7E 57 81 5F 6B q=...... .\T~W._k >+[0320] 30 BE 9A E1 98 29 47 D4 C0 8F 63 0A F8 27 1F CE 0....)G. ..c..'.. >+[0330] ED D9 BB 7B 12 24 D0 34 2A 7C F0 F7 77 F4 F1 1D ...{.$.4 *|..w... >+[0340] 4C 5D 75 2D 6B 0D 80 35 82 CC D8 7A 6B FA A0 55 L]u-k..5 ...zk..U >+[0350] 34 CD 87 15 61 38 78 D4 69 0F AA 72 D6 AC FA 99 4...a8x. i..r.... >+[0360] BC 70 39 27 A7 25 2E 1B 6F 36 01 FD E9 B4 9A 79 .p9'.%.. o6.....y >+[0370] 6C 19 DD A6 8C 78 B0 40 92 60 58 F0 28 AD 08 78 l....x.@ .`X.(..x >+[0380] 4A 29 06 2C 82 2B 1A E3 91 0B 5F EE D6 B8 66 47 J).,.+.. .._...fG >+[0390] 31 9B A3 DF 9F 79 D7 BB 0E 2C FA 0E C9 66 84 8D 1....y.. .,...f.. >+[03A0] FF BA BB 21 27 9E AD 86 84 55 8D 4C 4C 47 D9 5F ...!'... .U.LLG._ >+[03B0] B2 7D 26 CA B7 49 3C 9D 1B 67 71 11 3A 8A EB EA .}&..I<. .gq.:... >+[03C0] 0F 15 EB F0 1E 46 F7 A4 34 04 D7 E3 50 67 47 D3 .....F.. 4...PgG. >+[03D0] 66 21 17 77 51 A7 1F 1D 84 3B 7C B1 5D 4E B8 D4 f!.wQ... .;|.]N.. >+[03E0] F9 C5 75 06 AA 19 45 1C E9 06 9E AD 23 26 6B 10 ..u...E. ....#&k. >+[03F0] 53 A0 36 D3 58 9F 5E 8C CB A5 F6 BC C9 30 3C BC S.6.X.^. .....0<. >+[0400] AD FF 7C 92 F0 C6 9A 02 ..|..... >+ second_ticket : DATA_BLOB length=0 >+ further_creds : DATA_BLOB length=10683 >+[0000] 00 00 00 01 00 00 00 01 00 00 00 17 4B 54 45 53 ........ ....KTES >+[0010] 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E T.SAMBA. EXAMPLE. >+[0020] 43 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 73 74 72 COM....a dministr >+[0030] 61 74 6F 72 00 00 00 01 00 00 00 02 00 00 00 17 ator.... ........ >+[0040] 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D KTEST.SA MBA.EXAM >+[0050] 50 4C 45 2E 43 4F 4D 00 00 00 04 63 69 66 73 00 PLE.COM. ...cifs. >+[0060] 00 00 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 00 17 ...local ktest6.. >+[0070] 00 00 00 10 00 6E A1 B2 31 6D 48 C7 90 72 3A 0C .....n.. 1mH..r:. >+[0080] 4B 8B 83 8C 4D 99 4F 6A 4D 99 50 85 7D 44 0B 68 K...M.Oj M.P.}D.h >+[0090] 00 00 00 00 00 40 28 00 00 00 00 00 00 00 00 00 .....@(. ........ >+[00A0] 00 00 00 03 FA 61 82 03 F6 30 82 03 F2 A0 03 02 .....a.. .0...... >+[00B0] 01 05 A1 19 1B 17 4B 54 45 53 54 2E 53 41 4D 42 ......KT EST.SAMB >+[00C0] 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D A2 1E 30 A.EXAMPL E.COM..0 >+[00D0] 1C A0 03 02 01 01 A1 15 30 13 1B 04 63 69 66 73 ........ 0...cifs >+[00E0] 1B 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 A3 82 03 ..localk test6... >+[00F0] AE 30 82 03 AA A0 03 02 01 17 A1 03 02 01 02 A2 .0...... ........ >+[0100] 82 03 9C 04 82 03 98 C6 BB 64 A8 31 00 FC 5E 51 ........ .d.1..^Q >+[0110] 3C 87 F8 34 47 3B D0 6F 6F FD 9E A6 91 12 74 2D <..4G;.o o.....t- >+[0120] 44 BB AA 91 A0 2D 46 3E 9E FB FB C4 FB F1 15 FD D....-F> ........ >+[0130] BB DA EE 06 A9 20 6A 38 DC 46 06 27 D9 A2 9D 2D ..... j8 .F.'...- >+[0140] 1F FD 0D 7D 8A BB 0A 7C E8 47 17 BC 7B 70 E4 51 ...}...| .G..{p.Q >+[0150] 6A BA 51 68 62 28 4A 1E 51 D1 0D CD 02 55 75 44 j.Qhb(J. Q....UuD >+[0160] 8A B9 C2 84 F4 17 34 92 9B 31 85 9E 43 C1 0C 3A ......4. .1..C..: >+[0170] B2 69 7F 20 1A 18 1F 65 4F C0 20 C9 B5 AF E1 61 .i. ...e O. ....a >+[0180] 8C 90 10 63 26 A6 5D 05 3C CD 29 BB 7B 74 D5 8F ...c&.]. <.).{t.. >+[0190] 2C 7F 4B E8 84 24 57 37 8A C6 F7 91 FD 22 9A A5 ,.K..$W7 .....".. >+[01A0] 0D E9 4A 78 93 36 FC A8 8C 8A 27 8A C6 28 4B 7B ..Jx.6.. ..'..(K{ >+[01B0] DA 11 42 BC 09 10 81 82 14 0F 9C B8 48 26 91 78 ..B..... ....H&.x >+[01C0] A8 DD 97 6C 24 A1 D2 E8 85 19 B3 D3 85 4D 38 C7 ...l$... .....M8. >+[01D0] 7D 49 55 8E 85 46 E1 EE 7B BA 11 62 63 53 C5 16 }IU..F.. {..bcS.. >+[01E0] 4A 0C 1C 99 7C 0E FB 45 1D B4 98 58 67 7E 40 65 J...|..E ...Xg~@e >+[01F0] 4B 48 E2 89 9C 8B C2 B8 39 D1 04 C0 A8 56 E8 A1 KH...... 9....V.. >+[0200] 04 7A 7A C9 60 18 A0 29 E2 DC 82 4C 8F 18 CE 2F .zz.`..) ...L.../ >+[0210] 14 F0 18 5B 6C FF 85 45 88 73 CB A4 55 08 FC BF ...[l..E .s..U... >+[0220] C7 9F 51 0A DB 2C C1 E3 3C DD F6 F0 A3 2D F1 3B ..Q..,.. <....-.; >+[0230] A0 12 1D FC 2A 67 F5 1A 7F E5 7C 6C FB 8A 18 BD ....*g.. ..|l.... >+[0240] D1 5D E5 5E 68 30 AA 58 9E 10 13 E0 26 7E 7D C4 .].^h0.X ....&~}. >+[0250] E1 A5 B6 86 0F 1C 0F 13 A4 5E 5E 6A ED 42 79 31 ........ .^^j.By1 >+[0260] BB B3 5F 3A 3F DD CB 63 82 FB 06 AE 12 36 C9 1E .._:?..c .....6.. >+[0270] 06 7D 41 82 2E D2 FA 26 EC 17 50 5E D0 DE 26 85 .}A....& ..P^..&. >+[0280] 30 71 BC 45 3B DA 2E 08 8D B2 2A 3C E0 79 8F 77 0q.E;... ..*<.y.w >+[0290] 4C 01 69 7A 09 C7 88 E1 D1 DC FF 78 DB 25 7B B1 L.iz.... ...x.%{. >+[02A0] 3C BB 22 27 80 0D 75 96 18 B6 40 95 6D C8 AB 04 <."'..u. ..@.m... >+[02B0] 05 41 A1 C4 25 71 C4 53 3A A6 9C B2 4D E6 15 2C .A..%q.S :...M.., >+[02C0] B2 47 6C DA A8 7D CC A3 89 8B C9 1E 21 F5 E9 B2 .Gl..}.. ....!... >+[02D0] 42 95 68 28 AF C6 37 22 BA 30 8D 53 FA 08 0D CE B.h(..7" .0.S.... >+[02E0] CA 81 61 0D 84 A5 2D 75 BD 41 85 4C 88 56 72 C6 ..a...-u .A.L.Vr. >+[02F0] B6 10 F8 34 CD B2 F4 5C 94 FA 80 90 82 A0 BD 68 ...4...\ .......h >+[0300] EC 08 32 C3 B6 51 1E 3F 67 CB 7B EB 70 83 84 D4 ..2..Q.? g.{.p... >+[0310] CB 52 55 36 61 1E 60 90 5B 6F FE 9A 62 05 CF 26 .RU6a.`. [o..b..& >+[0320] 8E 65 E2 60 4B ED 63 B4 C4 E6 44 B4 2F B0 B8 07 .e.`K.c. ..D./... >+[0330] FE BE 0D 50 E4 56 A4 2E 0D 25 76 0B 0F 44 09 20 ...P.V.. .%v..D. >+[0340] 80 E5 C4 94 63 E0 54 46 1D AB 5E 0B 09 93 B1 30 ....c.TF ..^....0 >+[0350] 31 7B 04 DC 23 43 3B DB 7D 39 67 FE 9A 1F C1 08 1{..#C;. }9g..... >+[0360] AF 34 24 F6 74 E4 14 DA 34 8F 61 57 6A 7F 1D 4A .4$.t... 4.aWj..J >+[0370] 88 0A 90 78 93 F1 86 54 DB 22 86 D6 69 0F DF 44 ...x...T ."..i..D >+[0380] 7C D3 6B 9D 41 63 50 98 3A 97 B9 7B 4C 53 E3 85 |.k.AcP. :..{LS.. >+[0390] 73 9A C9 08 A0 75 12 50 02 87 B0 CF CC 84 84 D9 s....u.P ........ >+[03A0] BC FC 94 79 AF 6A A6 08 FF 19 7E E9 22 9B EC 5C ...y.j.. ..~."..\ >+[03B0] C1 6B 1D A4 B4 55 32 5E 23 C3 C0 D4 8B 80 E6 67 .k...U2^ #......g >+[03C0] B1 59 EB 9D 5D 9B AD C6 0E 7D E2 FE B1 24 8A B1 .Y..]... .}...$.. >+[03D0] 37 1E 60 7F 83 35 48 32 F7 03 E8 12 E6 21 7C 3D 7.`..5H2 .....!|= >+[03E0] 21 7F 6B 14 31 9C 1A A3 4C 2B 1C 5E EC 34 C1 2D !.k.1... L+.^.4.- >+[03F0] DA 19 6C E6 6D 8D 60 D7 55 9E E6 D0 B5 07 06 72 ..l.m.`. U......r >+[0400] C0 E9 4E 91 94 6B 3E 0B F1 0A 75 4D E8 CB 53 6B ..N..k>. ..uM..Sk >+[0410] 34 A4 2F 96 A5 39 1A 18 6E 27 00 6D 41 B7 D8 F5 4./..9.. n'.mA... >+[0420] 9A E5 01 FC 0B A8 97 56 EE 98 04 1D 98 84 5E 82 .......V ......^. >+[0430] C8 E8 EC 17 D5 FA 96 00 3B E1 98 1C D8 FA 66 A0 ........ ;.....f. >+[0440] DC 32 60 F6 03 46 08 3C E5 16 6F F2 8B 4D 72 9F .2`..F.< ..o..Mr. >+[0450] 0F E0 A9 71 6E 7C AE AA FB A3 4D F1 A1 B6 1B 9F ...qn|.. ..M..... >+[0460] 62 71 E1 2C 82 9B AE E3 07 9B 79 90 F1 C2 69 E5 bq.,.... ..y...i. >+[0470] 7E CB 57 E6 C9 1C 4E A8 C7 12 EA 4F 4C 52 17 03 ~.W...N. ...OLR.. >+[0480] AB D4 FD 34 60 F4 7C BE 9E 36 30 37 88 95 61 2E ...4`.|. .607..a. >+[0490] CF 70 AF 22 70 DB E8 AA 6E 3D 30 F7 4D 84 D5 00 .p."p... n=0.M... >+[04A0] 00 00 00 00 00 00 01 00 00 00 01 00 00 00 17 4B ........ .......K >+[04B0] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[04C0] 4C 45 2E 43 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 LE.COM.. ..admini >+[04D0] 73 74 72 61 74 6F 72 00 00 00 01 00 00 00 02 00 strator. ........ >+[04E0] 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 ...KTEST .SAMBA.E >+[04F0] 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 04 63 69 XAMPLE.C OM....ci >+[0500] 66 73 00 00 00 0B 6C 6F 63 61 6C 6B 74 65 73 74 fs....lo calktest >+[0510] 36 00 17 00 00 00 10 00 6E A1 B2 31 6D 48 C7 90 6....... n..1mH.. >+[0520] 72 3A 0C 4B 8B 83 8C 4D 99 4F 6A 4D 99 50 85 7D r:.K...M .OjM.P.} >+[0530] 44 0B 68 00 00 00 00 00 40 28 00 00 00 00 00 00 D.h..... @(...... >+[0540] 00 00 00 00 00 00 03 FA 61 82 03 F6 30 82 03 F2 ........ a...0... >+[0550] A0 03 02 01 05 A1 19 1B 17 4B 54 45 53 54 2E 53 ........ .KTEST.S >+[0560] 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D AMBA.EXA MPLE.COM >+[0570] A2 1E 30 1C A0 03 02 01 01 A1 15 30 13 1B 04 63 ..0..... ...0...c >+[0580] 69 66 73 1B 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 ifs..loc alktest6 >+[0590] A3 82 03 AE 30 82 03 AA A0 03 02 01 17 A1 03 02 ....0... ........ >+[05A0] 01 02 A2 82 03 9C 04 82 03 98 C6 BB 64 A8 31 00 ........ ....d.1. >+[05B0] FC 5E 51 3C 87 F8 34 47 3B D0 6F 6F FD 9E A6 91 .^Q<..4G ;.oo.... >+[05C0] 12 74 2D 44 BB AA 91 A0 2D 46 3E 9E FB FB C4 FB .t-D.... -F>..... >+[05D0] F1 15 FD BB DA EE 06 A9 20 6A 38 DC 46 06 27 D9 ........ j8.F.'. >+[05E0] A2 9D 2D 1F FD 0D 7D 8A BB 0A 7C E8 47 17 BC 7B ..-...}. ..|.G..{ >+[05F0] 70 E4 51 6A BA 51 68 62 28 4A 1E 51 D1 0D CD 02 p.Qj.Qhb (J.Q.... >+[0600] 55 75 44 8A B9 C2 84 F4 17 34 92 9B 31 85 9E 43 UuD..... .4..1..C >+[0610] C1 0C 3A B2 69 7F 20 1A 18 1F 65 4F C0 20 C9 B5 ..:.i. . ..eO. .. >+[0620] AF E1 61 8C 90 10 63 26 A6 5D 05 3C CD 29 BB 7B ..a...c& .].<.).{ >+[0630] 74 D5 8F 2C 7F 4B E8 84 24 57 37 8A C6 F7 91 FD t..,.K.. $W7..... >+[0640] 22 9A A5 0D E9 4A 78 93 36 FC A8 8C 8A 27 8A C6 "....Jx. 6....'.. >+[0650] 28 4B 7B DA 11 42 BC 09 10 81 82 14 0F 9C B8 48 (K{..B.. .......H >+[0660] 26 91 78 A8 DD 97 6C 24 A1 D2 E8 85 19 B3 D3 85 &.x...l$ ........ >+[0670] 4D 38 C7 7D 49 55 8E 85 46 E1 EE 7B BA 11 62 63 M8.}IU.. F..{..bc >+[0680] 53 C5 16 4A 0C 1C 99 7C 0E FB 45 1D B4 98 58 67 S..J...| ..E...Xg >+[0690] 7E 40 65 4B 48 E2 89 9C 8B C2 B8 39 D1 04 C0 A8 ~@eKH... ...9.... >+[06A0] 56 E8 A1 04 7A 7A C9 60 18 A0 29 E2 DC 82 4C 8F V...zz.` ..)...L. >+[06B0] 18 CE 2F 14 F0 18 5B 6C FF 85 45 88 73 CB A4 55 ../...[l ..E.s..U >+[06C0] 08 FC BF C7 9F 51 0A DB 2C C1 E3 3C DD F6 F0 A3 .....Q.. ,..<.... >+[06D0] 2D F1 3B A0 12 1D FC 2A 67 F5 1A 7F E5 7C 6C FB -.;....* g....|l. >+[06E0] 8A 18 BD D1 5D E5 5E 68 30 AA 58 9E 10 13 E0 26 ....].^h 0.X....& >+[06F0] 7E 7D C4 E1 A5 B6 86 0F 1C 0F 13 A4 5E 5E 6A ED ~}...... ....^^j. >+[0700] 42 79 31 BB B3 5F 3A 3F DD CB 63 82 FB 06 AE 12 By1.._:? ..c..... >+[0710] 36 C9 1E 06 7D 41 82 2E D2 FA 26 EC 17 50 5E D0 6...}A.. ..&..P^. >+[0720] DE 26 85 30 71 BC 45 3B DA 2E 08 8D B2 2A 3C E0 .&.0q.E; .....*<. >+[0730] 79 8F 77 4C 01 69 7A 09 C7 88 E1 D1 DC FF 78 DB y.wL.iz. ......x. >+[0740] 25 7B B1 3C BB 22 27 80 0D 75 96 18 B6 40 95 6D %{.<."'. .u...@.m >+[0750] C8 AB 04 05 41 A1 C4 25 71 C4 53 3A A6 9C B2 4D ....A..% q.S:...M >+[0760] E6 15 2C B2 47 6C DA A8 7D CC A3 89 8B C9 1E 21 ..,.Gl.. }......! >+[0770] F5 E9 B2 42 95 68 28 AF C6 37 22 BA 30 8D 53 FA ...B.h(. .7".0.S. >+[0780] 08 0D CE CA 81 61 0D 84 A5 2D 75 BD 41 85 4C 88 .....a.. .-u.A.L. >+[0790] 56 72 C6 B6 10 F8 34 CD B2 F4 5C 94 FA 80 90 82 Vr....4. ..\..... >+[07A0] A0 BD 68 EC 08 32 C3 B6 51 1E 3F 67 CB 7B EB 70 ..h..2.. Q.?g.{.p >+[07B0] 83 84 D4 CB 52 55 36 61 1E 60 90 5B 6F FE 9A 62 ....RU6a .`.[o..b >+[07C0] 05 CF 26 8E 65 E2 60 4B ED 63 B4 C4 E6 44 B4 2F ..&.e.`K .c...D./ >+[07D0] B0 B8 07 FE BE 0D 50 E4 56 A4 2E 0D 25 76 0B 0F ......P. V...%v.. >+[07E0] 44 09 20 80 E5 C4 94 63 E0 54 46 1D AB 5E 0B 09 D. ....c .TF..^.. >+[07F0] 93 B1 30 31 7B 04 DC 23 43 3B DB 7D 39 67 FE 9A ..01{..# C;.}9g.. >+[0800] 1F C1 08 AF 34 24 F6 74 E4 14 DA 34 8F 61 57 6A ....4$.t ...4.aWj >+[0810] 7F 1D 4A 88 0A 90 78 93 F1 86 54 DB 22 86 D6 69 ..J...x. ..T."..i >+[0820] 0F DF 44 7C D3 6B 9D 41 63 50 98 3A 97 B9 7B 4C ..D|.k.A cP.:..{L >+[0830] 53 E3 85 73 9A C9 08 A0 75 12 50 02 87 B0 CF CC S..s.... u.P..... >+[0840] 84 84 D9 BC FC 94 79 AF 6A A6 08 FF 19 7E E9 22 ......y. j....~." >+[0850] 9B EC 5C C1 6B 1D A4 B4 55 32 5E 23 C3 C0 D4 8B ..\.k... U2^#.... >+[0860] 80 E6 67 B1 59 EB 9D 5D 9B AD C6 0E 7D E2 FE B1 ..g.Y..] ....}... >+[0870] 24 8A B1 37 1E 60 7F 83 35 48 32 F7 03 E8 12 E6 $..7.`.. 5H2..... >+[0880] 21 7C 3D 21 7F 6B 14 31 9C 1A A3 4C 2B 1C 5E EC !|=!.k.1 ...L+.^. >+[0890] 34 C1 2D DA 19 6C E6 6D 8D 60 D7 55 9E E6 D0 B5 4.-..l.m .`.U.... >+[08A0] 07 06 72 C0 E9 4E 91 94 6B 3E 0B F1 0A 75 4D E8 ..r..N.. k>...uM. >+[08B0] CB 53 6B 34 A4 2F 96 A5 39 1A 18 6E 27 00 6D 41 .Sk4./.. 9..n'.mA >+[08C0] B7 D8 F5 9A E5 01 FC 0B A8 97 56 EE 98 04 1D 98 ........ ..V..... >+[08D0] 84 5E 82 C8 E8 EC 17 D5 FA 96 00 3B E1 98 1C D8 .^...... ...;.... >+[08E0] FA 66 A0 DC 32 60 F6 03 46 08 3C E5 16 6F F2 8B .f..2`.. F.<..o.. >+[08F0] 4D 72 9F 0F E0 A9 71 6E 7C AE AA FB A3 4D F1 A1 Mr....qn |....M.. >+[0900] B6 1B 9F 62 71 E1 2C 82 9B AE E3 07 9B 79 90 F1 ...bq.,. .....y.. >+[0910] C2 69 E5 7E CB 57 E6 C9 1C 4E A8 C7 12 EA 4F 4C .i.~.W.. .N....OL >+[0920] 52 17 03 AB D4 FD 34 60 F4 7C BE 9E 36 30 37 88 R.....4` .|..607. >+[0930] 95 61 2E CF 70 AF 22 70 DB E8 AA 6E 3D 30 F7 4D .a..p."p ...n=0.M >+[0940] 84 D5 00 00 00 00 00 00 00 01 00 00 00 01 00 00 ........ ........ >+[0950] 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 ..KTEST. SAMBA.EX >+[0960] 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D 61 64 6D AMPLE.CO M....adm >+[0970] 69 6E 69 73 74 72 61 74 6F 72 00 00 00 01 00 00 inistrat or...... >+[0980] 00 02 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 ......KT EST.SAMB >+[0990] 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 A.EXAMPL E.COM... >+[09A0] 04 63 69 66 73 00 00 00 0B 6C 6F 63 61 6C 6B 74 .cifs... .localkt >+[09B0] 65 73 74 36 00 17 00 00 00 10 00 6E A1 B2 31 6D est6.... ...n..1m >+[09C0] 48 C7 90 72 3A 0C 4B 8B 83 8C 4D 99 4F 6A 4D 99 H..r:.K. ..M.OjM. >+[09D0] 50 85 7D 44 0B 68 00 00 00 00 00 40 28 00 00 00 P.}D.h.. ...@(... >+[09E0] 00 00 00 00 00 00 00 00 00 03 FA 61 82 03 F6 30 ........ ...a...0 >+[09F0] 82 03 F2 A0 03 02 01 05 A1 19 1B 17 4B 54 45 53 ........ ....KTES >+[0A00] 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E T.SAMBA. EXAMPLE. >+[0A10] 43 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 15 30 13 COM..0.. ......0. >+[0A20] 1B 04 63 69 66 73 1B 0B 6C 6F 63 61 6C 6B 74 65 ..cifs.. localkte >+[0A30] 73 74 36 A3 82 03 AE 30 82 03 AA A0 03 02 01 17 st6....0 ........ >+[0A40] A1 03 02 01 02 A2 82 03 9C 04 82 03 98 C6 BB 64 ........ .......d >+[0A50] A8 31 00 FC 5E 51 3C 87 F8 34 47 3B D0 6F 6F FD .1..^Q<. .4G;.oo. >+[0A60] 9E A6 91 12 74 2D 44 BB AA 91 A0 2D 46 3E 9E FB ....t-D. ...-F>.. >+[0A70] FB C4 FB F1 15 FD BB DA EE 06 A9 20 6A 38 DC 46 ........ ... j8.F >+[0A80] 06 27 D9 A2 9D 2D 1F FD 0D 7D 8A BB 0A 7C E8 47 .'...-.. .}...|.G >+[0A90] 17 BC 7B 70 E4 51 6A BA 51 68 62 28 4A 1E 51 D1 ..{p.Qj. Qhb(J.Q. >+[0AA0] 0D CD 02 55 75 44 8A B9 C2 84 F4 17 34 92 9B 31 ...UuD.. ....4..1 >+[0AB0] 85 9E 43 C1 0C 3A B2 69 7F 20 1A 18 1F 65 4F C0 ..C..:.i . ...eO. >+[0AC0] 20 C9 B5 AF E1 61 8C 90 10 63 26 A6 5D 05 3C CD ....a.. .c&.].<. >+[0AD0] 29 BB 7B 74 D5 8F 2C 7F 4B E8 84 24 57 37 8A C6 ).{t..,. K..$W7.. >+[0AE0] F7 91 FD 22 9A A5 0D E9 4A 78 93 36 FC A8 8C 8A ...".... Jx.6.... >+[0AF0] 27 8A C6 28 4B 7B DA 11 42 BC 09 10 81 82 14 0F '..(K{.. B....... >+[0B00] 9C B8 48 26 91 78 A8 DD 97 6C 24 A1 D2 E8 85 19 ..H&.x.. .l$..... >+[0B10] B3 D3 85 4D 38 C7 7D 49 55 8E 85 46 E1 EE 7B BA ...M8.}I U..F..{. >+[0B20] 11 62 63 53 C5 16 4A 0C 1C 99 7C 0E FB 45 1D B4 .bcS..J. ..|..E.. >+[0B30] 98 58 67 7E 40 65 4B 48 E2 89 9C 8B C2 B8 39 D1 .Xg~@eKH ......9. >+[0B40] 04 C0 A8 56 E8 A1 04 7A 7A C9 60 18 A0 29 E2 DC ...V...z z.`..).. >+[0B50] 82 4C 8F 18 CE 2F 14 F0 18 5B 6C FF 85 45 88 73 .L.../.. .[l..E.s >+[0B60] CB A4 55 08 FC BF C7 9F 51 0A DB 2C C1 E3 3C DD ..U..... Q..,..<. >+[0B70] F6 F0 A3 2D F1 3B A0 12 1D FC 2A 67 F5 1A 7F E5 ...-.;.. ..*g.... >+[0B80] 7C 6C FB 8A 18 BD D1 5D E5 5E 68 30 AA 58 9E 10 |l.....] .^h0.X.. >+[0B90] 13 E0 26 7E 7D C4 E1 A5 B6 86 0F 1C 0F 13 A4 5E ..&~}... .......^ >+[0BA0] 5E 6A ED 42 79 31 BB B3 5F 3A 3F DD CB 63 82 FB ^j.By1.. _:?..c.. >+[0BB0] 06 AE 12 36 C9 1E 06 7D 41 82 2E D2 FA 26 EC 17 ...6...} A....&.. >+[0BC0] 50 5E D0 DE 26 85 30 71 BC 45 3B DA 2E 08 8D B2 P^..&.0q .E;..... >+[0BD0] 2A 3C E0 79 8F 77 4C 01 69 7A 09 C7 88 E1 D1 DC *<.y.wL. iz...... >+[0BE0] FF 78 DB 25 7B B1 3C BB 22 27 80 0D 75 96 18 B6 .x.%{.<. "'..u... >+[0BF0] 40 95 6D C8 AB 04 05 41 A1 C4 25 71 C4 53 3A A6 @.m....A ..%q.S:. >+[0C00] 9C B2 4D E6 15 2C B2 47 6C DA A8 7D CC A3 89 8B ..M..,.G l..}.... >+[0C10] C9 1E 21 F5 E9 B2 42 95 68 28 AF C6 37 22 BA 30 ..!...B. h(..7".0 >+[0C20] 8D 53 FA 08 0D CE CA 81 61 0D 84 A5 2D 75 BD 41 .S...... a...-u.A >+[0C30] 85 4C 88 56 72 C6 B6 10 F8 34 CD B2 F4 5C 94 FA .L.Vr... .4...\.. >+[0C40] 80 90 82 A0 BD 68 EC 08 32 C3 B6 51 1E 3F 67 CB .....h.. 2..Q.?g. >+[0C50] 7B EB 70 83 84 D4 CB 52 55 36 61 1E 60 90 5B 6F {.p....R U6a.`.[o >+[0C60] FE 9A 62 05 CF 26 8E 65 E2 60 4B ED 63 B4 C4 E6 ..b..&.e .`K.c... >+[0C70] 44 B4 2F B0 B8 07 FE BE 0D 50 E4 56 A4 2E 0D 25 D./..... .P.V...% >+[0C80] 76 0B 0F 44 09 20 80 E5 C4 94 63 E0 54 46 1D AB v..D. .. ..c.TF.. >+[0C90] 5E 0B 09 93 B1 30 31 7B 04 DC 23 43 3B DB 7D 39 ^....01{ ..#C;.}9 >+[0CA0] 67 FE 9A 1F C1 08 AF 34 24 F6 74 E4 14 DA 34 8F g......4 $.t...4. >+[0CB0] 61 57 6A 7F 1D 4A 88 0A 90 78 93 F1 86 54 DB 22 aWj..J.. .x...T." >+[0CC0] 86 D6 69 0F DF 44 7C D3 6B 9D 41 63 50 98 3A 97 ..i..D|. k.AcP.:. >+[0CD0] B9 7B 4C 53 E3 85 73 9A C9 08 A0 75 12 50 02 87 .{LS..s. ...u.P.. >+[0CE0] B0 CF CC 84 84 D9 BC FC 94 79 AF 6A A6 08 FF 19 ........ .y.j.... >+[0CF0] 7E E9 22 9B EC 5C C1 6B 1D A4 B4 55 32 5E 23 C3 ~."..\.k ...U2^#. >+[0D00] C0 D4 8B 80 E6 67 B1 59 EB 9D 5D 9B AD C6 0E 7D .....g.Y ..]....} >+[0D10] E2 FE B1 24 8A B1 37 1E 60 7F 83 35 48 32 F7 03 ...$..7. `..5H2.. >+[0D20] E8 12 E6 21 7C 3D 21 7F 6B 14 31 9C 1A A3 4C 2B ...!|=!. k.1...L+ >+[0D30] 1C 5E EC 34 C1 2D DA 19 6C E6 6D 8D 60 D7 55 9E .^.4.-.. l.m.`.U. >+[0D40] E6 D0 B5 07 06 72 C0 E9 4E 91 94 6B 3E 0B F1 0A .....r.. N..k>... >+[0D50] 75 4D E8 CB 53 6B 34 A4 2F 96 A5 39 1A 18 6E 27 uM..Sk4. /..9..n' >+[0D60] 00 6D 41 B7 D8 F5 9A E5 01 FC 0B A8 97 56 EE 98 .mA..... .....V.. >+[0D70] 04 1D 98 84 5E 82 C8 E8 EC 17 D5 FA 96 00 3B E1 ....^... ......;. >+[0D80] 98 1C D8 FA 66 A0 DC 32 60 F6 03 46 08 3C E5 16 ....f..2 `..F.<.. >+[0D90] 6F F2 8B 4D 72 9F 0F E0 A9 71 6E 7C AE AA FB A3 o..Mr... .qn|.... >+[0DA0] 4D F1 A1 B6 1B 9F 62 71 E1 2C 82 9B AE E3 07 9B M.....bq .,...... >+[0DB0] 79 90 F1 C2 69 E5 7E CB 57 E6 C9 1C 4E A8 C7 12 y...i.~. W...N... >+[0DC0] EA 4F 4C 52 17 03 AB D4 FD 34 60 F4 7C BE 9E 36 .OLR.... .4`.|..6 >+[0DD0] 30 37 88 95 61 2E CF 70 AF 22 70 DB E8 AA 6E 3D 07..a..p ."p...n= >+[0DE0] 30 F7 4D 84 D5 00 00 00 00 00 00 00 01 00 00 00 0.M..... ........ >+[0DF0] 01 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 .....KTE ST.SAMBA >+[0E00] 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D .EXAMPLE .COM.... >+[0E10] 61 64 6D 69 6E 69 73 74 72 61 74 6F 72 00 00 00 administ rator... >+[0E20] 01 00 00 00 02 00 00 00 17 4B 54 45 53 54 2E 53 ........ .KTEST.S >+[0E30] 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D AMBA.EXA MPLE.COM >+[0E40] 00 00 00 04 63 69 66 73 00 00 00 0B 4C 4F 43 41 ....cifs ....LOCA >+[0E50] 4C 4B 54 45 53 54 36 00 17 00 00 00 10 1D C8 5E LKTEST6. .......^ >+[0E60] 46 48 82 F9 29 DB C6 A6 F1 72 6D 8D E9 4D 99 4F FH..)... .rm..M.O >+[0E70] 6A 4D 99 85 09 7D 44 0B 68 00 00 00 00 00 40 28 jM...}D. h.....@( >+[0E80] 00 00 00 00 00 00 00 00 00 00 00 00 03 FA 61 82 ........ ......a. >+[0E90] 03 F6 30 82 03 F2 A0 03 02 01 05 A1 19 1B 17 4B ..0..... .......K >+[0EA0] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[0EB0] 4C 45 2E 43 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 LE.COM.. 0....... >+[0EC0] 15 30 13 1B 04 63 69 66 73 1B 0B 4C 4F 43 41 4C .0...cif s..LOCAL >+[0ED0] 4B 54 45 53 54 36 A3 82 03 AE 30 82 03 AA A0 03 KTEST6.. ..0..... >+[0EE0] 02 01 17 A1 03 02 01 02 A2 82 03 9C 04 82 03 98 ........ ........ >+[0EF0] 66 D8 19 46 FA CB 73 2D CF 88 FD 4A EE 07 48 DA f..F..s- ...J..H. >+[0F00] 0E BC 58 30 43 40 A4 9C 00 0F 3B 17 C1 2D F5 9C ..X0C@.. ..;..-.. >+[0F10] 3E D9 2F 1D CA 01 9B D7 2E EC D7 70 ED 8B 8B 1B >./..... ...p.... >+[0F20] 5E F2 4E EE DD 0F C0 8D 61 E5 D7 0A 56 00 32 B1 ^.N..... a...V.2. >+[0F30] DB 91 37 29 0F 2F 85 EE A8 43 BA A5 B8 D4 19 74 ..7)./.. .C.....t >+[0F40] 33 F0 69 52 E1 58 98 83 D6 16 0B 44 A9 63 9B D4 3.iR.X.. ...D.c.. >+[0F50] 4E 6E A7 3E CD 9A 96 4D C4 96 F5 07 6D 29 B6 ED Nn.>...M ....m).. >+[0F60] 2A 62 3D 53 22 33 D1 95 E9 DF 74 4C 2A E2 29 AF *b=S"3.. ..tL*.). >+[0F70] 5B 69 B0 48 2D AD 94 FD A5 1D 54 D8 E2 5E C1 68 [i.H-... ..T..^.h >+[0F80] 6F BA 02 01 79 C3 C9 97 0B 76 66 45 E2 3B 10 17 o...y... .vfE.;.. >+[0F90] 95 40 46 E4 85 B9 87 BB CF CF 19 8C 3A C0 EA 38 .@F..... ....:..8 >+[0FA0] 3B B9 E9 4B 05 89 E5 27 8C 62 95 BC 0D 65 F0 D2 ;..K...' .b...e.. >+[0FB0] C0 5E BC 65 01 D5 0B CB 17 31 0F 06 49 4F A2 4A .^.e.... .1..IO.J >+[0FC0] 70 77 DB BD 92 5B 37 5C EC 06 DF C5 E2 31 C8 40 pw...[7\ .....1.@ >+[0FD0] 09 11 68 14 E7 7D CE 54 4F 52 61 31 2C 1C 53 52 ..h..}.T ORa1,.SR >+[0FE0] DB BE D8 95 39 EE 7D C6 CE C8 22 95 92 97 97 3D ....9.}. .."....= >+[0FF0] 5E 66 0F AD DC C2 4E 2E 2B 9F 63 20 30 DF B7 C1 ^f....N. +.c 0... >+[1000] D4 65 AA 6F 2D 10 24 07 20 8D 88 6E 4B 09 04 31 .e.o-.$. ..nK..1 >+[1010] B6 A3 EB F7 37 32 0E 0C 73 C6 F6 B8 4D D9 0C 4C ....72.. s...M..L >+[1020] 5B EC 10 6A 51 19 EA 3F FF 46 E7 73 16 A7 1F 33 [..jQ..? .F.s...3 >+[1030] 98 7C 9B AD 5A 23 A9 40 7C 0F DF EE 0F AA C7 E8 .|..Z#.@ |....... >+[1040] 63 07 98 3A 4A 0D 18 62 01 21 B2 AE A5 69 B0 C1 c..:J..b .!...i.. >+[1050] 15 51 BA 97 D2 C5 42 5B C5 30 38 18 A9 48 AB D7 .Q....B[ .08..H.. >+[1060] FC A1 BC 9F 71 E7 EA 18 54 42 DA D6 A4 FC C1 DC ....q... TB...... >+[1070] F3 12 30 62 AC 98 E1 7D 2B 34 1E 52 4C 26 67 32 ..0b...} +4.RL&g2 >+[1080] D9 44 1A 08 27 0E DA D0 FC 84 66 35 81 D6 EB 98 .D..'... ..f5.... >+[1090] 46 6F 1E 47 E0 14 31 BE 47 80 65 AA 0B 20 D6 33 Fo.G..1. G.e.. .3 >+[10A0] 36 3B 0D 40 2F 5A 2E 0E 01 BE 00 EB 33 3E 4B 32 6;.@/Z.. ....3>K2 >+[10B0] 91 F4 22 96 E5 5F D4 D5 92 94 CC 5B 59 6A 3E D2 ..".._.. ...[Yj>. >+[10C0] FB A0 4F 99 C4 07 8B 6F 2B 14 37 CD 37 44 C0 1F ..O....o +.7.7D.. >+[10D0] 80 9C 43 46 F2 5E F4 FE D3 39 70 61 BE 72 5B 3A ..CF.^.. .9pa.r[: >+[10E0] 8F 37 95 78 1E AB D9 E7 E9 DA FC 47 09 81 A0 0D .7.x.... ...G.... >+[10F0] 62 E1 F9 34 36 D1 DB E6 98 D8 F4 3E 77 5A 4D E2 b..46... ...>wZM. >+[1100] 5F 20 70 3D 3D 5B 34 D9 FD A8 31 F7 D9 59 F7 A3 _ p==[4. ..1..Y.. >+[1110] F0 66 F7 D9 AD 1C CD D5 85 33 A0 87 22 31 D4 F3 .f...... .3.."1.. >+[1120] 67 80 68 20 A2 90 72 7A 6F 64 FD 68 82 9E 91 B8 g.h ..rz od.h.... >+[1130] E3 F7 6D 6C 38 74 F0 96 A2 F6 25 D7 92 58 14 60 ..ml8t.. ..%..X.` >+[1140] 9F AE 01 4C 0C 09 67 3E 35 67 71 1E 2A 86 21 D3 ...L..g> 5gq.*.!. >+[1150] 60 61 98 16 94 67 0B 52 76 63 93 BD A3 3B A9 F0 `a...g.R vc...;.. >+[1160] A2 6A B7 E6 0F 35 64 DA 6A EA 20 A6 3D 94 71 59 .j...5d. j. .=.qY >+[1170] 5E CB B2 D3 F9 4D FE 1B 4B D8 64 C8 3B 7A A8 E6 ^....M.. K.d.;z.. >+[1180] D2 D5 76 71 26 D4 5C DA 1A 55 17 F2 16 C9 2F 77 ..vq&.\. .U..../w >+[1190] DB 95 19 48 A5 AC D0 C3 31 9C 0A CC 1B 44 11 6B ...H.... 1....D.k >+[11A0] 7C 88 7A 5D CF 6E 12 DA EF C5 C7 34 1D F4 CC EA |.z].n.. ...4.... >+[11B0] 37 24 4B B3 0F C1 A3 F2 29 A0 D8 93 39 C6 16 57 7$K..... )...9..W >+[11C0] D5 BF 57 BF 6C 7E F7 90 E0 EB A3 8B 07 56 9C EC ..W.l~.. .....V.. >+[11D0] 15 3E 21 DA A5 7C 00 3C F9 D2 A7 1C 6F 16 25 31 .>!..|.< ....o.%1 >+[11E0] C5 28 A7 EA F3 47 31 50 DD E1 ED 0A 93 DB 85 CC .(...G1P ........ >+[11F0] 6B 4B 2C 7F E8 F8 2D A9 6D 1D 0A 87 F2 10 8C 82 kK,...-. m....... >+[1200] 2F 9B D4 9B 92 8C 77 40 50 42 1E 42 C4 0A 4F E3 /.....w@ PB.B..O. >+[1210] 6C 6C DC 81 C4 1E BB F0 7D CF 3C 73 22 5B C3 1A ll...... }.<s"[.. >+[1220] 97 35 EE 3A CD 6D F3 68 A3 C5 65 7E E9 54 C0 E3 .5.:.m.h ..e~.T.. >+[1230] 7D 6A 32 4C D1 3E D0 78 4B BF 18 9F A5 25 4A 92 }j2L.>.x K....%J. >+[1240] 1E 6C 8F 01 D6 59 D7 CF 2E A0 CC 98 F6 75 28 2F .l...Y.. .....u(/ >+[1250] F7 2A 70 28 A9 45 1F 75 C2 4E 62 ED D8 C4 A0 8D .*p(.E.u .Nb..... >+[1260] 55 B2 84 1C A4 CE 87 EF 24 EE BC CE 40 09 EB 05 U....... $...@... >+[1270] 0B D1 14 31 50 32 2F B6 A8 97 17 4B A7 95 01 50 ...1P2/. ...K...P >+[1280] 6E 0E 23 49 9C 72 21 91 00 00 00 00 00 00 00 01 n.#I.r!. ........ >+[1290] 00 00 00 01 00 00 00 17 4B 54 45 53 54 2E 53 41 ........ KTEST.SA >+[12A0] 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 MBA.EXAM PLE.COM. >+[12B0] 00 00 0D 61 64 6D 69 6E 69 73 74 72 61 74 6F 72 ...admin istrator >+[12C0] 00 00 00 01 00 00 00 02 00 00 00 17 4B 54 45 53 ........ ....KTES >+[12D0] 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E T.SAMBA. EXAMPLE. >+[12E0] 43 4F 4D 00 00 00 04 63 69 66 73 00 00 00 0B 4C COM....c ifs....L >+[12F0] 4F 43 41 4C 4B 54 45 53 54 36 00 17 00 00 00 10 OCALKTES T6...... >+[1300] 1D C8 5E 46 48 82 F9 29 DB C6 A6 F1 72 6D 8D E9 ..^FH..) ....rm.. >+[1310] 4D 99 4F 6A 4D 99 85 09 7D 44 0B 68 00 00 00 00 M.OjM... }D.h.... >+[1320] 00 40 28 00 00 00 00 00 00 00 00 00 00 00 00 03 .@(..... ........ >+[1330] FA 61 82 03 F6 30 82 03 F2 A0 03 02 01 05 A1 19 .a...0.. ........ >+[1340] 1B 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 ..KTEST. SAMBA.EX >+[1350] 41 4D 50 4C 45 2E 43 4F 4D A2 1E 30 1C A0 03 02 AMPLE.CO M..0.... >+[1360] 01 01 A1 15 30 13 1B 04 63 69 66 73 1B 0B 4C 4F ....0... cifs..LO >+[1370] 43 41 4C 4B 54 45 53 54 36 A3 82 03 AE 30 82 03 CALKTEST 6....0.. >+[1380] AA A0 03 02 01 17 A1 03 02 01 02 A2 82 03 9C 04 ........ ........ >+[1390] 82 03 98 66 D8 19 46 FA CB 73 2D CF 88 FD 4A EE ...f..F. .s-...J. >+[13A0] 07 48 DA 0E BC 58 30 43 40 A4 9C 00 0F 3B 17 C1 .H...X0C @....;.. >+[13B0] 2D F5 9C 3E D9 2F 1D CA 01 9B D7 2E EC D7 70 ED -..>./.. ......p. >+[13C0] 8B 8B 1B 5E F2 4E EE DD 0F C0 8D 61 E5 D7 0A 56 ...^.N.. ...a...V >+[13D0] 00 32 B1 DB 91 37 29 0F 2F 85 EE A8 43 BA A5 B8 .2...7). /...C... >+[13E0] D4 19 74 33 F0 69 52 E1 58 98 83 D6 16 0B 44 A9 ..t3.iR. X.....D. >+[13F0] 63 9B D4 4E 6E A7 3E CD 9A 96 4D C4 96 F5 07 6D c..Nn.>. ..M....m >+[1400] 29 B6 ED 2A 62 3D 53 22 33 D1 95 E9 DF 74 4C 2A )..*b=S" 3....tL* >+[1410] E2 29 AF 5B 69 B0 48 2D AD 94 FD A5 1D 54 D8 E2 .).[i.H- .....T.. >+[1420] 5E C1 68 6F BA 02 01 79 C3 C9 97 0B 76 66 45 E2 ^.ho...y ....vfE. >+[1430] 3B 10 17 95 40 46 E4 85 B9 87 BB CF CF 19 8C 3A ;...@F.. .......: >+[1440] C0 EA 38 3B B9 E9 4B 05 89 E5 27 8C 62 95 BC 0D ..8;..K. ..'.b... >+[1450] 65 F0 D2 C0 5E BC 65 01 D5 0B CB 17 31 0F 06 49 e...^.e. ....1..I >+[1460] 4F A2 4A 70 77 DB BD 92 5B 37 5C EC 06 DF C5 E2 O.Jpw... [7\..... >+[1470] 31 C8 40 09 11 68 14 E7 7D CE 54 4F 52 61 31 2C 1.@..h.. }.TORa1, >+[1480] 1C 53 52 DB BE D8 95 39 EE 7D C6 CE C8 22 95 92 .SR....9 .}...".. >+[1490] 97 97 3D 5E 66 0F AD DC C2 4E 2E 2B 9F 63 20 30 ..=^f... .N.+.c 0 >+[14A0] DF B7 C1 D4 65 AA 6F 2D 10 24 07 20 8D 88 6E 4B ....e.o- .$. ..nK >+[14B0] 09 04 31 B6 A3 EB F7 37 32 0E 0C 73 C6 F6 B8 4D ..1....7 2..s...M >+[14C0] D9 0C 4C 5B EC 10 6A 51 19 EA 3F FF 46 E7 73 16 ..L[..jQ ..?.F.s. >+[14D0] A7 1F 33 98 7C 9B AD 5A 23 A9 40 7C 0F DF EE 0F ..3.|..Z #.@|.... >+[14E0] AA C7 E8 63 07 98 3A 4A 0D 18 62 01 21 B2 AE A5 ...c..:J ..b.!... >+[14F0] 69 B0 C1 15 51 BA 97 D2 C5 42 5B C5 30 38 18 A9 i...Q... .B[.08.. >+[1500] 48 AB D7 FC A1 BC 9F 71 E7 EA 18 54 42 DA D6 A4 H......q ...TB... >+[1510] FC C1 DC F3 12 30 62 AC 98 E1 7D 2B 34 1E 52 4C .....0b. ..}+4.RL >+[1520] 26 67 32 D9 44 1A 08 27 0E DA D0 FC 84 66 35 81 &g2.D..' .....f5. >+[1530] D6 EB 98 46 6F 1E 47 E0 14 31 BE 47 80 65 AA 0B ...Fo.G. .1.G.e.. >+[1540] 20 D6 33 36 3B 0D 40 2F 5A 2E 0E 01 BE 00 EB 33 .36;.@/ Z......3 >+[1550] 3E 4B 32 91 F4 22 96 E5 5F D4 D5 92 94 CC 5B 59 >K2..".. _.....[Y >+[1560] 6A 3E D2 FB A0 4F 99 C4 07 8B 6F 2B 14 37 CD 37 j>...O.. ..o+.7.7 >+[1570] 44 C0 1F 80 9C 43 46 F2 5E F4 FE D3 39 70 61 BE D....CF. ^...9pa. >+[1580] 72 5B 3A 8F 37 95 78 1E AB D9 E7 E9 DA FC 47 09 r[:.7.x. ......G. >+[1590] 81 A0 0D 62 E1 F9 34 36 D1 DB E6 98 D8 F4 3E 77 ...b..46 ......>w >+[15A0] 5A 4D E2 5F 20 70 3D 3D 5B 34 D9 FD A8 31 F7 D9 ZM._ p== [4...1.. >+[15B0] 59 F7 A3 F0 66 F7 D9 AD 1C CD D5 85 33 A0 87 22 Y...f... ....3.." >+[15C0] 31 D4 F3 67 80 68 20 A2 90 72 7A 6F 64 FD 68 82 1..g.h . .rzod.h. >+[15D0] 9E 91 B8 E3 F7 6D 6C 38 74 F0 96 A2 F6 25 D7 92 .....ml8 t....%.. >+[15E0] 58 14 60 9F AE 01 4C 0C 09 67 3E 35 67 71 1E 2A X.`...L. .g>5gq.* >+[15F0] 86 21 D3 60 61 98 16 94 67 0B 52 76 63 93 BD A3 .!.`a... g.Rvc... >+[1600] 3B A9 F0 A2 6A B7 E6 0F 35 64 DA 6A EA 20 A6 3D ;...j... 5d.j. .= >+[1610] 94 71 59 5E CB B2 D3 F9 4D FE 1B 4B D8 64 C8 3B .qY^.... M..K.d.; >+[1620] 7A A8 E6 D2 D5 76 71 26 D4 5C DA 1A 55 17 F2 16 z....vq& .\..U... >+[1630] C9 2F 77 DB 95 19 48 A5 AC D0 C3 31 9C 0A CC 1B ./w...H. ...1.... >+[1640] 44 11 6B 7C 88 7A 5D CF 6E 12 DA EF C5 C7 34 1D D.k|.z]. n.....4. >+[1650] F4 CC EA 37 24 4B B3 0F C1 A3 F2 29 A0 D8 93 39 ...7$K.. ...)...9 >+[1660] C6 16 57 D5 BF 57 BF 6C 7E F7 90 E0 EB A3 8B 07 ..W..W.l ~....... >+[1670] 56 9C EC 15 3E 21 DA A5 7C 00 3C F9 D2 A7 1C 6F V...>!.. |.<....o >+[1680] 16 25 31 C5 28 A7 EA F3 47 31 50 DD E1 ED 0A 93 .%1.(... G1P..... >+[1690] DB 85 CC 6B 4B 2C 7F E8 F8 2D A9 6D 1D 0A 87 F2 ...kK,.. .-.m.... >+[16A0] 10 8C 82 2F 9B D4 9B 92 8C 77 40 50 42 1E 42 C4 .../.... .w@PB.B. >+[16B0] 0A 4F E3 6C 6C DC 81 C4 1E BB F0 7D CF 3C 73 22 .O.ll... ...}.<s" >+[16C0] 5B C3 1A 97 35 EE 3A CD 6D F3 68 A3 C5 65 7E E9 [...5.:. m.h..e~. >+[16D0] 54 C0 E3 7D 6A 32 4C D1 3E D0 78 4B BF 18 9F A5 T..}j2L. >.xK.... >+[16E0] 25 4A 92 1E 6C 8F 01 D6 59 D7 CF 2E A0 CC 98 F6 %J..l... Y....... >+[16F0] 75 28 2F F7 2A 70 28 A9 45 1F 75 C2 4E 62 ED D8 u(/.*p(. E.u.Nb.. >+[1700] C4 A0 8D 55 B2 84 1C A4 CE 87 EF 24 EE BC CE 40 ...U.... ...$...@ >+[1710] 09 EB 05 0B D1 14 31 50 32 2F B6 A8 97 17 4B A7 ......1P 2/....K. >+[1720] 95 01 50 6E 0E 23 49 9C 72 21 91 00 00 00 00 00 ..Pn.#I. r!...... >+[1730] 00 00 01 00 00 00 01 00 00 00 17 4B 54 45 53 54 ........ ...KTEST >+[1740] 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 .SAMBA.E XAMPLE.C >+[1750] 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 73 74 72 61 OM....ad ministra >+[1760] 74 6F 72 00 00 00 01 00 00 00 02 00 00 00 17 4B tor..... .......K >+[1770] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[1780] 4C 45 2E 43 4F 4D 00 00 00 04 63 69 66 73 00 00 LE.COM.. ..cifs.. >+[1790] 00 0B 4C 4F 43 41 4C 4B 54 45 53 54 36 00 17 00 ..LOCALK TEST6... >+[17A0] 00 00 10 1D C8 5E 46 48 82 F9 29 DB C6 A6 F1 72 .....^FH ..)....r >+[17B0] 6D 8D E9 4D 99 4F 6A 4D 99 85 09 7D 44 0B 68 00 m..M.OjM ...}D.h. >+[17C0] 00 00 00 00 40 28 00 00 00 00 00 00 00 00 00 00 ....@(.. ........ >+[17D0] 00 00 03 FA 61 82 03 F6 30 82 03 F2 A0 03 02 01 ....a... 0....... >+[17E0] 05 A1 19 1B 17 4B 54 45 53 54 2E 53 41 4D 42 41 .....KTE ST.SAMBA >+[17F0] 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D A2 1E 30 1C .EXAMPLE .COM..0. >+[1800] A0 03 02 01 01 A1 15 30 13 1B 04 63 69 66 73 1B .......0 ...cifs. >+[1810] 0B 4C 4F 43 41 4C 4B 54 45 53 54 36 A3 82 03 AE .LOCALKT EST6.... >+[1820] 30 82 03 AA A0 03 02 01 17 A1 03 02 01 02 A2 82 0....... ........ >+[1830] 03 9C 04 82 03 98 66 D8 19 46 FA CB 73 2D CF 88 ......f. .F..s-.. >+[1840] FD 4A EE 07 48 DA 0E BC 58 30 43 40 A4 9C 00 0F .J..H... X0C@.... >+[1850] 3B 17 C1 2D F5 9C 3E D9 2F 1D CA 01 9B D7 2E EC ;..-..>. /....... >+[1860] D7 70 ED 8B 8B 1B 5E F2 4E EE DD 0F C0 8D 61 E5 .p....^. N.....a. >+[1870] D7 0A 56 00 32 B1 DB 91 37 29 0F 2F 85 EE A8 43 ..V.2... 7)./...C >+[1880] BA A5 B8 D4 19 74 33 F0 69 52 E1 58 98 83 D6 16 .....t3. iR.X.... >+[1890] 0B 44 A9 63 9B D4 4E 6E A7 3E CD 9A 96 4D C4 96 .D.c..Nn .>...M.. >+[18A0] F5 07 6D 29 B6 ED 2A 62 3D 53 22 33 D1 95 E9 DF ..m)..*b =S"3.... >+[18B0] 74 4C 2A E2 29 AF 5B 69 B0 48 2D AD 94 FD A5 1D tL*.).[i .H-..... >+[18C0] 54 D8 E2 5E C1 68 6F BA 02 01 79 C3 C9 97 0B 76 T..^.ho. ..y....v >+[18D0] 66 45 E2 3B 10 17 95 40 46 E4 85 B9 87 BB CF CF fE.;...@ F....... >+[18E0] 19 8C 3A C0 EA 38 3B B9 E9 4B 05 89 E5 27 8C 62 ..:..8;. .K...'.b >+[18F0] 95 BC 0D 65 F0 D2 C0 5E BC 65 01 D5 0B CB 17 31 ...e...^ .e.....1 >+[1900] 0F 06 49 4F A2 4A 70 77 DB BD 92 5B 37 5C EC 06 ..IO.Jpw ...[7\.. >+[1910] DF C5 E2 31 C8 40 09 11 68 14 E7 7D CE 54 4F 52 ...1.@.. h..}.TOR >+[1920] 61 31 2C 1C 53 52 DB BE D8 95 39 EE 7D C6 CE C8 a1,.SR.. ..9.}... >+[1930] 22 95 92 97 97 3D 5E 66 0F AD DC C2 4E 2E 2B 9F "....=^f ....N.+. >+[1940] 63 20 30 DF B7 C1 D4 65 AA 6F 2D 10 24 07 20 8D c 0....e .o-.$. . >+[1950] 88 6E 4B 09 04 31 B6 A3 EB F7 37 32 0E 0C 73 C6 .nK..1.. ..72..s. >+[1960] F6 B8 4D D9 0C 4C 5B EC 10 6A 51 19 EA 3F FF 46 ..M..L[. .jQ..?.F >+[1970] E7 73 16 A7 1F 33 98 7C 9B AD 5A 23 A9 40 7C 0F .s...3.| ..Z#.@|. >+[1980] DF EE 0F AA C7 E8 63 07 98 3A 4A 0D 18 62 01 21 ......c. .:J..b.! >+[1990] B2 AE A5 69 B0 C1 15 51 BA 97 D2 C5 42 5B C5 30 ...i...Q ....B[.0 >+[19A0] 38 18 A9 48 AB D7 FC A1 BC 9F 71 E7 EA 18 54 42 8..H.... ..q...TB >+[19B0] DA D6 A4 FC C1 DC F3 12 30 62 AC 98 E1 7D 2B 34 ........ 0b...}+4 >+[19C0] 1E 52 4C 26 67 32 D9 44 1A 08 27 0E DA D0 FC 84 .RL&g2.D ..'..... >+[19D0] 66 35 81 D6 EB 98 46 6F 1E 47 E0 14 31 BE 47 80 f5....Fo .G..1.G. >+[19E0] 65 AA 0B 20 D6 33 36 3B 0D 40 2F 5A 2E 0E 01 BE e.. .36; .@/Z.... >+[19F0] 00 EB 33 3E 4B 32 91 F4 22 96 E5 5F D4 D5 92 94 ..3>K2.. ".._.... >+[1A00] CC 5B 59 6A 3E D2 FB A0 4F 99 C4 07 8B 6F 2B 14 .[Yj>... O....o+. >+[1A10] 37 CD 37 44 C0 1F 80 9C 43 46 F2 5E F4 FE D3 39 7.7D.... CF.^...9 >+[1A20] 70 61 BE 72 5B 3A 8F 37 95 78 1E AB D9 E7 E9 DA pa.r[:.7 .x...... >+[1A30] FC 47 09 81 A0 0D 62 E1 F9 34 36 D1 DB E6 98 D8 .G....b. .46..... >+[1A40] F4 3E 77 5A 4D E2 5F 20 70 3D 3D 5B 34 D9 FD A8 .>wZM._ p==[4... >+[1A50] 31 F7 D9 59 F7 A3 F0 66 F7 D9 AD 1C CD D5 85 33 1..Y...f .......3 >+[1A60] A0 87 22 31 D4 F3 67 80 68 20 A2 90 72 7A 6F 64 .."1..g. h ..rzod >+[1A70] FD 68 82 9E 91 B8 E3 F7 6D 6C 38 74 F0 96 A2 F6 .h...... ml8t.... >+[1A80] 25 D7 92 58 14 60 9F AE 01 4C 0C 09 67 3E 35 67 %..X.`.. .L..g>5g >+[1A90] 71 1E 2A 86 21 D3 60 61 98 16 94 67 0B 52 76 63 q.*.!.`a ...g.Rvc >+[1AA0] 93 BD A3 3B A9 F0 A2 6A B7 E6 0F 35 64 DA 6A EA ...;...j ...5d.j. >+[1AB0] 20 A6 3D 94 71 59 5E CB B2 D3 F9 4D FE 1B 4B D8 .=.qY^. ...M..K. >+[1AC0] 64 C8 3B 7A A8 E6 D2 D5 76 71 26 D4 5C DA 1A 55 d.;z.... vq&.\..U >+[1AD0] 17 F2 16 C9 2F 77 DB 95 19 48 A5 AC D0 C3 31 9C ..../w.. .H....1. >+[1AE0] 0A CC 1B 44 11 6B 7C 88 7A 5D CF 6E 12 DA EF C5 ...D.k|. z].n.... >+[1AF0] C7 34 1D F4 CC EA 37 24 4B B3 0F C1 A3 F2 29 A0 .4....7$ K.....). >+[1B00] D8 93 39 C6 16 57 D5 BF 57 BF 6C 7E F7 90 E0 EB ..9..W.. W.l~.... >+[1B10] A3 8B 07 56 9C EC 15 3E 21 DA A5 7C 00 3C F9 D2 ...V...> !..|.<.. >+[1B20] A7 1C 6F 16 25 31 C5 28 A7 EA F3 47 31 50 DD E1 ..o.%1.( ...G1P.. >+[1B30] ED 0A 93 DB 85 CC 6B 4B 2C 7F E8 F8 2D A9 6D 1D ......kK ,...-.m. >+[1B40] 0A 87 F2 10 8C 82 2F 9B D4 9B 92 8C 77 40 50 42 ....../. ....w@PB >+[1B50] 1E 42 C4 0A 4F E3 6C 6C DC 81 C4 1E BB F0 7D CF .B..O.ll ......}. >+[1B60] 3C 73 22 5B C3 1A 97 35 EE 3A CD 6D F3 68 A3 C5 <s"[...5 .:.m.h.. >+[1B70] 65 7E E9 54 C0 E3 7D 6A 32 4C D1 3E D0 78 4B BF e~.T..}j 2L.>.xK. >+[1B80] 18 9F A5 25 4A 92 1E 6C 8F 01 D6 59 D7 CF 2E A0 ...%J..l ...Y.... >+[1B90] CC 98 F6 75 28 2F F7 2A 70 28 A9 45 1F 75 C2 4E ...u(/.* p(.E.u.N >+[1BA0] 62 ED D8 C4 A0 8D 55 B2 84 1C A4 CE 87 EF 24 EE b.....U. ......$. >+[1BB0] BC CE 40 09 EB 05 0B D1 14 31 50 32 2F B6 A8 97 ..@..... .1P2/... >+[1BC0] 17 4B A7 95 01 50 6E 0E 23 49 9C 72 21 91 00 00 .K...Pn. #I.r!... >+[1BD0] 00 00 00 00 00 01 00 00 00 01 00 00 00 17 4B 54 ........ ......KT >+[1BE0] 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C EST.SAMB A.EXAMPL >+[1BF0] 45 2E 43 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 73 E.COM... .adminis >+[1C00] 74 72 61 74 6F 72 00 00 00 01 00 00 00 02 00 00 trator.. ........ >+[1C10] 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 ..KTEST. SAMBA.EX >+[1C20] 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 04 63 69 66 AMPLE.CO M....cif >+[1C30] 73 00 00 00 0B 4C 4F 43 41 4C 4B 54 45 53 54 36 s....LOC ALKTEST6 >+[1C40] 00 17 00 00 00 10 1D C8 5E 46 48 82 F9 29 DB C6 ........ ^FH..).. >+[1C50] A6 F1 72 6D 8D E9 4D 99 4F 6A 4D 99 85 09 7D 44 ..rm..M. OjM...}D >+[1C60] 0B 68 00 00 00 00 00 40 28 00 00 00 00 00 00 00 .h.....@ (....... >+[1C70] 00 00 00 00 00 03 FA 61 82 03 F6 30 82 03 F2 A0 .......a ...0.... >+[1C80] 03 02 01 05 A1 19 1B 17 4B 54 45 53 54 2E 53 41 ........ KTEST.SA >+[1C90] 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D A2 MBA.EXAM PLE.COM. >+[1CA0] 1E 30 1C A0 03 02 01 01 A1 15 30 13 1B 04 63 69 .0...... ..0...ci >+[1CB0] 66 73 1B 0B 4C 4F 43 41 4C 4B 54 45 53 54 36 A3 fs..LOCA LKTEST6. >+[1CC0] 82 03 AE 30 82 03 AA A0 03 02 01 17 A1 03 02 01 ...0.... ........ >+[1CD0] 02 A2 82 03 9C 04 82 03 98 66 D8 19 46 FA CB 73 ........ .f..F..s >+[1CE0] 2D CF 88 FD 4A EE 07 48 DA 0E BC 58 30 43 40 A4 -...J..H ...X0C@. >+[1CF0] 9C 00 0F 3B 17 C1 2D F5 9C 3E D9 2F 1D CA 01 9B ...;..-. .>./.... >+[1D00] D7 2E EC D7 70 ED 8B 8B 1B 5E F2 4E EE DD 0F C0 ....p... .^.N.... >+[1D10] 8D 61 E5 D7 0A 56 00 32 B1 DB 91 37 29 0F 2F 85 .a...V.2 ...7)./. >+[1D20] EE A8 43 BA A5 B8 D4 19 74 33 F0 69 52 E1 58 98 ..C..... t3.iR.X. >+[1D30] 83 D6 16 0B 44 A9 63 9B D4 4E 6E A7 3E CD 9A 96 ....D.c. .Nn.>... >+[1D40] 4D C4 96 F5 07 6D 29 B6 ED 2A 62 3D 53 22 33 D1 M....m). .*b=S"3. >+[1D50] 95 E9 DF 74 4C 2A E2 29 AF 5B 69 B0 48 2D AD 94 ...tL*.) .[i.H-.. >+[1D60] FD A5 1D 54 D8 E2 5E C1 68 6F BA 02 01 79 C3 C9 ...T..^. ho...y.. >+[1D70] 97 0B 76 66 45 E2 3B 10 17 95 40 46 E4 85 B9 87 ..vfE.;. ..@F.... >+[1D80] BB CF CF 19 8C 3A C0 EA 38 3B B9 E9 4B 05 89 E5 .....:.. 8;..K... >+[1D90] 27 8C 62 95 BC 0D 65 F0 D2 C0 5E BC 65 01 D5 0B '.b...e. ..^.e... >+[1DA0] CB 17 31 0F 06 49 4F A2 4A 70 77 DB BD 92 5B 37 ..1..IO. Jpw...[7 >+[1DB0] 5C EC 06 DF C5 E2 31 C8 40 09 11 68 14 E7 7D CE \.....1. @..h..}. >+[1DC0] 54 4F 52 61 31 2C 1C 53 52 DB BE D8 95 39 EE 7D TORa1,.S R....9.} >+[1DD0] C6 CE C8 22 95 92 97 97 3D 5E 66 0F AD DC C2 4E ...".... =^f....N >+[1DE0] 2E 2B 9F 63 20 30 DF B7 C1 D4 65 AA 6F 2D 10 24 .+.c 0.. ..e.o-.$ >+[1DF0] 07 20 8D 88 6E 4B 09 04 31 B6 A3 EB F7 37 32 0E . ..nK.. 1....72. >+[1E00] 0C 73 C6 F6 B8 4D D9 0C 4C 5B EC 10 6A 51 19 EA .s...M.. L[..jQ.. >+[1E10] 3F FF 46 E7 73 16 A7 1F 33 98 7C 9B AD 5A 23 A9 ?.F.s... 3.|..Z#. >+[1E20] 40 7C 0F DF EE 0F AA C7 E8 63 07 98 3A 4A 0D 18 @|...... .c..:J.. >+[1E30] 62 01 21 B2 AE A5 69 B0 C1 15 51 BA 97 D2 C5 42 b.!...i. ..Q....B >+[1E40] 5B C5 30 38 18 A9 48 AB D7 FC A1 BC 9F 71 E7 EA [.08..H. .....q.. >+[1E50] 18 54 42 DA D6 A4 FC C1 DC F3 12 30 62 AC 98 E1 .TB..... ...0b... >+[1E60] 7D 2B 34 1E 52 4C 26 67 32 D9 44 1A 08 27 0E DA }+4.RL&g 2.D..'.. >+[1E70] D0 FC 84 66 35 81 D6 EB 98 46 6F 1E 47 E0 14 31 ...f5... .Fo.G..1 >+[1E80] BE 47 80 65 AA 0B 20 D6 33 36 3B 0D 40 2F 5A 2E .G.e.. . 36;.@/Z. >+[1E90] 0E 01 BE 00 EB 33 3E 4B 32 91 F4 22 96 E5 5F D4 .....3>K 2..".._. >+[1EA0] D5 92 94 CC 5B 59 6A 3E D2 FB A0 4F 99 C4 07 8B ....[Yj> ...O.... >+[1EB0] 6F 2B 14 37 CD 37 44 C0 1F 80 9C 43 46 F2 5E F4 o+.7.7D. ...CF.^. >+[1EC0] FE D3 39 70 61 BE 72 5B 3A 8F 37 95 78 1E AB D9 ..9pa.r[ :.7.x... >+[1ED0] E7 E9 DA FC 47 09 81 A0 0D 62 E1 F9 34 36 D1 DB ....G... .b..46.. >+[1EE0] E6 98 D8 F4 3E 77 5A 4D E2 5F 20 70 3D 3D 5B 34 ....>wZM ._ p==[4 >+[1EF0] D9 FD A8 31 F7 D9 59 F7 A3 F0 66 F7 D9 AD 1C CD ...1..Y. ..f..... >+[1F00] D5 85 33 A0 87 22 31 D4 F3 67 80 68 20 A2 90 72 ..3.."1. .g.h ..r >+[1F10] 7A 6F 64 FD 68 82 9E 91 B8 E3 F7 6D 6C 38 74 F0 zod.h... ...ml8t. >+[1F20] 96 A2 F6 25 D7 92 58 14 60 9F AE 01 4C 0C 09 67 ...%..X. `...L..g >+[1F30] 3E 35 67 71 1E 2A 86 21 D3 60 61 98 16 94 67 0B >5gq.*.! .`a...g. >+[1F40] 52 76 63 93 BD A3 3B A9 F0 A2 6A B7 E6 0F 35 64 Rvc...;. ..j...5d >+[1F50] DA 6A EA 20 A6 3D 94 71 59 5E CB B2 D3 F9 4D FE .j. .=.q Y^....M. >+[1F60] 1B 4B D8 64 C8 3B 7A A8 E6 D2 D5 76 71 26 D4 5C .K.d.;z. ...vq&.\ >+[1F70] DA 1A 55 17 F2 16 C9 2F 77 DB 95 19 48 A5 AC D0 ..U..../ w...H... >+[1F80] C3 31 9C 0A CC 1B 44 11 6B 7C 88 7A 5D CF 6E 12 .1....D. k|.z].n. >+[1F90] DA EF C5 C7 34 1D F4 CC EA 37 24 4B B3 0F C1 A3 ....4... .7$K.... >+[1FA0] F2 29 A0 D8 93 39 C6 16 57 D5 BF 57 BF 6C 7E F7 .)...9.. W..W.l~. >+[1FB0] 90 E0 EB A3 8B 07 56 9C EC 15 3E 21 DA A5 7C 00 ......V. ..>!..|. >+[1FC0] 3C F9 D2 A7 1C 6F 16 25 31 C5 28 A7 EA F3 47 31 <....o.% 1.(...G1 >+[1FD0] 50 DD E1 ED 0A 93 DB 85 CC 6B 4B 2C 7F E8 F8 2D P....... .kK,...- >+[1FE0] A9 6D 1D 0A 87 F2 10 8C 82 2F 9B D4 9B 92 8C 77 .m...... ./.....w >+[1FF0] 40 50 42 1E 42 C4 0A 4F E3 6C 6C DC 81 C4 1E BB @PB.B..O .ll..... >+[2000] F0 7D CF 3C 73 22 5B C3 1A 97 35 EE 3A CD 6D F3 .}.<s"[. ..5.:.m. >+[2010] 68 A3 C5 65 7E E9 54 C0 E3 7D 6A 32 4C D1 3E D0 h..e~.T. .}j2L.>. >+[2020] 78 4B BF 18 9F A5 25 4A 92 1E 6C 8F 01 D6 59 D7 xK....%J ..l...Y. >+[2030] CF 2E A0 CC 98 F6 75 28 2F F7 2A 70 28 A9 45 1F ......u( /.*p(.E. >+[2040] 75 C2 4E 62 ED D8 C4 A0 8D 55 B2 84 1C A4 CE 87 u.Nb.... .U...... >+[2050] EF 24 EE BC CE 40 09 EB 05 0B D1 14 31 50 32 2F .$...@.. ....1P2/ >+[2060] B6 A8 97 17 4B A7 95 01 50 6E 0E 23 49 9C 72 21 ....K... Pn.#I.r! >+[2070] 91 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 ........ ........ >+[2080] 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 .KTEST.S AMBA.EXA >+[2090] 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D 61 64 6D 69 MPLE.COM ....admi >+[20A0] 6E 69 73 74 72 61 74 6F 72 00 00 00 01 00 00 00 nistrato r....... >+[20B0] 02 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 .....KTE ST.SAMBA >+[20C0] 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 04 .EXAMPLE .COM.... >+[20D0] 68 6F 73 74 00 00 00 0B 6C 6F 63 61 6C 6B 74 65 host.... localkte >+[20E0] 73 74 36 00 17 00 00 00 10 72 47 04 38 B6 E6 F0 st6..... .rG.8... >+[20F0] 44 9E 9F 27 66 E1 69 9C 9A 4D 99 4F 6A 4D 99 90 D..'f.i. .M.OjM.. >+[2100] F5 7D 44 0B 68 00 00 00 00 00 40 28 00 00 00 00 .}D.h... ..@(.... >+[2110] 00 00 00 00 00 00 00 00 03 FA 61 82 03 F6 30 82 ........ ..a...0. >+[2120] 03 F2 A0 03 02 01 05 A1 19 1B 17 4B 54 45 53 54 ........ ...KTEST >+[2130] 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 .SAMBA.E XAMPLE.C >+[2140] 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 15 30 13 1B OM..0... .....0.. >+[2150] 04 68 6F 73 74 1B 0B 6C 6F 63 61 6C 6B 74 65 73 .host..l ocalktes >+[2160] 74 36 A3 82 03 AE 30 82 03 AA A0 03 02 01 17 A1 t6....0. ........ >+[2170] 03 02 01 02 A2 82 03 9C 04 82 03 98 58 95 95 EB ........ ....X... >+[2180] CB 8F 68 D4 77 43 0F 3B 44 B4 15 DA 40 6D FD E9 ..h.wC.; D...@m.. >+[2190] 85 D3 2F CD B5 1E 96 CD F6 E9 67 91 36 08 9E B4 ../..... ..g.6... >+[21A0] B3 47 70 7A B3 4E 82 5A 4F 8E 4B F5 8D 04 E4 5C .Gpz.N.Z O.K....\ >+[21B0] C4 D8 0C AF 08 25 F9 C1 64 B2 3A 35 26 E9 B2 72 .....%.. d.:5&..r >+[21C0] 66 B5 E9 81 FC BE 12 1B CC 8A A5 82 31 F6 7F C3 f....... ....1... >+[21D0] 5A 19 A3 31 F2 99 14 1E 64 E4 41 E8 C7 C3 F3 DF Z..1.... d.A..... >+[21E0] F5 65 7D B0 9F DC 5D 25 1D 1A A8 EA AA 88 6D F4 .e}...]% ......m. >+[21F0] 7C 25 9F 53 F6 A6 8F B1 24 AF 98 FE 53 7B 35 3C |%.S.... $...S{5< >+[2200] DB EC 7F 09 74 E9 C4 8D 20 B4 47 08 0E 32 B8 C9 ....t... .G..2.. >+[2210] 45 27 12 F9 8E F5 D6 C2 DD 1A 96 0E 68 5F 39 65 E'...... ....h_9e >+[2220] 72 C7 BD 8E 04 0E 13 E1 03 27 AC 50 80 76 E6 7A r....... .'.P.v.z >+[2230] 8E F4 C2 72 4F 68 B3 34 00 A9 54 41 DA FD 96 94 ...rOh.4 ..TA.... >+[2240] 29 A1 59 15 2F DB 6C 94 85 49 C5 D0 6D 48 B0 C4 ).Y./.l. .I..mH.. >+[2250] 65 D0 95 1D DB 3D 25 D0 75 50 D4 CF FA 2F 71 57 e....=%. uP.../qW >+[2260] BD 6C 1C 59 E1 C3 5B C7 24 95 FF B0 20 EF 6A DB .l.Y..[. $... .j. >+[2270] 79 87 67 91 94 E9 16 E2 BB 74 7A 08 E1 6A 36 5F y.g..... .tz..j6_ >+[2280] DF 11 AB 35 9B 3E 32 48 83 89 41 4E 06 BF F9 BB ...5.>2H ..AN.... >+[2290] EC E4 D7 6D 77 C4 55 22 DF F7 91 4D CB C5 01 A5 ...mw.U" ...M.... >+[22A0] BA 2D 1E 92 76 04 E8 02 2F 5E AF 1C B3 B7 A6 FB .-..v... /^...... >+[22B0] 3A 9F D9 7C 6D DA B4 8F 31 00 A5 30 F2 76 72 9B :..|m... 1..0.vr. >+[22C0] 62 97 E0 56 E5 E4 C7 6B 8B FC 84 75 57 66 6E D7 b..V...k ...uWfn. >+[22D0] B7 41 6F 61 F4 5B 0F 87 68 F6 54 02 26 1B 1F B7 .Aoa.[.. h.T.&... >+[22E0] 60 D6 E7 FA 4F C7 DB 35 58 EC 13 21 D4 C6 A1 27 `...O..5 X..!...' >+[22F0] BA E7 82 DF 29 FB 9D 5D E8 35 28 C9 9C 4E D7 BE ....)..] .5(..N.. >+[2300] 2F 6D F1 E8 0B 5A 74 C9 93 9F AD 42 24 4B B7 3B /m...Zt. ...B$K.; >+[2310] 38 2A 11 CF F0 BD 85 40 48 D8 9D E7 6B 65 70 42 8*.....@ H...kepB >+[2320] 60 DA 9B 65 CB C8 C5 D7 40 3A 12 DC 64 AF 82 54 `..e.... @:..d..T >+[2330] 34 05 38 4F C6 FB 38 E2 73 A9 89 B7 FC 33 15 85 4.8O..8. s....3.. >+[2340] 9E CA E9 E0 89 18 18 84 02 65 B4 74 5B D4 A1 6F ........ .e.t[..o >+[2350] 5F 79 20 CB D7 36 C8 6D 5B 1E 5E 0C 82 16 9F CC _y ..6.m [.^..... >+[2360] 5A 1E 57 C1 B6 94 51 87 A1 3D 12 D4 8B FE 0F 93 Z.W...Q. .=...... >+[2370] ED 53 A3 F4 88 3C 35 05 89 FE AF 0B 36 62 E3 2F .S...<5. ....6b./ >+[2380] 5C 4A 0E 07 67 39 A3 8E C0 45 07 7F 73 32 BC DE \J..g9.. .E..s2.. >+[2390] 2D 00 8B 47 79 3D 1C A1 90 AE B6 8F 83 B2 1B 31 -..Gy=.. .......1 >+[23A0] EE E4 F2 C5 C1 4A E2 4A 2F 28 F0 AA 19 43 6A 14 .....J.J /(...Cj. >+[23B0] B1 42 61 90 34 2E EE 3D 16 9F 5D 9F 7A A2 01 7A .Ba.4..= ..].z..z >+[23C0] 4B 96 FA 4D C9 85 1A 75 27 B7 6B FD 4D 7D 9C 65 K..M...u '.k.M}.e >+[23D0] 97 DB 05 CC 76 68 EA 05 5D 5D BB BD 51 4B 5B F2 ....vh.. ]]..QK[. >+[23E0] 48 59 BD 1E AD 56 D4 69 A5 75 CD ED EC B1 3E AB HY...V.i .u....>. >+[23F0] FA B7 F8 8D 4F BE 95 63 38 1C 4C 70 26 C4 3A 21 ....O..c 8.Lp&.:! >+[2400] 80 61 05 3A D4 E2 28 2C 85 01 5A DA FC 10 60 F3 .a.:..(, ..Z...`. >+[2410] 74 0C FD DB 2F 5B 25 4B 14 E4 7D 8A DB 85 12 D2 t.../[%K ..}..... >+[2420] D7 69 CD B5 B1 93 CE E5 E6 4D 57 D3 C2 D3 2E A0 .i...... .MW..... >+[2430] 08 37 09 CD 19 99 09 FA 33 68 4A E0 92 46 21 0C .7...... 3hJ..F!. >+[2440] 99 9F DA 05 15 20 8B 3D 7C 7B CA D6 81 AC AA 83 ..... .= |{...... >+[2450] 48 C8 24 4C C8 FC A5 14 2C BC 49 1A 1C 49 61 1D H.$L.... ,.I..Ia. >+[2460] 24 86 42 B1 37 6A C8 3A AC 18 CC C0 50 84 12 48 $.B.7j.: ....P..H >+[2470] 8B 29 0A 49 26 A4 E2 B9 E5 96 E7 37 C3 DE 4C 23 .).I&... ...7..L# >+[2480] D2 D4 62 14 8F 1E 72 39 CF 03 BC A3 00 C7 63 51 ..b...r9 ......cQ >+[2490] A9 6B E4 3E B2 65 A1 A2 BB EC 06 41 85 50 22 02 .k.>.e.. ...A.P". >+[24A0] 46 2F 72 2B 32 1A A4 2D 85 94 02 47 69 8D AD 6D F/r+2..- ...Gi..m >+[24B0] 66 AB D4 E4 29 C8 C7 DA F4 18 31 2A DF 50 6A 05 f...)... ..1*.Pj. >+[24C0] D6 47 26 C4 F9 87 0F 35 24 6E 72 D6 23 7D 3A 94 .G&....5 $nr.#}:. >+[24D0] 14 8D E8 57 AA BA D7 CF A9 2D E7 4C 10 7C D8 0D ...W.... .-.L.|.. >+[24E0] 51 30 1F E1 FB E5 E2 6C EE AA 65 2F D8 22 05 67 Q0.....l ..e/.".g >+[24F0] 87 4D 4D D2 11 3D B4 1E AA 20 3F 76 E3 94 93 6D .MM..=.. . ?v...m >+[2500] AC 10 05 AF 09 BD 67 86 C5 83 93 D6 1C D3 81 D9 ......g. ........ >+[2510] B1 3B E1 76 00 00 00 00 00 00 00 01 00 00 00 01 .;.v.... ........ >+[2520] 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E ....KTES T.SAMBA. >+[2530] 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D 61 EXAMPLE. COM....a >+[2540] 64 6D 69 6E 69 73 74 72 61 74 6F 72 00 00 00 01 dministr ator.... >+[2550] 00 00 00 02 00 00 00 17 4B 54 45 53 54 2E 53 41 ........ KTEST.SA >+[2560] 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 MBA.EXAM PLE.COM. >+[2570] 00 00 04 68 6F 73 74 00 00 00 0B 4C 4F 43 41 4C ...host. ...LOCAL >+[2580] 4B 54 45 53 54 36 00 17 00 00 00 10 55 6E 3E FC KTEST6.. ....Un>. >+[2590] E2 F4 40 51 19 E6 6E EB 23 4C 48 8E 4D 99 4F 6A ..@Q..n. #LH.M.Oj >+[25A0] 4D 99 90 FC 7D 44 0B 68 00 00 00 00 00 40 28 00 M...}D.h .....@(. >+[25B0] 00 00 00 00 00 00 00 00 00 00 00 03 FA 61 82 03 ........ .....a.. >+[25C0] F6 30 82 03 F2 A0 03 02 01 05 A1 19 1B 17 4B 54 .0...... ......KT >+[25D0] 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C EST.SAMB A.EXAMPL >+[25E0] 45 2E 43 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 15 E.COM..0 ........ >+[25F0] 30 13 1B 04 68 6F 73 74 1B 0B 4C 4F 43 41 4C 4B 0...host ..LOCALK >+[2600] 54 45 53 54 36 A3 82 03 AE 30 82 03 AA A0 03 02 TEST6... .0...... >+[2610] 01 17 A1 03 02 01 02 A2 82 03 9C 04 82 03 98 6E ........ .......n >+[2620] 87 B7 7B 3A 7E EF 4A 1B 29 C9 E3 C4 1F 42 4F 0E ..{:~.J. )....BO. >+[2630] C8 AC AC 4E A2 77 1D DA 93 37 F1 AF DA A3 75 2D ...N.w.. .7....u- >+[2640] 12 8B 40 34 23 0E 8E A9 90 58 46 42 42 39 31 D6 ..@4#... .XFBB91. >+[2650] 03 9E 5D 81 D9 E8 F6 08 2B D9 96 88 8A 2F F1 CC ..]..... +..../.. >+[2660] F2 EA 9E 9A 4B 31 B6 04 2D 3D 4C 7F 92 DE 3B 04 ....K1.. -=L...;. >+[2670] 19 EE 28 D0 83 81 C3 46 CD 74 23 4C 14 34 DE 62 ..(....F .t#L.4.b >+[2680] 0A AC E5 12 16 75 E9 A8 4B 32 78 CC 8D AE A2 E5 .....u.. K2x..... >+[2690] 6D E8 09 70 76 52 F5 E5 18 F7 E7 91 15 6A 69 AB m..pvR.. .....ji. >+[26A0] B8 62 DD 80 F5 28 6D DF ED 10 DA AC FB 92 27 CF .b...(m. ......'. >+[26B0] 98 B5 77 9D A5 96 E6 9A CC B9 C3 91 78 22 35 9C ..w..... ....x"5. >+[26C0] A1 13 A3 20 28 D1 16 E5 3E 4A 85 1E 12 0B CA 4D ... (... >J.....M >+[26D0] C6 C8 03 C8 28 2C D8 29 5D 9A 76 4A 92 13 43 56 ....(,.) ].vJ..CV >+[26E0] AF F7 C1 71 25 72 5C 38 75 1C 07 F1 5E 86 05 72 ...q%r\8 u...^..r >+[26F0] 6F 69 95 42 B6 F2 DA A9 91 06 9F B9 54 20 33 A5 oi.B.... ....T 3. >+[2700] 31 60 3B 54 DC 3A 95 34 96 26 07 52 6B 0E 1D 3B 1`;T.:.4 .&.Rk..; >+[2710] D9 F8 48 20 AC CD 05 3B 99 F8 EE DB 83 28 CD C7 ..H ...; .....(.. >+[2720] 2F 45 00 7E 2F 0A 65 7A D1 9E 95 4B EE C3 34 93 /E.~/.ez ...K..4. >+[2730] A8 C7 DF 03 8B 14 D0 FC CE 56 90 AC EE 93 C5 D3 ........ .V...... >+[2740] F7 12 24 69 0B 20 8D A2 65 87 55 26 2A F9 9A 88 ..$i. .. e.U&*... >+[2750] D7 0D 86 61 D6 92 B6 FE E5 D1 66 F9 1F 9D F4 04 ...a.... ..f..... >+[2760] 48 A6 39 BC 54 20 EA 10 21 E9 6D 30 46 1D C2 1C H.9.T .. !.m0F... >+[2770] A4 E8 B4 63 85 37 27 25 80 52 41 60 C7 A1 32 21 ...c.7'% .RA`..2! >+[2780] 43 90 02 E6 5F 5A E9 4E AF F9 B5 13 BD 42 BD A3 C..._Z.N .....B.. >+[2790] A5 4D 10 45 83 4D 92 18 1F C9 CF FB 84 29 89 23 .M.E.M.. .....).# >+[27A0] AC 71 4B 89 1B 52 E5 06 8C 3E 7C 88 CB D3 B3 CF .qK..R.. .>|..... >+[27B0] B9 7A 67 D6 24 F4 AC 00 A6 AD 91 30 9A 95 53 F1 .zg.$... ...0..S. >+[27C0] 48 06 A6 39 DB CF DC 9D C9 55 76 26 5E C1 DB 5D H..9.... .Uv&^..] >+[27D0] B3 5B 3E AE 1A A0 10 BA 82 21 83 44 02 E0 99 33 .[>..... .!.D...3 >+[27E0] 40 BA 29 9E 28 E5 73 4C 23 94 A2 4F BF 07 ED 4F @.).(.sL #..O...O >+[27F0] 7C 45 9B 30 C8 41 6B 0A 55 13 6E F5 AD 7A 0C B2 |E.0.Ak. U.n..z.. >+[2800] EA FF D0 06 13 4D F3 24 82 7F F6 51 2F 4A 4F 0D .....M.$ ...Q/JO. >+[2810] 37 F8 14 6B E9 E4 82 BB 3A 75 63 63 12 E8 78 6F 7..k.... :ucc..xo >+[2820] 6F FC 6C D3 4B A6 F1 CC 2A F1 7D EB 82 26 2F D0 o.l.K... *.}..&/. >+[2830] A1 8B 3E 9A 71 D7 91 D3 08 E6 FD 62 1B 84 13 2D ..>.q... ...b...- >+[2840] 8E A0 A0 C3 85 78 2F 0D F8 E7 10 FC CB 05 A7 B9 .....x/. ........ >+[2850] 9A 33 90 B5 9B 26 E3 23 98 B0 91 4B EB 32 37 D6 .3...&.# ...K.27. >+[2860] F4 ED 61 08 D8 75 CC 03 83 2C 3C CF 21 63 9C F6 ..a..u.. .,<.!c.. >+[2870] AF 5B 4F 12 07 74 17 CD 98 BB E7 5E C7 17 2D C4 .[O..t.. ...^..-. >+[2880] 87 A4 74 6D 5E CE DB A3 01 B9 AD 20 73 38 78 22 ..tm^... ... s8x" >+[2890] 3D 45 F5 51 77 C6 47 63 45 61 81 D9 FF 31 90 C4 =E.Qw.Gc Ea...1.. >+[28A0] 6F 5A F8 FE 6A 56 5B D4 EE EC 49 C7 A7 51 AE 5C oZ..jV[. ..I..Q.\ >+[28B0] 85 53 70 3D 1A 49 83 59 CF 65 58 B3 48 7E 04 9E .Sp=.I.Y .eX.H~.. >+[28C0] C7 64 8A 05 73 E3 DC 1A 65 5D 4F 41 01 56 73 90 .d..s... e]OA.Vs. >+[28D0] 61 F3 84 1F FF CF 46 B2 06 46 56 97 93 B9 DB 32 a.....F. .FV....2 >+[28E0] 2A 64 8A 48 02 05 84 E9 FA 76 8B 94 96 89 A0 73 *d.H.... .v.....s >+[28F0] 20 75 4D 52 1D 23 13 D1 83 D7 5D 59 23 6A 87 C1 uMR.#.. ..]Y#j.. >+[2900] 09 3E 01 3A 28 65 42 8C 35 F1 91 EA 6A 1F 83 0D .>.:(eB. 5...j... >+[2910] 8F 57 69 81 D4 A2 D2 EA 0C BF AF 95 A3 F4 90 15 .Wi..... ........ >+[2920] 61 34 F2 6C 8B D0 DA B5 1E 43 AC CE C7 8A 1B 2B a4.l.... .C.....+ >+[2930] 29 2B 89 1C C5 53 C8 04 F7 1E 46 72 F3 A8 CE F7 )+...S.. ..Fr.... >+[2940] 59 76 55 E7 53 1C A2 9F D8 23 F7 EA 71 B0 74 83 YvU.S... .#..q.t. >+[2950] 71 95 3E DC A6 FA 2D A4 42 13 93 8B 2B FA A2 70 q.>...-. B...+..p >+[2960] 25 21 2D F6 E1 26 56 DF 58 79 25 16 E8 C9 03 EC %!-..&V. Xy%..... >+[2970] 72 5F 35 CF 59 6B E1 AD 85 85 7B AB 78 F2 0D AC r_5.Yk.. ..{.x... >+[2980] AB 89 F2 DA 85 E7 DE 09 77 99 EC 7C F3 97 1F 71 ........ w..|...q >+[2990] 3C DB 09 44 7A 3C 69 E5 03 B0 6D 4D 3B 6B 4C D5 <..Dz<i. ..mM;kL. >+[29A0] AB 52 2F 6F 81 2B 51 5B D2 66 44 1E B7 66 5D 7F .R/o.+Q[ .fD..f]. >+[29B0] 09 6A 92 27 27 62 08 00 00 00 00 .j.''b.. ... >+push returned Success >+pull returned Success >+ CCACHE: struct CCACHE >+ pvno : 0x05 (5) >+ version : 0x04 (4) >+ optional_header : union OPTIONAL_HEADER(case 0x4) >+ v4header: struct V4HEADER >+ v4tags: struct V4TAGS >+ tag: struct V4TAG >+ tag : 0x0001 (1) >+ field : union FIELD(case 0x1) >+ deltatime_tag: struct DELTATIME_TAG >+ kdc_sec_offset : 0 >+ kdc_usec_offset : 0 >+ further_tags : DATA_BLOB length=0 >+ principal: struct PRINCIPAL >+ name_type : 0x00000001 (1) >+ component_count : 0x00000001 (1) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(1) >+ components : 'administrator' >+ cred: struct CREDENTIAL >+ client: struct PRINCIPAL >+ name_type : 0x00000001 (1) >+ component_count : 0x00000001 (1) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(1) >+ components : 'administrator' >+ server: struct PRINCIPAL >+ name_type : 0x00000000 (0) >+ component_count : 0x00000002 (2) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(2) >+ components : 'krbtgt' >+ components : 'KTEST.SAMBA.EXAMPLE.COM' >+ keyblock: struct KEYBLOCK >+ enctype : 0x0017 (23) >+ data : DATA_BLOB length=16 >+[0000] 8B 94 0B 31 51 5B F7 A7 15 E9 EE D7 D7 0C 8C 90 ...1Q[.. ........ >+ authtime : 0x4d994f6a (1301892970) >+ starttime : 0x4d994f6a (1301892970) >+ endtime : 0x7d440b68 (2101611368) >+ renew_till : 0x7d440b68 (2101611368) >+ is_skey : 0x00 (0) >+ ticket_flags : 0x40e00000 (1088421888) >+ addresses: struct ADDRESSES >+ count : 0x00000000 (0) >+ data: ARRAY(0) >+ authdata: struct AUTHDATA >+ count : 0x00000000 (0) >+ data: ARRAY(0) >+ ticket : DATA_BLOB length=1032 >+[0000] 61 82 04 04 30 82 04 00 A0 03 02 01 05 A1 19 1B a...0... ........ >+[0010] 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 .KTEST.S AMBA.EXA >+[0020] 4D 50 4C 45 2E 43 4F 4D A2 2C 30 2A A0 03 02 01 MPLE.COM .,0*.... >+[0030] 00 A1 23 30 21 1B 06 6B 72 62 74 67 74 1B 17 4B ..#0!..k rbtgt..K >+[0040] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[0050] 4C 45 2E 43 4F 4D A3 82 03 AE 30 82 03 AA A0 03 LE.COM.. ..0..... >+[0060] 02 01 17 A1 03 02 01 01 A2 82 03 9C 04 82 03 98 ........ ........ >+[0070] 80 66 8F CF AB 24 9D C8 76 E4 28 F5 25 6B 73 B2 .f...$.. v.(.%ks. >+[0080] 4B 94 ED 09 10 29 05 C4 C0 B8 B9 33 FA C4 46 AB K....).. ...3..F. >+[0090] F4 B5 9E 5B 07 54 D6 58 1D B8 CA 04 41 A6 33 A6 ...[.T.X ....A.3. >+[00A0] 67 9D EB 83 70 65 A9 2D 65 A5 19 8C 55 2A 0F FC g...pe.- e...U*.. >+[00B0] 1B BB 7A BD 86 C0 32 06 F2 2F 0A A5 93 E7 D1 1E ..z...2. ./...... >+[00C0] 16 C4 27 DD 1F A7 61 03 FF 05 81 EF 49 B7 25 A3 ..'...a. ....I.%. >+[00D0] 6E EA E6 E8 15 E3 10 AF A3 F1 21 B3 D9 C0 67 2F n....... ..!...g/ >+[00E0] 0C 0C B7 42 D6 9A 34 8E D4 5E 55 C2 FE 62 03 37 ...B..4. .^U..b.7 >+[00F0] A5 58 9B 43 E7 26 E3 71 B2 E5 F1 91 B4 23 8F AC .X.C.&.q .....#.. >+[0100] 7A 31 3C 4E B4 94 E4 81 36 98 71 3B 98 7B B7 AB z1<N.... 6.q;.{.. >+[0110] D5 AA D3 34 2A 3B C8 D7 61 EE 60 F9 68 9C A0 56 ...4*;.. a.`.h..V >+[0120] 51 E7 85 81 DE EF B9 9F 8B 4A 07 E1 05 93 08 5A Q....... .J.....Z >+[0130] AE B3 92 A5 17 40 B1 1C 42 A9 E4 AD 3C B4 4E D3 .....@.. B...<.N. >+[0140] BE 68 C4 0C 81 C0 AB 2D 3E 81 09 BD 16 82 EB C5 .h.....- >....... >+[0150] 1A 69 EE 8C 4E A4 D8 55 A5 0B 23 0F D0 89 48 C4 .i..N..U ..#...H. >+[0160] 51 FE 32 FD CC F6 71 E1 95 2D CC 1D 0A 0C 8A A2 Q.2...q. .-...... >+[0170] 69 58 3B 65 88 53 EC D0 2E E1 C6 CC 6B BC 09 E5 iX;e.S.. ....k... >+[0180] B9 15 27 8B E4 B2 24 18 61 42 BB 8B 09 1B 8A 7B ..'...$. aB.....{ >+[0190] 13 D8 51 E1 0B 79 12 48 DE A9 54 04 00 6D DD E6 ..Q..y.H ..T..m.. >+[01A0] 5E 03 91 FF C7 6D 0B 7C 91 44 E1 0F C0 7E 32 34 ^....m.| .D...~24 >+[01B0] 82 86 94 F7 CD 53 EC 52 38 18 AA ED FF FC 5C 01 .....S.R 8.....\. >+[01C0] D2 EE 99 45 8E 5B E6 B3 46 B0 F6 3B 22 29 EC 11 ...E.[.. F..;").. >+[01D0] 30 6A F6 A1 1F 9E AE 71 E3 A6 E7 3F F3 7D 2B 75 0j.....q ...?.}+u >+[01E0] 70 4D 63 47 5C 18 2C 8B B1 1A 69 B6 C5 46 01 17 pMcG\.,. ..i..F.. >+[01F0] 8E 64 3D 47 88 20 1C AA D7 60 32 28 11 60 EA 28 .d=G. .. .`2(.`.( >+[0200] 66 99 4C B1 2A 28 96 BF 18 2A 3E F4 D6 84 E5 A0 f.L.*(.. .*>..... >+[0210] F4 4E E7 F9 54 95 22 96 2A 87 01 CC 3E A7 FF 42 .N..T.". *...>..B >+[0220] 6A A4 4A 3A B9 24 10 65 99 53 58 2A 4E 72 E7 1F j.J:.$.e .SX*Nr.. >+[0230] 82 BC BD 3C 6C 9D 33 3A CE C6 6E 72 A2 81 B3 84 ...<l.3: ..nr.... >+[0240] 82 DF 3C 1F 76 E5 B8 08 AD 0A 6C 7D 7B D5 0C 46 ..<.v... ..l}{..F >+[0250] 69 A4 F4 E9 9E 3D D7 2D E1 43 D1 7A 52 16 75 56 i....=.- .C.zR.uV >+[0260] 54 83 D5 2A 2F A7 D2 CB 48 FE FF DB AE 46 F2 5B T..*/... H....F.[ >+[0270] F4 52 BE C8 5E B1 04 95 52 35 3E 92 E0 02 F7 85 .R..^... R5>..... >+[0280] AB F0 D0 93 08 42 E5 37 19 24 4E C1 AF FC 92 A9 .....B.7 .$N..... >+[0290] B1 27 B1 9A 2A 62 34 F1 DC C0 6B 83 AE C3 74 E8 .'..*b4. ..k...t. >+[02A0] A3 05 DD 82 DD A3 D7 90 A8 E3 9C EB 64 16 23 06 ........ ....d.#. >+[02B0] 5D FB E4 35 7C 22 29 78 E3 3B 75 92 91 0C 9D A1 ]..5|")x .;u..... >+[02C0] 87 7C 2E 82 AE 49 9D 4A 50 A9 C2 D5 85 B0 16 5D .|...I.J P......] >+[02D0] A2 CD B0 DD 29 3F 6F 66 C9 C1 9F 5C F0 B6 FC D2 ....)?of ...\.... >+[02E0] 52 BE 7B F0 1F 26 AF 8A FC C3 A6 24 8C C0 10 06 R.{..&.. ...$.... >+[02F0] 73 1E 17 9E 6E 6F 32 44 6A DF 82 5D D0 6B 74 CE s...no2D j..].kt. >+[0300] 58 0B 4C 7B EB A1 13 44 B1 3E D8 F8 BA F4 4E 55 X.L{...D .>....NU >+[0310] 71 3D C1 09 D9 E7 97 9A 14 5C 54 7E 57 81 5F 6B q=...... .\T~W._k >+[0320] 30 BE 9A E1 98 29 47 D4 C0 8F 63 0A F8 27 1F CE 0....)G. ..c..'.. >+[0330] ED D9 BB 7B 12 24 D0 34 2A 7C F0 F7 77 F4 F1 1D ...{.$.4 *|..w... >+[0340] 4C 5D 75 2D 6B 0D 80 35 82 CC D8 7A 6B FA A0 55 L]u-k..5 ...zk..U >+[0350] 34 CD 87 15 61 38 78 D4 69 0F AA 72 D6 AC FA 99 4...a8x. i..r.... >+[0360] BC 70 39 27 A7 25 2E 1B 6F 36 01 FD E9 B4 9A 79 .p9'.%.. o6.....y >+[0370] 6C 19 DD A6 8C 78 B0 40 92 60 58 F0 28 AD 08 78 l....x.@ .`X.(..x >+[0380] 4A 29 06 2C 82 2B 1A E3 91 0B 5F EE D6 B8 66 47 J).,.+.. .._...fG >+[0390] 31 9B A3 DF 9F 79 D7 BB 0E 2C FA 0E C9 66 84 8D 1....y.. .,...f.. >+[03A0] FF BA BB 21 27 9E AD 86 84 55 8D 4C 4C 47 D9 5F ...!'... .U.LLG._ >+[03B0] B2 7D 26 CA B7 49 3C 9D 1B 67 71 11 3A 8A EB EA .}&..I<. .gq.:... >+[03C0] 0F 15 EB F0 1E 46 F7 A4 34 04 D7 E3 50 67 47 D3 .....F.. 4...PgG. >+[03D0] 66 21 17 77 51 A7 1F 1D 84 3B 7C B1 5D 4E B8 D4 f!.wQ... .;|.]N.. >+[03E0] F9 C5 75 06 AA 19 45 1C E9 06 9E AD 23 26 6B 10 ..u...E. ....#&k. >+[03F0] 53 A0 36 D3 58 9F 5E 8C CB A5 F6 BC C9 30 3C BC S.6.X.^. .....0<. >+[0400] AD FF 7C 92 F0 C6 9A 02 ..|..... >+ second_ticket : DATA_BLOB length=0 >+ further_creds : DATA_BLOB length=10683 >+[0000] 00 00 00 01 00 00 00 01 00 00 00 17 4B 54 45 53 ........ ....KTES >+[0010] 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E T.SAMBA. EXAMPLE. >+[0020] 43 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 73 74 72 COM....a dministr >+[0030] 61 74 6F 72 00 00 00 01 00 00 00 02 00 00 00 17 ator.... ........ >+[0040] 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D KTEST.SA MBA.EXAM >+[0050] 50 4C 45 2E 43 4F 4D 00 00 00 04 63 69 66 73 00 PLE.COM. ...cifs. >+[0060] 00 00 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 00 17 ...local ktest6.. >+[0070] 00 00 00 10 00 6E A1 B2 31 6D 48 C7 90 72 3A 0C .....n.. 1mH..r:. >+[0080] 4B 8B 83 8C 4D 99 4F 6A 4D 99 50 85 7D 44 0B 68 K...M.Oj M.P.}D.h >+[0090] 00 00 00 00 00 40 28 00 00 00 00 00 00 00 00 00 .....@(. ........ >+[00A0] 00 00 00 03 FA 61 82 03 F6 30 82 03 F2 A0 03 02 .....a.. .0...... >+[00B0] 01 05 A1 19 1B 17 4B 54 45 53 54 2E 53 41 4D 42 ......KT EST.SAMB >+[00C0] 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D A2 1E 30 A.EXAMPL E.COM..0 >+[00D0] 1C A0 03 02 01 01 A1 15 30 13 1B 04 63 69 66 73 ........ 0...cifs >+[00E0] 1B 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 A3 82 03 ..localk test6... >+[00F0] AE 30 82 03 AA A0 03 02 01 17 A1 03 02 01 02 A2 .0...... ........ >+[0100] 82 03 9C 04 82 03 98 C6 BB 64 A8 31 00 FC 5E 51 ........ .d.1..^Q >+[0110] 3C 87 F8 34 47 3B D0 6F 6F FD 9E A6 91 12 74 2D <..4G;.o o.....t- >+[0120] 44 BB AA 91 A0 2D 46 3E 9E FB FB C4 FB F1 15 FD D....-F> ........ >+[0130] BB DA EE 06 A9 20 6A 38 DC 46 06 27 D9 A2 9D 2D ..... j8 .F.'...- >+[0140] 1F FD 0D 7D 8A BB 0A 7C E8 47 17 BC 7B 70 E4 51 ...}...| .G..{p.Q >+[0150] 6A BA 51 68 62 28 4A 1E 51 D1 0D CD 02 55 75 44 j.Qhb(J. Q....UuD >+[0160] 8A B9 C2 84 F4 17 34 92 9B 31 85 9E 43 C1 0C 3A ......4. .1..C..: >+[0170] B2 69 7F 20 1A 18 1F 65 4F C0 20 C9 B5 AF E1 61 .i. ...e O. ....a >+[0180] 8C 90 10 63 26 A6 5D 05 3C CD 29 BB 7B 74 D5 8F ...c&.]. <.).{t.. >+[0190] 2C 7F 4B E8 84 24 57 37 8A C6 F7 91 FD 22 9A A5 ,.K..$W7 .....".. >+[01A0] 0D E9 4A 78 93 36 FC A8 8C 8A 27 8A C6 28 4B 7B ..Jx.6.. ..'..(K{ >+[01B0] DA 11 42 BC 09 10 81 82 14 0F 9C B8 48 26 91 78 ..B..... ....H&.x >+[01C0] A8 DD 97 6C 24 A1 D2 E8 85 19 B3 D3 85 4D 38 C7 ...l$... .....M8. >+[01D0] 7D 49 55 8E 85 46 E1 EE 7B BA 11 62 63 53 C5 16 }IU..F.. {..bcS.. >+[01E0] 4A 0C 1C 99 7C 0E FB 45 1D B4 98 58 67 7E 40 65 J...|..E ...Xg~@e >+[01F0] 4B 48 E2 89 9C 8B C2 B8 39 D1 04 C0 A8 56 E8 A1 KH...... 9....V.. >+[0200] 04 7A 7A C9 60 18 A0 29 E2 DC 82 4C 8F 18 CE 2F .zz.`..) ...L.../ >+[0210] 14 F0 18 5B 6C FF 85 45 88 73 CB A4 55 08 FC BF ...[l..E .s..U... >+[0220] C7 9F 51 0A DB 2C C1 E3 3C DD F6 F0 A3 2D F1 3B ..Q..,.. <....-.; >+[0230] A0 12 1D FC 2A 67 F5 1A 7F E5 7C 6C FB 8A 18 BD ....*g.. ..|l.... >+[0240] D1 5D E5 5E 68 30 AA 58 9E 10 13 E0 26 7E 7D C4 .].^h0.X ....&~}. >+[0250] E1 A5 B6 86 0F 1C 0F 13 A4 5E 5E 6A ED 42 79 31 ........ .^^j.By1 >+[0260] BB B3 5F 3A 3F DD CB 63 82 FB 06 AE 12 36 C9 1E .._:?..c .....6.. >+[0270] 06 7D 41 82 2E D2 FA 26 EC 17 50 5E D0 DE 26 85 .}A....& ..P^..&. >+[0280] 30 71 BC 45 3B DA 2E 08 8D B2 2A 3C E0 79 8F 77 0q.E;... ..*<.y.w >+[0290] 4C 01 69 7A 09 C7 88 E1 D1 DC FF 78 DB 25 7B B1 L.iz.... ...x.%{. >+[02A0] 3C BB 22 27 80 0D 75 96 18 B6 40 95 6D C8 AB 04 <."'..u. ..@.m... >+[02B0] 05 41 A1 C4 25 71 C4 53 3A A6 9C B2 4D E6 15 2C .A..%q.S :...M.., >+[02C0] B2 47 6C DA A8 7D CC A3 89 8B C9 1E 21 F5 E9 B2 .Gl..}.. ....!... >+[02D0] 42 95 68 28 AF C6 37 22 BA 30 8D 53 FA 08 0D CE B.h(..7" .0.S.... >+[02E0] CA 81 61 0D 84 A5 2D 75 BD 41 85 4C 88 56 72 C6 ..a...-u .A.L.Vr. >+[02F0] B6 10 F8 34 CD B2 F4 5C 94 FA 80 90 82 A0 BD 68 ...4...\ .......h >+[0300] EC 08 32 C3 B6 51 1E 3F 67 CB 7B EB 70 83 84 D4 ..2..Q.? g.{.p... >+[0310] CB 52 55 36 61 1E 60 90 5B 6F FE 9A 62 05 CF 26 .RU6a.`. [o..b..& >+[0320] 8E 65 E2 60 4B ED 63 B4 C4 E6 44 B4 2F B0 B8 07 .e.`K.c. ..D./... >+[0330] FE BE 0D 50 E4 56 A4 2E 0D 25 76 0B 0F 44 09 20 ...P.V.. .%v..D. >+[0340] 80 E5 C4 94 63 E0 54 46 1D AB 5E 0B 09 93 B1 30 ....c.TF ..^....0 >+[0350] 31 7B 04 DC 23 43 3B DB 7D 39 67 FE 9A 1F C1 08 1{..#C;. }9g..... >+[0360] AF 34 24 F6 74 E4 14 DA 34 8F 61 57 6A 7F 1D 4A .4$.t... 4.aWj..J >+[0370] 88 0A 90 78 93 F1 86 54 DB 22 86 D6 69 0F DF 44 ...x...T ."..i..D >+[0380] 7C D3 6B 9D 41 63 50 98 3A 97 B9 7B 4C 53 E3 85 |.k.AcP. :..{LS.. >+[0390] 73 9A C9 08 A0 75 12 50 02 87 B0 CF CC 84 84 D9 s....u.P ........ >+[03A0] BC FC 94 79 AF 6A A6 08 FF 19 7E E9 22 9B EC 5C ...y.j.. ..~."..\ >+[03B0] C1 6B 1D A4 B4 55 32 5E 23 C3 C0 D4 8B 80 E6 67 .k...U2^ #......g >+[03C0] B1 59 EB 9D 5D 9B AD C6 0E 7D E2 FE B1 24 8A B1 .Y..]... .}...$.. >+[03D0] 37 1E 60 7F 83 35 48 32 F7 03 E8 12 E6 21 7C 3D 7.`..5H2 .....!|= >+[03E0] 21 7F 6B 14 31 9C 1A A3 4C 2B 1C 5E EC 34 C1 2D !.k.1... L+.^.4.- >+[03F0] DA 19 6C E6 6D 8D 60 D7 55 9E E6 D0 B5 07 06 72 ..l.m.`. U......r >+[0400] C0 E9 4E 91 94 6B 3E 0B F1 0A 75 4D E8 CB 53 6B ..N..k>. ..uM..Sk >+[0410] 34 A4 2F 96 A5 39 1A 18 6E 27 00 6D 41 B7 D8 F5 4./..9.. n'.mA... >+[0420] 9A E5 01 FC 0B A8 97 56 EE 98 04 1D 98 84 5E 82 .......V ......^. >+[0430] C8 E8 EC 17 D5 FA 96 00 3B E1 98 1C D8 FA 66 A0 ........ ;.....f. >+[0440] DC 32 60 F6 03 46 08 3C E5 16 6F F2 8B 4D 72 9F .2`..F.< ..o..Mr. >+[0450] 0F E0 A9 71 6E 7C AE AA FB A3 4D F1 A1 B6 1B 9F ...qn|.. ..M..... >+[0460] 62 71 E1 2C 82 9B AE E3 07 9B 79 90 F1 C2 69 E5 bq.,.... ..y...i. >+[0470] 7E CB 57 E6 C9 1C 4E A8 C7 12 EA 4F 4C 52 17 03 ~.W...N. ...OLR.. >+[0480] AB D4 FD 34 60 F4 7C BE 9E 36 30 37 88 95 61 2E ...4`.|. .607..a. >+[0490] CF 70 AF 22 70 DB E8 AA 6E 3D 30 F7 4D 84 D5 00 .p."p... n=0.M... >+[04A0] 00 00 00 00 00 00 01 00 00 00 01 00 00 00 17 4B ........ .......K >+[04B0] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[04C0] 4C 45 2E 43 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 LE.COM.. ..admini >+[04D0] 73 74 72 61 74 6F 72 00 00 00 01 00 00 00 02 00 strator. ........ >+[04E0] 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 ...KTEST .SAMBA.E >+[04F0] 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 04 63 69 XAMPLE.C OM....ci >+[0500] 66 73 00 00 00 0B 6C 6F 63 61 6C 6B 74 65 73 74 fs....lo calktest >+[0510] 36 00 17 00 00 00 10 00 6E A1 B2 31 6D 48 C7 90 6....... n..1mH.. >+[0520] 72 3A 0C 4B 8B 83 8C 4D 99 4F 6A 4D 99 50 85 7D r:.K...M .OjM.P.} >+[0530] 44 0B 68 00 00 00 00 00 40 28 00 00 00 00 00 00 D.h..... @(...... >+[0540] 00 00 00 00 00 00 03 FA 61 82 03 F6 30 82 03 F2 ........ a...0... >+[0550] A0 03 02 01 05 A1 19 1B 17 4B 54 45 53 54 2E 53 ........ .KTEST.S >+[0560] 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D AMBA.EXA MPLE.COM >+[0570] A2 1E 30 1C A0 03 02 01 01 A1 15 30 13 1B 04 63 ..0..... ...0...c >+[0580] 69 66 73 1B 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 ifs..loc alktest6 >+[0590] A3 82 03 AE 30 82 03 AA A0 03 02 01 17 A1 03 02 ....0... ........ >+[05A0] 01 02 A2 82 03 9C 04 82 03 98 C6 BB 64 A8 31 00 ........ ....d.1. >+[05B0] FC 5E 51 3C 87 F8 34 47 3B D0 6F 6F FD 9E A6 91 .^Q<..4G ;.oo.... >+[05C0] 12 74 2D 44 BB AA 91 A0 2D 46 3E 9E FB FB C4 FB .t-D.... -F>..... >+[05D0] F1 15 FD BB DA EE 06 A9 20 6A 38 DC 46 06 27 D9 ........ j8.F.'. >+[05E0] A2 9D 2D 1F FD 0D 7D 8A BB 0A 7C E8 47 17 BC 7B ..-...}. ..|.G..{ >+[05F0] 70 E4 51 6A BA 51 68 62 28 4A 1E 51 D1 0D CD 02 p.Qj.Qhb (J.Q.... >+[0600] 55 75 44 8A B9 C2 84 F4 17 34 92 9B 31 85 9E 43 UuD..... .4..1..C >+[0610] C1 0C 3A B2 69 7F 20 1A 18 1F 65 4F C0 20 C9 B5 ..:.i. . ..eO. .. >+[0620] AF E1 61 8C 90 10 63 26 A6 5D 05 3C CD 29 BB 7B ..a...c& .].<.).{ >+[0630] 74 D5 8F 2C 7F 4B E8 84 24 57 37 8A C6 F7 91 FD t..,.K.. $W7..... >+[0640] 22 9A A5 0D E9 4A 78 93 36 FC A8 8C 8A 27 8A C6 "....Jx. 6....'.. >+[0650] 28 4B 7B DA 11 42 BC 09 10 81 82 14 0F 9C B8 48 (K{..B.. .......H >+[0660] 26 91 78 A8 DD 97 6C 24 A1 D2 E8 85 19 B3 D3 85 &.x...l$ ........ >+[0670] 4D 38 C7 7D 49 55 8E 85 46 E1 EE 7B BA 11 62 63 M8.}IU.. F..{..bc >+[0680] 53 C5 16 4A 0C 1C 99 7C 0E FB 45 1D B4 98 58 67 S..J...| ..E...Xg >+[0690] 7E 40 65 4B 48 E2 89 9C 8B C2 B8 39 D1 04 C0 A8 ~@eKH... ...9.... >+[06A0] 56 E8 A1 04 7A 7A C9 60 18 A0 29 E2 DC 82 4C 8F V...zz.` ..)...L. >+[06B0] 18 CE 2F 14 F0 18 5B 6C FF 85 45 88 73 CB A4 55 ../...[l ..E.s..U >+[06C0] 08 FC BF C7 9F 51 0A DB 2C C1 E3 3C DD F6 F0 A3 .....Q.. ,..<.... >+[06D0] 2D F1 3B A0 12 1D FC 2A 67 F5 1A 7F E5 7C 6C FB -.;....* g....|l. >+[06E0] 8A 18 BD D1 5D E5 5E 68 30 AA 58 9E 10 13 E0 26 ....].^h 0.X....& >+[06F0] 7E 7D C4 E1 A5 B6 86 0F 1C 0F 13 A4 5E 5E 6A ED ~}...... ....^^j. >+[0700] 42 79 31 BB B3 5F 3A 3F DD CB 63 82 FB 06 AE 12 By1.._:? ..c..... >+[0710] 36 C9 1E 06 7D 41 82 2E D2 FA 26 EC 17 50 5E D0 6...}A.. ..&..P^. >+[0720] DE 26 85 30 71 BC 45 3B DA 2E 08 8D B2 2A 3C E0 .&.0q.E; .....*<. >+[0730] 79 8F 77 4C 01 69 7A 09 C7 88 E1 D1 DC FF 78 DB y.wL.iz. ......x. >+[0740] 25 7B B1 3C BB 22 27 80 0D 75 96 18 B6 40 95 6D %{.<."'. .u...@.m >+[0750] C8 AB 04 05 41 A1 C4 25 71 C4 53 3A A6 9C B2 4D ....A..% q.S:...M >+[0760] E6 15 2C B2 47 6C DA A8 7D CC A3 89 8B C9 1E 21 ..,.Gl.. }......! >+[0770] F5 E9 B2 42 95 68 28 AF C6 37 22 BA 30 8D 53 FA ...B.h(. .7".0.S. >+[0780] 08 0D CE CA 81 61 0D 84 A5 2D 75 BD 41 85 4C 88 .....a.. .-u.A.L. >+[0790] 56 72 C6 B6 10 F8 34 CD B2 F4 5C 94 FA 80 90 82 Vr....4. ..\..... >+[07A0] A0 BD 68 EC 08 32 C3 B6 51 1E 3F 67 CB 7B EB 70 ..h..2.. Q.?g.{.p >+[07B0] 83 84 D4 CB 52 55 36 61 1E 60 90 5B 6F FE 9A 62 ....RU6a .`.[o..b >+[07C0] 05 CF 26 8E 65 E2 60 4B ED 63 B4 C4 E6 44 B4 2F ..&.e.`K .c...D./ >+[07D0] B0 B8 07 FE BE 0D 50 E4 56 A4 2E 0D 25 76 0B 0F ......P. V...%v.. >+[07E0] 44 09 20 80 E5 C4 94 63 E0 54 46 1D AB 5E 0B 09 D. ....c .TF..^.. >+[07F0] 93 B1 30 31 7B 04 DC 23 43 3B DB 7D 39 67 FE 9A ..01{..# C;.}9g.. >+[0800] 1F C1 08 AF 34 24 F6 74 E4 14 DA 34 8F 61 57 6A ....4$.t ...4.aWj >+[0810] 7F 1D 4A 88 0A 90 78 93 F1 86 54 DB 22 86 D6 69 ..J...x. ..T."..i >+[0820] 0F DF 44 7C D3 6B 9D 41 63 50 98 3A 97 B9 7B 4C ..D|.k.A cP.:..{L >+[0830] 53 E3 85 73 9A C9 08 A0 75 12 50 02 87 B0 CF CC S..s.... u.P..... >+[0840] 84 84 D9 BC FC 94 79 AF 6A A6 08 FF 19 7E E9 22 ......y. j....~." >+[0850] 9B EC 5C C1 6B 1D A4 B4 55 32 5E 23 C3 C0 D4 8B ..\.k... U2^#.... >+[0860] 80 E6 67 B1 59 EB 9D 5D 9B AD C6 0E 7D E2 FE B1 ..g.Y..] ....}... >+[0870] 24 8A B1 37 1E 60 7F 83 35 48 32 F7 03 E8 12 E6 $..7.`.. 5H2..... >+[0880] 21 7C 3D 21 7F 6B 14 31 9C 1A A3 4C 2B 1C 5E EC !|=!.k.1 ...L+.^. >+[0890] 34 C1 2D DA 19 6C E6 6D 8D 60 D7 55 9E E6 D0 B5 4.-..l.m .`.U.... >+[08A0] 07 06 72 C0 E9 4E 91 94 6B 3E 0B F1 0A 75 4D E8 ..r..N.. k>...uM. >+[08B0] CB 53 6B 34 A4 2F 96 A5 39 1A 18 6E 27 00 6D 41 .Sk4./.. 9..n'.mA >+[08C0] B7 D8 F5 9A E5 01 FC 0B A8 97 56 EE 98 04 1D 98 ........ ..V..... >+[08D0] 84 5E 82 C8 E8 EC 17 D5 FA 96 00 3B E1 98 1C D8 .^...... ...;.... >+[08E0] FA 66 A0 DC 32 60 F6 03 46 08 3C E5 16 6F F2 8B .f..2`.. F.<..o.. >+[08F0] 4D 72 9F 0F E0 A9 71 6E 7C AE AA FB A3 4D F1 A1 Mr....qn |....M.. >+[0900] B6 1B 9F 62 71 E1 2C 82 9B AE E3 07 9B 79 90 F1 ...bq.,. .....y.. >+[0910] C2 69 E5 7E CB 57 E6 C9 1C 4E A8 C7 12 EA 4F 4C .i.~.W.. .N....OL >+[0920] 52 17 03 AB D4 FD 34 60 F4 7C BE 9E 36 30 37 88 R.....4` .|..607. >+[0930] 95 61 2E CF 70 AF 22 70 DB E8 AA 6E 3D 30 F7 4D .a..p."p ...n=0.M >+[0940] 84 D5 00 00 00 00 00 00 00 01 00 00 00 01 00 00 ........ ........ >+[0950] 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 ..KTEST. SAMBA.EX >+[0960] 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D 61 64 6D AMPLE.CO M....adm >+[0970] 69 6E 69 73 74 72 61 74 6F 72 00 00 00 01 00 00 inistrat or...... >+[0980] 00 02 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 ......KT EST.SAMB >+[0990] 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 A.EXAMPL E.COM... >+[09A0] 04 63 69 66 73 00 00 00 0B 6C 6F 63 61 6C 6B 74 .cifs... .localkt >+[09B0] 65 73 74 36 00 17 00 00 00 10 00 6E A1 B2 31 6D est6.... ...n..1m >+[09C0] 48 C7 90 72 3A 0C 4B 8B 83 8C 4D 99 4F 6A 4D 99 H..r:.K. ..M.OjM. >+[09D0] 50 85 7D 44 0B 68 00 00 00 00 00 40 28 00 00 00 P.}D.h.. ...@(... >+[09E0] 00 00 00 00 00 00 00 00 00 03 FA 61 82 03 F6 30 ........ ...a...0 >+[09F0] 82 03 F2 A0 03 02 01 05 A1 19 1B 17 4B 54 45 53 ........ ....KTES >+[0A00] 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E T.SAMBA. EXAMPLE. >+[0A10] 43 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 15 30 13 COM..0.. ......0. >+[0A20] 1B 04 63 69 66 73 1B 0B 6C 6F 63 61 6C 6B 74 65 ..cifs.. localkte >+[0A30] 73 74 36 A3 82 03 AE 30 82 03 AA A0 03 02 01 17 st6....0 ........ >+[0A40] A1 03 02 01 02 A2 82 03 9C 04 82 03 98 C6 BB 64 ........ .......d >+[0A50] A8 31 00 FC 5E 51 3C 87 F8 34 47 3B D0 6F 6F FD .1..^Q<. .4G;.oo. >+[0A60] 9E A6 91 12 74 2D 44 BB AA 91 A0 2D 46 3E 9E FB ....t-D. ...-F>.. >+[0A70] FB C4 FB F1 15 FD BB DA EE 06 A9 20 6A 38 DC 46 ........ ... j8.F >+[0A80] 06 27 D9 A2 9D 2D 1F FD 0D 7D 8A BB 0A 7C E8 47 .'...-.. .}...|.G >+[0A90] 17 BC 7B 70 E4 51 6A BA 51 68 62 28 4A 1E 51 D1 ..{p.Qj. Qhb(J.Q. >+[0AA0] 0D CD 02 55 75 44 8A B9 C2 84 F4 17 34 92 9B 31 ...UuD.. ....4..1 >+[0AB0] 85 9E 43 C1 0C 3A B2 69 7F 20 1A 18 1F 65 4F C0 ..C..:.i . ...eO. >+[0AC0] 20 C9 B5 AF E1 61 8C 90 10 63 26 A6 5D 05 3C CD ....a.. .c&.].<. >+[0AD0] 29 BB 7B 74 D5 8F 2C 7F 4B E8 84 24 57 37 8A C6 ).{t..,. K..$W7.. >+[0AE0] F7 91 FD 22 9A A5 0D E9 4A 78 93 36 FC A8 8C 8A ...".... Jx.6.... >+[0AF0] 27 8A C6 28 4B 7B DA 11 42 BC 09 10 81 82 14 0F '..(K{.. B....... >+[0B00] 9C B8 48 26 91 78 A8 DD 97 6C 24 A1 D2 E8 85 19 ..H&.x.. .l$..... >+[0B10] B3 D3 85 4D 38 C7 7D 49 55 8E 85 46 E1 EE 7B BA ...M8.}I U..F..{. >+[0B20] 11 62 63 53 C5 16 4A 0C 1C 99 7C 0E FB 45 1D B4 .bcS..J. ..|..E.. >+[0B30] 98 58 67 7E 40 65 4B 48 E2 89 9C 8B C2 B8 39 D1 .Xg~@eKH ......9. >+[0B40] 04 C0 A8 56 E8 A1 04 7A 7A C9 60 18 A0 29 E2 DC ...V...z z.`..).. >+[0B50] 82 4C 8F 18 CE 2F 14 F0 18 5B 6C FF 85 45 88 73 .L.../.. .[l..E.s >+[0B60] CB A4 55 08 FC BF C7 9F 51 0A DB 2C C1 E3 3C DD ..U..... Q..,..<. >+[0B70] F6 F0 A3 2D F1 3B A0 12 1D FC 2A 67 F5 1A 7F E5 ...-.;.. ..*g.... >+[0B80] 7C 6C FB 8A 18 BD D1 5D E5 5E 68 30 AA 58 9E 10 |l.....] .^h0.X.. >+[0B90] 13 E0 26 7E 7D C4 E1 A5 B6 86 0F 1C 0F 13 A4 5E ..&~}... .......^ >+[0BA0] 5E 6A ED 42 79 31 BB B3 5F 3A 3F DD CB 63 82 FB ^j.By1.. _:?..c.. >+[0BB0] 06 AE 12 36 C9 1E 06 7D 41 82 2E D2 FA 26 EC 17 ...6...} A....&.. >+[0BC0] 50 5E D0 DE 26 85 30 71 BC 45 3B DA 2E 08 8D B2 P^..&.0q .E;..... >+[0BD0] 2A 3C E0 79 8F 77 4C 01 69 7A 09 C7 88 E1 D1 DC *<.y.wL. iz...... >+[0BE0] FF 78 DB 25 7B B1 3C BB 22 27 80 0D 75 96 18 B6 .x.%{.<. "'..u... >+[0BF0] 40 95 6D C8 AB 04 05 41 A1 C4 25 71 C4 53 3A A6 @.m....A ..%q.S:. >+[0C00] 9C B2 4D E6 15 2C B2 47 6C DA A8 7D CC A3 89 8B ..M..,.G l..}.... >+[0C10] C9 1E 21 F5 E9 B2 42 95 68 28 AF C6 37 22 BA 30 ..!...B. h(..7".0 >+[0C20] 8D 53 FA 08 0D CE CA 81 61 0D 84 A5 2D 75 BD 41 .S...... a...-u.A >+[0C30] 85 4C 88 56 72 C6 B6 10 F8 34 CD B2 F4 5C 94 FA .L.Vr... .4...\.. >+[0C40] 80 90 82 A0 BD 68 EC 08 32 C3 B6 51 1E 3F 67 CB .....h.. 2..Q.?g. >+[0C50] 7B EB 70 83 84 D4 CB 52 55 36 61 1E 60 90 5B 6F {.p....R U6a.`.[o >+[0C60] FE 9A 62 05 CF 26 8E 65 E2 60 4B ED 63 B4 C4 E6 ..b..&.e .`K.c... >+[0C70] 44 B4 2F B0 B8 07 FE BE 0D 50 E4 56 A4 2E 0D 25 D./..... .P.V...% >+[0C80] 76 0B 0F 44 09 20 80 E5 C4 94 63 E0 54 46 1D AB v..D. .. ..c.TF.. >+[0C90] 5E 0B 09 93 B1 30 31 7B 04 DC 23 43 3B DB 7D 39 ^....01{ ..#C;.}9 >+[0CA0] 67 FE 9A 1F C1 08 AF 34 24 F6 74 E4 14 DA 34 8F g......4 $.t...4. >+[0CB0] 61 57 6A 7F 1D 4A 88 0A 90 78 93 F1 86 54 DB 22 aWj..J.. .x...T." >+[0CC0] 86 D6 69 0F DF 44 7C D3 6B 9D 41 63 50 98 3A 97 ..i..D|. k.AcP.:. >+[0CD0] B9 7B 4C 53 E3 85 73 9A C9 08 A0 75 12 50 02 87 .{LS..s. ...u.P.. >+[0CE0] B0 CF CC 84 84 D9 BC FC 94 79 AF 6A A6 08 FF 19 ........ .y.j.... >+[0CF0] 7E E9 22 9B EC 5C C1 6B 1D A4 B4 55 32 5E 23 C3 ~."..\.k ...U2^#. >+[0D00] C0 D4 8B 80 E6 67 B1 59 EB 9D 5D 9B AD C6 0E 7D .....g.Y ..]....} >+[0D10] E2 FE B1 24 8A B1 37 1E 60 7F 83 35 48 32 F7 03 ...$..7. `..5H2.. >+[0D20] E8 12 E6 21 7C 3D 21 7F 6B 14 31 9C 1A A3 4C 2B ...!|=!. k.1...L+ >+[0D30] 1C 5E EC 34 C1 2D DA 19 6C E6 6D 8D 60 D7 55 9E .^.4.-.. l.m.`.U. >+[0D40] E6 D0 B5 07 06 72 C0 E9 4E 91 94 6B 3E 0B F1 0A .....r.. N..k>... >+[0D50] 75 4D E8 CB 53 6B 34 A4 2F 96 A5 39 1A 18 6E 27 uM..Sk4. /..9..n' >+[0D60] 00 6D 41 B7 D8 F5 9A E5 01 FC 0B A8 97 56 EE 98 .mA..... .....V.. >+[0D70] 04 1D 98 84 5E 82 C8 E8 EC 17 D5 FA 96 00 3B E1 ....^... ......;. >+[0D80] 98 1C D8 FA 66 A0 DC 32 60 F6 03 46 08 3C E5 16 ....f..2 `..F.<.. >+[0D90] 6F F2 8B 4D 72 9F 0F E0 A9 71 6E 7C AE AA FB A3 o..Mr... .qn|.... >+[0DA0] 4D F1 A1 B6 1B 9F 62 71 E1 2C 82 9B AE E3 07 9B M.....bq .,...... >+[0DB0] 79 90 F1 C2 69 E5 7E CB 57 E6 C9 1C 4E A8 C7 12 y...i.~. W...N... >+[0DC0] EA 4F 4C 52 17 03 AB D4 FD 34 60 F4 7C BE 9E 36 .OLR.... .4`.|..6 >+[0DD0] 30 37 88 95 61 2E CF 70 AF 22 70 DB E8 AA 6E 3D 07..a..p ."p...n= >+[0DE0] 30 F7 4D 84 D5 00 00 00 00 00 00 00 01 00 00 00 0.M..... ........ >+[0DF0] 01 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 .....KTE ST.SAMBA >+[0E00] 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D .EXAMPLE .COM.... >+[0E10] 61 64 6D 69 6E 69 73 74 72 61 74 6F 72 00 00 00 administ rator... >+[0E20] 01 00 00 00 02 00 00 00 17 4B 54 45 53 54 2E 53 ........ .KTEST.S >+[0E30] 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D AMBA.EXA MPLE.COM >+[0E40] 00 00 00 04 63 69 66 73 00 00 00 0B 4C 4F 43 41 ....cifs ....LOCA >+[0E50] 4C 4B 54 45 53 54 36 00 17 00 00 00 10 1D C8 5E LKTEST6. .......^ >+[0E60] 46 48 82 F9 29 DB C6 A6 F1 72 6D 8D E9 4D 99 4F FH..)... .rm..M.O >+[0E70] 6A 4D 99 85 09 7D 44 0B 68 00 00 00 00 00 40 28 jM...}D. h.....@( >+[0E80] 00 00 00 00 00 00 00 00 00 00 00 00 03 FA 61 82 ........ ......a. >+[0E90] 03 F6 30 82 03 F2 A0 03 02 01 05 A1 19 1B 17 4B ..0..... .......K >+[0EA0] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[0EB0] 4C 45 2E 43 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 LE.COM.. 0....... >+[0EC0] 15 30 13 1B 04 63 69 66 73 1B 0B 4C 4F 43 41 4C .0...cif s..LOCAL >+[0ED0] 4B 54 45 53 54 36 A3 82 03 AE 30 82 03 AA A0 03 KTEST6.. ..0..... >+[0EE0] 02 01 17 A1 03 02 01 02 A2 82 03 9C 04 82 03 98 ........ ........ >+[0EF0] 66 D8 19 46 FA CB 73 2D CF 88 FD 4A EE 07 48 DA f..F..s- ...J..H. >+[0F00] 0E BC 58 30 43 40 A4 9C 00 0F 3B 17 C1 2D F5 9C ..X0C@.. ..;..-.. >+[0F10] 3E D9 2F 1D CA 01 9B D7 2E EC D7 70 ED 8B 8B 1B >./..... ...p.... >+[0F20] 5E F2 4E EE DD 0F C0 8D 61 E5 D7 0A 56 00 32 B1 ^.N..... a...V.2. >+[0F30] DB 91 37 29 0F 2F 85 EE A8 43 BA A5 B8 D4 19 74 ..7)./.. .C.....t >+[0F40] 33 F0 69 52 E1 58 98 83 D6 16 0B 44 A9 63 9B D4 3.iR.X.. ...D.c.. >+[0F50] 4E 6E A7 3E CD 9A 96 4D C4 96 F5 07 6D 29 B6 ED Nn.>...M ....m).. >+[0F60] 2A 62 3D 53 22 33 D1 95 E9 DF 74 4C 2A E2 29 AF *b=S"3.. ..tL*.). >+[0F70] 5B 69 B0 48 2D AD 94 FD A5 1D 54 D8 E2 5E C1 68 [i.H-... ..T..^.h >+[0F80] 6F BA 02 01 79 C3 C9 97 0B 76 66 45 E2 3B 10 17 o...y... .vfE.;.. >+[0F90] 95 40 46 E4 85 B9 87 BB CF CF 19 8C 3A C0 EA 38 .@F..... ....:..8 >+[0FA0] 3B B9 E9 4B 05 89 E5 27 8C 62 95 BC 0D 65 F0 D2 ;..K...' .b...e.. >+[0FB0] C0 5E BC 65 01 D5 0B CB 17 31 0F 06 49 4F A2 4A .^.e.... .1..IO.J >+[0FC0] 70 77 DB BD 92 5B 37 5C EC 06 DF C5 E2 31 C8 40 pw...[7\ .....1.@ >+[0FD0] 09 11 68 14 E7 7D CE 54 4F 52 61 31 2C 1C 53 52 ..h..}.T ORa1,.SR >+[0FE0] DB BE D8 95 39 EE 7D C6 CE C8 22 95 92 97 97 3D ....9.}. .."....= >+[0FF0] 5E 66 0F AD DC C2 4E 2E 2B 9F 63 20 30 DF B7 C1 ^f....N. +.c 0... >+[1000] D4 65 AA 6F 2D 10 24 07 20 8D 88 6E 4B 09 04 31 .e.o-.$. ..nK..1 >+[1010] B6 A3 EB F7 37 32 0E 0C 73 C6 F6 B8 4D D9 0C 4C ....72.. s...M..L >+[1020] 5B EC 10 6A 51 19 EA 3F FF 46 E7 73 16 A7 1F 33 [..jQ..? .F.s...3 >+[1030] 98 7C 9B AD 5A 23 A9 40 7C 0F DF EE 0F AA C7 E8 .|..Z#.@ |....... >+[1040] 63 07 98 3A 4A 0D 18 62 01 21 B2 AE A5 69 B0 C1 c..:J..b .!...i.. >+[1050] 15 51 BA 97 D2 C5 42 5B C5 30 38 18 A9 48 AB D7 .Q....B[ .08..H.. >+[1060] FC A1 BC 9F 71 E7 EA 18 54 42 DA D6 A4 FC C1 DC ....q... TB...... >+[1070] F3 12 30 62 AC 98 E1 7D 2B 34 1E 52 4C 26 67 32 ..0b...} +4.RL&g2 >+[1080] D9 44 1A 08 27 0E DA D0 FC 84 66 35 81 D6 EB 98 .D..'... ..f5.... >+[1090] 46 6F 1E 47 E0 14 31 BE 47 80 65 AA 0B 20 D6 33 Fo.G..1. G.e.. .3 >+[10A0] 36 3B 0D 40 2F 5A 2E 0E 01 BE 00 EB 33 3E 4B 32 6;.@/Z.. ....3>K2 >+[10B0] 91 F4 22 96 E5 5F D4 D5 92 94 CC 5B 59 6A 3E D2 ..".._.. ...[Yj>. >+[10C0] FB A0 4F 99 C4 07 8B 6F 2B 14 37 CD 37 44 C0 1F ..O....o +.7.7D.. >+[10D0] 80 9C 43 46 F2 5E F4 FE D3 39 70 61 BE 72 5B 3A ..CF.^.. .9pa.r[: >+[10E0] 8F 37 95 78 1E AB D9 E7 E9 DA FC 47 09 81 A0 0D .7.x.... ...G.... >+[10F0] 62 E1 F9 34 36 D1 DB E6 98 D8 F4 3E 77 5A 4D E2 b..46... ...>wZM. >+[1100] 5F 20 70 3D 3D 5B 34 D9 FD A8 31 F7 D9 59 F7 A3 _ p==[4. ..1..Y.. >+[1110] F0 66 F7 D9 AD 1C CD D5 85 33 A0 87 22 31 D4 F3 .f...... .3.."1.. >+[1120] 67 80 68 20 A2 90 72 7A 6F 64 FD 68 82 9E 91 B8 g.h ..rz od.h.... >+[1130] E3 F7 6D 6C 38 74 F0 96 A2 F6 25 D7 92 58 14 60 ..ml8t.. ..%..X.` >+[1140] 9F AE 01 4C 0C 09 67 3E 35 67 71 1E 2A 86 21 D3 ...L..g> 5gq.*.!. >+[1150] 60 61 98 16 94 67 0B 52 76 63 93 BD A3 3B A9 F0 `a...g.R vc...;.. >+[1160] A2 6A B7 E6 0F 35 64 DA 6A EA 20 A6 3D 94 71 59 .j...5d. j. .=.qY >+[1170] 5E CB B2 D3 F9 4D FE 1B 4B D8 64 C8 3B 7A A8 E6 ^....M.. K.d.;z.. >+[1180] D2 D5 76 71 26 D4 5C DA 1A 55 17 F2 16 C9 2F 77 ..vq&.\. .U..../w >+[1190] DB 95 19 48 A5 AC D0 C3 31 9C 0A CC 1B 44 11 6B ...H.... 1....D.k >+[11A0] 7C 88 7A 5D CF 6E 12 DA EF C5 C7 34 1D F4 CC EA |.z].n.. ...4.... >+[11B0] 37 24 4B B3 0F C1 A3 F2 29 A0 D8 93 39 C6 16 57 7$K..... )...9..W >+[11C0] D5 BF 57 BF 6C 7E F7 90 E0 EB A3 8B 07 56 9C EC ..W.l~.. .....V.. >+[11D0] 15 3E 21 DA A5 7C 00 3C F9 D2 A7 1C 6F 16 25 31 .>!..|.< ....o.%1 >+[11E0] C5 28 A7 EA F3 47 31 50 DD E1 ED 0A 93 DB 85 CC .(...G1P ........ >+[11F0] 6B 4B 2C 7F E8 F8 2D A9 6D 1D 0A 87 F2 10 8C 82 kK,...-. m....... >+[1200] 2F 9B D4 9B 92 8C 77 40 50 42 1E 42 C4 0A 4F E3 /.....w@ PB.B..O. >+[1210] 6C 6C DC 81 C4 1E BB F0 7D CF 3C 73 22 5B C3 1A ll...... }.<s"[.. >+[1220] 97 35 EE 3A CD 6D F3 68 A3 C5 65 7E E9 54 C0 E3 .5.:.m.h ..e~.T.. >+[1230] 7D 6A 32 4C D1 3E D0 78 4B BF 18 9F A5 25 4A 92 }j2L.>.x K....%J. >+[1240] 1E 6C 8F 01 D6 59 D7 CF 2E A0 CC 98 F6 75 28 2F .l...Y.. .....u(/ >+[1250] F7 2A 70 28 A9 45 1F 75 C2 4E 62 ED D8 C4 A0 8D .*p(.E.u .Nb..... >+[1260] 55 B2 84 1C A4 CE 87 EF 24 EE BC CE 40 09 EB 05 U....... $...@... >+[1270] 0B D1 14 31 50 32 2F B6 A8 97 17 4B A7 95 01 50 ...1P2/. ...K...P >+[1280] 6E 0E 23 49 9C 72 21 91 00 00 00 00 00 00 00 01 n.#I.r!. ........ >+[1290] 00 00 00 01 00 00 00 17 4B 54 45 53 54 2E 53 41 ........ KTEST.SA >+[12A0] 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 MBA.EXAM PLE.COM. >+[12B0] 00 00 0D 61 64 6D 69 6E 69 73 74 72 61 74 6F 72 ...admin istrator >+[12C0] 00 00 00 01 00 00 00 02 00 00 00 17 4B 54 45 53 ........ ....KTES >+[12D0] 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E T.SAMBA. EXAMPLE. >+[12E0] 43 4F 4D 00 00 00 04 63 69 66 73 00 00 00 0B 4C COM....c ifs....L >+[12F0] 4F 43 41 4C 4B 54 45 53 54 36 00 17 00 00 00 10 OCALKTES T6...... >+[1300] 1D C8 5E 46 48 82 F9 29 DB C6 A6 F1 72 6D 8D E9 ..^FH..) ....rm.. >+[1310] 4D 99 4F 6A 4D 99 85 09 7D 44 0B 68 00 00 00 00 M.OjM... }D.h.... >+[1320] 00 40 28 00 00 00 00 00 00 00 00 00 00 00 00 03 .@(..... ........ >+[1330] FA 61 82 03 F6 30 82 03 F2 A0 03 02 01 05 A1 19 .a...0.. ........ >+[1340] 1B 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 ..KTEST. SAMBA.EX >+[1350] 41 4D 50 4C 45 2E 43 4F 4D A2 1E 30 1C A0 03 02 AMPLE.CO M..0.... >+[1360] 01 01 A1 15 30 13 1B 04 63 69 66 73 1B 0B 4C 4F ....0... cifs..LO >+[1370] 43 41 4C 4B 54 45 53 54 36 A3 82 03 AE 30 82 03 CALKTEST 6....0.. >+[1380] AA A0 03 02 01 17 A1 03 02 01 02 A2 82 03 9C 04 ........ ........ >+[1390] 82 03 98 66 D8 19 46 FA CB 73 2D CF 88 FD 4A EE ...f..F. .s-...J. >+[13A0] 07 48 DA 0E BC 58 30 43 40 A4 9C 00 0F 3B 17 C1 .H...X0C @....;.. >+[13B0] 2D F5 9C 3E D9 2F 1D CA 01 9B D7 2E EC D7 70 ED -..>./.. ......p. >+[13C0] 8B 8B 1B 5E F2 4E EE DD 0F C0 8D 61 E5 D7 0A 56 ...^.N.. ...a...V >+[13D0] 00 32 B1 DB 91 37 29 0F 2F 85 EE A8 43 BA A5 B8 .2...7). /...C... >+[13E0] D4 19 74 33 F0 69 52 E1 58 98 83 D6 16 0B 44 A9 ..t3.iR. X.....D. >+[13F0] 63 9B D4 4E 6E A7 3E CD 9A 96 4D C4 96 F5 07 6D c..Nn.>. ..M....m >+[1400] 29 B6 ED 2A 62 3D 53 22 33 D1 95 E9 DF 74 4C 2A )..*b=S" 3....tL* >+[1410] E2 29 AF 5B 69 B0 48 2D AD 94 FD A5 1D 54 D8 E2 .).[i.H- .....T.. >+[1420] 5E C1 68 6F BA 02 01 79 C3 C9 97 0B 76 66 45 E2 ^.ho...y ....vfE. >+[1430] 3B 10 17 95 40 46 E4 85 B9 87 BB CF CF 19 8C 3A ;...@F.. .......: >+[1440] C0 EA 38 3B B9 E9 4B 05 89 E5 27 8C 62 95 BC 0D ..8;..K. ..'.b... >+[1450] 65 F0 D2 C0 5E BC 65 01 D5 0B CB 17 31 0F 06 49 e...^.e. ....1..I >+[1460] 4F A2 4A 70 77 DB BD 92 5B 37 5C EC 06 DF C5 E2 O.Jpw... [7\..... >+[1470] 31 C8 40 09 11 68 14 E7 7D CE 54 4F 52 61 31 2C 1.@..h.. }.TORa1, >+[1480] 1C 53 52 DB BE D8 95 39 EE 7D C6 CE C8 22 95 92 .SR....9 .}...".. >+[1490] 97 97 3D 5E 66 0F AD DC C2 4E 2E 2B 9F 63 20 30 ..=^f... .N.+.c 0 >+[14A0] DF B7 C1 D4 65 AA 6F 2D 10 24 07 20 8D 88 6E 4B ....e.o- .$. ..nK >+[14B0] 09 04 31 B6 A3 EB F7 37 32 0E 0C 73 C6 F6 B8 4D ..1....7 2..s...M >+[14C0] D9 0C 4C 5B EC 10 6A 51 19 EA 3F FF 46 E7 73 16 ..L[..jQ ..?.F.s. >+[14D0] A7 1F 33 98 7C 9B AD 5A 23 A9 40 7C 0F DF EE 0F ..3.|..Z #.@|.... >+[14E0] AA C7 E8 63 07 98 3A 4A 0D 18 62 01 21 B2 AE A5 ...c..:J ..b.!... >+[14F0] 69 B0 C1 15 51 BA 97 D2 C5 42 5B C5 30 38 18 A9 i...Q... .B[.08.. >+[1500] 48 AB D7 FC A1 BC 9F 71 E7 EA 18 54 42 DA D6 A4 H......q ...TB... >+[1510] FC C1 DC F3 12 30 62 AC 98 E1 7D 2B 34 1E 52 4C .....0b. ..}+4.RL >+[1520] 26 67 32 D9 44 1A 08 27 0E DA D0 FC 84 66 35 81 &g2.D..' .....f5. >+[1530] D6 EB 98 46 6F 1E 47 E0 14 31 BE 47 80 65 AA 0B ...Fo.G. .1.G.e.. >+[1540] 20 D6 33 36 3B 0D 40 2F 5A 2E 0E 01 BE 00 EB 33 .36;.@/ Z......3 >+[1550] 3E 4B 32 91 F4 22 96 E5 5F D4 D5 92 94 CC 5B 59 >K2..".. _.....[Y >+[1560] 6A 3E D2 FB A0 4F 99 C4 07 8B 6F 2B 14 37 CD 37 j>...O.. ..o+.7.7 >+[1570] 44 C0 1F 80 9C 43 46 F2 5E F4 FE D3 39 70 61 BE D....CF. ^...9pa. >+[1580] 72 5B 3A 8F 37 95 78 1E AB D9 E7 E9 DA FC 47 09 r[:.7.x. ......G. >+[1590] 81 A0 0D 62 E1 F9 34 36 D1 DB E6 98 D8 F4 3E 77 ...b..46 ......>w >+[15A0] 5A 4D E2 5F 20 70 3D 3D 5B 34 D9 FD A8 31 F7 D9 ZM._ p== [4...1.. >+[15B0] 59 F7 A3 F0 66 F7 D9 AD 1C CD D5 85 33 A0 87 22 Y...f... ....3.." >+[15C0] 31 D4 F3 67 80 68 20 A2 90 72 7A 6F 64 FD 68 82 1..g.h . .rzod.h. >+[15D0] 9E 91 B8 E3 F7 6D 6C 38 74 F0 96 A2 F6 25 D7 92 .....ml8 t....%.. >+[15E0] 58 14 60 9F AE 01 4C 0C 09 67 3E 35 67 71 1E 2A X.`...L. .g>5gq.* >+[15F0] 86 21 D3 60 61 98 16 94 67 0B 52 76 63 93 BD A3 .!.`a... g.Rvc... >+[1600] 3B A9 F0 A2 6A B7 E6 0F 35 64 DA 6A EA 20 A6 3D ;...j... 5d.j. .= >+[1610] 94 71 59 5E CB B2 D3 F9 4D FE 1B 4B D8 64 C8 3B .qY^.... M..K.d.; >+[1620] 7A A8 E6 D2 D5 76 71 26 D4 5C DA 1A 55 17 F2 16 z....vq& .\..U... >+[1630] C9 2F 77 DB 95 19 48 A5 AC D0 C3 31 9C 0A CC 1B ./w...H. ...1.... >+[1640] 44 11 6B 7C 88 7A 5D CF 6E 12 DA EF C5 C7 34 1D D.k|.z]. n.....4. >+[1650] F4 CC EA 37 24 4B B3 0F C1 A3 F2 29 A0 D8 93 39 ...7$K.. ...)...9 >+[1660] C6 16 57 D5 BF 57 BF 6C 7E F7 90 E0 EB A3 8B 07 ..W..W.l ~....... >+[1670] 56 9C EC 15 3E 21 DA A5 7C 00 3C F9 D2 A7 1C 6F V...>!.. |.<....o >+[1680] 16 25 31 C5 28 A7 EA F3 47 31 50 DD E1 ED 0A 93 .%1.(... G1P..... >+[1690] DB 85 CC 6B 4B 2C 7F E8 F8 2D A9 6D 1D 0A 87 F2 ...kK,.. .-.m.... >+[16A0] 10 8C 82 2F 9B D4 9B 92 8C 77 40 50 42 1E 42 C4 .../.... .w@PB.B. >+[16B0] 0A 4F E3 6C 6C DC 81 C4 1E BB F0 7D CF 3C 73 22 .O.ll... ...}.<s" >+[16C0] 5B C3 1A 97 35 EE 3A CD 6D F3 68 A3 C5 65 7E E9 [...5.:. m.h..e~. >+[16D0] 54 C0 E3 7D 6A 32 4C D1 3E D0 78 4B BF 18 9F A5 T..}j2L. >.xK.... >+[16E0] 25 4A 92 1E 6C 8F 01 D6 59 D7 CF 2E A0 CC 98 F6 %J..l... Y....... >+[16F0] 75 28 2F F7 2A 70 28 A9 45 1F 75 C2 4E 62 ED D8 u(/.*p(. E.u.Nb.. >+[1700] C4 A0 8D 55 B2 84 1C A4 CE 87 EF 24 EE BC CE 40 ...U.... ...$...@ >+[1710] 09 EB 05 0B D1 14 31 50 32 2F B6 A8 97 17 4B A7 ......1P 2/....K. >+[1720] 95 01 50 6E 0E 23 49 9C 72 21 91 00 00 00 00 00 ..Pn.#I. r!...... >+[1730] 00 00 01 00 00 00 01 00 00 00 17 4B 54 45 53 54 ........ ...KTEST >+[1740] 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 .SAMBA.E XAMPLE.C >+[1750] 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 73 74 72 61 OM....ad ministra >+[1760] 74 6F 72 00 00 00 01 00 00 00 02 00 00 00 17 4B tor..... .......K >+[1770] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[1780] 4C 45 2E 43 4F 4D 00 00 00 04 63 69 66 73 00 00 LE.COM.. ..cifs.. >+[1790] 00 0B 4C 4F 43 41 4C 4B 54 45 53 54 36 00 17 00 ..LOCALK TEST6... >+[17A0] 00 00 10 1D C8 5E 46 48 82 F9 29 DB C6 A6 F1 72 .....^FH ..)....r >+[17B0] 6D 8D E9 4D 99 4F 6A 4D 99 85 09 7D 44 0B 68 00 m..M.OjM ...}D.h. >+[17C0] 00 00 00 00 40 28 00 00 00 00 00 00 00 00 00 00 ....@(.. ........ >+[17D0] 00 00 03 FA 61 82 03 F6 30 82 03 F2 A0 03 02 01 ....a... 0....... >+[17E0] 05 A1 19 1B 17 4B 54 45 53 54 2E 53 41 4D 42 41 .....KTE ST.SAMBA >+[17F0] 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D A2 1E 30 1C .EXAMPLE .COM..0. >+[1800] A0 03 02 01 01 A1 15 30 13 1B 04 63 69 66 73 1B .......0 ...cifs. >+[1810] 0B 4C 4F 43 41 4C 4B 54 45 53 54 36 A3 82 03 AE .LOCALKT EST6.... >+[1820] 30 82 03 AA A0 03 02 01 17 A1 03 02 01 02 A2 82 0....... ........ >+[1830] 03 9C 04 82 03 98 66 D8 19 46 FA CB 73 2D CF 88 ......f. .F..s-.. >+[1840] FD 4A EE 07 48 DA 0E BC 58 30 43 40 A4 9C 00 0F .J..H... X0C@.... >+[1850] 3B 17 C1 2D F5 9C 3E D9 2F 1D CA 01 9B D7 2E EC ;..-..>. /....... >+[1860] D7 70 ED 8B 8B 1B 5E F2 4E EE DD 0F C0 8D 61 E5 .p....^. N.....a. >+[1870] D7 0A 56 00 32 B1 DB 91 37 29 0F 2F 85 EE A8 43 ..V.2... 7)./...C >+[1880] BA A5 B8 D4 19 74 33 F0 69 52 E1 58 98 83 D6 16 .....t3. iR.X.... >+[1890] 0B 44 A9 63 9B D4 4E 6E A7 3E CD 9A 96 4D C4 96 .D.c..Nn .>...M.. >+[18A0] F5 07 6D 29 B6 ED 2A 62 3D 53 22 33 D1 95 E9 DF ..m)..*b =S"3.... >+[18B0] 74 4C 2A E2 29 AF 5B 69 B0 48 2D AD 94 FD A5 1D tL*.).[i .H-..... >+[18C0] 54 D8 E2 5E C1 68 6F BA 02 01 79 C3 C9 97 0B 76 T..^.ho. ..y....v >+[18D0] 66 45 E2 3B 10 17 95 40 46 E4 85 B9 87 BB CF CF fE.;...@ F....... >+[18E0] 19 8C 3A C0 EA 38 3B B9 E9 4B 05 89 E5 27 8C 62 ..:..8;. .K...'.b >+[18F0] 95 BC 0D 65 F0 D2 C0 5E BC 65 01 D5 0B CB 17 31 ...e...^ .e.....1 >+[1900] 0F 06 49 4F A2 4A 70 77 DB BD 92 5B 37 5C EC 06 ..IO.Jpw ...[7\.. >+[1910] DF C5 E2 31 C8 40 09 11 68 14 E7 7D CE 54 4F 52 ...1.@.. h..}.TOR >+[1920] 61 31 2C 1C 53 52 DB BE D8 95 39 EE 7D C6 CE C8 a1,.SR.. ..9.}... >+[1930] 22 95 92 97 97 3D 5E 66 0F AD DC C2 4E 2E 2B 9F "....=^f ....N.+. >+[1940] 63 20 30 DF B7 C1 D4 65 AA 6F 2D 10 24 07 20 8D c 0....e .o-.$. . >+[1950] 88 6E 4B 09 04 31 B6 A3 EB F7 37 32 0E 0C 73 C6 .nK..1.. ..72..s. >+[1960] F6 B8 4D D9 0C 4C 5B EC 10 6A 51 19 EA 3F FF 46 ..M..L[. .jQ..?.F >+[1970] E7 73 16 A7 1F 33 98 7C 9B AD 5A 23 A9 40 7C 0F .s...3.| ..Z#.@|. >+[1980] DF EE 0F AA C7 E8 63 07 98 3A 4A 0D 18 62 01 21 ......c. .:J..b.! >+[1990] B2 AE A5 69 B0 C1 15 51 BA 97 D2 C5 42 5B C5 30 ...i...Q ....B[.0 >+[19A0] 38 18 A9 48 AB D7 FC A1 BC 9F 71 E7 EA 18 54 42 8..H.... ..q...TB >+[19B0] DA D6 A4 FC C1 DC F3 12 30 62 AC 98 E1 7D 2B 34 ........ 0b...}+4 >+[19C0] 1E 52 4C 26 67 32 D9 44 1A 08 27 0E DA D0 FC 84 .RL&g2.D ..'..... >+[19D0] 66 35 81 D6 EB 98 46 6F 1E 47 E0 14 31 BE 47 80 f5....Fo .G..1.G. >+[19E0] 65 AA 0B 20 D6 33 36 3B 0D 40 2F 5A 2E 0E 01 BE e.. .36; .@/Z.... >+[19F0] 00 EB 33 3E 4B 32 91 F4 22 96 E5 5F D4 D5 92 94 ..3>K2.. ".._.... >+[1A00] CC 5B 59 6A 3E D2 FB A0 4F 99 C4 07 8B 6F 2B 14 .[Yj>... O....o+. >+[1A10] 37 CD 37 44 C0 1F 80 9C 43 46 F2 5E F4 FE D3 39 7.7D.... CF.^...9 >+[1A20] 70 61 BE 72 5B 3A 8F 37 95 78 1E AB D9 E7 E9 DA pa.r[:.7 .x...... >+[1A30] FC 47 09 81 A0 0D 62 E1 F9 34 36 D1 DB E6 98 D8 .G....b. .46..... >+[1A40] F4 3E 77 5A 4D E2 5F 20 70 3D 3D 5B 34 D9 FD A8 .>wZM._ p==[4... >+[1A50] 31 F7 D9 59 F7 A3 F0 66 F7 D9 AD 1C CD D5 85 33 1..Y...f .......3 >+[1A60] A0 87 22 31 D4 F3 67 80 68 20 A2 90 72 7A 6F 64 .."1..g. h ..rzod >+[1A70] FD 68 82 9E 91 B8 E3 F7 6D 6C 38 74 F0 96 A2 F6 .h...... ml8t.... >+[1A80] 25 D7 92 58 14 60 9F AE 01 4C 0C 09 67 3E 35 67 %..X.`.. .L..g>5g >+[1A90] 71 1E 2A 86 21 D3 60 61 98 16 94 67 0B 52 76 63 q.*.!.`a ...g.Rvc >+[1AA0] 93 BD A3 3B A9 F0 A2 6A B7 E6 0F 35 64 DA 6A EA ...;...j ...5d.j. >+[1AB0] 20 A6 3D 94 71 59 5E CB B2 D3 F9 4D FE 1B 4B D8 .=.qY^. ...M..K. >+[1AC0] 64 C8 3B 7A A8 E6 D2 D5 76 71 26 D4 5C DA 1A 55 d.;z.... vq&.\..U >+[1AD0] 17 F2 16 C9 2F 77 DB 95 19 48 A5 AC D0 C3 31 9C ..../w.. .H....1. >+[1AE0] 0A CC 1B 44 11 6B 7C 88 7A 5D CF 6E 12 DA EF C5 ...D.k|. z].n.... >+[1AF0] C7 34 1D F4 CC EA 37 24 4B B3 0F C1 A3 F2 29 A0 .4....7$ K.....). >+[1B00] D8 93 39 C6 16 57 D5 BF 57 BF 6C 7E F7 90 E0 EB ..9..W.. W.l~.... >+[1B10] A3 8B 07 56 9C EC 15 3E 21 DA A5 7C 00 3C F9 D2 ...V...> !..|.<.. >+[1B20] A7 1C 6F 16 25 31 C5 28 A7 EA F3 47 31 50 DD E1 ..o.%1.( ...G1P.. >+[1B30] ED 0A 93 DB 85 CC 6B 4B 2C 7F E8 F8 2D A9 6D 1D ......kK ,...-.m. >+[1B40] 0A 87 F2 10 8C 82 2F 9B D4 9B 92 8C 77 40 50 42 ....../. ....w@PB >+[1B50] 1E 42 C4 0A 4F E3 6C 6C DC 81 C4 1E BB F0 7D CF .B..O.ll ......}. >+[1B60] 3C 73 22 5B C3 1A 97 35 EE 3A CD 6D F3 68 A3 C5 <s"[...5 .:.m.h.. >+[1B70] 65 7E E9 54 C0 E3 7D 6A 32 4C D1 3E D0 78 4B BF e~.T..}j 2L.>.xK. >+[1B80] 18 9F A5 25 4A 92 1E 6C 8F 01 D6 59 D7 CF 2E A0 ...%J..l ...Y.... >+[1B90] CC 98 F6 75 28 2F F7 2A 70 28 A9 45 1F 75 C2 4E ...u(/.* p(.E.u.N >+[1BA0] 62 ED D8 C4 A0 8D 55 B2 84 1C A4 CE 87 EF 24 EE b.....U. ......$. >+[1BB0] BC CE 40 09 EB 05 0B D1 14 31 50 32 2F B6 A8 97 ..@..... .1P2/... >+[1BC0] 17 4B A7 95 01 50 6E 0E 23 49 9C 72 21 91 00 00 .K...Pn. #I.r!... >+[1BD0] 00 00 00 00 00 01 00 00 00 01 00 00 00 17 4B 54 ........ ......KT >+[1BE0] 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C EST.SAMB A.EXAMPL >+[1BF0] 45 2E 43 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 73 E.COM... .adminis >+[1C00] 74 72 61 74 6F 72 00 00 00 01 00 00 00 02 00 00 trator.. ........ >+[1C10] 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 ..KTEST. SAMBA.EX >+[1C20] 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 04 63 69 66 AMPLE.CO M....cif >+[1C30] 73 00 00 00 0B 4C 4F 43 41 4C 4B 54 45 53 54 36 s....LOC ALKTEST6 >+[1C40] 00 17 00 00 00 10 1D C8 5E 46 48 82 F9 29 DB C6 ........ ^FH..).. >+[1C50] A6 F1 72 6D 8D E9 4D 99 4F 6A 4D 99 85 09 7D 44 ..rm..M. OjM...}D >+[1C60] 0B 68 00 00 00 00 00 40 28 00 00 00 00 00 00 00 .h.....@ (....... >+[1C70] 00 00 00 00 00 03 FA 61 82 03 F6 30 82 03 F2 A0 .......a ...0.... >+[1C80] 03 02 01 05 A1 19 1B 17 4B 54 45 53 54 2E 53 41 ........ KTEST.SA >+[1C90] 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D A2 MBA.EXAM PLE.COM. >+[1CA0] 1E 30 1C A0 03 02 01 01 A1 15 30 13 1B 04 63 69 .0...... ..0...ci >+[1CB0] 66 73 1B 0B 4C 4F 43 41 4C 4B 54 45 53 54 36 A3 fs..LOCA LKTEST6. >+[1CC0] 82 03 AE 30 82 03 AA A0 03 02 01 17 A1 03 02 01 ...0.... ........ >+[1CD0] 02 A2 82 03 9C 04 82 03 98 66 D8 19 46 FA CB 73 ........ .f..F..s >+[1CE0] 2D CF 88 FD 4A EE 07 48 DA 0E BC 58 30 43 40 A4 -...J..H ...X0C@. >+[1CF0] 9C 00 0F 3B 17 C1 2D F5 9C 3E D9 2F 1D CA 01 9B ...;..-. .>./.... >+[1D00] D7 2E EC D7 70 ED 8B 8B 1B 5E F2 4E EE DD 0F C0 ....p... .^.N.... >+[1D10] 8D 61 E5 D7 0A 56 00 32 B1 DB 91 37 29 0F 2F 85 .a...V.2 ...7)./. >+[1D20] EE A8 43 BA A5 B8 D4 19 74 33 F0 69 52 E1 58 98 ..C..... t3.iR.X. >+[1D30] 83 D6 16 0B 44 A9 63 9B D4 4E 6E A7 3E CD 9A 96 ....D.c. .Nn.>... >+[1D40] 4D C4 96 F5 07 6D 29 B6 ED 2A 62 3D 53 22 33 D1 M....m). .*b=S"3. >+[1D50] 95 E9 DF 74 4C 2A E2 29 AF 5B 69 B0 48 2D AD 94 ...tL*.) .[i.H-.. >+[1D60] FD A5 1D 54 D8 E2 5E C1 68 6F BA 02 01 79 C3 C9 ...T..^. ho...y.. >+[1D70] 97 0B 76 66 45 E2 3B 10 17 95 40 46 E4 85 B9 87 ..vfE.;. ..@F.... >+[1D80] BB CF CF 19 8C 3A C0 EA 38 3B B9 E9 4B 05 89 E5 .....:.. 8;..K... >+[1D90] 27 8C 62 95 BC 0D 65 F0 D2 C0 5E BC 65 01 D5 0B '.b...e. ..^.e... >+[1DA0] CB 17 31 0F 06 49 4F A2 4A 70 77 DB BD 92 5B 37 ..1..IO. Jpw...[7 >+[1DB0] 5C EC 06 DF C5 E2 31 C8 40 09 11 68 14 E7 7D CE \.....1. @..h..}. >+[1DC0] 54 4F 52 61 31 2C 1C 53 52 DB BE D8 95 39 EE 7D TORa1,.S R....9.} >+[1DD0] C6 CE C8 22 95 92 97 97 3D 5E 66 0F AD DC C2 4E ...".... =^f....N >+[1DE0] 2E 2B 9F 63 20 30 DF B7 C1 D4 65 AA 6F 2D 10 24 .+.c 0.. ..e.o-.$ >+[1DF0] 07 20 8D 88 6E 4B 09 04 31 B6 A3 EB F7 37 32 0E . ..nK.. 1....72. >+[1E00] 0C 73 C6 F6 B8 4D D9 0C 4C 5B EC 10 6A 51 19 EA .s...M.. L[..jQ.. >+[1E10] 3F FF 46 E7 73 16 A7 1F 33 98 7C 9B AD 5A 23 A9 ?.F.s... 3.|..Z#. >+[1E20] 40 7C 0F DF EE 0F AA C7 E8 63 07 98 3A 4A 0D 18 @|...... .c..:J.. >+[1E30] 62 01 21 B2 AE A5 69 B0 C1 15 51 BA 97 D2 C5 42 b.!...i. ..Q....B >+[1E40] 5B C5 30 38 18 A9 48 AB D7 FC A1 BC 9F 71 E7 EA [.08..H. .....q.. >+[1E50] 18 54 42 DA D6 A4 FC C1 DC F3 12 30 62 AC 98 E1 .TB..... ...0b... >+[1E60] 7D 2B 34 1E 52 4C 26 67 32 D9 44 1A 08 27 0E DA }+4.RL&g 2.D..'.. >+[1E70] D0 FC 84 66 35 81 D6 EB 98 46 6F 1E 47 E0 14 31 ...f5... .Fo.G..1 >+[1E80] BE 47 80 65 AA 0B 20 D6 33 36 3B 0D 40 2F 5A 2E .G.e.. . 36;.@/Z. >+[1E90] 0E 01 BE 00 EB 33 3E 4B 32 91 F4 22 96 E5 5F D4 .....3>K 2..".._. >+[1EA0] D5 92 94 CC 5B 59 6A 3E D2 FB A0 4F 99 C4 07 8B ....[Yj> ...O.... >+[1EB0] 6F 2B 14 37 CD 37 44 C0 1F 80 9C 43 46 F2 5E F4 o+.7.7D. ...CF.^. >+[1EC0] FE D3 39 70 61 BE 72 5B 3A 8F 37 95 78 1E AB D9 ..9pa.r[ :.7.x... >+[1ED0] E7 E9 DA FC 47 09 81 A0 0D 62 E1 F9 34 36 D1 DB ....G... .b..46.. >+[1EE0] E6 98 D8 F4 3E 77 5A 4D E2 5F 20 70 3D 3D 5B 34 ....>wZM ._ p==[4 >+[1EF0] D9 FD A8 31 F7 D9 59 F7 A3 F0 66 F7 D9 AD 1C CD ...1..Y. ..f..... >+[1F00] D5 85 33 A0 87 22 31 D4 F3 67 80 68 20 A2 90 72 ..3.."1. .g.h ..r >+[1F10] 7A 6F 64 FD 68 82 9E 91 B8 E3 F7 6D 6C 38 74 F0 zod.h... ...ml8t. >+[1F20] 96 A2 F6 25 D7 92 58 14 60 9F AE 01 4C 0C 09 67 ...%..X. `...L..g >+[1F30] 3E 35 67 71 1E 2A 86 21 D3 60 61 98 16 94 67 0B >5gq.*.! .`a...g. >+[1F40] 52 76 63 93 BD A3 3B A9 F0 A2 6A B7 E6 0F 35 64 Rvc...;. ..j...5d >+[1F50] DA 6A EA 20 A6 3D 94 71 59 5E CB B2 D3 F9 4D FE .j. .=.q Y^....M. >+[1F60] 1B 4B D8 64 C8 3B 7A A8 E6 D2 D5 76 71 26 D4 5C .K.d.;z. ...vq&.\ >+[1F70] DA 1A 55 17 F2 16 C9 2F 77 DB 95 19 48 A5 AC D0 ..U..../ w...H... >+[1F80] C3 31 9C 0A CC 1B 44 11 6B 7C 88 7A 5D CF 6E 12 .1....D. k|.z].n. >+[1F90] DA EF C5 C7 34 1D F4 CC EA 37 24 4B B3 0F C1 A3 ....4... .7$K.... >+[1FA0] F2 29 A0 D8 93 39 C6 16 57 D5 BF 57 BF 6C 7E F7 .)...9.. W..W.l~. >+[1FB0] 90 E0 EB A3 8B 07 56 9C EC 15 3E 21 DA A5 7C 00 ......V. ..>!..|. >+[1FC0] 3C F9 D2 A7 1C 6F 16 25 31 C5 28 A7 EA F3 47 31 <....o.% 1.(...G1 >+[1FD0] 50 DD E1 ED 0A 93 DB 85 CC 6B 4B 2C 7F E8 F8 2D P....... .kK,...- >+[1FE0] A9 6D 1D 0A 87 F2 10 8C 82 2F 9B D4 9B 92 8C 77 .m...... ./.....w >+[1FF0] 40 50 42 1E 42 C4 0A 4F E3 6C 6C DC 81 C4 1E BB @PB.B..O .ll..... >+[2000] F0 7D CF 3C 73 22 5B C3 1A 97 35 EE 3A CD 6D F3 .}.<s"[. ..5.:.m. >+[2010] 68 A3 C5 65 7E E9 54 C0 E3 7D 6A 32 4C D1 3E D0 h..e~.T. .}j2L.>. >+[2020] 78 4B BF 18 9F A5 25 4A 92 1E 6C 8F 01 D6 59 D7 xK....%J ..l...Y. >+[2030] CF 2E A0 CC 98 F6 75 28 2F F7 2A 70 28 A9 45 1F ......u( /.*p(.E. >+[2040] 75 C2 4E 62 ED D8 C4 A0 8D 55 B2 84 1C A4 CE 87 u.Nb.... .U...... >+[2050] EF 24 EE BC CE 40 09 EB 05 0B D1 14 31 50 32 2F .$...@.. ....1P2/ >+[2060] B6 A8 97 17 4B A7 95 01 50 6E 0E 23 49 9C 72 21 ....K... Pn.#I.r! >+[2070] 91 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 ........ ........ >+[2080] 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 .KTEST.S AMBA.EXA >+[2090] 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D 61 64 6D 69 MPLE.COM ....admi >+[20A0] 6E 69 73 74 72 61 74 6F 72 00 00 00 01 00 00 00 nistrato r....... >+[20B0] 02 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 .....KTE ST.SAMBA >+[20C0] 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 04 .EXAMPLE .COM.... >+[20D0] 68 6F 73 74 00 00 00 0B 6C 6F 63 61 6C 6B 74 65 host.... localkte >+[20E0] 73 74 36 00 17 00 00 00 10 72 47 04 38 B6 E6 F0 st6..... .rG.8... >+[20F0] 44 9E 9F 27 66 E1 69 9C 9A 4D 99 4F 6A 4D 99 90 D..'f.i. .M.OjM.. >+[2100] F5 7D 44 0B 68 00 00 00 00 00 40 28 00 00 00 00 .}D.h... ..@(.... >+[2110] 00 00 00 00 00 00 00 00 03 FA 61 82 03 F6 30 82 ........ ..a...0. >+[2120] 03 F2 A0 03 02 01 05 A1 19 1B 17 4B 54 45 53 54 ........ ...KTEST >+[2130] 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 .SAMBA.E XAMPLE.C >+[2140] 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 15 30 13 1B OM..0... .....0.. >+[2150] 04 68 6F 73 74 1B 0B 6C 6F 63 61 6C 6B 74 65 73 .host..l ocalktes >+[2160] 74 36 A3 82 03 AE 30 82 03 AA A0 03 02 01 17 A1 t6....0. ........ >+[2170] 03 02 01 02 A2 82 03 9C 04 82 03 98 58 95 95 EB ........ ....X... >+[2180] CB 8F 68 D4 77 43 0F 3B 44 B4 15 DA 40 6D FD E9 ..h.wC.; D...@m.. >+[2190] 85 D3 2F CD B5 1E 96 CD F6 E9 67 91 36 08 9E B4 ../..... ..g.6... >+[21A0] B3 47 70 7A B3 4E 82 5A 4F 8E 4B F5 8D 04 E4 5C .Gpz.N.Z O.K....\ >+[21B0] C4 D8 0C AF 08 25 F9 C1 64 B2 3A 35 26 E9 B2 72 .....%.. d.:5&..r >+[21C0] 66 B5 E9 81 FC BE 12 1B CC 8A A5 82 31 F6 7F C3 f....... ....1... >+[21D0] 5A 19 A3 31 F2 99 14 1E 64 E4 41 E8 C7 C3 F3 DF Z..1.... d.A..... >+[21E0] F5 65 7D B0 9F DC 5D 25 1D 1A A8 EA AA 88 6D F4 .e}...]% ......m. >+[21F0] 7C 25 9F 53 F6 A6 8F B1 24 AF 98 FE 53 7B 35 3C |%.S.... $...S{5< >+[2200] DB EC 7F 09 74 E9 C4 8D 20 B4 47 08 0E 32 B8 C9 ....t... .G..2.. >+[2210] 45 27 12 F9 8E F5 D6 C2 DD 1A 96 0E 68 5F 39 65 E'...... ....h_9e >+[2220] 72 C7 BD 8E 04 0E 13 E1 03 27 AC 50 80 76 E6 7A r....... .'.P.v.z >+[2230] 8E F4 C2 72 4F 68 B3 34 00 A9 54 41 DA FD 96 94 ...rOh.4 ..TA.... >+[2240] 29 A1 59 15 2F DB 6C 94 85 49 C5 D0 6D 48 B0 C4 ).Y./.l. .I..mH.. >+[2250] 65 D0 95 1D DB 3D 25 D0 75 50 D4 CF FA 2F 71 57 e....=%. uP.../qW >+[2260] BD 6C 1C 59 E1 C3 5B C7 24 95 FF B0 20 EF 6A DB .l.Y..[. $... .j. >+[2270] 79 87 67 91 94 E9 16 E2 BB 74 7A 08 E1 6A 36 5F y.g..... .tz..j6_ >+[2280] DF 11 AB 35 9B 3E 32 48 83 89 41 4E 06 BF F9 BB ...5.>2H ..AN.... >+[2290] EC E4 D7 6D 77 C4 55 22 DF F7 91 4D CB C5 01 A5 ...mw.U" ...M.... >+[22A0] BA 2D 1E 92 76 04 E8 02 2F 5E AF 1C B3 B7 A6 FB .-..v... /^...... >+[22B0] 3A 9F D9 7C 6D DA B4 8F 31 00 A5 30 F2 76 72 9B :..|m... 1..0.vr. >+[22C0] 62 97 E0 56 E5 E4 C7 6B 8B FC 84 75 57 66 6E D7 b..V...k ...uWfn. >+[22D0] B7 41 6F 61 F4 5B 0F 87 68 F6 54 02 26 1B 1F B7 .Aoa.[.. h.T.&... >+[22E0] 60 D6 E7 FA 4F C7 DB 35 58 EC 13 21 D4 C6 A1 27 `...O..5 X..!...' >+[22F0] BA E7 82 DF 29 FB 9D 5D E8 35 28 C9 9C 4E D7 BE ....)..] .5(..N.. >+[2300] 2F 6D F1 E8 0B 5A 74 C9 93 9F AD 42 24 4B B7 3B /m...Zt. ...B$K.; >+[2310] 38 2A 11 CF F0 BD 85 40 48 D8 9D E7 6B 65 70 42 8*.....@ H...kepB >+[2320] 60 DA 9B 65 CB C8 C5 D7 40 3A 12 DC 64 AF 82 54 `..e.... @:..d..T >+[2330] 34 05 38 4F C6 FB 38 E2 73 A9 89 B7 FC 33 15 85 4.8O..8. s....3.. >+[2340] 9E CA E9 E0 89 18 18 84 02 65 B4 74 5B D4 A1 6F ........ .e.t[..o >+[2350] 5F 79 20 CB D7 36 C8 6D 5B 1E 5E 0C 82 16 9F CC _y ..6.m [.^..... >+[2360] 5A 1E 57 C1 B6 94 51 87 A1 3D 12 D4 8B FE 0F 93 Z.W...Q. .=...... >+[2370] ED 53 A3 F4 88 3C 35 05 89 FE AF 0B 36 62 E3 2F .S...<5. ....6b./ >+[2380] 5C 4A 0E 07 67 39 A3 8E C0 45 07 7F 73 32 BC DE \J..g9.. .E..s2.. >+[2390] 2D 00 8B 47 79 3D 1C A1 90 AE B6 8F 83 B2 1B 31 -..Gy=.. .......1 >+[23A0] EE E4 F2 C5 C1 4A E2 4A 2F 28 F0 AA 19 43 6A 14 .....J.J /(...Cj. >+[23B0] B1 42 61 90 34 2E EE 3D 16 9F 5D 9F 7A A2 01 7A .Ba.4..= ..].z..z >+[23C0] 4B 96 FA 4D C9 85 1A 75 27 B7 6B FD 4D 7D 9C 65 K..M...u '.k.M}.e >+[23D0] 97 DB 05 CC 76 68 EA 05 5D 5D BB BD 51 4B 5B F2 ....vh.. ]]..QK[. >+[23E0] 48 59 BD 1E AD 56 D4 69 A5 75 CD ED EC B1 3E AB HY...V.i .u....>. >+[23F0] FA B7 F8 8D 4F BE 95 63 38 1C 4C 70 26 C4 3A 21 ....O..c 8.Lp&.:! >+[2400] 80 61 05 3A D4 E2 28 2C 85 01 5A DA FC 10 60 F3 .a.:..(, ..Z...`. >+[2410] 74 0C FD DB 2F 5B 25 4B 14 E4 7D 8A DB 85 12 D2 t.../[%K ..}..... >+[2420] D7 69 CD B5 B1 93 CE E5 E6 4D 57 D3 C2 D3 2E A0 .i...... .MW..... >+[2430] 08 37 09 CD 19 99 09 FA 33 68 4A E0 92 46 21 0C .7...... 3hJ..F!. >+[2440] 99 9F DA 05 15 20 8B 3D 7C 7B CA D6 81 AC AA 83 ..... .= |{...... >+[2450] 48 C8 24 4C C8 FC A5 14 2C BC 49 1A 1C 49 61 1D H.$L.... ,.I..Ia. >+[2460] 24 86 42 B1 37 6A C8 3A AC 18 CC C0 50 84 12 48 $.B.7j.: ....P..H >+[2470] 8B 29 0A 49 26 A4 E2 B9 E5 96 E7 37 C3 DE 4C 23 .).I&... ...7..L# >+[2480] D2 D4 62 14 8F 1E 72 39 CF 03 BC A3 00 C7 63 51 ..b...r9 ......cQ >+[2490] A9 6B E4 3E B2 65 A1 A2 BB EC 06 41 85 50 22 02 .k.>.e.. ...A.P". >+[24A0] 46 2F 72 2B 32 1A A4 2D 85 94 02 47 69 8D AD 6D F/r+2..- ...Gi..m >+[24B0] 66 AB D4 E4 29 C8 C7 DA F4 18 31 2A DF 50 6A 05 f...)... ..1*.Pj. >+[24C0] D6 47 26 C4 F9 87 0F 35 24 6E 72 D6 23 7D 3A 94 .G&....5 $nr.#}:. >+[24D0] 14 8D E8 57 AA BA D7 CF A9 2D E7 4C 10 7C D8 0D ...W.... .-.L.|.. >+[24E0] 51 30 1F E1 FB E5 E2 6C EE AA 65 2F D8 22 05 67 Q0.....l ..e/.".g >+[24F0] 87 4D 4D D2 11 3D B4 1E AA 20 3F 76 E3 94 93 6D .MM..=.. . ?v...m >+[2500] AC 10 05 AF 09 BD 67 86 C5 83 93 D6 1C D3 81 D9 ......g. ........ >+[2510] B1 3B E1 76 00 00 00 00 00 00 00 01 00 00 00 01 .;.v.... ........ >+[2520] 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E ....KTES T.SAMBA. >+[2530] 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D 61 EXAMPLE. COM....a >+[2540] 64 6D 69 6E 69 73 74 72 61 74 6F 72 00 00 00 01 dministr ator.... >+[2550] 00 00 00 02 00 00 00 17 4B 54 45 53 54 2E 53 41 ........ KTEST.SA >+[2560] 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 MBA.EXAM PLE.COM. >+[2570] 00 00 04 68 6F 73 74 00 00 00 0B 4C 4F 43 41 4C ...host. ...LOCAL >+[2580] 4B 54 45 53 54 36 00 17 00 00 00 10 55 6E 3E FC KTEST6.. ....Un>. >+[2590] E2 F4 40 51 19 E6 6E EB 23 4C 48 8E 4D 99 4F 6A ..@Q..n. #LH.M.Oj >+[25A0] 4D 99 90 FC 7D 44 0B 68 00 00 00 00 00 40 28 00 M...}D.h .....@(. >+[25B0] 00 00 00 00 00 00 00 00 00 00 00 03 FA 61 82 03 ........ .....a.. >+[25C0] F6 30 82 03 F2 A0 03 02 01 05 A1 19 1B 17 4B 54 .0...... ......KT >+[25D0] 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C EST.SAMB A.EXAMPL >+[25E0] 45 2E 43 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 15 E.COM..0 ........ >+[25F0] 30 13 1B 04 68 6F 73 74 1B 0B 4C 4F 43 41 4C 4B 0...host ..LOCALK >+[2600] 54 45 53 54 36 A3 82 03 AE 30 82 03 AA A0 03 02 TEST6... .0...... >+[2610] 01 17 A1 03 02 01 02 A2 82 03 9C 04 82 03 98 6E ........ .......n >+[2620] 87 B7 7B 3A 7E EF 4A 1B 29 C9 E3 C4 1F 42 4F 0E ..{:~.J. )....BO. >+[2630] C8 AC AC 4E A2 77 1D DA 93 37 F1 AF DA A3 75 2D ...N.w.. .7....u- >+[2640] 12 8B 40 34 23 0E 8E A9 90 58 46 42 42 39 31 D6 ..@4#... .XFBB91. >+[2650] 03 9E 5D 81 D9 E8 F6 08 2B D9 96 88 8A 2F F1 CC ..]..... +..../.. >+[2660] F2 EA 9E 9A 4B 31 B6 04 2D 3D 4C 7F 92 DE 3B 04 ....K1.. -=L...;. >+[2670] 19 EE 28 D0 83 81 C3 46 CD 74 23 4C 14 34 DE 62 ..(....F .t#L.4.b >+[2680] 0A AC E5 12 16 75 E9 A8 4B 32 78 CC 8D AE A2 E5 .....u.. K2x..... >+[2690] 6D E8 09 70 76 52 F5 E5 18 F7 E7 91 15 6A 69 AB m..pvR.. .....ji. >+[26A0] B8 62 DD 80 F5 28 6D DF ED 10 DA AC FB 92 27 CF .b...(m. ......'. >+[26B0] 98 B5 77 9D A5 96 E6 9A CC B9 C3 91 78 22 35 9C ..w..... ....x"5. >+[26C0] A1 13 A3 20 28 D1 16 E5 3E 4A 85 1E 12 0B CA 4D ... (... >J.....M >+[26D0] C6 C8 03 C8 28 2C D8 29 5D 9A 76 4A 92 13 43 56 ....(,.) ].vJ..CV >+[26E0] AF F7 C1 71 25 72 5C 38 75 1C 07 F1 5E 86 05 72 ...q%r\8 u...^..r >+[26F0] 6F 69 95 42 B6 F2 DA A9 91 06 9F B9 54 20 33 A5 oi.B.... ....T 3. >+[2700] 31 60 3B 54 DC 3A 95 34 96 26 07 52 6B 0E 1D 3B 1`;T.:.4 .&.Rk..; >+[2710] D9 F8 48 20 AC CD 05 3B 99 F8 EE DB 83 28 CD C7 ..H ...; .....(.. >+[2720] 2F 45 00 7E 2F 0A 65 7A D1 9E 95 4B EE C3 34 93 /E.~/.ez ...K..4. >+[2730] A8 C7 DF 03 8B 14 D0 FC CE 56 90 AC EE 93 C5 D3 ........ .V...... >+[2740] F7 12 24 69 0B 20 8D A2 65 87 55 26 2A F9 9A 88 ..$i. .. e.U&*... >+[2750] D7 0D 86 61 D6 92 B6 FE E5 D1 66 F9 1F 9D F4 04 ...a.... ..f..... >+[2760] 48 A6 39 BC 54 20 EA 10 21 E9 6D 30 46 1D C2 1C H.9.T .. !.m0F... >+[2770] A4 E8 B4 63 85 37 27 25 80 52 41 60 C7 A1 32 21 ...c.7'% .RA`..2! >+[2780] 43 90 02 E6 5F 5A E9 4E AF F9 B5 13 BD 42 BD A3 C..._Z.N .....B.. >+[2790] A5 4D 10 45 83 4D 92 18 1F C9 CF FB 84 29 89 23 .M.E.M.. .....).# >+[27A0] AC 71 4B 89 1B 52 E5 06 8C 3E 7C 88 CB D3 B3 CF .qK..R.. .>|..... >+[27B0] B9 7A 67 D6 24 F4 AC 00 A6 AD 91 30 9A 95 53 F1 .zg.$... ...0..S. >+[27C0] 48 06 A6 39 DB CF DC 9D C9 55 76 26 5E C1 DB 5D H..9.... .Uv&^..] >+[27D0] B3 5B 3E AE 1A A0 10 BA 82 21 83 44 02 E0 99 33 .[>..... .!.D...3 >+[27E0] 40 BA 29 9E 28 E5 73 4C 23 94 A2 4F BF 07 ED 4F @.).(.sL #..O...O >+[27F0] 7C 45 9B 30 C8 41 6B 0A 55 13 6E F5 AD 7A 0C B2 |E.0.Ak. U.n..z.. >+[2800] EA FF D0 06 13 4D F3 24 82 7F F6 51 2F 4A 4F 0D .....M.$ ...Q/JO. >+[2810] 37 F8 14 6B E9 E4 82 BB 3A 75 63 63 12 E8 78 6F 7..k.... :ucc..xo >+[2820] 6F FC 6C D3 4B A6 F1 CC 2A F1 7D EB 82 26 2F D0 o.l.K... *.}..&/. >+[2830] A1 8B 3E 9A 71 D7 91 D3 08 E6 FD 62 1B 84 13 2D ..>.q... ...b...- >+[2840] 8E A0 A0 C3 85 78 2F 0D F8 E7 10 FC CB 05 A7 B9 .....x/. ........ >+[2850] 9A 33 90 B5 9B 26 E3 23 98 B0 91 4B EB 32 37 D6 .3...&.# ...K.27. >+[2860] F4 ED 61 08 D8 75 CC 03 83 2C 3C CF 21 63 9C F6 ..a..u.. .,<.!c.. >+[2870] AF 5B 4F 12 07 74 17 CD 98 BB E7 5E C7 17 2D C4 .[O..t.. ...^..-. >+[2880] 87 A4 74 6D 5E CE DB A3 01 B9 AD 20 73 38 78 22 ..tm^... ... s8x" >+[2890] 3D 45 F5 51 77 C6 47 63 45 61 81 D9 FF 31 90 C4 =E.Qw.Gc Ea...1.. >+[28A0] 6F 5A F8 FE 6A 56 5B D4 EE EC 49 C7 A7 51 AE 5C oZ..jV[. ..I..Q.\ >+[28B0] 85 53 70 3D 1A 49 83 59 CF 65 58 B3 48 7E 04 9E .Sp=.I.Y .eX.H~.. >+[28C0] C7 64 8A 05 73 E3 DC 1A 65 5D 4F 41 01 56 73 90 .d..s... e]OA.Vs. >+[28D0] 61 F3 84 1F FF CF 46 B2 06 46 56 97 93 B9 DB 32 a.....F. .FV....2 >+[28E0] 2A 64 8A 48 02 05 84 E9 FA 76 8B 94 96 89 A0 73 *d.H.... .v.....s >+[28F0] 20 75 4D 52 1D 23 13 D1 83 D7 5D 59 23 6A 87 C1 uMR.#.. ..]Y#j.. >+[2900] 09 3E 01 3A 28 65 42 8C 35 F1 91 EA 6A 1F 83 0D .>.:(eB. 5...j... >+[2910] 8F 57 69 81 D4 A2 D2 EA 0C BF AF 95 A3 F4 90 15 .Wi..... ........ >+[2920] 61 34 F2 6C 8B D0 DA B5 1E 43 AC CE C7 8A 1B 2B a4.l.... .C.....+ >+[2930] 29 2B 89 1C C5 53 C8 04 F7 1E 46 72 F3 A8 CE F7 )+...S.. ..Fr.... >+[2940] 59 76 55 E7 53 1C A2 9F D8 23 F7 EA 71 B0 74 83 YvU.S... .#..q.t. >+[2950] 71 95 3E DC A6 FA 2D A4 42 13 93 8B 2B FA A2 70 q.>...-. B...+..p >+[2960] 25 21 2D F6 E1 26 56 DF 58 79 25 16 E8 C9 03 EC %!-..&V. Xy%..... >+[2970] 72 5F 35 CF 59 6B E1 AD 85 85 7B AB 78 F2 0D AC r_5.Yk.. ..{.x... >+[2980] AB 89 F2 DA 85 E7 DE 09 77 99 EC 7C F3 97 1F 71 ........ w..|...q >+[2990] 3C DB 09 44 7A 3C 69 E5 03 B0 6D 4D 3B 6B 4C D5 <..Dz<i. ..mM;kL. >+[29A0] AB 52 2F 6F 81 2B 51 5B D2 66 44 1E B7 66 5D 7F .R/o.+Q[ .fD..f]. >+[29B0] 09 6A 92 27 27 62 08 00 00 00 00 .j.''b.. ... >+dump OK >diff --git a/source3/selftest/ktest-krb5_ccache-3.txt b/source3/selftest/ktest-krb5_ccache-3.txt >new file mode 100644 >index 00000000000..76c492cd2b1 >--- /dev/null >+++ b/source3/selftest/ktest-krb5_ccache-3.txt >@@ -0,0 +1,832 @@ >+pull returned Success >+ CCACHE: struct CCACHE >+ pvno : 0x05 (5) >+ version : 0x04 (4) >+ optional_header : union OPTIONAL_HEADER(case 0x4) >+ v4header: struct V4HEADER >+ v4tags: struct V4TAGS >+ tag: struct V4TAG >+ tag : 0x0001 (1) >+ field : union FIELD(case 0x1) >+ deltatime_tag: struct DELTATIME_TAG >+ kdc_sec_offset : 0 >+ kdc_usec_offset : 0 >+ further_tags : DATA_BLOB length=0 >+ principal: struct PRINCIPAL >+ name_type : 0x00000001 (1) >+ component_count : 0x00000001 (1) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(1) >+ components : 'administrator' >+ cred: struct CREDENTIAL >+ client: struct PRINCIPAL >+ name_type : 0x00000001 (1) >+ component_count : 0x00000001 (1) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(1) >+ components : 'administrator' >+ server: struct PRINCIPAL >+ name_type : 0x00000000 (0) >+ component_count : 0x00000002 (2) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(2) >+ components : 'krbtgt' >+ components : 'KTEST.SAMBA.EXAMPLE.COM' >+ keyblock: struct KEYBLOCK >+ enctype : 0x0017 (23) >+ data : DATA_BLOB length=16 >+[0000] E5 E4 15 C8 A8 0F 4D 95 F9 1B E3 B9 98 CA A1 7F ......M. ........ >+ authtime : 0x4d9b9045 (1302040645) >+ starttime : 0x4d9b9045 (1302040645) >+ endtime : 0x7d464c43 (2101759043) >+ renew_till : 0x7d464c43 (2101759043) >+ is_skey : 0x00 (0) >+ ticket_flags : 0x40e00000 (1088421888) >+ addresses: struct ADDRESSES >+ count : 0x00000000 (0) >+ data: ARRAY(0) >+ authdata: struct AUTHDATA >+ count : 0x00000000 (0) >+ data: ARRAY(0) >+ ticket : DATA_BLOB length=1032 >+[0000] 61 82 04 04 30 82 04 00 A0 03 02 01 05 A1 19 1B a...0... ........ >+[0010] 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 .KTEST.S AMBA.EXA >+[0020] 4D 50 4C 45 2E 43 4F 4D A2 2C 30 2A A0 03 02 01 MPLE.COM .,0*.... >+[0030] 00 A1 23 30 21 1B 06 6B 72 62 74 67 74 1B 17 4B ..#0!..k rbtgt..K >+[0040] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[0050] 4C 45 2E 43 4F 4D A3 82 03 AE 30 82 03 AA A0 03 LE.COM.. ..0..... >+[0060] 02 01 17 A1 03 02 01 01 A2 82 03 9C 04 82 03 98 ........ ........ >+[0070] 01 40 48 A6 B8 F0 DA 43 54 A5 18 CF B0 15 CB 68 .@H....C T......h >+[0080] 9F A0 69 44 87 A9 FF 06 25 B9 29 48 59 64 26 48 ..iD.... %.)HYd&H >+[0090] 96 7C 46 6A 79 E5 F0 77 DB 46 6C 20 A1 59 D9 F8 .|Fjy..w .Fl .Y.. >+[00A0] 6A 8A 2D B5 D9 EF A4 54 DE 19 20 C0 7B 93 D4 3D j.-....T .. .{..= >+[00B0] ED 72 35 AF 9D 87 75 9E 44 01 A4 6C D9 EA 94 A3 .r5...u. D..l.... >+[00C0] 18 C6 42 75 E3 0A 0C 76 9A AE 75 BC A3 02 91 BC ..Bu...v ..u..... >+[00D0] 2D BB 3C 23 73 A6 1A A7 8A 3E 85 42 5D 1F 5D 7D -.<#s... .>.B].]} >+[00E0] 0B 1F C3 88 2A 93 40 F9 E9 18 7D 3F 73 DA AC 1F ....*.@. ..}?s... >+[00F0] E7 7B C3 B8 14 56 C3 63 86 5B AF C9 C3 21 9F 94 .{...V.c .[...!.. >+[0100] B4 67 06 60 7F 56 2D F4 C7 22 CD B4 1C 14 B7 5B .g.`.V-. .".....[ >+[0110] 26 67 9D 18 28 B5 5D C2 FC 13 B6 CA 9F AB CD 32 &g..(.]. .......2 >+[0120] 71 D5 51 5F A2 11 5A 5D 4A B3 3B 1D D1 6B 4F 7D q.Q_..Z] J.;..kO} >+[0130] E9 54 F0 B4 AC 80 DE 27 80 C5 64 3C 0B 22 79 1C .T.....' ..d<."y. >+[0140] 9E D1 58 A1 3E 20 5A 9F E3 34 49 D8 16 C6 6B 2D ..X.> Z. .4I...k- >+[0150] 36 0E E2 C2 3F 44 DE 63 32 DB EB 78 50 A2 6F 37 6...?D.c 2..xP.o7 >+[0160] 05 2B 13 D4 31 07 D4 2A C0 53 B1 30 39 79 C3 D8 .+..1..* .S.09y.. >+[0170] C4 4C 30 97 E8 F9 DA ED 10 B0 D0 21 71 8B 56 F3 .L0..... ...!q.V. >+[0180] 0F 3A 2D 26 A2 3D AD 70 27 82 95 59 0A D7 7D 4E .:-&.=.p '..Y..}N >+[0190] 2D 76 96 4D 94 70 2A BB 26 3B 7E FC E1 59 5A 55 -v.M.p*. &;~..YZU >+[01A0] 04 A2 DA 27 AD 46 70 45 43 C0 FB C1 42 7F F0 CB ...'.FpE C...B... >+[01B0] 21 D2 CD 54 35 7C 60 13 EE BB BB 60 6B 91 2B BE !..T5|`. ...`k.+. >+[01C0] 91 8A CF 49 29 F8 60 D1 AB A5 51 B5 5E 4B B2 3A ...I).`. ..Q.^K.: >+[01D0] F4 56 3A 89 2D 88 D0 73 08 A6 FB D8 6E B3 B1 4E .V:.-..s ....n..N >+[01E0] D8 90 27 58 D2 53 40 B2 A0 3C 40 4D E9 21 C6 83 ..'X.S@. .<@M.!.. >+[01F0] FC 15 14 F0 8C 08 46 C5 29 14 E3 84 CC 2C 56 C9 ......F. )....,V. >+[0200] 20 53 45 34 D0 BE E0 CC F7 F1 15 D4 D4 B1 3C 43 SE4.... ......<C >+[0210] EB 5E 9D 33 07 B4 5B E7 D8 24 B0 EB 7B 27 24 6B .^.3..[. .$..{'$k >+[0220] 2A 90 C9 17 D9 24 CF FD 56 28 D7 73 74 03 2F DA *....$.. V(.st./. >+[0230] C4 E0 B3 78 E4 9A 60 4D 5C C7 F5 CF 9C 14 7C B6 ...x..`M \.....|. >+[0240] 1B 5D 76 D1 E3 73 73 2F 41 BD E3 E7 F0 92 B4 5B .]v..ss/ A......[ >+[0250] 07 B4 16 77 DC 3C 28 A4 92 82 C5 7C CA 00 9C 77 ...w.<(. ...|...w >+[0260] B8 28 7F D0 3F EA 2B C1 79 2B 73 FF E0 E0 A5 17 .(..?.+. y+s..... >+[0270] 02 CA 6C B6 02 D2 51 D3 CE 6F 5B 56 E0 7B 38 22 ..l...Q. .o[V.{8" >+[0280] 76 52 48 2D 0A 2F 15 58 A9 FE 03 65 E1 D5 A8 60 vRH-./.X ...e...` >+[0290] E3 5D E6 53 D8 AA 05 D0 90 61 EF B6 28 4A B9 84 .].S.... .a..(J.. >+[02A0] 56 79 80 D2 53 08 1D 17 C4 05 4E F8 04 10 2B CF Vy..S... ..N...+. >+[02B0] 08 DD 61 68 27 21 A5 8A C0 35 6A 0A 94 6D 9E FD ..ah'!.. .5j..m.. >+[02C0] C9 45 AC E3 4F 60 BB 96 AF D4 4E 71 A9 D9 BE 33 .E..O`.. ..Nq...3 >+[02D0] DC 61 8B 14 77 6C A7 72 70 02 65 62 32 9C 8E 53 .a..wl.r p.eb2..S >+[02E0] C9 A3 5B B9 14 3C 00 A2 1D C7 CD 36 5B 5F BE 40 ..[..<.. ...6[_.@ >+[02F0] 28 E2 58 0D D1 05 53 78 F0 86 0F 80 1A 6A 1D DC (.X...Sx .....j.. >+[0300] D4 CD F2 83 0E 25 E1 60 DB C7 F4 B6 05 4F 0D 11 .....%.` .....O.. >+[0310] A4 AE A5 F8 6D 14 CF DF 03 C5 27 75 75 B5 0C F1 ....m... ..'uu... >+[0320] C3 01 F9 A4 FD 2E 0B BD 51 A8 C1 3B DE 48 CF 3A ........ Q..;.H.: >+[0330] CF B3 41 23 9A 9D 0C 79 11 7C 9B D3 71 43 4E 9D ..A#...y .|..qCN. >+[0340] B5 52 19 28 2C A0 4E 0E 8D 7A 84 9A B9 A0 EB FA .R.(,.N. .z...... >+[0350] 6E A1 DF B9 2F 6B FE 5E AE 85 D1 6B A2 C5 BE 07 n.../k.^ ...k.... >+[0360] E7 D6 33 3A 0F 2B ED FB 30 6F 88 1E F9 09 CC C3 ..3:.+.. 0o...... >+[0370] 8F 59 A0 D4 8D 9F A6 08 B0 D3 ED EB 15 13 1B 8E .Y...... ........ >+[0380] 19 C6 14 9C 25 E7 E9 EF 5A 67 7B CD 86 C4 D1 51 ....%... Zg{....Q >+[0390] 2B DE 27 30 D9 F5 6E F9 E4 3E CF 42 54 AE 42 61 +.'0..n. .>.BT.Ba >+[03A0] C5 22 B7 AE 51 76 8F 12 83 7F E1 9F 97 D8 31 38 ."..Qv.. ......18 >+[03B0] A6 B9 11 B4 E1 BA 19 5B E4 A5 A3 6F 4B B3 03 93 .......[ ...oK... >+[03C0] 4C D6 1E 08 FC 94 D1 C5 7C AA 95 EB 9C 7A C2 57 L....... |....z.W >+[03D0] 60 CA 17 FF 8E 66 80 76 CB 35 46 26 C3 BD CA 83 `....f.v .5F&.... >+[03E0] F0 04 08 0D 4C 5D B2 E4 7C 1C 82 28 D7 2C 42 B1 ....L].. |..(.,B. >+[03F0] 36 72 60 5E 26 4A 79 D0 41 94 3C 2C 65 0E 32 18 6r`^&Jy. A.<,e.2. >+[0400] B8 56 26 9D D3 84 78 BB .V&...x. >+ second_ticket : DATA_BLOB length=0 >+ further_creds : DATA_BLOB length=4748 >+[0000] 00 00 00 01 00 00 00 01 00 00 00 17 4B 54 45 53 ........ ....KTES >+[0010] 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E T.SAMBA. EXAMPLE. >+[0020] 43 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 73 74 72 COM....a dministr >+[0030] 61 74 6F 72 00 00 00 01 00 00 00 02 00 00 00 17 ator.... ........ >+[0040] 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D KTEST.SA MBA.EXAM >+[0050] 50 4C 45 2E 43 4F 4D 00 00 00 04 68 6F 73 74 00 PLE.COM. ...host. >+[0060] 00 00 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 00 17 ...local ktest6.. >+[0070] 00 00 00 10 EA 0D 3A 24 41 21 F7 7D 7D A3 C5 BB ......:$ A!.}}... >+[0080] A4 88 F6 17 4D 9B 90 45 4D 9B 90 52 7D 46 4C 43 ....M..E M..R}FLC >+[0090] 00 00 00 00 00 40 28 00 00 00 00 00 00 00 00 00 .....@(. ........ >+[00A0] 00 00 00 03 FA 61 82 03 F6 30 82 03 F2 A0 03 02 .....a.. .0...... >+[00B0] 01 05 A1 19 1B 17 4B 54 45 53 54 2E 53 41 4D 42 ......KT EST.SAMB >+[00C0] 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D A2 1E 30 A.EXAMPL E.COM..0 >+[00D0] 1C A0 03 02 01 01 A1 15 30 13 1B 04 68 6F 73 74 ........ 0...host >+[00E0] 1B 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 A3 82 03 ..localk test6... >+[00F0] AE 30 82 03 AA A0 03 02 01 17 A1 03 02 01 03 A2 .0...... ........ >+[0100] 82 03 9C 04 82 03 98 44 8B C4 7D BA 9F FE 59 F6 .......D ..}...Y. >+[0110] C1 DF 62 89 02 A4 55 54 AB D6 D6 2E 8B 5E 35 3D ..b...UT .....^5= >+[0120] D9 46 9D 8B 49 93 A6 66 5F 1A 8B 81 AD 09 19 E9 .F..I..f _....... >+[0130] 59 CE 58 18 50 63 4A A6 7D 6F 71 21 51 4A 41 C2 Y.X.PcJ. }oq!QJA. >+[0140] A1 FE B0 D5 0A 3D 38 9F E5 3B 72 A2 7A 59 22 A4 .....=8. .;r.zY". >+[0150] B7 1C A3 8D DB EA 5D A5 E2 D3 1D AE 42 D0 7F 75 ......]. ....B..u >+[0160] B5 E9 ED B5 04 7B 67 1E 28 90 7D 3D 1A 3E F6 62 .....{g. (.}=.>.b >+[0170] D0 A1 56 89 28 76 5C 19 1A FD 66 E5 F2 86 E7 58 ..V.(v\. ..f....X >+[0180] 93 31 90 C5 CD F8 71 96 56 21 15 13 F0 EA C2 CC .1....q. V!...... >+[0190] 48 4C B4 50 EF F9 81 44 29 8A 75 C4 31 75 D1 BA HL.P...D ).u.1u.. >+[01A0] E2 0B 05 B2 E0 EA 64 3A 11 45 84 3D 69 55 FF E6 ......d: .E.=iU.. >+[01B0] 32 7E C9 CA C4 28 E8 40 B6 5E F9 26 0F 09 12 1F 2~...(.@ .^.&.... >+[01C0] 1F D4 9C 9A 50 E8 B7 6D F8 4F 55 6E 2A D4 AC 6A ....P..m .OUn*..j >+[01D0] 79 D1 C2 2A 88 99 F8 39 75 36 F1 2D C7 89 0A C6 y..*...9 u6.-.... >+[01E0] B4 C7 A1 7B F1 BF 22 87 A4 B2 93 22 54 A1 72 25 ...{..". ..."T.r% >+[01F0] AF 67 FE 20 D5 C8 29 47 28 FF 51 FB F9 4E 2C 17 .g. ..)G (.Q..N,. >+[0200] 10 BE 2E 13 8B 18 BE 3C A3 BE 50 49 A7 65 DD 2E .......< ..PI.e.. >+[0210] CC EB D6 0F 47 4E DB 7E 08 D5 F0 37 79 36 8F 24 ....GN.~ ...7y6.$ >+[0220] 34 28 86 89 EC A3 84 7F 44 4E 37 03 B5 D8 89 1C 4(...... DN7..... >+[0230] C7 AA AC 42 70 5F 96 73 35 8B 83 D1 16 24 27 C1 ...Bp_.s 5....$'. >+[0240] EC 0E AE 83 59 5A C2 EB C1 91 B6 3D BB 8D 21 49 ....YZ.. ...=..!I >+[0250] 63 41 3C 91 1D E9 01 C2 4F A9 E4 42 C1 FD 54 E3 cA<..... O..B..T. >+[0260] 7B 3B DF 24 3D 98 E9 84 F8 1D 8D CE 4D 85 AC 8A {;.$=... ....M... >+[0270] 12 15 48 C4 DA 1B 3C B8 FC A3 0B AF E2 4D 71 E9 ..H...<. .....Mq. >+[0280] 0A 28 53 DC 4E 6C 23 2C 73 26 50 FE 37 03 BF D1 .(S.Nl#, s&P.7... >+[0290] 5F 8A 39 4F 04 2E 4A CE 3C 90 11 0C DA 84 5C C3 _.9O..J. <.....\. >+[02A0] F8 BE C7 74 ED F4 CF 7E B2 AE 9B 47 D6 2A 1D 93 ...t...~ ...G.*.. >+[02B0] 3F A8 8B 51 E9 A3 A0 59 55 DB E3 52 67 E3 DE FF ?..Q...Y U..Rg... >+[02C0] B1 56 74 A0 87 21 99 23 8C 8E D1 92 A6 3D 93 D6 .Vt..!.# .....=.. >+[02D0] 4D 5B 84 2B B1 8D DD E4 F7 01 A6 6C 4A DF 3C 6E M[.+.... ...lJ.<n >+[02E0] A0 FA 74 93 BE 18 7C 30 29 9D B8 DB 5F D1 AA B7 ..t...|0 )..._... >+[02F0] 51 7C 2A 90 1A 8B 06 95 E1 80 0D 27 B2 6C 52 1C Q|*..... ...'.lR. >+[0300] C7 D1 E9 16 14 F1 6C 57 48 28 BD 13 B5 83 BA A7 ......lW H(...... >+[0310] 75 31 69 52 03 38 69 13 62 ED C6 DC C2 01 C8 F1 u1iR.8i. b....... >+[0320] 45 02 4D 8C 64 CF 96 90 3E C2 08 EC 2B 8D 92 93 E.M.d... >...+... >+[0330] 4B 6D 22 B3 41 DE 85 35 2D 19 09 E5 68 8E 1F 98 Km".A..5 -...h... >+[0340] 1B F2 73 F2 D4 91 08 89 42 0C 05 8B 42 77 6B CC ..s..... B...Bwk. >+[0350] 18 78 43 1A 73 C2 7C E7 C2 23 28 56 F7 A0 19 B3 .xC.s.|. .#(V.... >+[0360] 99 A6 25 4F C3 5E 70 EC 78 BB 30 15 36 77 B3 A6 ..%O.^p. x.0.6w.. >+[0370] 89 98 B6 A0 85 CC 8F E7 41 40 B5 E0 89 93 25 04 ........ A@....%. >+[0380] B8 1D 0B 06 31 1D C7 30 52 E1 64 29 8C 64 B9 89 ....1..0 R.d).d.. >+[0390] 1F 86 5A AD 74 15 1C C8 AF 37 7B 27 E0 C0 DB 73 ..Z.t... .7{'...s >+[03A0] 30 72 65 D3 C0 A5 07 61 E9 0C 07 A1 27 18 8F 50 0re....a ....'..P >+[03B0] DB CE FB 4C DD 75 98 F2 28 D2 76 FF F2 41 9F D5 ...L.u.. (.v..A.. >+[03C0] 74 22 8A 03 73 B1 A8 B3 B8 80 93 E5 E2 CD 4B F2 t"..s... ......K. >+[03D0] 6B 99 DF 5B 5B C7 22 69 81 2A 8A CD 2A F9 9D 08 k..[[."i .*..*... >+[03E0] B8 B0 40 77 D3 43 8B AF 40 DD 0C CB 45 E3 88 CB ..@w.C.. @...E... >+[03F0] 06 AA 63 38 EB DD 72 89 03 0E DC 3E 97 3F 16 D4 ..c8..r. ...>.?.. >+[0400] 1A 21 40 D8 30 BD B0 B4 04 C2 7A 22 43 15 A2 D8 .!@.0... ..z"C... >+[0410] 2F 08 28 3B 63 26 AA B3 1C B6 FC E4 0B 2A CD 0E /.(;c&.. .....*.. >+[0420] A8 7C E8 11 33 03 D3 C5 6C 35 6A 5D 3C 5A 80 1A .|..3... l5j]<Z.. >+[0430] BC 1C 54 DE 5C 6A E2 F3 A1 18 8E 47 88 8B 71 11 ..T.\j.. ...G..q. >+[0440] 09 2F 29 88 D9 BB DC 34 09 E1 2F 7E A7 E8 29 DC ./)....4 ../~..). >+[0450] F9 5A 1D 9E C8 A4 CC 52 8A E6 CB 4A 3F F9 77 F7 .Z.....R ...J?.w. >+[0460] 53 64 62 9E 5F E6 D7 F6 43 E6 9C 03 C9 55 B1 CB Sdb._... C....U.. >+[0470] 25 40 74 AA E9 AB 34 58 E1 E8 9B B3 1D 9E 83 FD %@t...4X ........ >+[0480] 7A BF DC 45 2D A8 9A F8 AF 9C 63 EF 1B 2B 9D CC z..E-... ..c..+.. >+[0490] F3 08 74 EC 6E 40 8E 18 62 BD F3 87 66 87 67 00 ..t.n@.. b...f.g. >+[04A0] 00 00 00 00 00 00 01 00 00 00 01 00 00 00 17 4B ........ .......K >+[04B0] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[04C0] 4C 45 2E 43 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 LE.COM.. ..admini >+[04D0] 73 74 72 61 74 6F 72 00 00 00 01 00 00 00 02 00 strator. ........ >+[04E0] 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 ...KTEST .SAMBA.E >+[04F0] 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 04 63 69 XAMPLE.C OM....ci >+[0500] 66 73 00 00 00 0B 6C 6F 63 61 6C 6B 74 65 73 74 fs....lo calktest >+[0510] 36 00 17 00 00 00 10 92 C6 A1 91 6D 55 01 4E BE 6....... ...mU.N. >+[0520] E4 3F E3 36 B0 D3 28 4D 9B 90 45 4D 9B 90 5A 7D .?.6..(M ..EM..Z} >+[0530] 46 4C 43 00 00 00 00 00 40 28 00 00 00 00 00 00 FLC..... @(...... >+[0540] 00 00 00 00 00 00 03 FA 61 82 03 F6 30 82 03 F2 ........ a...0... >+[0550] A0 03 02 01 05 A1 19 1B 17 4B 54 45 53 54 2E 53 ........ .KTEST.S >+[0560] 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D AMBA.EXA MPLE.COM >+[0570] A2 1E 30 1C A0 03 02 01 01 A1 15 30 13 1B 04 63 ..0..... ...0...c >+[0580] 69 66 73 1B 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 ifs..loc alktest6 >+[0590] A3 82 03 AE 30 82 03 AA A0 03 02 01 17 A1 03 02 ....0... ........ >+[05A0] 01 03 A2 82 03 9C 04 82 03 98 FE 09 00 80 36 35 ........ ......65 >+[05B0] D4 6E 71 0C 33 22 36 9E 89 88 32 E3 34 4A 4C BF .nq.3"6. ..2.4JL. >+[05C0] 80 19 81 CC A0 CB 96 DB 31 F7 2A 19 75 DE 0E DA ........ 1.*.u... >+[05D0] D0 18 FA 9E 75 E6 E4 13 C9 BE 3F C0 1B AD 5B 98 ....u... ..?...[. >+[05E0] E9 FC A3 9D 16 FF C8 91 03 AC 8B E6 2D 15 B3 F1 ........ ....-... >+[05F0] 23 4E 25 9E 45 3A F8 8A 19 B7 71 52 A6 92 1C FB #N%.E:.. ..qR.... >+[0600] 1F D4 4C 51 AF 9C 0E 73 D9 A8 D8 43 F2 64 71 BC ..LQ...s ...C.dq. >+[0610] AD B1 7B 8F BF 8D FF 72 89 0F 5E B6 C2 E3 C0 01 ..{....r ..^..... >+[0620] 98 41 AD 3F 6E DC 87 F5 9A E6 40 0C 17 0F 75 80 .A.?n... ..@...u. >+[0630] 0C 28 62 06 EB BF F8 69 8C 43 48 38 A8 AE F2 5E .(b....i .CH8...^ >+[0640] 45 11 23 FB 6B 85 83 54 BA 60 39 CE 08 00 D1 05 E.#.k..T .`9..... >+[0650] 5F 6F 79 96 30 28 06 DD C7 75 52 8E 3C C4 3F FC _oy.0(.. .uR.<.?. >+[0660] C1 31 28 2C 64 3B D1 7E 2F C2 DB B0 E8 A8 EF C5 .1(,d;.~ /....... >+[0670] F2 DC 43 D0 14 21 C8 D0 D3 15 45 8E 2A 3E 3B 4A ..C..!.. ..E.*>;J >+[0680] 60 25 3D 11 E4 F9 16 02 3E 55 8F CE D2 E9 95 E7 `%=..... >U...... >+[0690] B1 C4 8F C4 0B 3E 3C 14 15 28 1A 21 49 15 CE 8E .....><. .(.!I... >+[06A0] 91 5E 98 71 00 1F 29 D3 12 C8 D0 11 4F E7 14 E3 .^.q..). ....O... >+[06B0] 72 1B 61 6D 7B 8A 00 A6 5E 01 01 50 C2 CF 1A A9 r.am{... ^..P.... >+[06C0] 34 8C BA 33 9E 62 C5 69 97 6A 24 3D E0 C6 3F C6 4..3.b.i .j$=..?. >+[06D0] F4 36 B1 80 D6 5C 44 19 5B 65 C7 CA 47 DE 4B 65 .6...\D. [e..G.Ke >+[06E0] 41 29 9F F8 EA E8 E0 3B E2 C6 98 9D 58 A4 6C 62 A).....; ....X.lb >+[06F0] EF 25 12 C9 0E 97 CE 9D F0 D8 08 AD 13 73 A6 82 .%...... .....s.. >+[0700] C5 54 23 F4 A4 CB 91 35 91 BD 10 B4 04 DD 55 7E .T#....5 ......U~ >+[0710] C9 DE AE CB B0 8F C0 D8 28 AE BD 78 64 91 6C AB ........ (..xd.l. >+[0720] CA 36 EA 0E 0E 97 DC 40 ED 26 1D 09 17 28 30 D3 .6.....@ .&...(0. >+[0730] 78 DC F7 D2 9C 78 DA 6F 6F 57 00 B3 FD 8E 75 A1 x....x.o oW....u. >+[0740] 56 98 5C 4B D8 61 A6 0A 89 27 CD 11 BF 7F 79 53 V.\K.a.. .'....yS >+[0750] D9 50 9A 8D EC DD DB BB B8 23 27 0D 20 5B 53 51 .P...... .#'. [SQ >+[0760] 07 C4 26 31 3B D4 DF ED 3C 40 B4 1C 8B 46 E2 A6 ..&1;... <@...F.. >+[0770] B7 0F 97 D2 B3 1D 19 FD 13 60 7B 38 E6 37 0C 59 ........ .`{8.7.Y >+[0780] B0 A8 47 5D 32 A5 0C 57 76 EF 2C ED 40 9F BF 4B ..G]2..W v.,.@..K >+[0790] 43 99 3C 68 C4 DE 84 9C A1 36 8C CA CB 2A 08 36 C.<h.... .6...*.6 >+[07A0] 4E CD 43 06 9E F8 E7 1D 52 3B 59 37 4F 6F 65 D9 N.C..... R;Y7Ooe. >+[07B0] 2A F9 AD 5A 50 95 71 3F B1 5F C8 8E 2E E9 E4 FE *..ZP.q? ._...... >+[07C0] C8 A9 42 2C EE 18 E0 81 3C 00 E2 80 8D 8A 8B 71 ..B,.... <......q >+[07D0] C7 F5 AC 5C 36 1D E0 BC F0 11 57 67 CB 2C BE F6 ...\6... ..Wg.,.. >+[07E0] 90 4E F9 90 97 14 1F 0C 9D 5D 4D DF 0D D0 C0 C5 .N...... .]M..... >+[07F0] 08 E7 31 72 8E 35 63 17 8D 8B 3D 49 14 C8 A5 90 ..1r.5c. ..=I.... >+[0800] 88 24 AF 75 CA 0A CB 95 8A 2C 70 A6 CE 2F 3F B6 .$.u.... .,p../?. >+[0810] D7 1A 44 AC 05 93 EF 3D 03 C7 C2 8E 0F 31 9F 53 ..D....= .....1.S >+[0820] 67 CA 73 D3 B8 07 76 36 35 6F B5 32 30 38 86 7E g.s...v6 5o.208.~ >+[0830] 7E 95 3F DC F4 6F A9 67 0E 15 E8 4A CA 3F 18 0E ~.?..o.g ...J.?.. >+[0840] C6 E7 20 22 6B F1 39 6A 9C A6 47 64 81 E4 CB A8 .. "k.9j ..Gd.... >+[0850] 31 FF E2 97 13 41 89 45 79 53 2B A8 90 97 DE 7B 1....A.E yS+....{ >+[0860] 18 56 95 02 2A 94 D2 7E 5C D0 A0 BC A0 38 D2 BC .V..*..~ \....8.. >+[0870] 03 91 F7 35 FE 1A 5E 80 10 13 4E 83 CB F6 D7 8A ...5..^. ..N..... >+[0880] 02 A2 E8 1F D8 9B F1 76 F9 18 66 56 9C 4D 9E BF .......v ..fV.M.. >+[0890] 1D F4 66 86 E0 7B 88 EC 9C F7 50 13 7D 34 8A 54 ..f..{.. ..P.}4.T >+[08A0] 7A E1 EC F6 44 12 47 84 7D 16 B4 42 25 E5 A2 CC z...D.G. }..B%... >+[08B0] D8 CA 7A 38 21 85 A3 F8 41 6D 0D AC 1D FA 36 5D ..z8!... Am....6] >+[08C0] 23 EA 20 CC 43 A5 7E D9 25 97 BC 0E 74 F5 3D 98 #. .C.~. %...t.=. >+[08D0] B9 79 C2 65 50 0E 8D E7 7A F3 F3 88 37 A3 40 01 .y.eP... z...7.@. >+[08E0] 96 C6 FC 1D 6E 9E 06 A1 90 A0 78 3C DA 7F E9 C6 ....n... ..x<.... >+[08F0] 23 47 70 04 03 EE C2 4A C3 95 07 44 00 BD 29 2A #Gp....J ...D..)* >+[0900] B5 FA 17 1E D6 BC 00 A0 93 55 E0 82 0A AB 04 D4 ........ .U...... >+[0910] D5 56 84 2A B2 56 51 05 DB 30 E2 83 5A 75 D3 A8 .V.*.VQ. .0..Zu.. >+[0920] 30 B7 3E C4 25 70 A8 34 E4 A2 EB 3E FB D8 2D 10 0.>.%p.4 ...>..-. >+[0930] 72 8E DA 4D 2D 55 EC 49 66 5E 01 96 E4 C1 0C 23 r..M-U.I f^.....# >+[0940] 57 91 00 00 00 00 00 00 00 01 00 00 00 01 00 00 W....... ........ >+[0950] 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 ..KTEST. SAMBA.EX >+[0960] 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D 61 64 6D AMPLE.CO M....adm >+[0970] 69 6E 69 73 74 72 61 74 6F 72 00 00 00 01 00 00 inistrat or...... >+[0980] 00 02 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 ......KT EST.SAMB >+[0990] 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 A.EXAMPL E.COM... >+[09A0] 04 68 6F 73 74 00 00 00 0B 4C 4F 43 41 4C 4B 54 .host... .LOCALKT >+[09B0] 45 53 54 36 00 17 00 00 00 10 9D AE 06 BE 29 E0 EST6.... ......). >+[09C0] F7 9A 46 97 29 E0 69 8E 5A F0 4D 9B 90 45 4D 9B ..F.).i. Z.M..EM. >+[09D0] 90 61 7D 46 4C 43 00 00 00 00 00 40 28 00 00 00 .a}FLC.. ...@(... >+[09E0] 00 00 00 00 00 00 00 00 00 03 FA 61 82 03 F6 30 ........ ...a...0 >+[09F0] 82 03 F2 A0 03 02 01 05 A1 19 1B 17 4B 54 45 53 ........ ....KTES >+[0A00] 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E T.SAMBA. EXAMPLE. >+[0A10] 43 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 15 30 13 COM..0.. ......0. >+[0A20] 1B 04 68 6F 73 74 1B 0B 4C 4F 43 41 4C 4B 54 45 ..host.. LOCALKTE >+[0A30] 53 54 36 A3 82 03 AE 30 82 03 AA A0 03 02 01 17 ST6....0 ........ >+[0A40] A1 03 02 01 03 A2 82 03 9C 04 82 03 98 B9 C5 6E ........ .......n >+[0A50] 77 F9 59 6D 19 F0 A6 56 2F 14 B3 9A A3 17 06 A6 w.Ym...V /....... >+[0A60] AD F5 92 38 6A 1E EA 3D 53 BF 5E 95 13 FF 5D BB ...8j..= S.^...]. >+[0A70] 43 4F 51 AE FB 12 3B 06 67 36 91 B9 E0 C4 C4 F3 COQ...;. g6...... >+[0A80] 45 A0 48 E6 DC 49 E8 EA 6F 55 D2 3F 79 57 54 FF E.H..I.. oU.?yWT. >+[0A90] 10 8D 89 4A A4 E2 B2 80 FD EE 36 C5 D5 4C D0 97 ...J.... ..6..L.. >+[0AA0] B3 EC 96 8B E8 5A 05 F0 13 39 8B 1B B3 C4 32 2A .....Z.. .9....2* >+[0AB0] 9B BB EF 06 C4 1C 53 2F 0A F6 A8 C6 BE 09 57 26 ......S/ ......W& >+[0AC0] B9 39 7B 7B 50 13 2D 6C 52 FF C4 B5 83 28 A8 47 .9{{P.-l R....(.G >+[0AD0] 5A CD 1C DD A7 65 FD 8A 84 2A 10 E7 44 E6 83 E7 Z....e.. .*..D... >+[0AE0] E7 AA B8 E5 0A 8B 7E E1 87 7B 3D C4 9F 68 BD 19 ......~. .{=..h.. >+[0AF0] 2B 59 5E 5A 45 0D B5 71 CC A6 C7 03 3C B3 17 D3 +Y^ZE..q ....<... >+[0B00] AF 99 F6 A2 52 A0 99 F7 39 56 B4 33 B4 C5 F4 CC ....R... 9V.3.... >+[0B10] 74 34 4C 00 76 26 10 D1 3A 87 6E 6A 52 9B 7A BF t4L.v&.. :.njR.z. >+[0B20] 4E 59 36 32 C5 41 29 CF E1 BF 14 E0 54 BF 4A 25 NY62.A). ....T.J% >+[0B30] 1F 0B 6E 9A 8C 0E 5D 47 A9 64 1B A4 9D 99 A9 09 ..n...]G .d...... >+[0B40] 39 14 E7 41 22 98 8C 62 CC E2 B5 91 8E C1 31 EB 9..A"..b ......1. >+[0B50] B2 70 A6 3B 86 FC DD 19 0B 3F 5D C9 B5 1A 95 73 .p.;.... .?]....s >+[0B60] EB 97 89 BE 14 87 85 17 BE 40 F6 80 14 23 4D 66 ........ .@...#Mf >+[0B70] E4 B0 E5 51 46 34 DA 1C C8 CB FF C6 84 A3 DF D2 ...QF4.. ........ >+[0B80] DC 00 AF 7B 27 C8 78 44 CB 6E 7B CC 5C 94 1E 7A ...{'.xD .n{.\..z >+[0B90] 95 29 19 F4 14 BE 5C 23 C3 B9 A4 2C 5D 4D F3 61 .)....\# ...,]M.a >+[0BA0] 63 1F D4 FE 37 EE 44 14 06 B7 14 50 B6 74 37 75 c...7.D. ...P.t7u >+[0BB0] 2C AB 06 F0 93 F9 93 34 75 63 44 7E 12 48 D1 F1 ,......4 ucD~.H.. >+[0BC0] 06 55 14 11 B9 23 43 CE 01 16 3E 6B A3 BD 23 55 .U...#C. ..>k..#U >+[0BD0] DE 48 5D AF E1 2B 89 E8 E7 C2 E2 34 25 A2 09 4A .H]..+.. ...4%..J >+[0BE0] 1F BE 05 AA DE 4B 08 65 27 4C 9B C7 54 96 C2 FB .....K.e 'L..T... >+[0BF0] E2 CE 53 4A 32 93 8D 0B 44 77 8C D3 65 54 F9 0E ..SJ2... Dw..eT.. >+[0C00] 7F 74 1E FE 3D 74 83 0F 2F E7 9F BC A2 B0 2B 25 .t..=t.. /.....+% >+[0C10] BB D2 6F A8 49 C1 3E 9E B5 93 67 74 39 A4 FE 84 ..o.I.>. ..gt9... >+[0C20] 4C 45 5F 30 74 E0 CA 5F F6 46 EC 89 B5 2D C8 14 LE_0t.._ .F...-.. >+[0C30] 69 76 BC 93 15 F4 60 30 5F AB EB 02 DD 12 4C 62 iv....`0 _.....Lb >+[0C40] F9 73 F7 01 E1 7F 2A 6F 09 05 BF 3A 3A 7E 69 A3 .s....*o ...::~i. >+[0C50] 7B FC 20 2B D6 CE C0 74 4F BB 29 E4 BE CE 04 9D {. +...t O.)..... >+[0C60] 24 D4 98 4A ED 94 A8 81 CD 26 A0 63 EA 09 57 42 $..J.... .&.c..WB >+[0C70] 26 B7 B5 4E B5 CB 45 35 A7 84 D8 74 CA C3 9F FF &..N..E5 ...t.... >+[0C80] C8 1E 2A 75 34 01 C5 A7 B4 9D 6F A3 E1 BB 2B F8 ..*u4... ..o...+. >+[0C90] F0 21 D6 77 57 74 2E 80 DB 76 53 01 86 33 17 32 .!.wWt.. .vS..3.2 >+[0CA0] 2E 16 E1 8D 89 3A B2 67 ED A3 ED 39 82 87 26 A6 .....:.g ...9..&. >+[0CB0] DB CE 59 84 E4 0A A6 CA 7E 07 98 F7 02 91 6E 56 ..Y..... ~.....nV >+[0CC0] 9F 60 03 D3 88 B0 FF EB 20 CA 9E 5B 37 26 67 00 .`...... ..[7&g. >+[0CD0] CC BD 9D 53 15 31 53 14 FD 9C E1 28 08 CB C4 0B ...S.1S. ...(.... >+[0CE0] E3 50 D9 DB 0C E2 E4 F9 44 50 E9 28 6E 01 96 AA .P...... DP.(n... >+[0CF0] C1 D2 4E B2 DE 38 A2 F8 94 32 79 AE 49 64 FB 57 ..N..8.. .2y.Id.W >+[0D00] 50 F6 73 E8 98 43 C6 DD 67 3C 91 AC 97 C9 2E 8C P.s..C.. g<...... >+[0D10] 06 59 A1 FC 49 EC 2F BF 6F 64 21 63 ED C8 6C CE .Y..I./. od!c..l. >+[0D20] 37 28 7B 80 7F 5F 85 F6 98 93 C0 66 A8 D6 F1 2C 7({.._.. ...f..., >+[0D30] D8 01 68 B1 C8 EA 82 0D 5B 9B 35 4F 3D B3 47 19 ..h..... [.5O=.G. >+[0D40] 54 7A C6 9F AD D7 54 CF B0 DB 3E 18 BA 2A 39 08 Tz....T. ..>..*9. >+[0D50] 0C C4 98 4B 43 DE 53 68 25 B1 83 93 1D E1 6C BF ...KC.Sh %.....l. >+[0D60] F5 B4 A9 83 17 34 64 8C 2F 91 80 97 4A 48 EC 90 .....4d. /...JH.. >+[0D70] BB FA 92 2C 01 80 E4 99 91 0E 67 88 D5 75 AB 7C ...,.... ..g..u.| >+[0D80] 98 59 98 45 C9 11 A9 8C 02 98 91 DE AB A0 FF 45 .Y.E.... .......E >+[0D90] 11 66 6F C5 DE 61 6D C6 DB C9 CA A3 A0 2B B1 73 .fo..am. .....+.s >+[0DA0] 05 85 37 BF AB CA 43 7A 6F 38 C8 BE ED CE 12 49 ..7...Cz o8.....I >+[0DB0] 93 C7 7C 1A 33 60 52 7A 67 67 AA 60 57 7E C8 FF ..|.3`Rz gg.`W~.. >+[0DC0] DF 91 91 18 45 74 C0 9E 36 19 BC 42 F9 46 CC 84 ....Et.. 6..B.F.. >+[0DD0] 09 2E 8C 59 1A E3 65 51 F4 87 6F 4C 3E 29 38 E6 ...Y..eQ ..oL>)8. >+[0DE0] 77 E8 A9 B7 FA 00 00 00 00 00 00 00 01 00 00 00 w....... ........ >+[0DF0] 01 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 .....KTE ST.SAMBA >+[0E00] 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D .EXAMPLE .COM.... >+[0E10] 61 64 6D 69 6E 69 73 74 72 61 74 6F 72 00 00 00 administ rator... >+[0E20] 01 00 00 00 02 00 00 00 17 4B 54 45 53 54 2E 53 ........ .KTEST.S >+[0E30] 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D AMBA.EXA MPLE.COM >+[0E40] 00 00 00 04 63 69 66 73 00 00 00 0B 4C 4F 43 41 ....cifs ....LOCA >+[0E50] 4C 4B 54 45 53 54 36 00 17 00 00 00 10 01 78 D0 LKTEST6. ......x. >+[0E60] 3B 9B FF F0 88 86 4B 3B FE 41 A9 6B 00 4D 9B 90 ;.....K; .A.k.M.. >+[0E70] 45 4D 9B 90 6B 7D 46 4C 43 00 00 00 00 00 40 28 EM..k}FL C.....@( >+[0E80] 00 00 00 00 00 00 00 00 00 00 00 00 03 FA 61 82 ........ ......a. >+[0E90] 03 F6 30 82 03 F2 A0 03 02 01 05 A1 19 1B 17 4B ..0..... .......K >+[0EA0] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[0EB0] 4C 45 2E 43 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 LE.COM.. 0....... >+[0EC0] 15 30 13 1B 04 63 69 66 73 1B 0B 4C 4F 43 41 4C .0...cif s..LOCAL >+[0ED0] 4B 54 45 53 54 36 A3 82 03 AE 30 82 03 AA A0 03 KTEST6.. ..0..... >+[0EE0] 02 01 17 A1 03 02 01 03 A2 82 03 9C 04 82 03 98 ........ ........ >+[0EF0] CA EA 4D 46 2D D1 E9 58 5D 25 8D 9F DF EA C9 01 ..MF-..X ]%...... >+[0F00] B6 08 27 CD 14 85 02 DC 20 C6 51 AA F9 6A B1 CE ..'..... .Q..j.. >+[0F10] F5 77 84 BF 9A AC 6B A7 B2 F2 1F 60 BF CB C6 FC .w....k. ...`.... >+[0F20] C7 14 B7 41 1C A8 C9 70 7B 86 BC 8E 70 2B 65 4B ...A...p {...p+eK >+[0F30] DC F5 B9 23 F8 08 BF 96 C9 A8 77 F4 54 67 25 F8 ...#.... ..w.Tg%. >+[0F40] 0F A8 C5 D6 D1 BB 46 5E A0 7E D2 98 9C CD AF E0 ......F^ .~...... >+[0F50] 82 62 ED 39 D2 FB F2 E8 9B 1B EE E5 B4 1B C9 0A .b.9.... ........ >+[0F60] 86 27 52 6E 11 8B D7 AD B4 54 F9 C6 69 8D E0 F1 .'Rn.... .T..i... >+[0F70] CD 63 1C 89 7C 8F B6 A0 71 53 A6 DA B1 66 D2 9D .c..|... qS...f.. >+[0F80] D3 4C A8 FB C6 9D 81 74 10 8E 84 D2 3D D8 1C BE .L.....t ....=... >+[0F90] BB 3F F7 BF 91 3E 89 66 43 A1 E0 90 1B 1A 97 FF .?...>.f C....... >+[0FA0] EF CC 35 75 14 62 4F 67 3A 29 F4 F9 C5 2E BE C5 ..5u.bOg :)...... >+[0FB0] C2 2B A8 35 22 D9 92 31 1D 49 2A A5 19 AA 08 0F .+.5"..1 .I*..... >+[0FC0] A8 22 0B 68 D2 A2 D7 07 7B 37 1E A3 AC 9B 4F 0A .".h.... {7....O. >+[0FD0] A4 FA 7F 37 6F 3E 35 79 4E 00 4B B6 28 A3 6A E4 ...7o>5y N.K.(.j. >+[0FE0] 0C 95 53 BA E8 41 07 DA BE E9 08 B9 51 24 91 49 ..S..A.. ....Q$.I >+[0FF0] 78 5D 44 12 BC 85 63 81 B8 E0 88 D5 95 0C D3 A8 x]D...c. ........ >+[1000] 1D 32 4B E4 A0 C8 A7 7D 3C 97 EE D8 59 AC 3A 21 .2K....} <...Y.:! >+[1010] 09 F2 7A CC D0 4A F3 50 10 DC FC 26 BB C2 6A 8E ..z..J.P ...&..j. >+[1020] 8B 14 2B 2D 50 2E B3 1E 9B D2 69 56 22 F2 48 BD ..+-P... ..iV".H. >+[1030] E9 2E 2F 28 DE 77 67 5F 68 AA 29 05 4B 36 58 40 ../(.wg_ h.).K6X@ >+[1040] E5 54 11 C5 4D 68 96 49 9D 53 37 87 5F D2 3A 9B .T..Mh.I .S7._.:. >+[1050] E9 8E 79 BE AE 11 B4 6B AB FD DB 8A F5 A0 9B 29 ..y....k .......) >+[1060] D9 F5 ED CA FA 3F FE 35 FC F4 69 7E E4 D0 44 29 .....?.5 ..i~..D) >+[1070] 48 FF 82 61 26 FC D3 E2 10 EE 14 F7 4A E3 CD F2 H..a&... ....J... >+[1080] 8B BC 8B 43 64 2C DE 40 6E BB E1 56 C0 B6 2C D0 ...Cd,.@ n..V..,. >+[1090] E5 1E E9 B3 FB 38 48 66 ED AF D2 25 D1 35 5C C6 .....8Hf ...%.5\. >+[10A0] F0 4D 36 19 0B EC 33 07 34 D0 27 8D 14 DC 01 45 .M6...3. 4.'....E >+[10B0] DE F8 73 A6 A0 F4 C1 91 9D BD 05 E3 70 25 E1 10 ..s..... ....p%.. >+[10C0] 44 F6 4B 46 F7 24 84 BF 20 96 AD 6A 96 94 81 58 D.KF.$.. ..j...X >+[10D0] 80 95 06 92 F5 7F 17 39 3B 32 47 B2 C5 CE 7B 73 .......9 ;2G...{s >+[10E0] CF 53 AE FA D1 9A 60 5A 98 EC 8C FA BD C0 CE 8D .S....`Z ........ >+[10F0] C5 27 E6 17 1A 4D 47 D8 3F 5D A9 7C FB 2C B3 05 .'...MG. ?].|.,.. >+[1100] 0C 69 20 48 99 80 11 DC 48 AB A7 EA 5B 98 C1 15 .i H.... H...[... >+[1110] 27 AE FA 3E 1E 1E E0 E1 F8 32 C0 54 13 D6 30 34 '..>.... .2.T..04 >+[1120] 71 98 26 61 6C 1C C4 C7 4E C4 A6 7E FE A8 B8 89 q.&al... N..~.... >+[1130] 2A 70 3C 19 58 8D 57 45 55 83 0A C2 B5 F7 89 0E *p<.X.WE U....... >+[1140] 7B 7A 17 0C CF 6E 08 A5 F7 21 4A 62 81 4F 49 CA {z...n.. .!Jb.OI. >+[1150] E2 ED C2 B4 C7 33 5C BC A1 A0 DE 4E 09 37 BE 24 .....3\. ...N.7.$ >+[1160] 62 22 94 55 75 AA 53 DE E0 74 5A B0 B8 E9 BF 2B b".Uu.S. .tZ....+ >+[1170] 12 65 2F 90 6B 84 ED 11 AD F7 CE 19 A1 96 E4 1E .e/.k... ........ >+[1180] 8C EA C8 81 1B 47 4F 5F B1 5D A5 8B E3 0D 5A 80 .....GO_ .]....Z. >+[1190] 89 EC 4B D9 CE ED E8 67 7F 96 FC 1B EF 65 C2 68 ..K....g .....e.h >+[11A0] 40 F7 20 36 83 58 62 F4 CA 02 F4 5C 0D 46 B1 CB @. 6.Xb. ...\.F.. >+[11B0] 50 D2 D8 3D B7 9A 96 48 8C CF EB E6 8C F4 B2 B4 P..=...H ........ >+[11C0] 47 C9 34 C9 DC 14 F1 33 1B 6F 9E 65 27 D7 9D 46 G.4....3 .o.e'..F >+[11D0] 1E 91 FF 2E FB 8E 97 5D 17 8F 48 54 7C 3C A0 11 .......] ..HT|<.. >+[11E0] 9C AA 77 E9 79 DE 26 D1 F0 7C EA 24 73 BE EC 60 ..w.y.&. .|.$s..` >+[11F0] B4 EE BD ED 0D 0A AB 74 60 6E 46 C0 35 5B 65 1A .......t `nF.5[e. >+[1200] A4 4A 5C 22 AC B9 CD B7 56 06 88 09 FC 48 68 55 .J\".... V....HhU >+[1210] B7 5E 39 72 DF 8A 4C CD 79 74 B0 84 0B 78 DA B2 .^9r..L. yt...x.. >+[1220] 55 F8 06 0B 5C 27 06 B3 CA 10 65 6B 04 A3 64 11 U...\'.. ..ek..d. >+[1230] 04 09 DC DF 67 00 70 B1 16 DF 24 E9 27 85 11 91 ....g.p. ..$.'... >+[1240] 31 CB 92 95 50 18 91 08 C2 A1 A3 76 C7 1A FC 64 1...P... ...v...d >+[1250] 9E 2C 3A E7 30 F4 16 0D A0 56 C0 BC D2 FE 2D A0 .,:.0... .V....-. >+[1260] 20 A4 E2 82 AD F0 C5 12 71 09 23 E1 66 52 53 D0 ....... q.#.fRS. >+[1270] 89 30 E7 BE B7 C2 89 F2 1C 7A F6 8E D7 28 F0 A4 .0...... .z...(.. >+[1280] 33 46 7C A2 79 66 DE 26 00 00 00 00 3F|.yf.& .... >+push returned Success >+pull returned Success >+ CCACHE: struct CCACHE >+ pvno : 0x05 (5) >+ version : 0x04 (4) >+ optional_header : union OPTIONAL_HEADER(case 0x4) >+ v4header: struct V4HEADER >+ v4tags: struct V4TAGS >+ tag: struct V4TAG >+ tag : 0x0001 (1) >+ field : union FIELD(case 0x1) >+ deltatime_tag: struct DELTATIME_TAG >+ kdc_sec_offset : 0 >+ kdc_usec_offset : 0 >+ further_tags : DATA_BLOB length=0 >+ principal: struct PRINCIPAL >+ name_type : 0x00000001 (1) >+ component_count : 0x00000001 (1) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(1) >+ components : 'administrator' >+ cred: struct CREDENTIAL >+ client: struct PRINCIPAL >+ name_type : 0x00000001 (1) >+ component_count : 0x00000001 (1) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(1) >+ components : 'administrator' >+ server: struct PRINCIPAL >+ name_type : 0x00000000 (0) >+ component_count : 0x00000002 (2) >+ realm : 'KTEST.SAMBA.EXAMPLE.COM' >+ components: ARRAY(2) >+ components : 'krbtgt' >+ components : 'KTEST.SAMBA.EXAMPLE.COM' >+ keyblock: struct KEYBLOCK >+ enctype : 0x0017 (23) >+ data : DATA_BLOB length=16 >+[0000] E5 E4 15 C8 A8 0F 4D 95 F9 1B E3 B9 98 CA A1 7F ......M. ........ >+ authtime : 0x4d9b9045 (1302040645) >+ starttime : 0x4d9b9045 (1302040645) >+ endtime : 0x7d464c43 (2101759043) >+ renew_till : 0x7d464c43 (2101759043) >+ is_skey : 0x00 (0) >+ ticket_flags : 0x40e00000 (1088421888) >+ addresses: struct ADDRESSES >+ count : 0x00000000 (0) >+ data: ARRAY(0) >+ authdata: struct AUTHDATA >+ count : 0x00000000 (0) >+ data: ARRAY(0) >+ ticket : DATA_BLOB length=1032 >+[0000] 61 82 04 04 30 82 04 00 A0 03 02 01 05 A1 19 1B a...0... ........ >+[0010] 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 .KTEST.S AMBA.EXA >+[0020] 4D 50 4C 45 2E 43 4F 4D A2 2C 30 2A A0 03 02 01 MPLE.COM .,0*.... >+[0030] 00 A1 23 30 21 1B 06 6B 72 62 74 67 74 1B 17 4B ..#0!..k rbtgt..K >+[0040] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[0050] 4C 45 2E 43 4F 4D A3 82 03 AE 30 82 03 AA A0 03 LE.COM.. ..0..... >+[0060] 02 01 17 A1 03 02 01 01 A2 82 03 9C 04 82 03 98 ........ ........ >+[0070] 01 40 48 A6 B8 F0 DA 43 54 A5 18 CF B0 15 CB 68 .@H....C T......h >+[0080] 9F A0 69 44 87 A9 FF 06 25 B9 29 48 59 64 26 48 ..iD.... %.)HYd&H >+[0090] 96 7C 46 6A 79 E5 F0 77 DB 46 6C 20 A1 59 D9 F8 .|Fjy..w .Fl .Y.. >+[00A0] 6A 8A 2D B5 D9 EF A4 54 DE 19 20 C0 7B 93 D4 3D j.-....T .. .{..= >+[00B0] ED 72 35 AF 9D 87 75 9E 44 01 A4 6C D9 EA 94 A3 .r5...u. D..l.... >+[00C0] 18 C6 42 75 E3 0A 0C 76 9A AE 75 BC A3 02 91 BC ..Bu...v ..u..... >+[00D0] 2D BB 3C 23 73 A6 1A A7 8A 3E 85 42 5D 1F 5D 7D -.<#s... .>.B].]} >+[00E0] 0B 1F C3 88 2A 93 40 F9 E9 18 7D 3F 73 DA AC 1F ....*.@. ..}?s... >+[00F0] E7 7B C3 B8 14 56 C3 63 86 5B AF C9 C3 21 9F 94 .{...V.c .[...!.. >+[0100] B4 67 06 60 7F 56 2D F4 C7 22 CD B4 1C 14 B7 5B .g.`.V-. .".....[ >+[0110] 26 67 9D 18 28 B5 5D C2 FC 13 B6 CA 9F AB CD 32 &g..(.]. .......2 >+[0120] 71 D5 51 5F A2 11 5A 5D 4A B3 3B 1D D1 6B 4F 7D q.Q_..Z] J.;..kO} >+[0130] E9 54 F0 B4 AC 80 DE 27 80 C5 64 3C 0B 22 79 1C .T.....' ..d<."y. >+[0140] 9E D1 58 A1 3E 20 5A 9F E3 34 49 D8 16 C6 6B 2D ..X.> Z. .4I...k- >+[0150] 36 0E E2 C2 3F 44 DE 63 32 DB EB 78 50 A2 6F 37 6...?D.c 2..xP.o7 >+[0160] 05 2B 13 D4 31 07 D4 2A C0 53 B1 30 39 79 C3 D8 .+..1..* .S.09y.. >+[0170] C4 4C 30 97 E8 F9 DA ED 10 B0 D0 21 71 8B 56 F3 .L0..... ...!q.V. >+[0180] 0F 3A 2D 26 A2 3D AD 70 27 82 95 59 0A D7 7D 4E .:-&.=.p '..Y..}N >+[0190] 2D 76 96 4D 94 70 2A BB 26 3B 7E FC E1 59 5A 55 -v.M.p*. &;~..YZU >+[01A0] 04 A2 DA 27 AD 46 70 45 43 C0 FB C1 42 7F F0 CB ...'.FpE C...B... >+[01B0] 21 D2 CD 54 35 7C 60 13 EE BB BB 60 6B 91 2B BE !..T5|`. ...`k.+. >+[01C0] 91 8A CF 49 29 F8 60 D1 AB A5 51 B5 5E 4B B2 3A ...I).`. ..Q.^K.: >+[01D0] F4 56 3A 89 2D 88 D0 73 08 A6 FB D8 6E B3 B1 4E .V:.-..s ....n..N >+[01E0] D8 90 27 58 D2 53 40 B2 A0 3C 40 4D E9 21 C6 83 ..'X.S@. .<@M.!.. >+[01F0] FC 15 14 F0 8C 08 46 C5 29 14 E3 84 CC 2C 56 C9 ......F. )....,V. >+[0200] 20 53 45 34 D0 BE E0 CC F7 F1 15 D4 D4 B1 3C 43 SE4.... ......<C >+[0210] EB 5E 9D 33 07 B4 5B E7 D8 24 B0 EB 7B 27 24 6B .^.3..[. .$..{'$k >+[0220] 2A 90 C9 17 D9 24 CF FD 56 28 D7 73 74 03 2F DA *....$.. V(.st./. >+[0230] C4 E0 B3 78 E4 9A 60 4D 5C C7 F5 CF 9C 14 7C B6 ...x..`M \.....|. >+[0240] 1B 5D 76 D1 E3 73 73 2F 41 BD E3 E7 F0 92 B4 5B .]v..ss/ A......[ >+[0250] 07 B4 16 77 DC 3C 28 A4 92 82 C5 7C CA 00 9C 77 ...w.<(. ...|...w >+[0260] B8 28 7F D0 3F EA 2B C1 79 2B 73 FF E0 E0 A5 17 .(..?.+. y+s..... >+[0270] 02 CA 6C B6 02 D2 51 D3 CE 6F 5B 56 E0 7B 38 22 ..l...Q. .o[V.{8" >+[0280] 76 52 48 2D 0A 2F 15 58 A9 FE 03 65 E1 D5 A8 60 vRH-./.X ...e...` >+[0290] E3 5D E6 53 D8 AA 05 D0 90 61 EF B6 28 4A B9 84 .].S.... .a..(J.. >+[02A0] 56 79 80 D2 53 08 1D 17 C4 05 4E F8 04 10 2B CF Vy..S... ..N...+. >+[02B0] 08 DD 61 68 27 21 A5 8A C0 35 6A 0A 94 6D 9E FD ..ah'!.. .5j..m.. >+[02C0] C9 45 AC E3 4F 60 BB 96 AF D4 4E 71 A9 D9 BE 33 .E..O`.. ..Nq...3 >+[02D0] DC 61 8B 14 77 6C A7 72 70 02 65 62 32 9C 8E 53 .a..wl.r p.eb2..S >+[02E0] C9 A3 5B B9 14 3C 00 A2 1D C7 CD 36 5B 5F BE 40 ..[..<.. ...6[_.@ >+[02F0] 28 E2 58 0D D1 05 53 78 F0 86 0F 80 1A 6A 1D DC (.X...Sx .....j.. >+[0300] D4 CD F2 83 0E 25 E1 60 DB C7 F4 B6 05 4F 0D 11 .....%.` .....O.. >+[0310] A4 AE A5 F8 6D 14 CF DF 03 C5 27 75 75 B5 0C F1 ....m... ..'uu... >+[0320] C3 01 F9 A4 FD 2E 0B BD 51 A8 C1 3B DE 48 CF 3A ........ Q..;.H.: >+[0330] CF B3 41 23 9A 9D 0C 79 11 7C 9B D3 71 43 4E 9D ..A#...y .|..qCN. >+[0340] B5 52 19 28 2C A0 4E 0E 8D 7A 84 9A B9 A0 EB FA .R.(,.N. .z...... >+[0350] 6E A1 DF B9 2F 6B FE 5E AE 85 D1 6B A2 C5 BE 07 n.../k.^ ...k.... >+[0360] E7 D6 33 3A 0F 2B ED FB 30 6F 88 1E F9 09 CC C3 ..3:.+.. 0o...... >+[0370] 8F 59 A0 D4 8D 9F A6 08 B0 D3 ED EB 15 13 1B 8E .Y...... ........ >+[0380] 19 C6 14 9C 25 E7 E9 EF 5A 67 7B CD 86 C4 D1 51 ....%... Zg{....Q >+[0390] 2B DE 27 30 D9 F5 6E F9 E4 3E CF 42 54 AE 42 61 +.'0..n. .>.BT.Ba >+[03A0] C5 22 B7 AE 51 76 8F 12 83 7F E1 9F 97 D8 31 38 ."..Qv.. ......18 >+[03B0] A6 B9 11 B4 E1 BA 19 5B E4 A5 A3 6F 4B B3 03 93 .......[ ...oK... >+[03C0] 4C D6 1E 08 FC 94 D1 C5 7C AA 95 EB 9C 7A C2 57 L....... |....z.W >+[03D0] 60 CA 17 FF 8E 66 80 76 CB 35 46 26 C3 BD CA 83 `....f.v .5F&.... >+[03E0] F0 04 08 0D 4C 5D B2 E4 7C 1C 82 28 D7 2C 42 B1 ....L].. |..(.,B. >+[03F0] 36 72 60 5E 26 4A 79 D0 41 94 3C 2C 65 0E 32 18 6r`^&Jy. A.<,e.2. >+[0400] B8 56 26 9D D3 84 78 BB .V&...x. >+ second_ticket : DATA_BLOB length=0 >+ further_creds : DATA_BLOB length=4748 >+[0000] 00 00 00 01 00 00 00 01 00 00 00 17 4B 54 45 53 ........ ....KTES >+[0010] 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E T.SAMBA. EXAMPLE. >+[0020] 43 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 73 74 72 COM....a dministr >+[0030] 61 74 6F 72 00 00 00 01 00 00 00 02 00 00 00 17 ator.... ........ >+[0040] 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D KTEST.SA MBA.EXAM >+[0050] 50 4C 45 2E 43 4F 4D 00 00 00 04 68 6F 73 74 00 PLE.COM. ...host. >+[0060] 00 00 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 00 17 ...local ktest6.. >+[0070] 00 00 00 10 EA 0D 3A 24 41 21 F7 7D 7D A3 C5 BB ......:$ A!.}}... >+[0080] A4 88 F6 17 4D 9B 90 45 4D 9B 90 52 7D 46 4C 43 ....M..E M..R}FLC >+[0090] 00 00 00 00 00 40 28 00 00 00 00 00 00 00 00 00 .....@(. ........ >+[00A0] 00 00 00 03 FA 61 82 03 F6 30 82 03 F2 A0 03 02 .....a.. .0...... >+[00B0] 01 05 A1 19 1B 17 4B 54 45 53 54 2E 53 41 4D 42 ......KT EST.SAMB >+[00C0] 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D A2 1E 30 A.EXAMPL E.COM..0 >+[00D0] 1C A0 03 02 01 01 A1 15 30 13 1B 04 68 6F 73 74 ........ 0...host >+[00E0] 1B 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 A3 82 03 ..localk test6... >+[00F0] AE 30 82 03 AA A0 03 02 01 17 A1 03 02 01 03 A2 .0...... ........ >+[0100] 82 03 9C 04 82 03 98 44 8B C4 7D BA 9F FE 59 F6 .......D ..}...Y. >+[0110] C1 DF 62 89 02 A4 55 54 AB D6 D6 2E 8B 5E 35 3D ..b...UT .....^5= >+[0120] D9 46 9D 8B 49 93 A6 66 5F 1A 8B 81 AD 09 19 E9 .F..I..f _....... >+[0130] 59 CE 58 18 50 63 4A A6 7D 6F 71 21 51 4A 41 C2 Y.X.PcJ. }oq!QJA. >+[0140] A1 FE B0 D5 0A 3D 38 9F E5 3B 72 A2 7A 59 22 A4 .....=8. .;r.zY". >+[0150] B7 1C A3 8D DB EA 5D A5 E2 D3 1D AE 42 D0 7F 75 ......]. ....B..u >+[0160] B5 E9 ED B5 04 7B 67 1E 28 90 7D 3D 1A 3E F6 62 .....{g. (.}=.>.b >+[0170] D0 A1 56 89 28 76 5C 19 1A FD 66 E5 F2 86 E7 58 ..V.(v\. ..f....X >+[0180] 93 31 90 C5 CD F8 71 96 56 21 15 13 F0 EA C2 CC .1....q. V!...... >+[0190] 48 4C B4 50 EF F9 81 44 29 8A 75 C4 31 75 D1 BA HL.P...D ).u.1u.. >+[01A0] E2 0B 05 B2 E0 EA 64 3A 11 45 84 3D 69 55 FF E6 ......d: .E.=iU.. >+[01B0] 32 7E C9 CA C4 28 E8 40 B6 5E F9 26 0F 09 12 1F 2~...(.@ .^.&.... >+[01C0] 1F D4 9C 9A 50 E8 B7 6D F8 4F 55 6E 2A D4 AC 6A ....P..m .OUn*..j >+[01D0] 79 D1 C2 2A 88 99 F8 39 75 36 F1 2D C7 89 0A C6 y..*...9 u6.-.... >+[01E0] B4 C7 A1 7B F1 BF 22 87 A4 B2 93 22 54 A1 72 25 ...{..". ..."T.r% >+[01F0] AF 67 FE 20 D5 C8 29 47 28 FF 51 FB F9 4E 2C 17 .g. ..)G (.Q..N,. >+[0200] 10 BE 2E 13 8B 18 BE 3C A3 BE 50 49 A7 65 DD 2E .......< ..PI.e.. >+[0210] CC EB D6 0F 47 4E DB 7E 08 D5 F0 37 79 36 8F 24 ....GN.~ ...7y6.$ >+[0220] 34 28 86 89 EC A3 84 7F 44 4E 37 03 B5 D8 89 1C 4(...... DN7..... >+[0230] C7 AA AC 42 70 5F 96 73 35 8B 83 D1 16 24 27 C1 ...Bp_.s 5....$'. >+[0240] EC 0E AE 83 59 5A C2 EB C1 91 B6 3D BB 8D 21 49 ....YZ.. ...=..!I >+[0250] 63 41 3C 91 1D E9 01 C2 4F A9 E4 42 C1 FD 54 E3 cA<..... O..B..T. >+[0260] 7B 3B DF 24 3D 98 E9 84 F8 1D 8D CE 4D 85 AC 8A {;.$=... ....M... >+[0270] 12 15 48 C4 DA 1B 3C B8 FC A3 0B AF E2 4D 71 E9 ..H...<. .....Mq. >+[0280] 0A 28 53 DC 4E 6C 23 2C 73 26 50 FE 37 03 BF D1 .(S.Nl#, s&P.7... >+[0290] 5F 8A 39 4F 04 2E 4A CE 3C 90 11 0C DA 84 5C C3 _.9O..J. <.....\. >+[02A0] F8 BE C7 74 ED F4 CF 7E B2 AE 9B 47 D6 2A 1D 93 ...t...~ ...G.*.. >+[02B0] 3F A8 8B 51 E9 A3 A0 59 55 DB E3 52 67 E3 DE FF ?..Q...Y U..Rg... >+[02C0] B1 56 74 A0 87 21 99 23 8C 8E D1 92 A6 3D 93 D6 .Vt..!.# .....=.. >+[02D0] 4D 5B 84 2B B1 8D DD E4 F7 01 A6 6C 4A DF 3C 6E M[.+.... ...lJ.<n >+[02E0] A0 FA 74 93 BE 18 7C 30 29 9D B8 DB 5F D1 AA B7 ..t...|0 )..._... >+[02F0] 51 7C 2A 90 1A 8B 06 95 E1 80 0D 27 B2 6C 52 1C Q|*..... ...'.lR. >+[0300] C7 D1 E9 16 14 F1 6C 57 48 28 BD 13 B5 83 BA A7 ......lW H(...... >+[0310] 75 31 69 52 03 38 69 13 62 ED C6 DC C2 01 C8 F1 u1iR.8i. b....... >+[0320] 45 02 4D 8C 64 CF 96 90 3E C2 08 EC 2B 8D 92 93 E.M.d... >...+... >+[0330] 4B 6D 22 B3 41 DE 85 35 2D 19 09 E5 68 8E 1F 98 Km".A..5 -...h... >+[0340] 1B F2 73 F2 D4 91 08 89 42 0C 05 8B 42 77 6B CC ..s..... B...Bwk. >+[0350] 18 78 43 1A 73 C2 7C E7 C2 23 28 56 F7 A0 19 B3 .xC.s.|. .#(V.... >+[0360] 99 A6 25 4F C3 5E 70 EC 78 BB 30 15 36 77 B3 A6 ..%O.^p. x.0.6w.. >+[0370] 89 98 B6 A0 85 CC 8F E7 41 40 B5 E0 89 93 25 04 ........ A@....%. >+[0380] B8 1D 0B 06 31 1D C7 30 52 E1 64 29 8C 64 B9 89 ....1..0 R.d).d.. >+[0390] 1F 86 5A AD 74 15 1C C8 AF 37 7B 27 E0 C0 DB 73 ..Z.t... .7{'...s >+[03A0] 30 72 65 D3 C0 A5 07 61 E9 0C 07 A1 27 18 8F 50 0re....a ....'..P >+[03B0] DB CE FB 4C DD 75 98 F2 28 D2 76 FF F2 41 9F D5 ...L.u.. (.v..A.. >+[03C0] 74 22 8A 03 73 B1 A8 B3 B8 80 93 E5 E2 CD 4B F2 t"..s... ......K. >+[03D0] 6B 99 DF 5B 5B C7 22 69 81 2A 8A CD 2A F9 9D 08 k..[[."i .*..*... >+[03E0] B8 B0 40 77 D3 43 8B AF 40 DD 0C CB 45 E3 88 CB ..@w.C.. @...E... >+[03F0] 06 AA 63 38 EB DD 72 89 03 0E DC 3E 97 3F 16 D4 ..c8..r. ...>.?.. >+[0400] 1A 21 40 D8 30 BD B0 B4 04 C2 7A 22 43 15 A2 D8 .!@.0... ..z"C... >+[0410] 2F 08 28 3B 63 26 AA B3 1C B6 FC E4 0B 2A CD 0E /.(;c&.. .....*.. >+[0420] A8 7C E8 11 33 03 D3 C5 6C 35 6A 5D 3C 5A 80 1A .|..3... l5j]<Z.. >+[0430] BC 1C 54 DE 5C 6A E2 F3 A1 18 8E 47 88 8B 71 11 ..T.\j.. ...G..q. >+[0440] 09 2F 29 88 D9 BB DC 34 09 E1 2F 7E A7 E8 29 DC ./)....4 ../~..). >+[0450] F9 5A 1D 9E C8 A4 CC 52 8A E6 CB 4A 3F F9 77 F7 .Z.....R ...J?.w. >+[0460] 53 64 62 9E 5F E6 D7 F6 43 E6 9C 03 C9 55 B1 CB Sdb._... C....U.. >+[0470] 25 40 74 AA E9 AB 34 58 E1 E8 9B B3 1D 9E 83 FD %@t...4X ........ >+[0480] 7A BF DC 45 2D A8 9A F8 AF 9C 63 EF 1B 2B 9D CC z..E-... ..c..+.. >+[0490] F3 08 74 EC 6E 40 8E 18 62 BD F3 87 66 87 67 00 ..t.n@.. b...f.g. >+[04A0] 00 00 00 00 00 00 01 00 00 00 01 00 00 00 17 4B ........ .......K >+[04B0] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[04C0] 4C 45 2E 43 4F 4D 00 00 00 0D 61 64 6D 69 6E 69 LE.COM.. ..admini >+[04D0] 73 74 72 61 74 6F 72 00 00 00 01 00 00 00 02 00 strator. ........ >+[04E0] 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 ...KTEST .SAMBA.E >+[04F0] 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 04 63 69 XAMPLE.C OM....ci >+[0500] 66 73 00 00 00 0B 6C 6F 63 61 6C 6B 74 65 73 74 fs....lo calktest >+[0510] 36 00 17 00 00 00 10 92 C6 A1 91 6D 55 01 4E BE 6....... ...mU.N. >+[0520] E4 3F E3 36 B0 D3 28 4D 9B 90 45 4D 9B 90 5A 7D .?.6..(M ..EM..Z} >+[0530] 46 4C 43 00 00 00 00 00 40 28 00 00 00 00 00 00 FLC..... @(...... >+[0540] 00 00 00 00 00 00 03 FA 61 82 03 F6 30 82 03 F2 ........ a...0... >+[0550] A0 03 02 01 05 A1 19 1B 17 4B 54 45 53 54 2E 53 ........ .KTEST.S >+[0560] 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D AMBA.EXA MPLE.COM >+[0570] A2 1E 30 1C A0 03 02 01 01 A1 15 30 13 1B 04 63 ..0..... ...0...c >+[0580] 69 66 73 1B 0B 6C 6F 63 61 6C 6B 74 65 73 74 36 ifs..loc alktest6 >+[0590] A3 82 03 AE 30 82 03 AA A0 03 02 01 17 A1 03 02 ....0... ........ >+[05A0] 01 03 A2 82 03 9C 04 82 03 98 FE 09 00 80 36 35 ........ ......65 >+[05B0] D4 6E 71 0C 33 22 36 9E 89 88 32 E3 34 4A 4C BF .nq.3"6. ..2.4JL. >+[05C0] 80 19 81 CC A0 CB 96 DB 31 F7 2A 19 75 DE 0E DA ........ 1.*.u... >+[05D0] D0 18 FA 9E 75 E6 E4 13 C9 BE 3F C0 1B AD 5B 98 ....u... ..?...[. >+[05E0] E9 FC A3 9D 16 FF C8 91 03 AC 8B E6 2D 15 B3 F1 ........ ....-... >+[05F0] 23 4E 25 9E 45 3A F8 8A 19 B7 71 52 A6 92 1C FB #N%.E:.. ..qR.... >+[0600] 1F D4 4C 51 AF 9C 0E 73 D9 A8 D8 43 F2 64 71 BC ..LQ...s ...C.dq. >+[0610] AD B1 7B 8F BF 8D FF 72 89 0F 5E B6 C2 E3 C0 01 ..{....r ..^..... >+[0620] 98 41 AD 3F 6E DC 87 F5 9A E6 40 0C 17 0F 75 80 .A.?n... ..@...u. >+[0630] 0C 28 62 06 EB BF F8 69 8C 43 48 38 A8 AE F2 5E .(b....i .CH8...^ >+[0640] 45 11 23 FB 6B 85 83 54 BA 60 39 CE 08 00 D1 05 E.#.k..T .`9..... >+[0650] 5F 6F 79 96 30 28 06 DD C7 75 52 8E 3C C4 3F FC _oy.0(.. .uR.<.?. >+[0660] C1 31 28 2C 64 3B D1 7E 2F C2 DB B0 E8 A8 EF C5 .1(,d;.~ /....... >+[0670] F2 DC 43 D0 14 21 C8 D0 D3 15 45 8E 2A 3E 3B 4A ..C..!.. ..E.*>;J >+[0680] 60 25 3D 11 E4 F9 16 02 3E 55 8F CE D2 E9 95 E7 `%=..... >U...... >+[0690] B1 C4 8F C4 0B 3E 3C 14 15 28 1A 21 49 15 CE 8E .....><. .(.!I... >+[06A0] 91 5E 98 71 00 1F 29 D3 12 C8 D0 11 4F E7 14 E3 .^.q..). ....O... >+[06B0] 72 1B 61 6D 7B 8A 00 A6 5E 01 01 50 C2 CF 1A A9 r.am{... ^..P.... >+[06C0] 34 8C BA 33 9E 62 C5 69 97 6A 24 3D E0 C6 3F C6 4..3.b.i .j$=..?. >+[06D0] F4 36 B1 80 D6 5C 44 19 5B 65 C7 CA 47 DE 4B 65 .6...\D. [e..G.Ke >+[06E0] 41 29 9F F8 EA E8 E0 3B E2 C6 98 9D 58 A4 6C 62 A).....; ....X.lb >+[06F0] EF 25 12 C9 0E 97 CE 9D F0 D8 08 AD 13 73 A6 82 .%...... .....s.. >+[0700] C5 54 23 F4 A4 CB 91 35 91 BD 10 B4 04 DD 55 7E .T#....5 ......U~ >+[0710] C9 DE AE CB B0 8F C0 D8 28 AE BD 78 64 91 6C AB ........ (..xd.l. >+[0720] CA 36 EA 0E 0E 97 DC 40 ED 26 1D 09 17 28 30 D3 .6.....@ .&...(0. >+[0730] 78 DC F7 D2 9C 78 DA 6F 6F 57 00 B3 FD 8E 75 A1 x....x.o oW....u. >+[0740] 56 98 5C 4B D8 61 A6 0A 89 27 CD 11 BF 7F 79 53 V.\K.a.. .'....yS >+[0750] D9 50 9A 8D EC DD DB BB B8 23 27 0D 20 5B 53 51 .P...... .#'. [SQ >+[0760] 07 C4 26 31 3B D4 DF ED 3C 40 B4 1C 8B 46 E2 A6 ..&1;... <@...F.. >+[0770] B7 0F 97 D2 B3 1D 19 FD 13 60 7B 38 E6 37 0C 59 ........ .`{8.7.Y >+[0780] B0 A8 47 5D 32 A5 0C 57 76 EF 2C ED 40 9F BF 4B ..G]2..W v.,.@..K >+[0790] 43 99 3C 68 C4 DE 84 9C A1 36 8C CA CB 2A 08 36 C.<h.... .6...*.6 >+[07A0] 4E CD 43 06 9E F8 E7 1D 52 3B 59 37 4F 6F 65 D9 N.C..... R;Y7Ooe. >+[07B0] 2A F9 AD 5A 50 95 71 3F B1 5F C8 8E 2E E9 E4 FE *..ZP.q? ._...... >+[07C0] C8 A9 42 2C EE 18 E0 81 3C 00 E2 80 8D 8A 8B 71 ..B,.... <......q >+[07D0] C7 F5 AC 5C 36 1D E0 BC F0 11 57 67 CB 2C BE F6 ...\6... ..Wg.,.. >+[07E0] 90 4E F9 90 97 14 1F 0C 9D 5D 4D DF 0D D0 C0 C5 .N...... .]M..... >+[07F0] 08 E7 31 72 8E 35 63 17 8D 8B 3D 49 14 C8 A5 90 ..1r.5c. ..=I.... >+[0800] 88 24 AF 75 CA 0A CB 95 8A 2C 70 A6 CE 2F 3F B6 .$.u.... .,p../?. >+[0810] D7 1A 44 AC 05 93 EF 3D 03 C7 C2 8E 0F 31 9F 53 ..D....= .....1.S >+[0820] 67 CA 73 D3 B8 07 76 36 35 6F B5 32 30 38 86 7E g.s...v6 5o.208.~ >+[0830] 7E 95 3F DC F4 6F A9 67 0E 15 E8 4A CA 3F 18 0E ~.?..o.g ...J.?.. >+[0840] C6 E7 20 22 6B F1 39 6A 9C A6 47 64 81 E4 CB A8 .. "k.9j ..Gd.... >+[0850] 31 FF E2 97 13 41 89 45 79 53 2B A8 90 97 DE 7B 1....A.E yS+....{ >+[0860] 18 56 95 02 2A 94 D2 7E 5C D0 A0 BC A0 38 D2 BC .V..*..~ \....8.. >+[0870] 03 91 F7 35 FE 1A 5E 80 10 13 4E 83 CB F6 D7 8A ...5..^. ..N..... >+[0880] 02 A2 E8 1F D8 9B F1 76 F9 18 66 56 9C 4D 9E BF .......v ..fV.M.. >+[0890] 1D F4 66 86 E0 7B 88 EC 9C F7 50 13 7D 34 8A 54 ..f..{.. ..P.}4.T >+[08A0] 7A E1 EC F6 44 12 47 84 7D 16 B4 42 25 E5 A2 CC z...D.G. }..B%... >+[08B0] D8 CA 7A 38 21 85 A3 F8 41 6D 0D AC 1D FA 36 5D ..z8!... Am....6] >+[08C0] 23 EA 20 CC 43 A5 7E D9 25 97 BC 0E 74 F5 3D 98 #. .C.~. %...t.=. >+[08D0] B9 79 C2 65 50 0E 8D E7 7A F3 F3 88 37 A3 40 01 .y.eP... z...7.@. >+[08E0] 96 C6 FC 1D 6E 9E 06 A1 90 A0 78 3C DA 7F E9 C6 ....n... ..x<.... >+[08F0] 23 47 70 04 03 EE C2 4A C3 95 07 44 00 BD 29 2A #Gp....J ...D..)* >+[0900] B5 FA 17 1E D6 BC 00 A0 93 55 E0 82 0A AB 04 D4 ........ .U...... >+[0910] D5 56 84 2A B2 56 51 05 DB 30 E2 83 5A 75 D3 A8 .V.*.VQ. .0..Zu.. >+[0920] 30 B7 3E C4 25 70 A8 34 E4 A2 EB 3E FB D8 2D 10 0.>.%p.4 ...>..-. >+[0930] 72 8E DA 4D 2D 55 EC 49 66 5E 01 96 E4 C1 0C 23 r..M-U.I f^.....# >+[0940] 57 91 00 00 00 00 00 00 00 01 00 00 00 01 00 00 W....... ........ >+[0950] 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 ..KTEST. SAMBA.EX >+[0960] 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D 61 64 6D AMPLE.CO M....adm >+[0970] 69 6E 69 73 74 72 61 74 6F 72 00 00 00 01 00 00 inistrat or...... >+[0980] 00 02 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 ......KT EST.SAMB >+[0990] 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 A.EXAMPL E.COM... >+[09A0] 04 68 6F 73 74 00 00 00 0B 4C 4F 43 41 4C 4B 54 .host... .LOCALKT >+[09B0] 45 53 54 36 00 17 00 00 00 10 9D AE 06 BE 29 E0 EST6.... ......). >+[09C0] F7 9A 46 97 29 E0 69 8E 5A F0 4D 9B 90 45 4D 9B ..F.).i. Z.M..EM. >+[09D0] 90 61 7D 46 4C 43 00 00 00 00 00 40 28 00 00 00 .a}FLC.. ...@(... >+[09E0] 00 00 00 00 00 00 00 00 00 03 FA 61 82 03 F6 30 ........ ...a...0 >+[09F0] 82 03 F2 A0 03 02 01 05 A1 19 1B 17 4B 54 45 53 ........ ....KTES >+[0A00] 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E T.SAMBA. EXAMPLE. >+[0A10] 43 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 15 30 13 COM..0.. ......0. >+[0A20] 1B 04 68 6F 73 74 1B 0B 4C 4F 43 41 4C 4B 54 45 ..host.. LOCALKTE >+[0A30] 53 54 36 A3 82 03 AE 30 82 03 AA A0 03 02 01 17 ST6....0 ........ >+[0A40] A1 03 02 01 03 A2 82 03 9C 04 82 03 98 B9 C5 6E ........ .......n >+[0A50] 77 F9 59 6D 19 F0 A6 56 2F 14 B3 9A A3 17 06 A6 w.Ym...V /....... >+[0A60] AD F5 92 38 6A 1E EA 3D 53 BF 5E 95 13 FF 5D BB ...8j..= S.^...]. >+[0A70] 43 4F 51 AE FB 12 3B 06 67 36 91 B9 E0 C4 C4 F3 COQ...;. g6...... >+[0A80] 45 A0 48 E6 DC 49 E8 EA 6F 55 D2 3F 79 57 54 FF E.H..I.. oU.?yWT. >+[0A90] 10 8D 89 4A A4 E2 B2 80 FD EE 36 C5 D5 4C D0 97 ...J.... ..6..L.. >+[0AA0] B3 EC 96 8B E8 5A 05 F0 13 39 8B 1B B3 C4 32 2A .....Z.. .9....2* >+[0AB0] 9B BB EF 06 C4 1C 53 2F 0A F6 A8 C6 BE 09 57 26 ......S/ ......W& >+[0AC0] B9 39 7B 7B 50 13 2D 6C 52 FF C4 B5 83 28 A8 47 .9{{P.-l R....(.G >+[0AD0] 5A CD 1C DD A7 65 FD 8A 84 2A 10 E7 44 E6 83 E7 Z....e.. .*..D... >+[0AE0] E7 AA B8 E5 0A 8B 7E E1 87 7B 3D C4 9F 68 BD 19 ......~. .{=..h.. >+[0AF0] 2B 59 5E 5A 45 0D B5 71 CC A6 C7 03 3C B3 17 D3 +Y^ZE..q ....<... >+[0B00] AF 99 F6 A2 52 A0 99 F7 39 56 B4 33 B4 C5 F4 CC ....R... 9V.3.... >+[0B10] 74 34 4C 00 76 26 10 D1 3A 87 6E 6A 52 9B 7A BF t4L.v&.. :.njR.z. >+[0B20] 4E 59 36 32 C5 41 29 CF E1 BF 14 E0 54 BF 4A 25 NY62.A). ....T.J% >+[0B30] 1F 0B 6E 9A 8C 0E 5D 47 A9 64 1B A4 9D 99 A9 09 ..n...]G .d...... >+[0B40] 39 14 E7 41 22 98 8C 62 CC E2 B5 91 8E C1 31 EB 9..A"..b ......1. >+[0B50] B2 70 A6 3B 86 FC DD 19 0B 3F 5D C9 B5 1A 95 73 .p.;.... .?]....s >+[0B60] EB 97 89 BE 14 87 85 17 BE 40 F6 80 14 23 4D 66 ........ .@...#Mf >+[0B70] E4 B0 E5 51 46 34 DA 1C C8 CB FF C6 84 A3 DF D2 ...QF4.. ........ >+[0B80] DC 00 AF 7B 27 C8 78 44 CB 6E 7B CC 5C 94 1E 7A ...{'.xD .n{.\..z >+[0B90] 95 29 19 F4 14 BE 5C 23 C3 B9 A4 2C 5D 4D F3 61 .)....\# ...,]M.a >+[0BA0] 63 1F D4 FE 37 EE 44 14 06 B7 14 50 B6 74 37 75 c...7.D. ...P.t7u >+[0BB0] 2C AB 06 F0 93 F9 93 34 75 63 44 7E 12 48 D1 F1 ,......4 ucD~.H.. >+[0BC0] 06 55 14 11 B9 23 43 CE 01 16 3E 6B A3 BD 23 55 .U...#C. ..>k..#U >+[0BD0] DE 48 5D AF E1 2B 89 E8 E7 C2 E2 34 25 A2 09 4A .H]..+.. ...4%..J >+[0BE0] 1F BE 05 AA DE 4B 08 65 27 4C 9B C7 54 96 C2 FB .....K.e 'L..T... >+[0BF0] E2 CE 53 4A 32 93 8D 0B 44 77 8C D3 65 54 F9 0E ..SJ2... Dw..eT.. >+[0C00] 7F 74 1E FE 3D 74 83 0F 2F E7 9F BC A2 B0 2B 25 .t..=t.. /.....+% >+[0C10] BB D2 6F A8 49 C1 3E 9E B5 93 67 74 39 A4 FE 84 ..o.I.>. ..gt9... >+[0C20] 4C 45 5F 30 74 E0 CA 5F F6 46 EC 89 B5 2D C8 14 LE_0t.._ .F...-.. >+[0C30] 69 76 BC 93 15 F4 60 30 5F AB EB 02 DD 12 4C 62 iv....`0 _.....Lb >+[0C40] F9 73 F7 01 E1 7F 2A 6F 09 05 BF 3A 3A 7E 69 A3 .s....*o ...::~i. >+[0C50] 7B FC 20 2B D6 CE C0 74 4F BB 29 E4 BE CE 04 9D {. +...t O.)..... >+[0C60] 24 D4 98 4A ED 94 A8 81 CD 26 A0 63 EA 09 57 42 $..J.... .&.c..WB >+[0C70] 26 B7 B5 4E B5 CB 45 35 A7 84 D8 74 CA C3 9F FF &..N..E5 ...t.... >+[0C80] C8 1E 2A 75 34 01 C5 A7 B4 9D 6F A3 E1 BB 2B F8 ..*u4... ..o...+. >+[0C90] F0 21 D6 77 57 74 2E 80 DB 76 53 01 86 33 17 32 .!.wWt.. .vS..3.2 >+[0CA0] 2E 16 E1 8D 89 3A B2 67 ED A3 ED 39 82 87 26 A6 .....:.g ...9..&. >+[0CB0] DB CE 59 84 E4 0A A6 CA 7E 07 98 F7 02 91 6E 56 ..Y..... ~.....nV >+[0CC0] 9F 60 03 D3 88 B0 FF EB 20 CA 9E 5B 37 26 67 00 .`...... ..[7&g. >+[0CD0] CC BD 9D 53 15 31 53 14 FD 9C E1 28 08 CB C4 0B ...S.1S. ...(.... >+[0CE0] E3 50 D9 DB 0C E2 E4 F9 44 50 E9 28 6E 01 96 AA .P...... DP.(n... >+[0CF0] C1 D2 4E B2 DE 38 A2 F8 94 32 79 AE 49 64 FB 57 ..N..8.. .2y.Id.W >+[0D00] 50 F6 73 E8 98 43 C6 DD 67 3C 91 AC 97 C9 2E 8C P.s..C.. g<...... >+[0D10] 06 59 A1 FC 49 EC 2F BF 6F 64 21 63 ED C8 6C CE .Y..I./. od!c..l. >+[0D20] 37 28 7B 80 7F 5F 85 F6 98 93 C0 66 A8 D6 F1 2C 7({.._.. ...f..., >+[0D30] D8 01 68 B1 C8 EA 82 0D 5B 9B 35 4F 3D B3 47 19 ..h..... [.5O=.G. >+[0D40] 54 7A C6 9F AD D7 54 CF B0 DB 3E 18 BA 2A 39 08 Tz....T. ..>..*9. >+[0D50] 0C C4 98 4B 43 DE 53 68 25 B1 83 93 1D E1 6C BF ...KC.Sh %.....l. >+[0D60] F5 B4 A9 83 17 34 64 8C 2F 91 80 97 4A 48 EC 90 .....4d. /...JH.. >+[0D70] BB FA 92 2C 01 80 E4 99 91 0E 67 88 D5 75 AB 7C ...,.... ..g..u.| >+[0D80] 98 59 98 45 C9 11 A9 8C 02 98 91 DE AB A0 FF 45 .Y.E.... .......E >+[0D90] 11 66 6F C5 DE 61 6D C6 DB C9 CA A3 A0 2B B1 73 .fo..am. .....+.s >+[0DA0] 05 85 37 BF AB CA 43 7A 6F 38 C8 BE ED CE 12 49 ..7...Cz o8.....I >+[0DB0] 93 C7 7C 1A 33 60 52 7A 67 67 AA 60 57 7E C8 FF ..|.3`Rz gg.`W~.. >+[0DC0] DF 91 91 18 45 74 C0 9E 36 19 BC 42 F9 46 CC 84 ....Et.. 6..B.F.. >+[0DD0] 09 2E 8C 59 1A E3 65 51 F4 87 6F 4C 3E 29 38 E6 ...Y..eQ ..oL>)8. >+[0DE0] 77 E8 A9 B7 FA 00 00 00 00 00 00 00 01 00 00 00 w....... ........ >+[0DF0] 01 00 00 00 17 4B 54 45 53 54 2E 53 41 4D 42 41 .....KTE ST.SAMBA >+[0E00] 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D 00 00 00 0D .EXAMPLE .COM.... >+[0E10] 61 64 6D 69 6E 69 73 74 72 61 74 6F 72 00 00 00 administ rator... >+[0E20] 01 00 00 00 02 00 00 00 17 4B 54 45 53 54 2E 53 ........ .KTEST.S >+[0E30] 41 4D 42 41 2E 45 58 41 4D 50 4C 45 2E 43 4F 4D AMBA.EXA MPLE.COM >+[0E40] 00 00 00 04 63 69 66 73 00 00 00 0B 4C 4F 43 41 ....cifs ....LOCA >+[0E50] 4C 4B 54 45 53 54 36 00 17 00 00 00 10 01 78 D0 LKTEST6. ......x. >+[0E60] 3B 9B FF F0 88 86 4B 3B FE 41 A9 6B 00 4D 9B 90 ;.....K; .A.k.M.. >+[0E70] 45 4D 9B 90 6B 7D 46 4C 43 00 00 00 00 00 40 28 EM..k}FL C.....@( >+[0E80] 00 00 00 00 00 00 00 00 00 00 00 00 03 FA 61 82 ........ ......a. >+[0E90] 03 F6 30 82 03 F2 A0 03 02 01 05 A1 19 1B 17 4B ..0..... .......K >+[0EA0] 54 45 53 54 2E 53 41 4D 42 41 2E 45 58 41 4D 50 TEST.SAM BA.EXAMP >+[0EB0] 4C 45 2E 43 4F 4D A2 1E 30 1C A0 03 02 01 01 A1 LE.COM.. 0....... >+[0EC0] 15 30 13 1B 04 63 69 66 73 1B 0B 4C 4F 43 41 4C .0...cif s..LOCAL >+[0ED0] 4B 54 45 53 54 36 A3 82 03 AE 30 82 03 AA A0 03 KTEST6.. ..0..... >+[0EE0] 02 01 17 A1 03 02 01 03 A2 82 03 9C 04 82 03 98 ........ ........ >+[0EF0] CA EA 4D 46 2D D1 E9 58 5D 25 8D 9F DF EA C9 01 ..MF-..X ]%...... >+[0F00] B6 08 27 CD 14 85 02 DC 20 C6 51 AA F9 6A B1 CE ..'..... .Q..j.. >+[0F10] F5 77 84 BF 9A AC 6B A7 B2 F2 1F 60 BF CB C6 FC .w....k. ...`.... >+[0F20] C7 14 B7 41 1C A8 C9 70 7B 86 BC 8E 70 2B 65 4B ...A...p {...p+eK >+[0F30] DC F5 B9 23 F8 08 BF 96 C9 A8 77 F4 54 67 25 F8 ...#.... ..w.Tg%. >+[0F40] 0F A8 C5 D6 D1 BB 46 5E A0 7E D2 98 9C CD AF E0 ......F^ .~...... >+[0F50] 82 62 ED 39 D2 FB F2 E8 9B 1B EE E5 B4 1B C9 0A .b.9.... ........ >+[0F60] 86 27 52 6E 11 8B D7 AD B4 54 F9 C6 69 8D E0 F1 .'Rn.... .T..i... >+[0F70] CD 63 1C 89 7C 8F B6 A0 71 53 A6 DA B1 66 D2 9D .c..|... qS...f.. >+[0F80] D3 4C A8 FB C6 9D 81 74 10 8E 84 D2 3D D8 1C BE .L.....t ....=... >+[0F90] BB 3F F7 BF 91 3E 89 66 43 A1 E0 90 1B 1A 97 FF .?...>.f C....... >+[0FA0] EF CC 35 75 14 62 4F 67 3A 29 F4 F9 C5 2E BE C5 ..5u.bOg :)...... >+[0FB0] C2 2B A8 35 22 D9 92 31 1D 49 2A A5 19 AA 08 0F .+.5"..1 .I*..... >+[0FC0] A8 22 0B 68 D2 A2 D7 07 7B 37 1E A3 AC 9B 4F 0A .".h.... {7....O. >+[0FD0] A4 FA 7F 37 6F 3E 35 79 4E 00 4B B6 28 A3 6A E4 ...7o>5y N.K.(.j. >+[0FE0] 0C 95 53 BA E8 41 07 DA BE E9 08 B9 51 24 91 49 ..S..A.. ....Q$.I >+[0FF0] 78 5D 44 12 BC 85 63 81 B8 E0 88 D5 95 0C D3 A8 x]D...c. ........ >+[1000] 1D 32 4B E4 A0 C8 A7 7D 3C 97 EE D8 59 AC 3A 21 .2K....} <...Y.:! >+[1010] 09 F2 7A CC D0 4A F3 50 10 DC FC 26 BB C2 6A 8E ..z..J.P ...&..j. >+[1020] 8B 14 2B 2D 50 2E B3 1E 9B D2 69 56 22 F2 48 BD ..+-P... ..iV".H. >+[1030] E9 2E 2F 28 DE 77 67 5F 68 AA 29 05 4B 36 58 40 ../(.wg_ h.).K6X@ >+[1040] E5 54 11 C5 4D 68 96 49 9D 53 37 87 5F D2 3A 9B .T..Mh.I .S7._.:. >+[1050] E9 8E 79 BE AE 11 B4 6B AB FD DB 8A F5 A0 9B 29 ..y....k .......) >+[1060] D9 F5 ED CA FA 3F FE 35 FC F4 69 7E E4 D0 44 29 .....?.5 ..i~..D) >+[1070] 48 FF 82 61 26 FC D3 E2 10 EE 14 F7 4A E3 CD F2 H..a&... ....J... >+[1080] 8B BC 8B 43 64 2C DE 40 6E BB E1 56 C0 B6 2C D0 ...Cd,.@ n..V..,. >+[1090] E5 1E E9 B3 FB 38 48 66 ED AF D2 25 D1 35 5C C6 .....8Hf ...%.5\. >+[10A0] F0 4D 36 19 0B EC 33 07 34 D0 27 8D 14 DC 01 45 .M6...3. 4.'....E >+[10B0] DE F8 73 A6 A0 F4 C1 91 9D BD 05 E3 70 25 E1 10 ..s..... ....p%.. >+[10C0] 44 F6 4B 46 F7 24 84 BF 20 96 AD 6A 96 94 81 58 D.KF.$.. ..j...X >+[10D0] 80 95 06 92 F5 7F 17 39 3B 32 47 B2 C5 CE 7B 73 .......9 ;2G...{s >+[10E0] CF 53 AE FA D1 9A 60 5A 98 EC 8C FA BD C0 CE 8D .S....`Z ........ >+[10F0] C5 27 E6 17 1A 4D 47 D8 3F 5D A9 7C FB 2C B3 05 .'...MG. ?].|.,.. >+[1100] 0C 69 20 48 99 80 11 DC 48 AB A7 EA 5B 98 C1 15 .i H.... H...[... >+[1110] 27 AE FA 3E 1E 1E E0 E1 F8 32 C0 54 13 D6 30 34 '..>.... .2.T..04 >+[1120] 71 98 26 61 6C 1C C4 C7 4E C4 A6 7E FE A8 B8 89 q.&al... N..~.... >+[1130] 2A 70 3C 19 58 8D 57 45 55 83 0A C2 B5 F7 89 0E *p<.X.WE U....... >+[1140] 7B 7A 17 0C CF 6E 08 A5 F7 21 4A 62 81 4F 49 CA {z...n.. .!Jb.OI. >+[1150] E2 ED C2 B4 C7 33 5C BC A1 A0 DE 4E 09 37 BE 24 .....3\. ...N.7.$ >+[1160] 62 22 94 55 75 AA 53 DE E0 74 5A B0 B8 E9 BF 2B b".Uu.S. .tZ....+ >+[1170] 12 65 2F 90 6B 84 ED 11 AD F7 CE 19 A1 96 E4 1E .e/.k... ........ >+[1180] 8C EA C8 81 1B 47 4F 5F B1 5D A5 8B E3 0D 5A 80 .....GO_ .]....Z. >+[1190] 89 EC 4B D9 CE ED E8 67 7F 96 FC 1B EF 65 C2 68 ..K....g .....e.h >+[11A0] 40 F7 20 36 83 58 62 F4 CA 02 F4 5C 0D 46 B1 CB @. 6.Xb. ...\.F.. >+[11B0] 50 D2 D8 3D B7 9A 96 48 8C CF EB E6 8C F4 B2 B4 P..=...H ........ >+[11C0] 47 C9 34 C9 DC 14 F1 33 1B 6F 9E 65 27 D7 9D 46 G.4....3 .o.e'..F >+[11D0] 1E 91 FF 2E FB 8E 97 5D 17 8F 48 54 7C 3C A0 11 .......] ..HT|<.. >+[11E0] 9C AA 77 E9 79 DE 26 D1 F0 7C EA 24 73 BE EC 60 ..w.y.&. .|.$s..` >+[11F0] B4 EE BD ED 0D 0A AB 74 60 6E 46 C0 35 5B 65 1A .......t `nF.5[e. >+[1200] A4 4A 5C 22 AC B9 CD B7 56 06 88 09 FC 48 68 55 .J\".... V....HhU >+[1210] B7 5E 39 72 DF 8A 4C CD 79 74 B0 84 0B 78 DA B2 .^9r..L. yt...x.. >+[1220] 55 F8 06 0B 5C 27 06 B3 CA 10 65 6B 04 A3 64 11 U...\'.. ..ek..d. >+[1230] 04 09 DC DF 67 00 70 B1 16 DF 24 E9 27 85 11 91 ....g.p. ..$.'... >+[1240] 31 CB 92 95 50 18 91 08 C2 A1 A3 76 C7 1A FC 64 1...P... ...v...d >+[1250] 9E 2C 3A E7 30 F4 16 0D A0 56 C0 BC D2 FE 2D A0 .,:.0... .V....-. >+[1260] 20 A4 E2 82 AD F0 C5 12 71 09 23 E1 66 52 53 D0 ....... q.#.fRS. >+[1270] 89 30 E7 BE B7 C2 89 F2 1C 7A F6 8E D7 28 F0 A4 .0...... .z...(.. >+[1280] 33 46 7C A2 79 66 DE 26 00 00 00 00 3F|.yf.& .... >+dump OK >-- >2.25.1 > > >From 7626691b06245f56949686878b0f7b70288b7711 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Apr 2021 11:02:47 +1200 >Subject: [PATCH 072/686] krb5: Add Python functions to create a credentials > cache containing a service ticket > >This is a FILE: format credentials cache readable by the MIT/Heimdal >Kerberos libraries. This allows us to glue the Python ASN1 Kerberos >system to the MIT/Heimdal one. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 2d88a6ff3dbcf650b09ef9c8c37170ca6663b533) >--- > python/samba/tests/krb5/kdc_base_test.py | 167 ++++++++++++++++++++++- > 1 file changed, 163 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 1c7f05dda6d..d8193ae9cdc 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1,6 +1,6 @@ > # Unix SMB/CIFS implementation. > # Copyright (C) Stefan Metzmacher 2020 >-# Copyright (C) 2020 Catalyst.Net Ltd >+# Copyright (C) 2020-2021 Catalyst.Net Ltd > # > # 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 >@@ -18,6 +18,8 @@ > > import sys > import os >+from datetime import datetime >+import tempfile > > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" >@@ -26,10 +28,10 @@ import ldb > from ldb import SCOPE_BASE > from samba import generate_random_password > from samba.auth import system_session >-from samba.credentials import Credentials >-from samba.dcerpc import krb5pac >+from samba.credentials import Credentials, SPECIFIED, MUST_USE_KERBEROS >+from samba.dcerpc import krb5pac, krb5ccache > from samba.dsdb import UF_WORKSTATION_TRUST_ACCOUNT, UF_NORMAL_ACCOUNT >-from samba.ndr import ndr_unpack >+from samba.ndr import ndr_pack, ndr_unpack > from samba.samdb import SamDB > > from samba.tests import delete_force >@@ -38,6 +40,8 @@ import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > AD_IF_RELEVANT, > AD_WIN2K_PAC, >+ AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5, > KDC_ERR_PREAUTH_REQUIRED, > KRB_AS_REP, > KRB_TGS_REP, >@@ -46,6 +50,8 @@ from samba.tests.krb5.rfc4120_constants import ( > KU_PA_ENC_TIMESTAMP, > KU_TGS_REP_ENC_PART_SUB_KEY, > KU_TICKET, >+ NT_PRINCIPAL, >+ NT_SRV_HST, > PADATA_ENC_TIMESTAMP, > PADATA_ETYPE_INFO2, > ) >@@ -445,3 +451,156 @@ class KDCBaseTest(RawKerberosTest): > msg = ldb.Message(dn) > msg[name] = ldb.MessageElement(values, flag, name) > self.ldb.modify(msg) >+ >+ def create_ccache(self, cname, ticket, enc_part): >+ """ Lay out a version 4 on-disk credentials cache, to be read using the >+ FILE: protocol. >+ """ >+ >+ field = krb5ccache.DELTATIME_TAG() >+ field.kdc_sec_offset = 0 >+ field.kdc_usec_offset = 0 >+ >+ v4tag = krb5ccache.V4TAG() >+ v4tag.tag = 1 >+ v4tag.field = field >+ >+ v4tags = krb5ccache.V4TAGS() >+ v4tags.tag = v4tag >+ v4tags.further_tags = b'' >+ >+ optional_header = krb5ccache.V4HEADER() >+ optional_header.v4tags = v4tags >+ >+ cname_string = cname['name-string'] >+ >+ cprincipal = krb5ccache.PRINCIPAL() >+ cprincipal.name_type = cname['name-type'] >+ cprincipal.component_count = len(cname_string) >+ cprincipal.realm = ticket['realm'] >+ cprincipal.components = cname_string >+ >+ sname = ticket['sname'] >+ sname_string = sname['name-string'] >+ >+ sprincipal = krb5ccache.PRINCIPAL() >+ sprincipal.name_type = sname['name-type'] >+ sprincipal.component_count = len(sname_string) >+ sprincipal.realm = ticket['realm'] >+ sprincipal.components = sname_string >+ >+ key = self.EncryptionKey_import(enc_part['key']) >+ >+ key_data = key.export_obj() >+ keyblock = krb5ccache.KEYBLOCK() >+ keyblock.enctype = key_data['keytype'] >+ keyblock.data = key_data['keyvalue'] >+ >+ addresses = krb5ccache.ADDRESSES() >+ addresses.count = 0 >+ addresses.data = [] >+ >+ authdata = krb5ccache.AUTHDATA() >+ authdata.count = 0 >+ authdata.data = [] >+ >+ # Re-encode the ticket, since it was decoded by another layer. >+ ticket_data = self.der_encode(ticket, asn1Spec=krb5_asn1.Ticket()) >+ >+ authtime = enc_part['authtime'] >+ try: >+ starttime = enc_part['starttime'] >+ except KeyError: >+ starttime = authtime >+ endtime = enc_part['endtime'] >+ >+ cred = krb5ccache.CREDENTIAL() >+ cred.client = cprincipal >+ cred.server = sprincipal >+ cred.keyblock = keyblock >+ cred.authtime = int(datetime.strptime(authtime.decode(), >+ "%Y%m%d%H%M%SZ").timestamp()) >+ cred.starttime = int(datetime.strptime(starttime.decode(), >+ "%Y%m%d%H%M%SZ").timestamp()) >+ cred.endtime = int(datetime.strptime(endtime.decode(), >+ "%Y%m%d%H%M%SZ").timestamp()) >+ cred.renew_till = cred.endtime >+ cred.is_skey = 0 >+ cred.ticket_flags = int(enc_part['flags'], 2) >+ cred.addresses = addresses >+ cred.authdata = authdata >+ cred.ticket = ticket_data >+ cred.second_ticket = b'' >+ >+ ccache = krb5ccache.CCACHE() >+ ccache.pvno = 5 >+ ccache.version = 4 >+ ccache.optional_header = optional_header >+ ccache.principal = cprincipal >+ ccache.cred = cred >+ >+ # Serialise the credentials cache structure. >+ result = ndr_pack(ccache) >+ >+ # Create a temporary file and write the credentials. >+ cachefile = tempfile.NamedTemporaryFile(dir=self.tempdir, delete=False) >+ cachefile.write(result) >+ cachefile.close() >+ >+ return cachefile >+ >+ def create_ccache_with_user(self, user_credentials, mach_name, >+ service="host"): >+ # Obtain a service ticket authorising the user and place it into a >+ # newly created credentials cache file. >+ >+ user_name = user_credentials.get_username() >+ realm = user_credentials.get_realm() >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ sname = self.PrincipalName_create(name_type=NT_SRV_HST, >+ names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.check_pre_authenication(rep) >+ >+ # Do the next AS-REQ >+ padata = self.get_pa_data(user_credentials, rep) >+ key = self.get_as_rep_key(user_credentials, rep) >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ # Request a ticket to the host service on the machine account >+ ticket = rep['ticket'] >+ enc_part = self.get_as_rep_enc_data(key, rep) >+ key = self.EncryptionKey_import(enc_part['key']) >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ sname = self.PrincipalName_create(name_type=NT_SRV_HST, >+ names=[service, mach_name]) >+ >+ (rep, enc_part) = self.tgs_req( >+ cname, sname, realm, ticket, key, etype) >+ self.check_tgs_reply(rep) >+ key = self.EncryptionKey_import(enc_part['key']) >+ >+ # Check the contents of the pac, and the ticket >+ ticket = rep['ticket'] >+ >+ # Write the ticket into a credentials cache file that can be ingested >+ # by the main credentials code. >+ cachefile = self.create_ccache(cname, ticket, enc_part) >+ >+ # Create a credentials object to reference the credentials cache. >+ creds = Credentials() >+ creds.set_kerberos_state(MUST_USE_KERBEROS) >+ creds.set_username(user_name, SPECIFIED) >+ creds.set_realm(realm) >+ creds.set_named_ccache(cachefile.name, SPECIFIED, self.lp) >+ >+ # Return the credentials along with the cache file. >+ return (creds, cachefile) >-- >2.25.1 > > >From ba7335006e1361534e023686cee49b3f87c03b8d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Apr 2021 11:06:33 +1200 >Subject: [PATCH 073/686] python: Add credentials cache test > >Test that we can use a credentials cache with a user's service ticket >obtained with our Python code to connect to a service using the normal >credentials system backed on to MIT/Heimdal Kerberos 5 libraries. This >will allow us to validate the output of the MIT/Heimdal libraries in the >future. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit c15f26ec40860782b22e862f9bdf665745387718) >--- > python/samba/tests/krb5/raw_testcase.py | 8 +- > python/samba/tests/krb5/rfc4120_constants.py | 1 + > python/samba/tests/krb5/test_ccache.py | 127 +++++++++++++++++++ > python/samba/tests/usage.py | 1 + > source4/selftest/tests.py | 2 + > 5 files changed, 135 insertions(+), 4 deletions(-) > create mode 100755 python/samba/tests/krb5/test_ccache.py > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 82e68ee7019..27ab89ecf99 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -25,7 +25,7 @@ import random > > import samba.tests > from samba.credentials import Credentials >-from samba.tests import TestCase >+from samba.tests import TestCaseInTempDir > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > import samba.tests.krb5.kcrypto as kcrypto > >@@ -178,11 +178,11 @@ class Krb5EncryptionKey(object): > return EncryptionKey_obj > > >-class RawKerberosTest(TestCase): >+class RawKerberosTest(TestCaseInTempDir): > """A raw Kerberos Test case.""" > > def setUp(self): >- super(RawKerberosTest, self).setUp() >+ super().setUp() > self.do_asn1_print = False > self.do_hexdump = False > >@@ -192,7 +192,7 @@ class RawKerberosTest(TestCase): > > def tearDown(self): > self._disconnect("tearDown") >- super(TestCase, self).tearDown() >+ super().tearDown() > > def _disconnect(self, reason): > if self.s is None: >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index 5bbf1229d09..702f6084217 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -46,6 +46,7 @@ KDC_ERR_SKEW = 37 > # Name types > NT_UNKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-UNKNOWN')) > NT_PRINCIPAL = int(krb5_asn1.NameTypeValues('kRB5-NT-PRINCIPAL')) >+NT_SRV_HST = int(krb5_asn1.NameTypeValues('kRB5-NT-SRV-HST')) > NT_SRV_INST = int(krb5_asn1.NameTypeValues('kRB5-NT-SRV-INST')) > NT_ENTERPRISE_PRINCIPAL = int(krb5_asn1.NameTypeValues( > 'kRB5-NT-ENTERPRISE-PRINCIPAL')) >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >new file mode 100755 >index 00000000000..e0998a4c43f >--- /dev/null >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -0,0 +1,127 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) 2021 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+from ldb import SCOPE_SUBTREE >+from samba import gensec >+from samba.auth import AuthContext >+from samba.dcerpc import security >+from samba.ndr import ndr_unpack >+ >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class CcacheTests(KDCBaseTest): >+ """Test for authentication using Kerberos credentials stored in a >+ credentials cache file. >+ """ >+ >+ def test_ccache(self): >+ # Create a user account and a machine account, along with a Kerberos >+ # credentials cache file where the service ticket authenticating the >+ # user are stored. >+ >+ user_name = "ccacheusr" >+ mach_name = "ccachemac" >+ >+ # Create the user account. >+ (user_credentials, _) = self.create_account(user_name) >+ >+ # Create the machine account. >+ (mach_credentials, _) = self.create_account(mach_name, >+ machine_account=True) >+ >+ # Talk to the KDC to obtain the service ticket, which gets placed into >+ # the cache. The machine account name has to match the name in the >+ # ticket, to ensure that the krbtgt ticket doesn't also need to be >+ # stored. >+ (creds, cachefile) = self.create_ccache_with_user(user_credentials, >+ mach_name) >+ >+ # Authenticate in-process to the machine account using the user's >+ # cached credentials. >+ >+ settings = {} >+ settings["lp_ctx"] = self.lp >+ settings["target_hostname"] = mach_name >+ >+ gensec_client = gensec.Security.start_client(settings) >+ gensec_client.set_credentials(creds) >+ gensec_client.want_feature(gensec.FEATURE_SEAL) >+ gensec_client.start_mech_by_sasl_name("GSSAPI") >+ >+ auth_context = AuthContext(lp_ctx=self.lp, ldb=self.ldb, methods=[]) >+ >+ gensec_server = gensec.Security.start_server(settings, auth_context) >+ gensec_server.set_credentials(mach_credentials) >+ >+ gensec_server.start_mech_by_sasl_name("GSSAPI") >+ >+ client_finished = False >+ server_finished = False >+ server_to_client = b'' >+ >+ # Operate as both the client and the server to verify the user's >+ # credentials. >+ while not client_finished or not server_finished: >+ if not client_finished: >+ print("running client gensec_update") >+ (client_finished, client_to_server) = gensec_client.update( >+ server_to_client) >+ if not server_finished: >+ print("running server gensec_update") >+ (server_finished, server_to_client) = gensec_server.update( >+ client_to_server) >+ >+ # Ensure that the first SID contained within the obtained security >+ # token is the SID of the user we created. >+ >+ # Retrieve the user account's SID. >+ ldb_res = self.ldb.search(scope=SCOPE_SUBTREE, >+ expression="(sAMAccountName=%s)" % user_name, >+ attrs=["objectSid"]) >+ self.assertEqual(1, len(ldb_res)) >+ sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) >+ >+ # Retrieve the SIDs from the security token. >+ session = gensec_server.session_info() >+ token = session.security_token >+ token_sids = token.sids >+ self.assertGreater(len(token_sids), 0) >+ >+ # Ensure that they match. >+ self.assertEqual(sid, token_sids[0]) >+ >+ # Remove the cached credentials file. >+ os.remove(cachefile.name) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 14f7cbfd7cd..f97b30d68df 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -93,6 +93,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/kdc_tests.py', > 'python/samba/tests/krb5/kdc_base_test.py', > 'python/samba/tests/krb5/kdc_tgs_tests.py', >+ 'python/samba/tests/krb5/test_ccache.py', > 'python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py', > } > >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 3310d47f167..c2fe31bdb4d 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -723,6 +723,8 @@ planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", > > planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests") > >+planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache") >+ > for env in ["ad_dc", smbv1_disabled_testenv]: > planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) > planoldpythontestsuite(env + ":local", "samba.tests.ntacls_backup", >-- >2.25.1 > > >From 1224fb0d2c4fb07b2078f6cf4a492b67666beb34 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 29 Apr 2021 20:58:11 +1200 >Subject: [PATCH 074/686] python: Add LDAP credentials cache test > >Test that we can use a credentials cache with a user's service ticket >obtained with our Python code to connect to a service through LDAP. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 7663b5c37fa3413f7c67c018107322494e4a6fd9) >--- > python/samba/tests/krb5/test_ldap.py | 94 ++++++++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > source4/selftest/tests.py | 1 + > 3 files changed, 96 insertions(+) > create mode 100755 python/samba/tests/krb5/test_ldap.py > >diff --git a/python/samba/tests/krb5/test_ldap.py b/python/samba/tests/krb5/test_ldap.py >new file mode 100755 >index 00000000000..6a4bf52d77f >--- /dev/null >+++ b/python/samba/tests/krb5/test_ldap.py >@@ -0,0 +1,94 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) 2021 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+from ldb import SCOPE_BASE, SCOPE_SUBTREE >+from samba.dcerpc import security >+from samba.ndr import ndr_unpack >+from samba.samdb import SamDB >+ >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class LdapTests(KDCBaseTest): >+ """Test for LDAP authentication using Kerberos credentials stored in a >+ credentials cache file. >+ """ >+ >+ def test_ldap(self): >+ # Create a user account and a machine account, along with a Kerberos >+ # credentials cache file where the service ticket authenticating the >+ # user are stored. >+ >+ user_name = "ldapusr" >+ mach_name = self.dns_host_name >+ service = "ldap" >+ >+ # Create the user account. >+ (user_credentials, _) = self.create_account(user_name) >+ >+ # Talk to the KDC to obtain the service ticket, which gets placed into >+ # the cache. The machine account name has to match the name in the >+ # ticket, to ensure that the krbtgt ticket doesn't also need to be >+ # stored. >+ (creds, cachefile) = self.create_ccache_with_user(user_credentials, >+ mach_name, >+ service) >+ >+ # Authenticate in-process to the machine account using the user's >+ # cached credentials. >+ >+ # Retrieve the user account's SID. >+ ldb_res = self.ldb.search(scope=SCOPE_SUBTREE, >+ expression="(sAMAccountName=%s)" % user_name, >+ attrs=["objectSid"]) >+ self.assertEqual(1, len(ldb_res)) >+ sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) >+ >+ # Connect to the machine account and retrieve the user SID. >+ ldb_as_user = SamDB(url="ldap://%s" % mach_name, >+ credentials=creds, >+ lp=self.lp) >+ ldb_res = ldb_as_user.search('', >+ scope=SCOPE_BASE, >+ attrs=["tokenGroups"]) >+ self.assertEqual(1, len(ldb_res)) >+ >+ token_sid = ndr_unpack(security.dom_sid, ldb_res[0]["tokenGroups"][0]) >+ >+ # Ensure that they match. >+ self.assertEqual(sid, token_sid) >+ >+ # Remove the cached credentials file. >+ os.remove(cachefile.name) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index f97b30d68df..919c800dee8 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -94,6 +94,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/kdc_base_test.py', > 'python/samba/tests/krb5/kdc_tgs_tests.py', > 'python/samba/tests/krb5/test_ccache.py', >+ 'python/samba/tests/krb5/test_ldap.py', > 'python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py', > } > >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index c2fe31bdb4d..883212cc65e 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -724,6 +724,7 @@ planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", > planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests") > > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache") >+planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap") > > for env in ["ad_dc", smbv1_disabled_testenv]: > planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) >-- >2.25.1 > > >From aaaa1ce71e61326a8065a842bc860226178b6dce Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 29 Apr 2021 21:04:25 +1200 >Subject: [PATCH 075/686] python: Add RPC credentials cache test > >Test that we can use a credentials cache with a user's service ticket >obtained with our Python code to connect to a service through RPC. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 072451a033da07c0cdaa005dd1020ef1c7951e99) >--- > python/samba/tests/krb5/test_rpc.py | 77 +++++++++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > source4/selftest/tests.py | 1 + > 3 files changed, 79 insertions(+) > create mode 100755 python/samba/tests/krb5/test_rpc.py > >diff --git a/python/samba/tests/krb5/test_rpc.py b/python/samba/tests/krb5/test_rpc.py >new file mode 100755 >index 00000000000..da1c4eb88ac >--- /dev/null >+++ b/python/samba/tests/krb5/test_rpc.py >@@ -0,0 +1,77 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) 2021 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+from samba.dcerpc import lsa >+ >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class RpcTests(KDCBaseTest): >+ """Test for RPC authentication using Kerberos credentials stored in a >+ credentials cache file. >+ """ >+ >+ def test_rpc(self): >+ # Create a user account and a machine account, along with a Kerberos >+ # credentials cache file where the service ticket authenticating the >+ # user are stored. >+ >+ user_name = "rpcusr" >+ mach_name = self.dns_host_name >+ service = "cifs" >+ >+ # Create the user account. >+ (user_credentials, _) = self.create_account(user_name) >+ >+ # Talk to the KDC to obtain the service ticket, which gets placed into >+ # the cache. The machine account name has to match the name in the >+ # ticket, to ensure that the krbtgt ticket doesn't also need to be >+ # stored. >+ (creds, cachefile) = self.create_ccache_with_user(user_credentials, >+ mach_name, >+ service) >+ >+ # Authenticate in-process to the machine account using the user's >+ # cached credentials. >+ >+ binding_str = "ncacn_np:%s[\\pipe\\lsarpc]" % mach_name >+ conn = lsa.lsarpc(binding_str, self.lp, creds) >+ >+ (account_name, _) = conn.GetUserName(None, None, None) >+ >+ self.assertEqual(user_name, account_name.string) >+ >+ # Remove the cached credentials file. >+ os.remove(cachefile.name) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 919c800dee8..c0f8736a4e5 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -95,6 +95,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/kdc_tgs_tests.py', > 'python/samba/tests/krb5/test_ccache.py', > 'python/samba/tests/krb5/test_ldap.py', >+ 'python/samba/tests/krb5/test_rpc.py', > 'python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py', > } > >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 883212cc65e..84a78860d1d 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -725,6 +725,7 @@ planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests") > > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap") >+planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_rpc") > > for env in ["ad_dc", smbv1_disabled_testenv]: > planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) >-- >2.25.1 > > >From 8eb32a1ef013f2325df3b607cc3a0c1fded6bf44 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 3 May 2021 15:55:01 +1200 >Subject: [PATCH 076/686] libsmb: Remove overflow check > >Pointer overflow is undefined, so this check does not accomplish >anything. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit db5b34c7682e36630908356cf674fddd18d8fa1f) >--- > source3/libsmb/clifsinfo.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c >index 09c0d9535f1..cc9f7382d49 100644 >--- a/source3/libsmb/clifsinfo.c >+++ b/source3/libsmb/clifsinfo.c >@@ -650,7 +650,7 @@ static void cli_posix_whoami_done(struct tevent_req *subreq) > * parsing network packets in C. > */ > >- if (num_rdata < 40 || rdata + num_rdata < rdata) { >+ if (num_rdata < 40) { > tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); > return; > } >-- >2.25.1 > > >From b265c38c5ba632f8e4419610950a2b63d89da8d1 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 3 May 2021 16:16:51 +1200 >Subject: [PATCH 077/686] libsmb: Avoid undefined behaviour when parsing whoami > state > >If num_gids is such that the gids array would overflow the rdata buffer, >'p + 8' could produce a result pointing outside the buffer, and thus >result in undefined behaviour. To avoid this, we check num_gids against >the size of the buffer beforehand. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 9d8aeed33d8edf7a5dc96dbe35e4e164e2baeeeb) >--- > source3/libsmb/clifsinfo.c | 12 +++++++----- > 1 file changed, 7 insertions(+), 5 deletions(-) > >diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c >index cc9f7382d49..aca559d153b 100644 >--- a/source3/libsmb/clifsinfo.c >+++ b/source3/libsmb/clifsinfo.c >@@ -661,6 +661,13 @@ static void cli_posix_whoami_done(struct tevent_req *subreq) > state->num_gids = IVAL(rdata, 24); > state->num_sids = IVAL(rdata, 28); > >+ /* Ensure the gid array doesn't overflow */ >+ if (state->num_gids > (num_rdata - 40) / sizeof(uint64_t)) { >+ tevent_req_nterror(req, >+ NT_STATUS_INVALID_NETWORK_RESPONSE); >+ return; >+ } >+ > state->gids = talloc_array(state, uint64_t, state->num_gids); > if (tevent_req_nomem(state->gids, req)) { > return; >@@ -673,11 +680,6 @@ static void cli_posix_whoami_done(struct tevent_req *subreq) > p = rdata + 40; > > for (i = 0; i < state->num_gids; i++) { >- if (p + 8 > rdata + num_rdata) { >- tevent_req_nterror(req, >- NT_STATUS_INVALID_NETWORK_RESPONSE); >- return; >- } > state->gids[i] = BVAL(p, 0); > p += 8; > } >-- >2.25.1 > > >From f127ec82dde5676543db85d09f494e8952772eb7 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 3 May 2021 16:22:43 +1200 >Subject: [PATCH 078/686] libsmb: Check to see that whoami is not receiving > more data than it requested > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 9e414233c84d2f2fa4a9415be9ee975eca8b9bfd) >--- > source3/libsmb/clifsinfo.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c >index aca559d153b..6f3c07a8a7e 100644 >--- a/source3/libsmb/clifsinfo.c >+++ b/source3/libsmb/clifsinfo.c >@@ -570,6 +570,8 @@ struct posix_whoami_state { > > static void cli_posix_whoami_done(struct tevent_req *subreq); > >+static const uint32_t posix_whoami_max_rdata = 62*1024; >+ > struct tevent_req *cli_posix_whoami_send(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, > struct cli_state *cli) >@@ -586,7 +588,7 @@ struct tevent_req *cli_posix_whoami_send(TALLOC_CTX *mem_ctx, > SSVAL(state->setup, 0, TRANSACT2_QFSINFO); > SSVAL(state->param, 0, SMB_QUERY_POSIX_WHOAMI); > >- state->max_rdata = 62*1024; >+ state->max_rdata = posix_whoami_max_rdata; > > subreq = cli_trans_send(state, /* mem ctx. */ > ev, /* event ctx. */ >@@ -650,7 +652,7 @@ static void cli_posix_whoami_done(struct tevent_req *subreq) > * parsing network packets in C. > */ > >- if (num_rdata < 40) { >+ if (num_rdata < 40 || num_rdata > posix_whoami_max_rdata) { > tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); > return; > } >-- >2.25.1 > > >From 272693762f53179a43768da545237dc0ebc788cf Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 3 May 2021 16:24:42 +1200 >Subject: [PATCH 079/686] libsmb: Ensure that whoami parses all the data > provided to it > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 9b96ebea5c6966b096cf1100a0895a9c41f2aa1d) >--- > source3/libsmb/clifsinfo.c | 7 +++++++ > 1 file changed, 7 insertions(+) > >diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c >index 6f3c07a8a7e..f09428bdbcb 100644 >--- a/source3/libsmb/clifsinfo.c >+++ b/source3/libsmb/clifsinfo.c >@@ -714,6 +714,13 @@ static void cli_posix_whoami_done(struct tevent_req *subreq) > p += sid_size; > num_rdata -= sid_size; > } >+ >+ if (num_rdata != 0) { >+ tevent_req_nterror(req, >+ NT_STATUS_INVALID_NETWORK_RESPONSE); >+ return; >+ } >+ > tevent_req_done(req); > } > >-- >2.25.1 > > >From cf319349ca0028e864bfc3485d080ed8a81ee138 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 30 Apr 2021 12:49:24 +1200 >Subject: [PATCH 080/686] pylibsmb: Add posix_whoami() > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >[abartlet@samba.org backport from commit >482559436f12a85adb3409433aac3ab06baa82b1 as the 4.13 backport >doesn't have ealier pylibsmb changes including >752a8f870de2bb087802a1287d7fb6c7624ac631 >(s3:pylibsmb: remove unused SECINFO_DEFAULT_FLAGS)] >--- > source3/libsmb/pylibsmb.c | 138 +++++++++++++++++++++++++++++++++++++- > 1 file changed, 137 insertions(+), 1 deletion(-) > >diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c >index b63101b85a0..7f5a07eac8a 100644 >--- a/source3/libsmb/pylibsmb.c >+++ b/source3/libsmb/pylibsmb.c >@@ -42,6 +42,8 @@ > SECINFO_DACL | SECINFO_PROTECTED_DACL | SECINFO_UNPROTECTED_DACL | \ > SECINFO_SACL | SECINFO_PROTECTED_SACL | SECINFO_UNPROTECTED_SACL) > >+static PyTypeObject *dom_sid_Type = NULL; >+ > static PyTypeObject *get_pytype(const char *module, const char *type) > { > PyObject *mod; >@@ -1357,6 +1359,123 @@ static PyObject *py_smb_mkdir(struct py_cli_state *self, PyObject *args) > Py_RETURN_NONE; > } > >+/* >+ * Does a whoami call >+ */ >+static PyObject *py_smb_posix_whoami(struct py_cli_state *self, >+ PyObject *Py_UNUSED(ignored)) >+{ >+ TALLOC_CTX *frame = talloc_stackframe(); >+ NTSTATUS status; >+ struct tevent_req *req = NULL; >+ uint64_t uid; >+ uint64_t gid; >+ uint32_t num_gids; >+ uint64_t *gids = NULL; >+ uint32_t num_sids; >+ struct dom_sid *sids = NULL; >+ bool guest; >+ PyObject *py_gids = NULL; >+ PyObject *py_sids = NULL; >+ PyObject *py_guest = NULL; >+ PyObject *py_ret = NULL; >+ Py_ssize_t i; >+ >+ req = cli_posix_whoami_send(frame, self->ev, self->cli); >+ if (!py_tevent_req_wait_exc(self, req)) { >+ goto fail; >+ } >+ status = cli_posix_whoami_recv(req, >+ frame, >+ &uid, >+ &gid, >+ &num_gids, >+ &gids, >+ &num_sids, >+ &sids, >+ &guest); >+ if (!NT_STATUS_IS_OK(status)) { >+ PyErr_SetNTSTATUS(status); >+ goto fail; >+ } >+ if (num_gids > PY_SSIZE_T_MAX) { >+ PyErr_SetString(PyExc_OverflowError, "posix_whoami: Too many GIDs"); >+ goto fail; >+ } >+ if (num_sids > PY_SSIZE_T_MAX) { >+ PyErr_SetString(PyExc_OverflowError, "posix_whoami: Too many SIDs"); >+ goto fail; >+ } >+ >+ py_gids = PyList_New(num_gids); >+ if (!py_gids) { >+ goto fail; >+ } >+ for (i = 0; i < num_gids; ++i) { >+ int ret; >+ PyObject *py_item = PyLong_FromUnsignedLongLong(gids[i]); >+ if (!py_item) { >+ goto fail2; >+ } >+ >+ ret = PyList_SetItem(py_gids, i, py_item); >+ if (ret) { >+ goto fail2; >+ } >+ } >+ py_sids = PyList_New(num_sids); >+ if (!py_sids) { >+ goto fail2; >+ } >+ for (i = 0; i < num_sids; ++i) { >+ int ret; >+ struct dom_sid *sid; >+ PyObject *py_item; >+ >+ sid = dom_sid_dup(frame, &sids[i]); >+ if (!sid) { >+ PyErr_NoMemory(); >+ goto fail3; >+ } >+ >+ py_item = pytalloc_steal(dom_sid_Type, sid); >+ if (!py_item) { >+ PyErr_NoMemory(); >+ goto fail3; >+ } >+ >+ ret = PyList_SetItem(py_sids, i, py_item); >+ if (ret) { >+ goto fail3; >+ } >+ } >+ >+ py_guest = guest ? Py_True : Py_False; >+ >+ py_ret = Py_BuildValue("KKNNO", >+ uid, >+ gid, >+ py_gids, >+ py_sids, >+ py_guest); >+ if (!py_ret) { >+ goto fail3; >+ } >+ >+ TALLOC_FREE(frame); >+ return py_ret; >+ >+fail3: >+ Py_CLEAR(py_sids); >+ >+fail2: >+ Py_CLEAR(py_gids); >+ >+fail: >+ TALLOC_FREE(frame); >+ return NULL; >+} >+ > /* > * Checks existence of a directory > */ >@@ -1612,6 +1731,8 @@ static PyMethodDef py_cli_state_methods[] = { > "unlink(path) -> None\n\n \t\tDelete a file." }, > { "mkdir", (PyCFunction)py_smb_mkdir, METH_VARARGS, > "mkdir(path) -> None\n\n \t\tCreate a directory." }, >+ { "posix_whoami", (PyCFunction)py_smb_posix_whoami, METH_NOARGS, >+ "posix_whoami() -> (uid, gid, gids, sids, guest)" }, > { "rmdir", (PyCFunction)py_smb_rmdir, METH_VARARGS, > "rmdir(path) -> None\n\n \t\tDelete a directory." }, > { "chkpath", (PyCFunction)py_smb_chkpath, METH_VARARGS, >@@ -1664,16 +1785,31 @@ static struct PyModuleDef moduledef = { > MODULE_INIT_FUNC(libsmb_samba_internal) > { > PyObject *m = NULL; >+ PyObject *mod = NULL; > > talloc_stackframe(); > >+ if (PyType_Ready(&py_cli_state_type) < 0) { >+ return NULL; >+ } >+ > m = PyModule_Create(&moduledef); > if (m == NULL) { > return m; > } >- if (PyType_Ready(&py_cli_state_type) < 0) { >+ >+ /* Import dom_sid type from dcerpc.security */ >+ mod = PyImport_ImportModule("samba.dcerpc.security"); >+ if (mod == NULL) { > return NULL; > } >+ >+ dom_sid_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "dom_sid"); >+ if (dom_sid_Type == NULL) { >+ Py_DECREF(mod); >+ return NULL; >+ } >+ > Py_INCREF(&py_cli_state_type); > PyModule_AddObject(m, "Conn", (PyObject *)&py_cli_state_type); > >-- >2.25.1 > > >From 986d9b56eda1da4c309c96afdf1bf3d5addfa203 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 30 Apr 2021 08:58:11 +1200 >Subject: [PATCH 081/686] python: Add SMB credentials cache test > >Test that we can use a credentials cache with a user's service ticket >obtained with our Python code to connect to a service through SMB. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 78a0b57b51642df07deed8aeb6e39e608fafda60) >--- > python/samba/tests/krb5/test_smb.py | 108 ++++++++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > source4/selftest/tests.py | 1 + > 3 files changed, 110 insertions(+) > create mode 100755 python/samba/tests/krb5/test_smb.py > >diff --git a/python/samba/tests/krb5/test_smb.py b/python/samba/tests/krb5/test_smb.py >new file mode 100755 >index 00000000000..0262a37ebb5 >--- /dev/null >+++ b/python/samba/tests/krb5/test_smb.py >@@ -0,0 +1,108 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) 2021 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+from ldb import SCOPE_SUBTREE >+from samba.dcerpc import security >+from samba.ndr import ndr_unpack >+from samba.samba3 import libsmb_samba_internal as libsmb >+from samba.samba3 import param as s3param >+ >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class SmbTests(KDCBaseTest): >+ """Test for SMB authentication using Kerberos credentials stored in a >+ credentials cache file. >+ """ >+ >+ def test_smb(self): >+ # Create a user account and a machine account, along with a Kerberos >+ # credentials cache file where the service ticket authenticating the >+ # user are stored. >+ >+ user_name = "smbusr" >+ mach_name = self.dns_host_name >+ service = "cifs" >+ share = "tmp" >+ >+ # Create the user account. >+ (user_credentials, _) = self.create_account(user_name) >+ >+ # Talk to the KDC to obtain the service ticket, which gets placed into >+ # the cache. The machine account name has to match the name in the >+ # ticket, to ensure that the krbtgt ticket doesn't also need to be >+ # stored. >+ (creds, cachefile) = self.create_ccache_with_user(user_credentials, >+ mach_name, >+ service) >+ >+ # Set the Kerberos 5 credentials cache environment variable. This is >+ # required because the codepath that gets run (gse_krb5) looks for it >+ # in here and not in the credentials object. >+ krb5_ccname = os.environ.get("KRB5CCNAME", "") >+ self.addCleanup(os.environ.__setitem__, "KRB5CCNAME", krb5_ccname) >+ os.environ["KRB5CCNAME"] = "FILE:" + cachefile.name >+ >+ # Authenticate in-process to the machine account using the user's >+ # cached credentials. >+ >+ # Retrieve the user account's SID. >+ ldb_res = self.ldb.search(scope=SCOPE_SUBTREE, >+ expression="(sAMAccountName=%s)" % user_name, >+ attrs=["objectSid"]) >+ self.assertEqual(1, len(ldb_res)) >+ sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) >+ >+ # Connect to a share and retrieve the user SID. >+ s3_lp = s3param.get_context() >+ s3_lp.load(self.lp.configfile) >+ >+ min_protocol = s3_lp.get("client min protocol") >+ self.addCleanup(s3_lp.set, "client min protocol", min_protocol) >+ s3_lp.set("client min protocol", "NT1") >+ >+ max_protocol = s3_lp.get("client max protocol") >+ self.addCleanup(s3_lp.set, "client max protocol", max_protocol) >+ s3_lp.set("client max protocol", "NT1") >+ >+ conn = libsmb.Conn(mach_name, share, lp=s3_lp, creds=creds) >+ >+ (uid, gid, gids, sids, guest) = conn.posix_whoami() >+ >+ # Ensure that they match. >+ self.assertEqual(sid, sids[0]) >+ >+ # Remove the cached credentials file. >+ os.remove(cachefile.name) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index c0f8736a4e5..ad13012c9bb 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -96,6 +96,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/test_ccache.py', > 'python/samba/tests/krb5/test_ldap.py', > 'python/samba/tests/krb5/test_rpc.py', >+ 'python/samba/tests/krb5/test_smb.py', > 'python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py', > } > >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 84a78860d1d..68a51813e4f 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -726,6 +726,7 @@ planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_rpc") >+planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb") > > for env in ["ad_dc", smbv1_disabled_testenv]: > planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) >-- >2.25.1 > > >From 64f74cbf1aeb43864f723a680f14bc5d83c29225 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 3 May 2021 14:42:10 +1200 >Subject: [PATCH 082/686] python: Ensure reference counts are properly > incremented > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 290c1dc0975867a71c02e911708323d1f38b6f96) >--- > lib/talloc/pytalloc.c | 4 ++-- > libgpo/pygpo.c | 2 +- > source4/auth/gensec/pygensec.c | 4 ++-- > source4/librpc/ndr/py_security.c | 2 +- > source4/ntvfs/posix/python/pyposix_eadb.c | 2 +- > source4/ntvfs/posix/python/pyxattr_native.c | 4 ++-- > source4/ntvfs/posix/python/pyxattr_tdb.c | 2 +- > 7 files changed, 10 insertions(+), 10 deletions(-) > >diff --git a/lib/talloc/pytalloc.c b/lib/talloc/pytalloc.c >index 95dbb297a46..e583c05ea6f 100644 >--- a/lib/talloc/pytalloc.c >+++ b/lib/talloc/pytalloc.c >@@ -43,14 +43,14 @@ static PyObject *pytalloc_report_full(PyObject *self, PyObject *args) > } else { > talloc_report_full(pytalloc_get_mem_ctx(py_obj), stdout); > } >- return Py_None; >+ Py_RETURN_NONE; > } > > /* enable null tracking */ > static PyObject *pytalloc_enable_null_tracking(PyObject *self) > { > talloc_enable_null_tracking(); >- return Py_None; >+ Py_RETURN_NONE; > } > > /* return the number of talloc blocks */ >diff --git a/libgpo/pygpo.c b/libgpo/pygpo.c >index b8dfcd5572f..4cfd5720065 100644 >--- a/libgpo/pygpo.c >+++ b/libgpo/pygpo.c >@@ -40,7 +40,7 @@ static PyObject* GPO_get_##ATTR(PyObject *self, void *closure) \ > if (gpo_ptr->ATTR) \ > return PyStr_FromString(gpo_ptr->ATTR); \ > else \ >- return Py_None; \ >+ Py_RETURN_NONE; \ > } > GPO_getter(ds_path) > GPO_getter(file_sys_path) >diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c >index ca60d3bdc5e..9ede11c9d8d 100644 >--- a/source4/auth/gensec/pygensec.c >+++ b/source4/auth/gensec/pygensec.c >@@ -414,9 +414,9 @@ static PyObject *py_gensec_have_feature(PyObject *self, PyObject *args) > return NULL; > > if (gensec_have_feature(security, feature)) { >- return Py_True; >+ Py_RETURN_TRUE; > } >- return Py_False; >+ Py_RETURN_FALSE; > } > > static PyObject *py_gensec_set_max_update_size(PyObject *self, PyObject *args) >diff --git a/source4/librpc/ndr/py_security.c b/source4/librpc/ndr/py_security.c >index 79a9fa5ac11..37c6a57e00e 100644 >--- a/source4/librpc/ndr/py_security.c >+++ b/source4/librpc/ndr/py_security.c >@@ -341,7 +341,7 @@ static PyObject *py_descriptor_richcmp( > break; > } > >- return Py_NotImplemented; >+ Py_RETURN_NOTIMPLEMENTED; > } > > static void py_descriptor_patch(PyTypeObject *type) >diff --git a/source4/ntvfs/posix/python/pyposix_eadb.c b/source4/ntvfs/posix/python/pyposix_eadb.c >index 646498225b3..18e240420a4 100644 >--- a/source4/ntvfs/posix/python/pyposix_eadb.c >+++ b/source4/ntvfs/posix/python/pyposix_eadb.c >@@ -31,7 +31,7 @@ > > static PyObject *py_is_xattr_supported(PyObject *self) > { >- return Py_True; >+ Py_RETURN_TRUE; > } > > static PyObject *py_wrap_setxattr(PyObject *self, PyObject *args) >diff --git a/source4/ntvfs/posix/python/pyxattr_native.c b/source4/ntvfs/posix/python/pyxattr_native.c >index b1fa2a208e5..6af48348a4b 100644 >--- a/source4/ntvfs/posix/python/pyxattr_native.c >+++ b/source4/ntvfs/posix/python/pyxattr_native.c >@@ -28,9 +28,9 @@ > static PyObject *py_is_xattr_supported(PyObject *self) > { > #if !defined(HAVE_XATTR_SUPPORT) >- return Py_False; >+ Py_RETURN_FALSE; > #else >- return Py_True; >+ Py_RETURN_TRUE; > #endif > } > >diff --git a/source4/ntvfs/posix/python/pyxattr_tdb.c b/source4/ntvfs/posix/python/pyxattr_tdb.c >index f9a1fa5fd80..9e4e73a4049 100644 >--- a/source4/ntvfs/posix/python/pyxattr_tdb.c >+++ b/source4/ntvfs/posix/python/pyxattr_tdb.c >@@ -35,7 +35,7 @@ > > static PyObject *py_is_xattr_supported(PyObject *self) > { >- return Py_True; >+ Py_RETURN_TRUE; > } > > static PyObject *py_wrap_setxattr(PyObject *self, PyObject *args) >-- >2.25.1 > > >From fcc2ae7822450cd5ef7cdb119ccf248c1c1b5c3c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 3 May 2021 14:43:04 +1200 >Subject: [PATCH 083/686] python: Fix erroneous increments of reference counts > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 66695f0f94775c4db24fb625fe78ff44d964b5ad) >--- > source3/passdb/py_passdb.c | 4 ---- > 1 file changed, 4 deletions(-) > >diff --git a/source3/passdb/py_passdb.c b/source3/passdb/py_passdb.c >index 40e3a4e13aa..0b5c720215c 100644 >--- a/source3/passdb/py_passdb.c >+++ b/source3/passdb/py_passdb.c >@@ -1915,8 +1915,6 @@ static PyObject *py_pdb_enum_group_mapping(PyObject *self, PyObject *args) > PyObject *py_gmap_list, *py_group_map; > int i; > >- Py_INCREF(Py_None); >- > if (!PyArg_ParseTuple(args, "|O!ii:enum_group_mapping", dom_sid_Type, &py_domain_sid, > &lsa_sidtype_value, &unix_only)) { > talloc_free(frame); >@@ -2604,8 +2602,6 @@ static PyObject *py_pdb_search_aliases(PyObject *self, PyObject *args) > PyObject *py_domain_sid = Py_None; > struct dom_sid *domain_sid = NULL; > >- Py_INCREF(Py_None); >- > if (!PyArg_ParseTuple(args, "|O!:search_aliases", dom_sid_Type, &py_domain_sid)) { > talloc_free(frame); > return NULL; >-- >2.25.1 > > >From ac295637596de9c8337d31d8a6c8831a4e774344 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 10 May 2021 16:43:03 +1200 >Subject: [PATCH 084/686] python: Fix ticket timestamp conversion when local > timezone is not UTC > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit b9006f33343ba8bb82ef8ffe1fd90c780961b41e) >--- > python/samba/tests/krb5/kdc_base_test.py | 23 +++++++++++++++++++---- > 1 file changed, 19 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index d8193ae9cdc..e345f739e1c 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -18,7 +18,7 @@ > > import sys > import os >-from datetime import datetime >+from datetime import datetime, timezone > import tempfile > > sys.path.insert(0, "bin/python") >@@ -519,11 +519,26 @@ class KDCBaseTest(RawKerberosTest): > cred.server = sprincipal > cred.keyblock = keyblock > cred.authtime = int(datetime.strptime(authtime.decode(), >- "%Y%m%d%H%M%SZ").timestamp()) >+ "%Y%m%d%H%M%SZ") >+ .replace(tzinfo=timezone.utc).timestamp()) > cred.starttime = int(datetime.strptime(starttime.decode(), >- "%Y%m%d%H%M%SZ").timestamp()) >+ "%Y%m%d%H%M%SZ") >+ .replace(tzinfo=timezone.utc).timestamp()) > cred.endtime = int(datetime.strptime(endtime.decode(), >- "%Y%m%d%H%M%SZ").timestamp()) >+ "%Y%m%d%H%M%SZ") >+ .replace(tzinfo=timezone.utc).timestamp()) >+ >+ # Account for clock skew of up to five minutes. >+ self.assertLess(cred.authtime - 5*60, >+ datetime.now(timezone.utc).timestamp(), >+ "Ticket not yet valid - clocks may be out of sync.") >+ self.assertLess(cred.starttime - 5*60, >+ datetime.now(timezone.utc).timestamp(), >+ "Ticket not yet valid - clocks may be out of sync.") >+ self.assertGreater(cred.endtime - 60*60, >+ datetime.now(timezone.utc).timestamp(), >+ "Ticket already expired/about to expire - clocks may be out of sync.") >+ > cred.renew_till = cred.endtime > cred.is_skey = 0 > cred.ticket_flags = int(enc_part['flags'], 2) >-- >2.25.1 > > >From f8c88994a2d7a8967fa9cd7ab99d1700b7668a38 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 10 May 2021 15:06:06 +1200 >Subject: [PATCH 085/686] python: Make credentials cache test run against > Windows > >Windows, unlike Samba, requires the service principal name to be set >when requesting a ticket to that service. > >Additionally, default_realm from the libdefaults section of krb5.conf >should be set so that the correct realm is used. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Wed May 19 02:22:01 UTC 2021 on sn-devel-184 > >(cherry picked from commit 7791acb074b84ec7b571a81f15b56d33e2214ce9) >--- > python/samba/tests/krb5/test_ccache.py | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >index e0998a4c43f..32c9e3cce6b 100755 >--- a/python/samba/tests/krb5/test_ccache.py >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -47,13 +47,16 @@ class CcacheTests(KDCBaseTest): > > user_name = "ccacheusr" > mach_name = "ccachemac" >+ service = "host" > > # Create the user account. > (user_credentials, _) = self.create_account(user_name) > > # Create the machine account. > (mach_credentials, _) = self.create_account(mach_name, >- machine_account=True) >+ machine_account=True, >+ spn="%s/%s" % (service, >+ mach_name)) > > # Talk to the KDC to obtain the service ticket, which gets placed into > # the cache. The machine account name has to match the name in the >-- >2.25.1 > > >From 9adbf463335c5214614212c0fc36ec7df5ac1492 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 9 Apr 2020 21:04:44 +0200 >Subject: [PATCH 086/686] auth/credentials: allow credentials.Credentials to > act as base class > >In tests it's useful to add more details. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 1f413b2b2977687884781ca2399dadf6611ab461) >--- > auth/credentials/pycredentials.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c >index a58859a70d8..b4239730818 100644 >--- a/auth/credentials/pycredentials.c >+++ b/auth/credentials/pycredentials.c >@@ -849,7 +849,7 @@ static struct PyModuleDef moduledef = { > PyTypeObject PyCredentials = { > .tp_name = "credentials.Credentials", > .tp_new = py_creds_new, >- .tp_flags = Py_TPFLAGS_DEFAULT, >+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, > .tp_methods = py_creds_methods, > }; > >-- >2.25.1 > > >From 4e0d4a12856ffaa967c7f73d81bff0ae2aad7f63 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Apr 2020 16:50:55 +0200 >Subject: [PATCH 087/686] Rename > python/samba/tests/krb5/{rfc4120_pyasn1_regen.sh => pyasn1_regen.sh} > >This is a clearer name for the script > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit fef08add9ec324fb0c3902e96c2a91c07646d499) >--- > .../samba/tests/krb5/{rfc4120_pyasn1_regen.sh => pyasn1_regen.sh} | 0 > 1 file changed, 0 insertions(+), 0 deletions(-) > rename python/samba/tests/krb5/{rfc4120_pyasn1_regen.sh => pyasn1_regen.sh} (100%) > >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1_regen.sh b/python/samba/tests/krb5/pyasn1_regen.sh >similarity index 100% >rename from python/samba/tests/krb5/rfc4120_pyasn1_regen.sh >rename to python/samba/tests/krb5/pyasn1_regen.sh >-- >2.25.1 > > >From f7dbab94dccd187231e5597146e82969fdd46fbc Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 9 Apr 2020 11:10:11 +0200 >Subject: [PATCH 088/686] tests/krb5/rfc4120.asn1: Improve definitions to allow > expanded testing > >Update and re-generate the ASN.1 to allow an improved testsuite. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d4492a8aaaf70cbe81af7e6703b4ea9fc1f24162) >--- > python/samba/tests/krb5/rfc4120.asn1 | 70 ++++++++++- > python/samba/tests/krb5/rfc4120_pyasn1.py | 134 +++++++++++++++++++++- > 2 files changed, 199 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 >index 654f9788ca7..d81d06ad6f7 100644 >--- a/python/samba/tests/krb5/rfc4120.asn1 >+++ b/python/samba/tests/krb5/rfc4120.asn1 >@@ -386,14 +386,14 @@ PA-ENC-TS-ENC ::= SEQUENCE { > } > > ETYPE-INFO-ENTRY ::= SEQUENCE { >- etype [0] Int32, >+ etype [0] EncryptionType, --Int32 EncryptionType -- > salt [1] OCTET STRING OPTIONAL > } > > ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY > > ETYPE-INFO2-ENTRY ::= SEQUENCE { >- etype [0] Int32, >+ etype [0] EncryptionType, --Int32 EncryptionType -- > salt [1] KerberosString OPTIONAL, > s2kparams [2] OCTET STRING OPTIONAL > } >@@ -425,9 +425,48 @@ PA-S4U2Self ::= SEQUENCE { > auth [3] KerberosString > } > >+-- >+-- >+-- MS-KILE Start >+ >+KERB-ERROR-DATA ::= SEQUENCE { >+ data-type [1] KerbErrorDataType, >+ data-value [2] OCTET STRING OPTIONAL >+} >+ >+KerbErrorDataType ::= INTEGER >+ >+KERB-PA-PAC-REQUEST ::= SEQUENCE { >+ include-pac[0] BOOLEAN --If TRUE, and no pac present, include PAC. >+ --If FALSE, and PAC present, remove PAC >+} >+ >+KERB-LOCAL ::= OCTET STRING -- Implementation-specific data which MUST be >+ -- ignored if Kerberos client is not local. >+ >+KERB-AD-RESTRICTION-ENTRY ::= SEQUENCE { >+ restriction-type [0] Int32, >+ restriction [1] OCTET STRING -- LSAP_TOKEN_INFO_INTEGRITY structure >+} >+ >+PA-SUPPORTED-ENCTYPES ::= Int32 -- Supported Encryption Types Bit Field -- > >+PACOptionFlags ::= KerberosFlags -- Claims (0) >+ -- Branch Aware (1) >+ -- Forward to Full DC (2) >+ -- Resource Based Constrained Delegation (3) >+PA-PAC-OPTIONS ::= SEQUENCE { >+ options [0] PACOptionFlags >+} >+-- Note: KerberosFlags ::= BIT STRING (SIZE (32..MAX)) >+-- minimum number of bits shall be sent, but no fewer than 32 > >+KERB-KEY-LIST-REQ ::= SEQUENCE OF EncryptionType -- Int32 encryption type -- >+KERB-KEY-LIST-REP ::= SEQUENCE OF EncryptionKey > >+-- MS-KILE End >+-- >+-- > > -- > -- >@@ -504,6 +543,15 @@ KDCOptionsSequence ::= SEQUENCE { > dummy [0] KDCOptionsValues > } > >+APOptionsValues ::= BIT STRING { -- KerberosFlags >+ reserved(0), >+ use-session-key(1), >+ mutual-required(2) >+} >+APOptionsSequence ::= SEQUENCE { >+ dummy [0] APOptionsValues >+} >+ > MessageTypeValues ::= INTEGER { > krb-as-req(10), -- Request for initial authentication > krb-as-rep(11), -- Response to KRB_AS_REQ request >@@ -669,4 +717,22 @@ EncryptionTypeSequence ::= SEQUENCE { > dummy [0] EncryptionTypeValues > } > >+KerbErrorDataTypeValues ::= INTEGER { >+ kERB-AP-ERR-TYPE-SKEW-RECOVERY(2), >+ kERB-ERR-TYPE-EXTENDED(3) >+} >+KerbErrorDataTypeSequence ::= SEQUENCE { >+ dummy [0] KerbErrorDataTypeValues >+} >+ >+PACOptionFlagsValues ::= BIT STRING { -- KerberosFlags >+ claims(0), >+ branch-aware(1), >+ forward-to-full-dc(2), >+ resource-based-constrained-delegation(3) >+} >+PACOptionFlagsSequence ::= SEQUENCE { >+ dummy [0] PACOptionFlagsValues >+} >+ > END >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1.py b/python/samba/tests/krb5/rfc4120_pyasn1.py >index 1d89f94adf1..56fe02a68f0 100644 >--- a/python/samba/tests/krb5/rfc4120_pyasn1.py >+++ b/python/samba/tests/krb5/rfc4120_pyasn1.py >@@ -1,5 +1,5 @@ > # Auto-generated by asn1ate v.0.6.1.dev0 from rfc4120.asn1 >-# (last modified on 2020-11-06 11:30:42.476808) >+# (last modified on 2021-06-16 08:54:13.969508) > > # KerberosV5Spec2 > from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful >@@ -175,6 +175,26 @@ AP_REQ.componentType = namedtype.NamedTypes( > ) > > >+class APOptionsValues(univ.BitString): >+ pass >+ >+ >+APOptionsValues.namedValues = namedval.NamedValues( >+ ('reserved', 0), >+ ('use-session-key', 1), >+ ('mutual-required', 2) >+) >+ >+ >+class APOptionsSequence(univ.Sequence): >+ pass >+ >+ >+APOptionsSequence.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('dummy', APOptionsValues().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ > class PADataType(Int32): > pass > >@@ -384,7 +404,7 @@ class ETYPE_INFO_ENTRY(univ.Sequence): > > > ETYPE_INFO_ENTRY.componentType = namedtype.NamedTypes( >- namedtype.NamedType('etype', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('etype', EncryptionType().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), > namedtype.OptionalNamedType('salt', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) > ) > >@@ -401,7 +421,7 @@ class ETYPE_INFO2_ENTRY(univ.Sequence): > > > ETYPE_INFO2_ENTRY.componentType = namedtype.NamedTypes( >- namedtype.NamedType('etype', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('etype', EncryptionType().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), > namedtype.OptionalNamedType('salt', KerberosString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), > namedtype.OptionalNamedType('s2kparams', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) > ) >@@ -636,6 +656,57 @@ KDCOptionsSequence.componentType = namedtype.NamedTypes( > ) > > >+class KERB_AD_RESTRICTION_ENTRY(univ.Sequence): >+ pass >+ >+ >+KERB_AD_RESTRICTION_ENTRY.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('restriction-type', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('restriction', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+) >+ >+ >+class KerbErrorDataType(univ.Integer): >+ pass >+ >+ >+class KERB_ERROR_DATA(univ.Sequence): >+ pass >+ >+ >+KERB_ERROR_DATA.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('data-type', KerbErrorDataType().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('data-value', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) >+) >+ >+ >+class KERB_KEY_LIST_REP(univ.SequenceOf): >+ pass >+ >+ >+KERB_KEY_LIST_REP.componentType = EncryptionKey() >+ >+ >+class KERB_KEY_LIST_REQ(univ.SequenceOf): >+ pass >+ >+ >+KERB_KEY_LIST_REQ.componentType = EncryptionType() >+ >+ >+class KERB_LOCAL(univ.OctetString): >+ pass >+ >+ >+class KERB_PA_PAC_REQUEST(univ.Sequence): >+ pass >+ >+ >+KERB_PA_PAC_REQUEST.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('include-pac', univ.Boolean().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ > class KRB_CRED(univ.Sequence): > pass > >@@ -710,6 +781,25 @@ KRB_SAFE.componentType = namedtype.NamedTypes( > ) > > >+class KerbErrorDataTypeValues(univ.Integer): >+ pass >+ >+ >+KerbErrorDataTypeValues.namedValues = namedval.NamedValues( >+ ('kERB-AP-ERR-TYPE-SKEW-RECOVERY', 2), >+ ('kERB-ERR-TYPE-EXTENDED', 3) >+) >+ >+ >+class KerbErrorDataTypeSequence(univ.Sequence): >+ pass >+ >+ >+KerbErrorDataTypeSequence.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('dummy', KerbErrorDataTypeValues().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ > class MessageTypeValues(univ.Integer): > pass > >@@ -781,6 +871,19 @@ PA_ENC_TS_ENC.componentType = namedtype.NamedTypes( > ) > > >+class PACOptionFlags(KerberosFlags): >+ pass >+ >+ >+class PA_PAC_OPTIONS(univ.Sequence): >+ pass >+ >+ >+PA_PAC_OPTIONS.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('options', PACOptionFlags().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ > class PA_S4U2Self(univ.Sequence): > pass > >@@ -793,6 +896,31 @@ PA_S4U2Self.componentType = namedtype.NamedTypes( > ) > > >+class PA_SUPPORTED_ENCTYPES(Int32): >+ pass >+ >+ >+class PACOptionFlagsValues(univ.BitString): >+ pass >+ >+ >+PACOptionFlagsValues.namedValues = namedval.NamedValues( >+ ('claims', 0), >+ ('branch-aware', 1), >+ ('forward-to-full-dc', 2), >+ ('resource-based-constrained-delegation', 3) >+) >+ >+ >+class PACOptionFlagsSequence(univ.Sequence): >+ pass >+ >+ >+PACOptionFlagsSequence.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('dummy', PACOptionFlagsValues().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) >+) >+ >+ > class PADataTypeValues(univ.Integer): > pass > >-- >2.25.1 > > >From c8853c3e86263c255f829f450065e139df543a20 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 9 Apr 2020 10:55:28 +0200 >Subject: [PATCH 089/686] tests/krb5/raw_testcase.py: Add > get_{client,server,krbtgt}_creds() > >These helpful functions allow us to build the various credentials >that we will use in validating the KDC responses in this test. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit c3222870b92db7f867557c2896b7bf39915d469a) >--- > python/samba/tests/krb5/raw_testcase.py | 199 +++++++++++++++++++++--- > python/samba/tests/krb5/simple_tests.py | 6 +- > 2 files changed, 183 insertions(+), 22 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 27ab89ecf99..b28939f0388 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -22,10 +22,12 @@ import struct > import time > import datetime > import random >+import binascii > > import samba.tests > from samba.credentials import Credentials > from samba.tests import TestCaseInTempDir >+from samba.dcerpc import security > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > import samba.tests.krb5.kcrypto as kcrypto > >@@ -177,6 +179,81 @@ class Krb5EncryptionKey(object): > } > return EncryptionKey_obj > >+class KerberosCredentials(Credentials): >+ def __init__(self): >+ super(KerberosCredentials, self).__init__() >+ all_enc_types = 0 >+ all_enc_types |= security.KERB_ENCTYPE_RC4_HMAC_MD5 >+ all_enc_types |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 >+ all_enc_types |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 >+ >+ self.as_supported_enctypes = all_enc_types >+ self.tgs_supported_enctypes = all_enc_types >+ self.ap_supported_enctypes = all_enc_types >+ >+ self.kvno = None >+ self.forced_keys = {} >+ >+ self.forced_salt = None >+ return >+ >+ def set_as_supported_enctypes(self, value): >+ self.as_supported_enctypes = int(value) >+ return >+ >+ def set_tgs_supported_enctypes(self, value): >+ self.tgs_supported_enctypes = int(value) >+ return >+ >+ def set_ap_supported_enctypes(self, value): >+ self.ap_supported_enctypes = int(value) >+ return >+ >+ def _get_krb5_etypes(self, supported_enctypes): >+ etypes = () >+ >+ if supported_enctypes & security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96: >+ etypes += (kcrypto.Enctype.AES256,) >+ if supported_enctypes & security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96: >+ etypes += (kcrypto.Enctype.AES128,) >+ if supported_enctypes & security.KERB_ENCTYPE_RC4_HMAC_MD5: >+ etypes += (kcrypto.Enctype.RC4,) >+ >+ return etypes >+ >+ def get_as_krb5_etypes(self): >+ return self._get_krb5_etypes(self.as_supported_enctypes) >+ >+ def get_tgs_krb5_etypes(self): >+ return self._get_krb5_etypes(self.tgs_supported_enctypes) >+ >+ def get_ap_krb5_etypes(self): >+ return self._get_krb5_etypes(self.ap_supported_enctypes) >+ >+ def set_kvno(self, kvno): >+ self.kvno = kvno >+ >+ def get_kvno(self): >+ return self.kvno >+ >+ def set_forced_key(self, etype, hexkey): >+ etype = int(etype) >+ contents = binascii.a2b_hex(hexkey) >+ key = kcrypto.Key(etype, contents) >+ self.forced_keys[etype] = Krb5EncryptionKey(key, self.kvno) >+ >+ def get_forced_key(self, etype): >+ etype = int(etype) >+ if etype in self.forced_keys: >+ return self.forced_keys[etype] >+ return None >+ >+ def set_forced_salt(self, salt): >+ self.forced_salt = bytes(salt) >+ return >+ >+ def get_forced_salt(self): >+ return self.forced_salt > > class RawKerberosTest(TestCaseInTempDir): > """A raw Kerberos Test case.""" >@@ -229,33 +306,113 @@ class RawKerberosTest(TestCaseInTempDir): > sys.stderr.write("connected[%s]\n" % self.host) > return > >- def get_user_creds(self): >- c = Credentials() >+ def _get_krb5_creds(self, prefix, >+ default_username=None, >+ allow_missing_password=False, >+ require_strongest_key=False): >+ c = KerberosCredentials() > c.guess() >- domain = samba.tests.env_get_var_value('DOMAIN') >- realm = samba.tests.env_get_var_value('REALM') >- username = samba.tests.env_get_var_value('USERNAME') >- password = samba.tests.env_get_var_value('PASSWORD') >- c.set_domain(domain) >- c.set_realm(realm) >- c.set_username(username) >- c.set_password(password) >- return c > >- def get_service_creds(self, allow_missing_password=False): >- c = Credentials() >- c.guess() >- domain = samba.tests.env_get_var_value('DOMAIN') >- realm = samba.tests.env_get_var_value('REALM') >- username = samba.tests.env_get_var_value('SERVICE_USERNAME') >- password = samba.tests.env_get_var_value( >- 'SERVICE_PASSWORD', >- allow_missing=allow_missing_password) >+ def env_get_var(varname, prefix, fallback_default=True, allow_missing=False): >+ val = None >+ if prefix is not None: >+ allow_missing_prefix = allow_missing >+ if fallback_default: >+ allow_missing_prefix = True >+ val = samba.tests.env_get_var_value('%s_%s' % (prefix, varname), >+ allow_missing=allow_missing_prefix) >+ else: >+ fallback_default = True >+ if val is None and fallback_default: >+ val = samba.tests.env_get_var_value(varname, >+ allow_missing=allow_missing) >+ return val >+ >+ domain = env_get_var('DOMAIN', prefix) >+ realm = env_get_var('REALM', prefix) >+ allow_missing_username = False >+ if default_username is not None: >+ allow_missing_username = True >+ username = env_get_var('USERNAME', prefix, >+ fallback_default=False, >+ allow_missing=allow_missing_username) >+ if username is None: >+ username = default_username >+ password = env_get_var('PASSWORD', prefix, >+ fallback_default=False, >+ allow_missing=allow_missing_password) > c.set_domain(domain) > c.set_realm(realm) > c.set_username(username) > if password is not None: > c.set_password(password) >+ as_supported_enctypes = env_get_var('AS_SUPPORTED_ENCTYPES', >+ prefix, allow_missing=True) >+ if as_supported_enctypes is not None: >+ c.set_as_supported_enctypes(as_supported_enctypes) >+ tgs_supported_enctypes = env_get_var('TGS_SUPPORTED_ENCTYPES', >+ prefix, allow_missing=True) >+ if tgs_supported_enctypes is not None: >+ c.set_tgs_supported_enctypes(tgs_supported_enctypes) >+ ap_supported_enctypes = env_get_var('AP_SUPPORTED_ENCTYPES', >+ prefix, allow_missing=True) >+ if ap_supported_enctypes is not None: >+ c.set_ap_supported_enctypes(ap_supported_enctypes) >+ >+ if require_strongest_key: >+ kvno_allow_missing = False >+ if password is None: >+ aes256_allow_missing = False >+ else: >+ aes256_allow_missing = True >+ else: >+ kvno_allow_missing = True >+ aes256_allow_missing = True >+ kvno = env_get_var('KVNO', prefix, >+ fallback_default=False, >+ allow_missing=kvno_allow_missing) >+ if kvno is not None: >+ c.set_kvno(kvno) >+ aes256_key = env_get_var('AES256_KEY_HEX', prefix, >+ fallback_default=False, >+ allow_missing=aes256_allow_missing) >+ if aes256_key is not None: >+ c.set_forced_key(kcrypto.Enctype.AES256, aes256_key) >+ aes128_key = env_get_var('AES128_KEY_HEX', prefix, >+ fallback_default=False, allow_missing=True) >+ if aes128_key is not None: >+ c.set_forced_key(kcrypto.Enctype.AES128, aes128_key) >+ rc4_key = env_get_var('RC4_KEY_HEX', prefix, >+ fallback_default=False, allow_missing=True) >+ if rc4_key is not None: >+ c.set_forced_key(kcrypto.Enctype.RC4, rc4_key) >+ return c >+ >+ def get_user_creds(self, allow_missing_password=False): >+ c = self._get_krb5_creds(prefix=None, >+ allow_missing_password=allow_missing_password) >+ return c >+ >+ def get_service_creds(self, allow_missing_password=False): >+ c = self._get_krb5_creds(prefix='SERVICE', >+ allow_missing_password=allow_missing_password) >+ return c >+ >+ def get_client_creds(self, allow_missing_password=False): >+ c = self._get_krb5_creds(prefix='CLIENT', >+ allow_missing_password=allow_missing_password) >+ return c >+ >+ def get_server_creds(self, allow_missing_password=False): >+ c = self._get_krb5_creds(prefix='SERVER', >+ allow_missing_password=allow_missing_password) >+ return c >+ >+ def get_krbtgt_creds(self, require_strongest_key=False): >+ c = self._get_krb5_creds(prefix='KRBTGT', >+ default_username='krbtgt', >+ allow_missing_password=True, >+ require_strongest_key=require_strongest_key) > return c > > def get_anon_creds(self): >@@ -473,6 +630,8 @@ class RawKerberosTest(TestCaseInTempDir): > return Krb5EncryptionKey(key, kvno) > > def PasswordKey_create(self, etype=None, pwd=None, salt=None, kvno=None): >+ self.assertIsNotNone(pwd) >+ self.assertIsNotNone(salt) > key = kcrypto.string_to_key(etype, pwd, salt) > return Krb5EncryptionKey(key, kvno) > >diff --git a/python/samba/tests/krb5/simple_tests.py b/python/samba/tests/krb5/simple_tests.py >index 889b91a9bf0..2da76a3cf5e 100755 >--- a/python/samba/tests/krb5/simple_tests.py >+++ b/python/samba/tests/krb5/simple_tests.py >@@ -44,10 +44,12 @@ class SimpleKerberosTests(RawKerberosTest): > def test_simple(self): > user_creds = self.get_user_creds() > user = user_creds.get_username() >- realm = user_creds.get_realm() >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_account = krbtgt_creds.get_username() >+ realm = krbtgt_creds.get_realm() > > cname = self.PrincipalName_create(name_type=1, names=[user]) >- sname = self.PrincipalName_create(name_type=2, names=["krbtgt", realm]) >+ sname = self.PrincipalName_create(name_type=2, names=[krbtgt_account, realm]) > > till = self.get_KerberosTime(offset=36000) > >-- >2.25.1 > > >From 483fd0bfa4002eb436b36601805aed4de0652cc3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 9 Apr 2020 22:28:32 +0200 >Subject: [PATCH 090/686] tests/krb5/raw_testcase.py: introduce > STRICT_CHECKING=0 in order to relax the checks in future > >We should write tests as strict as possible in order to let them run >against Windows servers. > >But at the same time we want to allow tests to be useful for Samba >too... > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit dff611976d6a067614e37add99edae214815a68b) >--- > python/samba/tests/krb5/raw_testcase.py | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b28939f0388..333aab70c8e 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -263,6 +263,11 @@ class RawKerberosTest(TestCaseInTempDir): > self.do_asn1_print = False > self.do_hexdump = False > >+ strict_checking = samba.tests.env_get_var_value('STRICT_CHECKING', allow_missing=True) >+ if strict_checking is None: >+ strict_checking = '1' >+ self.strict_checking = bool(int(strict_checking)) >+ > self.host = samba.tests.env_get_var_value('SERVER') > > self.s = None >-- >2.25.1 > > >From 3267fe9a5d64ef8cb2a94c51ee1de88a860f66a7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Apr 2020 13:49:52 +0200 >Subject: [PATCH 091/686] tests/krb5/raw_testcase.py: add assertElement*() > >These helper functions make writing subsequent Kerberos test >clearer. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 61e1b179812e48797146584998afc5bd0168beae) >--- > python/samba/tests/krb5/raw_testcase.py | 54 +++++++++++++++++++++++++ > 1 file changed, 54 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 333aab70c8e..eb294a75a95 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -605,6 +605,36 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(value) > return > >+ def getElementValue(self, obj, elem): >+ v = None >+ try: >+ v = obj[elem] >+ except KeyError: >+ pass >+ return v >+ >+ def assertElementMissing(self, obj, elem): >+ v = self.getElementValue(obj, elem) >+ self.assertIsNone(v) >+ return >+ >+ def assertElementPresent(self, obj, elem): >+ v = self.getElementValue(obj, elem) >+ self.assertIsNotNone(v) >+ return >+ >+ def assertElementEqual(self, obj, elem, value): >+ v = self.getElementValue(obj, elem) >+ self.assertIsNotNone(v) >+ self.assertEqual(v, value) >+ return >+ >+ def assertElementEqualUTF8(self, obj, elem, value): >+ v = self.getElementValue(obj, elem) >+ self.assertIsNotNone(v) >+ self.assertEqual(v, bytes(value, 'utf8')) >+ return >+ > def assertPrincipalEqual(self, princ1, princ2): > self.assertEqual(princ1['name-type'], princ2['name-type']) > self.assertEqual( >@@ -618,6 +648,30 @@ class RawKerberosTest(TestCaseInTempDir): > msg="princ1=%s != princ2=%s" % (princ1, princ2)) > return > >+ def assertElementEqualPrincipal(self, obj, elem, value): >+ v = self.getElementValue(obj, elem) >+ self.assertIsNotNone(v) >+ v = pyasn1_native_decode(v, asn1Spec=krb5_asn1.PrincipalName()) >+ self.assertPrincipalEqual(v, value) >+ return >+ >+ def assertElementKVNO(self, obj, elem, value): >+ v = self.getElementValue(obj, elem) >+ if value == "autodetect": >+ value = v >+ if value is not None: >+ self.assertIsNotNone(v) >+ # The value on the wire should never be 0 >+ self.assertNotEqual(v, 0) >+ # value == 0 means we don't know the kvno >+ # but enforce at any value != 0 is present >+ value = int(value) >+ if value != 0: >+ self.assertEqual(v, value) >+ else: >+ self.assertIsNone(v) >+ return >+ > def get_KerberosTimeWithUsec(self, epoch=None, offset=None): > if epoch is None: > epoch = time.time() >-- >2.25.1 > > >From 09fcc3d2cf6b6e28b0bf5de0fb374f85b3fb1fe1 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Apr 2020 17:50:00 +0200 >Subject: [PATCH 092/686] tests/krb5/raw_testcase.py: Allow prettyPrint of more > RFC-defined values > >By setting krb5_asn1.APOptions.prettyPrint = BitString_NamedValues_prettyPrint >we allow the BitString_NamedValues_prettyPrint() routine to show more named values. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 34e079ce9a232a765fb3a2b25441434df35df54c) >--- > python/samba/tests/krb5/raw_testcase.py | 6 ++++++ > 1 file changed, 6 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index eb294a75a95..29745fa4089 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -111,6 +111,12 @@ krb5_asn1.KDCOptions.namedValues =\ > krb5_asn1.KDCOptionsValues.namedValues > krb5_asn1.KDCOptions.prettyPrint =\ > BitString_NamedValues_prettyPrint >+krb5_asn1.APOptions.prettyPrintNamedValues =\ >+ krb5_asn1.APOptionsValues.namedValues >+krb5_asn1.APOptions.namedValues =\ >+ krb5_asn1.APOptionsValues.namedValues >+krb5_asn1.APOptions.prettyPrint =\ >+ BitString_NamedValues_prettyPrint > > > def Integer_NamedValues_prettyPrint(self, scope=0): >-- >2.25.1 > > >From 63aa730c5132275aab132531d8058ecc8a530e84 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Apr 2020 17:57:37 +0200 >Subject: [PATCH 093/686] tests/krb5/raw_testcase.py: Allow prettyPrint of more > MS-KILE-defined values > >By setting krb5_asn1.APOptions.prettyPrint = BitString_NamedValues_prettyPrint >we allow the BitString_NamedValues_prettyPrint() routine to show more named values. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 3abb3b41368666535a216a98c3e7d15a5d498f7e) >--- > python/samba/tests/krb5/raw_testcase.py | 10 ++++++++++ > 1 file changed, 10 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 29745fa4089..1ef15db9f8c 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -117,6 +117,12 @@ krb5_asn1.APOptions.namedValues =\ > krb5_asn1.APOptionsValues.namedValues > krb5_asn1.APOptions.prettyPrint =\ > BitString_NamedValues_prettyPrint >+krb5_asn1.PACOptionFlags.prettyPrintNamedValues =\ >+ krb5_asn1.PACOptionFlagsValues.namedValues >+krb5_asn1.PACOptionFlags.namedValues =\ >+ krb5_asn1.PACOptionFlagsValues.namedValues >+krb5_asn1.PACOptionFlags.prettyPrint =\ >+ BitString_NamedValues_prettyPrint > > > def Integer_NamedValues_prettyPrint(self, scope=0): >@@ -149,6 +155,10 @@ krb5_asn1.ChecksumType.prettyPrintNamedValues =\ > krb5_asn1.ChecksumTypeValues.namedValues > krb5_asn1.ChecksumType.prettyPrint =\ > Integer_NamedValues_prettyPrint >+krb5_asn1.KerbErrorDataType.prettyPrintNamedValues =\ >+ krb5_asn1.KerbErrorDataTypeValues.namedValues >+krb5_asn1.KerbErrorDataType.prettyPrint =\ >+ Integer_NamedValues_prettyPrint > > > class Krb5EncryptionKey(object): >-- >2.25.1 > > >From e0d65be896b4f2b42a52da67ee3e60a7541c5f16 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 21 Apr 2020 14:45:01 +0200 >Subject: [PATCH 094/686] tests/krb5/raw_testcase.py: split > KDC_REQ_BODY_create() from KDC_REQ_create() > >This allows us to reuse body in future and calculate checksums on it. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit b03fcfeb6c005936818ce50d511e9f9cc75aa9fb) >--- > python/samba/tests/krb5/raw_testcase.py | 81 +++++++------------------ > 1 file changed, 23 insertions(+), 58 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 1ef15db9f8c..71a4753717f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -872,19 +872,7 @@ class RawKerberosTest(TestCaseInTempDir): > def KDC_REQ_create(self, > msg_type, > padata, >- kdc_options, >- cname, >- realm, >- sname, >- from_time, >- till_time, >- renew_time, >- nonce, >- etypes, >- addresses, >- EncAuthorizationData, >- EncAuthorizationData_key, >- additional_tickets, >+ req_body, > asn1Spec=None, > asn1_print=None, > hexdump=None): >@@ -897,25 +885,10 @@ class RawKerberosTest(TestCaseInTempDir): > # req-body [4] KDC-REQ-BODY > # } > # >- KDC_REQ_BODY_obj = self.KDC_REQ_BODY_create(kdc_options, >- cname, >- realm, >- sname, >- from_time, >- till_time, >- renew_time, >- nonce, >- etypes, >- addresses, >- EncAuthorizationData, >- EncAuthorizationData_key, >- additional_tickets, >- asn1_print=asn1_print, >- hexdump=hexdump) > KDC_REQ_obj = { > 'pvno': 5, > 'msg-type': msg_type, >- 'req-body': KDC_REQ_BODY_obj, >+ 'req-body': req_body, > } > if padata is not None: > KDC_REQ_obj['padata'] = padata >@@ -974,22 +947,26 @@ class RawKerberosTest(TestCaseInTempDir): > # additional-tickets [11] SEQUENCE OF Ticket OPTIONAL > # -- NOTE: not empty > # } >+ KDC_REQ_BODY_obj = self.KDC_REQ_BODY_create( >+ kdc_options, >+ cname, >+ realm, >+ sname, >+ from_time, >+ till_time, >+ renew_time, >+ nonce, >+ etypes, >+ addresses, >+ EncAuthorizationData, >+ EncAuthorizationData_key, >+ additional_tickets, >+ asn1_print=asn1_print, >+ hexdump=hexdump) > obj, decoded = self.KDC_REQ_create( > msg_type=10, > padata=padata, >- kdc_options=kdc_options, >- cname=cname, >- realm=realm, >- sname=sname, >- from_time=from_time, >- till_time=till_time, >- renew_time=renew_time, >- nonce=nonce, >- etypes=etypes, >- addresses=addresses, >- EncAuthorizationData=EncAuthorizationData, >- EncAuthorizationData_key=EncAuthorizationData_key, >- additional_tickets=additional_tickets, >+ req_body=KDC_REQ_BODY_obj, > asn1Spec=krb5_asn1.AS_REQ(), > asn1_print=asn1_print, > hexdump=hexdump) >@@ -1115,11 +1092,11 @@ class RawKerberosTest(TestCaseInTempDir): > EncAuthorizationData=EncAuthorizationData, > EncAuthorizationData_key=EncAuthorizationData_key, > additional_tickets=additional_tickets) >- req_body = self.der_encode(req_body, asn1Spec=krb5_asn1.KDC_REQ_BODY(), >- asn1_print=asn1_print, hexdump=hexdump) >+ req_body_blob = self.der_encode(req_body, asn1Spec=krb5_asn1.KDC_REQ_BODY(), >+ asn1_print=asn1_print, hexdump=hexdump) > > req_body_checksum = self.Checksum_create( >- ticket_session_key, 6, req_body, ctype=body_checksum_type) >+ ticket_session_key, 6, req_body_blob, ctype=body_checksum_type) > > subkey_obj = None > if authenticator_subkey is not None: >@@ -1158,19 +1135,7 @@ class RawKerberosTest(TestCaseInTempDir): > obj, decoded = self.KDC_REQ_create( > msg_type=12, > padata=padata, >- kdc_options=kdc_options, >- cname=None, >- realm=realm, >- sname=sname, >- from_time=from_time, >- till_time=till_time, >- renew_time=renew_time, >- nonce=nonce, >- etypes=etypes, >- addresses=addresses, >- EncAuthorizationData=EncAuthorizationData, >- EncAuthorizationData_key=EncAuthorizationData_key, >- additional_tickets=additional_tickets, >+ req_body=req_body, > asn1Spec=krb5_asn1.TGS_REQ(), > asn1_print=asn1_print, > hexdump=hexdump) >-- >2.25.1 > > >From d1200e1f4784513724cdc72e02778d47b577ed9f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 16 Apr 2020 10:43:54 +0200 >Subject: [PATCH 095/686] tests/krb5/raw_testcase.py: add > KERB_PA_PAC_REQUEST_create() > >This allows building the pre-authentication data that encodes >the request for the KDC (or more likely a request not to include) >the KRB5 PAC in the resulting ticket. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit ee2ac2b8ccafe3e6d560d893a4135a28e393914d) >--- > python/samba/tests/krb5/raw_testcase.py | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 71a4753717f..f341911ef53 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -799,6 +799,21 @@ class RawKerberosTest(TestCaseInTempDir): > } > return PA_ENC_TS_ENC_obj > >+ def KERB_PA_PAC_REQUEST_create(self, include_pac, pa_data_create=True): >+ #KERB-PA-PAC-REQUEST ::= SEQUENCE { >+ # include-pac[0] BOOLEAN --If TRUE, and no pac present, include PAC. >+ # --If FALSE, and PAC present, remove PAC >+ #} >+ KERB_PA_PAC_REQUEST_obj = { >+ 'include-pac': include_pac, >+ } >+ if not pa_data_create: >+ return KERB_PA_PAC_REQUEST_obj >+ pa_pac = self.der_encode(KERB_PA_PAC_REQUEST_obj, >+ asn1Spec=krb5_asn1.KERB_PA_PAC_REQUEST()) >+ pa_data = self.PA_DATA_create(128, pa_pac) # PA-PAC-REQUEST >+ return pa_data >+ > def KDC_REQ_BODY_create(self, > kdc_options, > cname, >-- >2.25.1 > > >From 18b9bd1717c2ee9fcdf939317cf018ff72586cd5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 20 Apr 2020 20:02:52 +0200 >Subject: [PATCH 096/686] tests/krb5/raw_testcase.py: add methods to iterate > over etype permutations > >It's often useful to run tests over a lot of input parameter >permutations. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit e3905035847a5268c1a65366830cc739280ae437) >--- > python/samba/tests/krb5/raw_testcase.py | 58 +++++++++++++++++++++++++ > 1 file changed, 58 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index f341911ef53..a002a442d03 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -23,6 +23,7 @@ import time > import datetime > import random > import binascii >+import itertools > > import samba.tests > from samba.credentials import Credentials >@@ -274,6 +275,63 @@ class KerberosCredentials(Credentials): > class RawKerberosTest(TestCaseInTempDir): > """A raw Kerberos Test case.""" > >+ etypes_to_test = ( >+ { "value": -1111, "name": "dummy", }, >+ { "value": kcrypto.Enctype.AES256, "name": "aes128", }, >+ { "value": kcrypto.Enctype.AES128, "name": "aes256", }, >+ { "value": kcrypto.Enctype.RC4, "name": "rc4", }, >+ ) >+ >+ setup_etype_test_permutations_done = False >+ >+ @classmethod >+ def setup_etype_test_permutations(cls): >+ if cls.setup_etype_test_permutations_done: >+ return >+ >+ res = [] >+ >+ num_idxs = len(cls.etypes_to_test) >+ permutations = [] >+ for num in range(1, num_idxs+1): >+ chunk = list(itertools.permutations(range(num_idxs), num)) >+ for e in chunk: >+ el = list(e) >+ permutations.append(el) >+ >+ for p in permutations: >+ name = None >+ etypes = () >+ for idx in p: >+ n = cls.etypes_to_test[idx]["name"] >+ if name is None: >+ name = n >+ else: >+ name += "_%s" % n >+ etypes += (cls.etypes_to_test[idx]["value"],) >+ >+ r = { "name": name, "etypes": etypes, } >+ res.append(r) >+ >+ cls.etype_test_permutations = res >+ cls.setup_etype_test_permutations_done = True >+ return >+ >+ @classmethod >+ def etype_test_permutation_name_idx(cls): >+ cls.setup_etype_test_permutations() >+ res = [] >+ idx = 0 >+ for e in cls.etype_test_permutations: >+ r = (e['name'], idx) >+ idx += 1 >+ res.append(r) >+ return res >+ >+ def etype_test_permutation_by_idx(self, idx): >+ e = self.etype_test_permutations[idx] >+ return (e['name'], e['etypes']) >+ > def setUp(self): > super().setUp() > self.do_asn1_print = False >-- >2.25.1 > > >From 23f8227d6d8a81ebda235a71d4d391f42bc589bb Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 16 Apr 2020 17:13:35 +0200 >Subject: [PATCH 097/686] tests/krb5/raw_testcase.py: Add > TicketDecryptionKey_from_creds() > >This will allow building test_as_req_enc_timestamp() > >It also introduces ways to specify keys in hex formated environment >variables ${PREFIX}_{AES256,AES128,RC4}_KEY_HEX. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 69ce2a6408f78d41eb865b89726021ad7643b065) >--- > python/samba/tests/krb5/raw_testcase.py | 29 +++++++++++++++++++++++++ > 1 file changed, 29 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index a002a442d03..7d0dc9c9609 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -784,6 +784,35 @@ class RawKerberosTest(TestCaseInTempDir): > return self.PasswordKey_create( > etype=e, pwd=password, salt=salt, kvno=kvno) > >+ def TicketDecryptionKey_from_creds(self, creds, etype=None): >+ >+ if etype is None: >+ etypes = creds.get_tgs_krb5_etypes() >+ etype = etypes[0] >+ >+ forced_key = creds.get_forced_key(etype) >+ if forced_key is not None: >+ return forced_key >+ >+ kvno = creds.get_kvno() >+ >+ fail_msg = ("%s has no fixed key for etype[%s] kvno[%s] " >+ "nor a password specified, " % ( >+ creds.get_username(), etype, kvno)) >+ >+ if etype == kcrypto.Enctype.RC4: >+ nthash = creds.get_nt_hash() >+ self.assertIsNotNone(nthash, msg=fail_msg) >+ return self.SessionKey_create(etype=etype, contents=nthash, kvno=kvno) >+ >+ password = creds.get_password() >+ self.assertIsNotNone(password, msg=fail_msg) >+ salt = creds.get_forced_salt() >+ if salt is None: >+ salt = bytes("%s%s" % (creds.get_realm(), creds.get_username()), >+ encoding='utf-8') >+ return self.PasswordKey_create(etype=etype, pwd=password, salt=salt, kvno=kvno) >+ > def RandomKey(self, etype): > e = kcrypto._get_enctype_profile(etype) > contents = samba.generate_random_bytes(e.keysize) >-- >2.25.1 > > >From a3b6f91e45766e557c712f696c93a9c377c84903 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 21 Apr 2020 11:07:45 +0200 >Subject: [PATCH 098/686] tests/krb5/raw_testcase.py: introduce a > _generic_kdc_exchange() infrastructure > >This will allow us to write tests, which will all cross check almost >every aspect of the KDC response (including encrypted parts). > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 6e2f2adc8e825634780077e24a9e437bdc68155a) >--- > python/samba/tests/krb5/raw_testcase.py | 634 +++++++++++++++++++ > python/samba/tests/krb5/rfc4120_constants.py | 11 + > 2 files changed, 645 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 7d0dc9c9609..8c8926b0ad2 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -30,6 +30,27 @@ from samba.credentials import Credentials > from samba.tests import TestCaseInTempDir > from samba.dcerpc import security > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+from samba.tests.krb5.rfc4120_constants import ( >+ KDC_ERR_ETYPE_NOSUPP, >+ KDC_ERR_PREAUTH_REQUIRED, >+ KRB_AS_REP, >+ KRB_AS_REQ, >+ KRB_ERROR, >+ KRB_TGS_REP, >+ KRB_TGS_REQ, >+ KU_AS_REP_ENC_PART, >+ KU_TGS_REP_ENC_PART_SESSION, >+ KU_TGS_REP_ENC_PART_SUB_KEY, >+ KU_TGS_REQ_AUTH, >+ KU_TGS_REQ_AUTH_CKSUM, >+ KU_TICKET, >+ PADATA_ENC_TIMESTAMP, >+ PADATA_ETYPE_INFO, >+ PADATA_ETYPE_INFO2, >+ PADATA_KDC_REQ, >+ PADATA_PK_AS_REQ, >+ PADATA_PK_AS_REP_19 >+) > import samba.tests.krb5.kcrypto as kcrypto > > from pyasn1.codec.der.decoder import decode as pyasn1_der_decode >@@ -272,6 +293,24 @@ class KerberosCredentials(Credentials): > def get_forced_salt(self): > return self.forced_salt > >+class KerberosTicketCreds(object): >+ def __init__(self, ticket, session_key, >+ crealm=None, cname=None, >+ srealm=None, sname=None, >+ decryption_key=None, >+ ticket_private=None, >+ encpart_private=None): >+ self.ticket = ticket >+ self.session_key = session_key >+ self.crealm = crealm >+ self.cname = cname >+ self.srealm = srealm >+ self.sname = sname >+ self.decryption_key = decryption_key >+ self.ticket_private = ticket_private >+ self.encpart_private = encpart_private >+ return >+ > class RawKerberosTest(TestCaseInTempDir): > """A raw Kerberos Test case.""" > >@@ -758,6 +797,12 @@ class RawKerberosTest(TestCaseInTempDir): > (s, _) = self.get_KerberosTimeWithUsec(epoch=epoch, offset=offset) > return s > >+ def get_Nonce(self): >+ nonce_min=0x7f000000 >+ nonce_max=0x7fffffff >+ v = random.randint(nonce_min, nonce_max) >+ return v >+ > def SessionKey_create(self, etype, contents, kvno=None): > key = kcrypto.Key(etype, contents) > return Krb5EncryptionKey(key, kvno) >@@ -1268,3 +1313,592 @@ class RawKerberosTest(TestCaseInTempDir): > pa_s4u2self = self.der_encode( > PA_S4U2Self_obj, asn1Spec=krb5_asn1.PA_S4U2Self()) > return self.PA_DATA_create(129, pa_s4u2self) >+ >+ def _generic_kdc_exchange(self, >+ kdc_exchange_dict, # required >+ kdc_options=None, # required >+ cname=None, # optional >+ realm=None, # required >+ sname=None, # optional >+ from_time=None, # optional >+ till_time=None, # required >+ renew_time=None, # optional >+ nonce=None, # required >+ etypes=None, # required >+ addresses=None, # optional >+ EncAuthorizationData=None, # optional >+ EncAuthorizationData_key=None, # optional >+ additional_tickets=None): # optional >+ >+ check_error_fn = kdc_exchange_dict['check_error_fn'] >+ check_rep_fn = kdc_exchange_dict['check_rep_fn'] >+ generate_padata_fn = kdc_exchange_dict['generate_padata_fn'] >+ callback_dict = kdc_exchange_dict['callback_dict'] >+ req_msg_type = kdc_exchange_dict['req_msg_type'] >+ req_asn1Spec = kdc_exchange_dict['req_asn1Spec'] >+ rep_msg_type = kdc_exchange_dict['rep_msg_type'] >+ >+ if till_time is None: >+ till_time = self.get_KerberosTime(offset=36000) >+ if nonce is None: >+ nonce = self.get_Nonce() >+ >+ req_body = self.KDC_REQ_BODY_create(kdc_options=kdc_options, >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=from_time, >+ till_time=till_time, >+ renew_time=renew_time, >+ nonce=nonce, >+ etypes=etypes, >+ addresses=addresses, >+ EncAuthorizationData=EncAuthorizationData, >+ EncAuthorizationData_key=EncAuthorizationData_key, >+ additional_tickets=additional_tickets) >+ if generate_padata_fn is not None: >+ # This can alter req_body... >+ padata, req_body = generate_padata_fn(kdc_exchange_dict, >+ callback_dict, >+ req_body) >+ else: >+ padata = None >+ >+ kdc_exchange_dict['req_padata'] = padata >+ kdc_exchange_dict['req_body'] = req_body >+ >+ req_obj,req_decoded = self.KDC_REQ_create(msg_type=req_msg_type, >+ padata=padata, >+ req_body=req_body, >+ asn1Spec=req_asn1Spec()) >+ >+ rep = self.send_recv_transaction(req_decoded) >+ self.assertIsNotNone(rep) >+ >+ msg_type = self.getElementValue(rep, 'msg-type') >+ self.assertIsNotNone(msg_type) >+ >+ allowed_msg_types = () >+ if check_error_fn is not None: >+ allowed_msg_types = (KRB_ERROR,) >+ if check_rep_fn is not None: >+ allowed_msg_types += (rep_msg_type,) >+ self.assertIn(msg_type, allowed_msg_types) >+ >+ if msg_type == KRB_ERROR: >+ return check_error_fn(kdc_exchange_dict, >+ callback_dict, >+ rep) >+ >+ return check_rep_fn(kdc_exchange_dict, callback_dict, rep) >+ >+ def as_exchange_dict(self, >+ expected_crealm=None, >+ expected_cname=None, >+ expected_srealm=None, >+ expected_sname=None, >+ ticket_decryption_key=None, >+ generate_padata_fn=None, >+ check_error_fn=None, >+ check_rep_fn=None, >+ check_padata_fn=None, >+ check_kdc_private_fn=None, >+ callback_dict=dict(), >+ expected_error_mode=None, >+ client_as_etypes=None, >+ expected_salt=None): >+ kdc_exchange_dict = { >+ 'req_msg_type': KRB_AS_REQ, >+ 'req_asn1Spec': krb5_asn1.AS_REQ, >+ 'rep_msg_type': KRB_AS_REP, >+ 'rep_asn1Spec': krb5_asn1.AS_REP, >+ 'rep_encpart_asn1Spec': krb5_asn1.EncASRepPart, >+ 'expected_crealm': expected_crealm, >+ 'expected_cname': expected_cname, >+ 'expected_srealm': expected_srealm, >+ 'expected_sname': expected_sname, >+ 'ticket_decryption_key': ticket_decryption_key, >+ 'generate_padata_fn': generate_padata_fn, >+ 'check_error_fn': check_error_fn, >+ 'check_rep_fn': check_rep_fn, >+ 'check_padata_fn': check_padata_fn, >+ 'check_kdc_private_fn': check_kdc_private_fn, >+ 'callback_dict': callback_dict, >+ 'expected_error_mode': expected_error_mode, >+ 'client_as_etypes': client_as_etypes, >+ 'expected_salt': expected_salt, >+ } >+ return kdc_exchange_dict >+ >+ def tgs_exchange_dict(self, >+ expected_crealm=None, >+ expected_cname=None, >+ expected_srealm=None, >+ expected_sname=None, >+ ticket_decryption_key=None, >+ generate_padata_fn=None, >+ check_error_fn=None, >+ check_rep_fn=None, >+ check_padata_fn=None, >+ check_kdc_private_fn=None, >+ callback_dict=dict(), >+ tgt=None, >+ authenticator_subkey=None, >+ body_checksum_type=None): >+ kdc_exchange_dict = { >+ 'req_msg_type': KRB_TGS_REQ, >+ 'req_asn1Spec': krb5_asn1.TGS_REQ, >+ 'rep_msg_type': KRB_TGS_REP, >+ 'rep_asn1Spec': krb5_asn1.TGS_REP, >+ 'rep_encpart_asn1Spec': krb5_asn1.EncTGSRepPart, >+ 'expected_crealm': expected_crealm, >+ 'expected_cname': expected_cname, >+ 'expected_srealm': expected_srealm, >+ 'expected_sname': expected_sname, >+ 'ticket_decryption_key': ticket_decryption_key, >+ 'generate_padata_fn': generate_padata_fn, >+ 'check_error_fn': check_error_fn, >+ 'check_rep_fn': check_rep_fn, >+ 'check_padata_fn': check_padata_fn, >+ 'check_kdc_private_fn': check_kdc_private_fn, >+ 'callback_dict': callback_dict, >+ 'tgt': tgt, >+ 'body_checksum_type': body_checksum_type, >+ 'authenticator_subkey': authenticator_subkey, >+ } >+ return kdc_exchange_dict >+ >+ def generic_check_kdc_rep(self, >+ kdc_exchange_dict, >+ callback_dict, >+ rep): >+ >+ expected_crealm = kdc_exchange_dict['expected_crealm'] >+ expected_cname = kdc_exchange_dict['expected_cname'] >+ expected_srealm = kdc_exchange_dict['expected_srealm'] >+ expected_sname = kdc_exchange_dict['expected_sname'] >+ ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] >+ check_padata_fn = kdc_exchange_dict['check_padata_fn'] >+ check_kdc_private_fn = kdc_exchange_dict['check_kdc_private_fn'] >+ rep_encpart_asn1Spec = kdc_exchange_dict['rep_encpart_asn1Spec'] >+ msg_type = kdc_exchange_dict['rep_msg_type'] >+ >+ self.assertElementEqual(rep, 'msg-type', msg_type) # AS-REP | TGS-REP >+ padata = self.getElementValue(rep, 'padata') >+ self.assertElementEqualUTF8(rep, 'crealm', expected_crealm) >+ self.assertElementEqualPrincipal(rep, 'cname', expected_cname) >+ self.assertElementPresent(rep, 'ticket') >+ ticket = self.getElementValue(rep, 'ticket') >+ ticket_encpart = None >+ ticket_cipher = None >+ if ticket is not None: # Never None, but gives indentation >+ self.assertElementPresent(ticket, 'tkt-vno') >+ self.assertElementEqualUTF8(ticket, 'realm', expected_srealm) >+ self.assertElementEqualPrincipal(ticket, 'sname', expected_sname) >+ self.assertElementPresent(ticket, 'enc-part') >+ ticket_encpart = self.getElementValue(ticket, 'enc-part') >+ if ticket_encpart is not None: # Never None, but gives indentation >+ self.assertElementPresent(ticket_encpart, 'etype') >+ # 0 means present, with any value != 0 >+ self.assertElementKVNO(ticket_encpart, 'kvno', 0) >+ self.assertElementPresent(ticket_encpart, 'cipher') >+ ticket_cipher = self.getElementValue(ticket_encpart, 'cipher') >+ self.assertElementPresent(rep, 'enc-part') >+ encpart = self.getElementValue(rep, 'enc-part') >+ encpart_cipher = None >+ if encpart is not None: # Never None, but gives indentation >+ self.assertElementPresent(encpart, 'etype') >+ self.assertElementKVNO(ticket_encpart, 'kvno', 'autodetect') >+ self.assertElementPresent(encpart, 'cipher') >+ encpart_cipher = self.getElementValue(encpart, 'cipher') >+ >+ encpart_decryption_key = None >+ if check_padata_fn is not None: >+ # See if get the decryption key from the preauth phase >+ encpart_decryption_key,encpart_decryption_usage = \ >+ check_padata_fn(kdc_exchange_dict, callback_dict, >+ rep, padata) >+ >+ ticket_private = None >+ if ticket_decryption_key is not None: >+ self.assertElementEqual(ticket_encpart, 'etype', ticket_decryption_key.etype) >+ self.assertElementKVNO(ticket_encpart, 'kvno', ticket_decryption_key.kvno) >+ ticket_decpart = ticket_decryption_key.decrypt(KU_TICKET, ticket_cipher) >+ ticket_private = self.der_decode(ticket_decpart, asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ encpart_private = None >+ if encpart_decryption_key is not None: >+ self.assertElementEqual(encpart, 'etype', encpart_decryption_key.etype) >+ self.assertElementKVNO(encpart, 'kvno', encpart_decryption_key.kvno) >+ rep_decpart = encpart_decryption_key.decrypt(encpart_decryption_usage, encpart_cipher) >+ encpart_private = self.der_decode(rep_decpart, asn1Spec=rep_encpart_asn1Spec()) >+ >+ if check_kdc_private_fn is not None: >+ check_kdc_private_fn(kdc_exchange_dict, callback_dict, >+ rep, ticket_private, encpart_private) >+ >+ return rep >+ >+ def generic_check_kdc_private(self, >+ kdc_exchange_dict, >+ callback_dict, >+ rep, >+ ticket_private, >+ encpart_private): >+ >+ expected_crealm = kdc_exchange_dict['expected_crealm'] >+ expected_cname = kdc_exchange_dict['expected_cname'] >+ expected_srealm = kdc_exchange_dict['expected_srealm'] >+ expected_sname = kdc_exchange_dict['expected_sname'] >+ ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] >+ >+ ticket = self.getElementValue(rep, 'ticket') >+ >+ ticket_session_key = None >+ if ticket_private is not None: >+ self.assertElementPresent(ticket_private, 'flags') >+ self.assertElementPresent(ticket_private, 'key') >+ ticket_key = self.getElementValue(ticket_private, 'key') >+ if ticket_key is not None: # Never None, but gives indentation >+ self.assertElementPresent(ticket_key, 'keytype') >+ self.assertElementPresent(ticket_key, 'keyvalue') >+ ticket_session_key = self.EncryptionKey_import(ticket_key) >+ self.assertElementEqualUTF8(ticket_private, 'crealm', expected_crealm) >+ self.assertElementEqualPrincipal(ticket_private, 'cname', expected_cname) >+ self.assertElementPresent(ticket_private, 'transited') >+ self.assertElementPresent(ticket_private, 'authtime') >+ if self.strict_checking: >+ self.assertElementPresent(ticket_private, 'starttime') >+ self.assertElementPresent(ticket_private, 'endtime') >+ # TODO self.assertElementPresent(ticket_private, 'renew-till') >+ # TODO self.assertElementMissing(ticket_private, 'caddr') >+ self.assertElementPresent(ticket_private, 'authorization-data') >+ >+ encpart_session_key = None >+ if encpart_private is not None: >+ self.assertElementPresent(encpart_private, 'key') >+ encpart_key = self.getElementValue(encpart_private, 'key') >+ if encpart_key is not None: # Never None, but gives indentation >+ self.assertElementPresent(encpart_key, 'keytype') >+ self.assertElementPresent(encpart_key, 'keyvalue') >+ encpart_session_key = self.EncryptionKey_import(encpart_key) >+ self.assertElementPresent(encpart_private, 'last-req') >+ self.assertElementPresent(encpart_private, 'nonce') >+ # TODO self.assertElementPresent(encpart_private, 'key-expiration') >+ self.assertElementPresent(encpart_private, 'flags') >+ self.assertElementPresent(encpart_private, 'authtime') >+ if self.strict_checking: >+ self.assertElementPresent(encpart_private, 'starttime') >+ self.assertElementPresent(encpart_private, 'endtime') >+ # TODO self.assertElementPresent(encpart_private, 'renew-till') >+ self.assertElementEqualUTF8(encpart_private, 'srealm', expected_srealm) >+ self.assertElementEqualPrincipal(encpart_private, 'sname', expected_sname) >+ # TODO self.assertElementMissing(encpart_private, 'caddr') >+ >+ if ticket_session_key is not None and encpart_session_key is not None: >+ self.assertEqual(ticket_session_key.etype, encpart_session_key.etype) >+ self.assertEqual(ticket_session_key.key.contents, encpart_session_key.key.contents) >+ if encpart_session_key is not None: >+ session_key = encpart_session_key >+ else: >+ session_key = ticket_session_key >+ ticket_creds = KerberosTicketCreds(ticket, >+ session_key, >+ crealm=expected_crealm, >+ cname=expected_cname, >+ srealm=expected_srealm, >+ sname=expected_sname, >+ decryption_key=ticket_decryption_key, >+ ticket_private=ticket_private, >+ encpart_private=encpart_private) >+ >+ kdc_exchange_dict['rep_ticket_creds'] = ticket_creds >+ return >+ >+ def generic_check_as_error(self, >+ kdc_exchange_dict, >+ callback_dict, >+ rep): >+ >+ expected_crealm = kdc_exchange_dict['expected_crealm'] >+ expected_cname = kdc_exchange_dict['expected_cname'] >+ expected_srealm = kdc_exchange_dict['expected_srealm'] >+ expected_sname = kdc_exchange_dict['expected_sname'] >+ expected_salt = kdc_exchange_dict['expected_salt'] >+ client_as_etypes = kdc_exchange_dict['client_as_etypes'] >+ expected_error_mode = kdc_exchange_dict['expected_error_mode'] >+ req_body = kdc_exchange_dict['req_body'] >+ proposed_etypes = req_body['etype'] >+ >+ kdc_exchange_dict['preauth_etype_info2'] = None >+ >+ expect_etype_info2 = () >+ expect_etype_info = False >+ unexpect_etype_info = True >+ expected_aes_type = 0 >+ expected_rc4_type = 0 >+ if kcrypto.Enctype.RC4 in proposed_etypes: >+ expect_etype_info = True >+ for etype in proposed_etypes: >+ if etype in (kcrypto.Enctype.AES256,kcrypto.Enctype.AES128): >+ expect_etype_info = False >+ if etype not in client_as_etypes: >+ continue >+ if etype in (kcrypto.Enctype.AES256,kcrypto.Enctype.AES128): >+ if etype > expected_aes_type: >+ expected_aes_type = etype >+ if etype in (kcrypto.Enctype.RC4,): >+ unexpect_etype_info = False >+ if etype > expected_rc4_type: >+ expected_rc4_type = etype >+ >+ if expected_aes_type != 0: >+ expect_etype_info2 += (expected_aes_type,) >+ if expected_rc4_type != 0: >+ expect_etype_info2 += (expected_rc4_type,) >+ >+ expected_error = KDC_ERR_ETYPE_NOSUPP >+ expected_patypes = () >+ if expect_etype_info: >+ self.assertGreater(len(expect_etype_info2), 0) >+ expected_patypes += (PADATA_ETYPE_INFO,) >+ if len(expect_etype_info2) != 0: >+ expected_error = KDC_ERR_PREAUTH_REQUIRED >+ expected_patypes += (PADATA_ETYPE_INFO2,) >+ >+ expected_patypes += (PADATA_ENC_TIMESTAMP,) >+ expected_patypes += (PADATA_PK_AS_REQ,) >+ expected_patypes += (PADATA_PK_AS_REP_19,) >+ >+ self.assertElementEqual(rep, 'msg-type', KRB_ERROR) >+ self.assertElementEqual(rep, 'error-code', expected_error) >+ self.assertElementMissing(rep, 'ctime') >+ self.assertElementMissing(rep, 'cusec') >+ self.assertElementPresent(rep, 'stime') >+ self.assertElementPresent(rep, 'susec') >+ # error-code checked above >+ if self.strict_checking: >+ self.assertElementMissing(rep, 'crealm') >+ self.assertElementMissing(rep, 'cname') >+ self.assertElementEqualUTF8(rep, 'realm', expected_srealm) >+ self.assertElementEqualPrincipal(rep, 'sname', expected_sname) >+ if self.strict_checking: >+ self.assertElementMissing(rep, 'e-text') >+ if expected_error_mode != KDC_ERR_PREAUTH_REQUIRED: >+ self.assertElementMissing(rep, 'e-data') >+ return >+ edata = self.getElementValue(rep, 'e-data') >+ if self.strict_checking: >+ self.assertIsNotNone(edata) >+ if edata is not None: >+ rep_padata = self.der_decode(edata, asn1Spec=krb5_asn1.METHOD_DATA()) >+ self.assertGreater(len(rep_padata), 0) >+ else: >+ rep_padata = [] >+ >+ if self.strict_checking: >+ for i in range(0, len(expected_patypes)): >+ self.assertElementEqual(rep_padata[i], 'padata-type', expected_patypes[i]) >+ self.assertEqual(len(rep_padata), len(expected_patypes)) >+ >+ etype_info2 = None >+ etype_info = None >+ enc_timestamp = None >+ pk_as_req = None >+ pk_as_rep19 = None >+ for pa in rep_padata: >+ patype = self.getElementValue(pa, 'padata-type') >+ pavalue = self.getElementValue(pa, 'padata-value') >+ if patype == PADATA_ETYPE_INFO2: >+ self.assertIsNone(etype_info2) >+ etype_info2 = self.der_decode(pavalue, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ continue >+ if patype == PADATA_ETYPE_INFO: >+ self.assertIsNone(etype_info) >+ etype_info = self.der_decode(pavalue, asn1Spec=krb5_asn1.ETYPE_INFO()) >+ continue >+ if patype == PADATA_ENC_TIMESTAMP: >+ self.assertIsNone(enc_timestamp) >+ enc_timestamp = pavalue >+ self.assertEqual(len(enc_timestamp), 0) >+ continue >+ if patype == PADATA_PK_AS_REQ: >+ self.assertIsNone(pk_as_req) >+ pk_as_req = pavalue >+ self.assertEqual(len(pk_as_req), 0) >+ continue >+ if patype == PADATA_PK_AS_REP_19: >+ self.assertIsNone(pk_as_rep19) >+ pk_as_rep19 = pavalue >+ self.assertEqual(len(pk_as_rep19), 0) >+ continue >+ >+ if expected_error == KDC_ERR_ETYPE_NOSUPP: >+ self.assertIsNone(etype_info2) >+ self.assertIsNone(etype_info) >+ if self.strict_checking: >+ self.assertIsNotNone(enc_timestamp) >+ self.assertIsNotNone(pk_as_req) >+ self.assertIsNotNone(pk_as_rep19) >+ return >+ >+ self.assertIsNotNone(etype_info2) >+ if expect_etype_info: >+ self.assertIsNotNone(etype_info) >+ else: >+ if self.strict_checking: >+ self.assertIsNone(etype_info) >+ if unexpect_etype_info: >+ self.assertIsNone(etype_info) >+ >+ self.assertGreaterEqual(len(etype_info2), 1) >+ self.assertLessEqual(len(etype_info2), len(expect_etype_info2)) >+ if self.strict_checking: >+ self.assertEqual(len(etype_info2), len(expect_etype_info2)) >+ for i in range(0, len(etype_info2)): >+ e = self.getElementValue(etype_info2[i], 'etype') >+ self.assertEqual(e, expect_etype_info2[i]) >+ salt = self.getElementValue(etype_info2[i], 'salt') >+ if e == kcrypto.Enctype.RC4: >+ self.assertIsNone(salt) >+ else: >+ self.assertIsNotNone(salt) >+ if expected_salt is not None: >+ self.assertEqual(salt, expected_salt) >+ s2kparams = self.getElementValue(etype_info2[i], 's2kparams') >+ if self.strict_checking: >+ self.assertIsNone(s2kparams) >+ if etype_info is not None: >+ self.assertEqual(len(etype_info), 1) >+ e = self.getElementValue(etype_info[0], 'etype') >+ self.assertEqual(e, kcrypto.Enctype.RC4) >+ self.assertEqual(e, expect_etype_info2[0]) >+ salt = self.getElementValue(etype_info[0], 'salt') >+ if self.strict_checking: >+ self.assertIsNotNone(salt) >+ self.assertEqual(len(salt), 0) >+ >+ self.assertIsNotNone(enc_timestamp) >+ self.assertIsNotNone(pk_as_req) >+ self.assertIsNotNone(pk_as_rep19) >+ >+ kdc_exchange_dict['preauth_etype_info2'] = etype_info2 >+ return >+ >+ def generate_simple_tgs_padata(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body): >+ tgt = kdc_exchange_dict['tgt'] >+ authenticator_subkey = kdc_exchange_dict['authenticator_subkey'] >+ body_checksum_type = kdc_exchange_dict['body_checksum_type'] >+ >+ req_body_blob = self.der_encode(req_body, asn1Spec=krb5_asn1.KDC_REQ_BODY()) >+ >+ req_body_checksum = self.Checksum_create(tgt.session_key, >+ KU_TGS_REQ_AUTH_CKSUM, >+ req_body_blob, >+ ctype=body_checksum_type) >+ >+ subkey_obj = None >+ if authenticator_subkey is not None: >+ subkey_obj = authenticator_subkey.export_obj() >+ seq_number = random.randint(0, 0xfffffffe) >+ (ctime, cusec) = self.get_KerberosTimeWithUsec() >+ authenticator_obj = self.Authenticator_create(crealm=tgt.crealm, >+ cname=tgt.cname, >+ cksum=req_body_checksum, >+ cusec=cusec, >+ ctime=ctime, >+ subkey=subkey_obj, >+ seq_number=seq_number, >+ authorization_data=None) >+ authenticator_blob = self.der_encode(authenticator_obj, asn1Spec=krb5_asn1.Authenticator()) >+ >+ authenticator = self.EncryptedData_create(tgt.session_key, >+ KU_TGS_REQ_AUTH, >+ authenticator_blob) >+ >+ ap_options = krb5_asn1.APOptions('0') >+ ap_req_obj = self.AP_REQ_create(ap_options=str(ap_options), >+ ticket=tgt.ticket, >+ authenticator=authenticator) >+ ap_req = self.der_encode(ap_req_obj, asn1Spec=krb5_asn1.AP_REQ()) >+ pa_tgs_req = self.PA_DATA_create(PADATA_KDC_REQ, ap_req) >+ padata = [pa_tgs_req] >+ >+ return padata, req_body >+ >+ def check_simple_tgs_padata(self, >+ kdc_exchange_dict, >+ callback_dict, >+ rep, >+ padata): >+ tgt = kdc_exchange_dict['tgt'] >+ authenticator_subkey = kdc_exchange_dict['authenticator_subkey'] >+ if authenticator_subkey is not None: >+ subkey = authenticator_subkey >+ subkey_usage = KU_TGS_REP_ENC_PART_SUB_KEY >+ else: >+ subkey = tgt.session_key >+ subkey_usage = KU_TGS_REP_ENC_PART_SESSION >+ >+ return subkey, subkey_usage >+ >+ def _test_as_exchange(self, >+ cname, >+ realm, >+ sname, >+ till, >+ client_as_etypes, >+ expected_error_mode, >+ expected_crealm, >+ expected_cname, >+ expected_srealm, >+ expected_sname, >+ expected_salt, >+ etypes, >+ padata, >+ kdc_options, >+ preauth_key=None, >+ ticket_decryption_key=None): >+ >+ def _generate_padata_copy(_kdc_exchange_dict, >+ _callback_dict, >+ req_body): >+ return padata, req_body >+ >+ def _check_padata_preauth_key(_kdc_exchange_dict, >+ _callback_dict, >+ rep, >+ padata): >+ as_rep_usage = KU_AS_REP_ENC_PART >+ return preauth_key, as_rep_usage >+ >+ kdc_exchange_dict = self.as_exchange_dict( >+ expected_crealm=expected_crealm, >+ expected_cname=expected_cname, >+ expected_srealm=expected_srealm, >+ expected_sname=expected_sname, >+ ticket_decryption_key=ticket_decryption_key, >+ generate_padata_fn=_generate_padata_copy, >+ check_error_fn=self.generic_check_as_error, >+ check_rep_fn=self.generic_check_kdc_rep, >+ check_padata_fn=_check_padata_preauth_key, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ expected_error_mode=expected_error_mode, >+ client_as_etypes=client_as_etypes, >+ expected_salt=expected_salt) >+ >+ rep = self._generic_kdc_exchange(kdc_exchange_dict, >+ kdc_options=str(kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ till_time=till, >+ etypes=etypes) >+ >+ if expected_error_mode == 0: # AS-REP >+ return rep >+ >+ return kdc_exchange_dict['preauth_etype_info2'] >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index 702f6084217..a4c5e079b66 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -28,16 +28,27 @@ ARCFOUR_HMAC_MD5 = int( > # Message types > KRB_ERROR = int(krb5_asn1.MessageTypeValues('krb-error')) > KRB_AS_REP = int(krb5_asn1.MessageTypeValues('krb-as-rep')) >+KRB_AS_REQ = int(krb5_asn1.MessageTypeValues('krb-as-req')) > KRB_TGS_REP = int(krb5_asn1.MessageTypeValues('krb-tgs-rep')) >+KRB_TGS_REQ = int(krb5_asn1.MessageTypeValues('krb-tgs-req')) > > # PAData types > PADATA_ENC_TIMESTAMP = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-ENC-TIMESTAMP')) >+PADATA_ETYPE_INFO = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-ETYPE-INFO')) > PADATA_ETYPE_INFO2 = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-ETYPE-INFO2')) >+PADATA_KDC_REQ = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-KDC-REQ')) >+PADATA_PK_AS_REQ = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-PK-AS-REQ')) >+PADATA_PK_AS_REP_19 = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-PK-AS-REP-19')) > > # Error codes > KDC_ERR_C_PRINCIPAL_UNKNOWN = 6 >+KDC_ERR_ETYPE_NOSUPP = 14 > KDC_ERR_PREAUTH_FAILED = 24 > KDC_ERR_PREAUTH_REQUIRED = 25 > KDC_ERR_BADMATCH = 36 >-- >2.25.1 > > >From 04a4f049ee737e0e6393db951f7b0b1799f17ed9 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 21 Apr 2020 11:07:45 +0200 >Subject: [PATCH 099/686] tests/krb5/as_req_tests.py: add new tests to cover > more of the AS-REQ protocol > >Example commands: > >Windows 2012R2: >SERVER=172.31.9.188 STRICT_CHECKING=1 DOMAIN=W2012R2-L6 REALM=W2012R2-L6.BASE CLIENT_USERNAME=ldaptestuser CLIENT_PASSWORD=a1B2c3D4 CLIENT_AS_SUPPORTED_ENCTYPES=28 python/samba/tests/krb5/as_req_tests.py AsReqKerberosTests >SERVER=172.31.9.188 STRICT_CHECKING=1 DOMAIN=W2012R2-L6 REALM=W2012R2-L6.BASE CLIENT_USERNAME=administrator CLIENT_PASSWORD=A1b2C3d4 CLIENT_AS_SUPPORTED_ENCTYPES=4 python/samba/tests/krb5/as_req_tests.py AsReqKerberosTests > >Windows 2008R2: >SERVER=172.31.9.133 STRICT_CHECKING=1 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE CLIENT_USERNAME=cifsmount CLIENT_PASSWORD=A1b2C3d4-08 CLIENT_AS_SUPPORTED_ENCTYPES=28 python/samba/tests/krb5/as_req_tests.py AsReqKerberosTests >SERVER=172.31.9.133 STRICT_CHECKING=1 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE CLIENT_USERNAME=administrator CLIENT_PASSWORD=A1b2C3d4 CLIENT_AS_SUPPORTED_ENCTYPES=4 python/samba/tests/krb5/as_req_tests.py AsReqKerberosTests > >Samba 4.14: >SERVER=172.31.9.163 STRICT_CHECKING=0 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE CLIENT_USERNAME=cifsmount CLIENT_PASSWORD=A1b2C3d4-08 CLIENT_AS_SUPPORTED_ENCTYPES=28 python/samba/tests/krb5/as_req_tests.py AsReqKerberosTests >SERVER=172.31.9.163 STRICT_CHECKING=0 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE CLIENT_USERNAME=administrator CLIENT_PASSWORD=A1b2C3d4 CLIENT_AS_SUPPORTED_ENCTYPES=4 python/samba/tests/krb5/as_req_tests.py AsReqKerberosTests > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 01d86954d217e38be333aa1ce7db1d3d9059cd4c) >--- > python/samba/tests/krb5/as_req_tests.py | 121 ++++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > 2 files changed, 122 insertions(+) > create mode 100755 python/samba/tests/krb5/as_req_tests.py > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >new file mode 100755 >index 00000000000..3ad37c6bdf2 >--- /dev/null >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -0,0 +1,121 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+from samba.tests import DynamicTestCase >+from samba.tests.krb5.raw_testcase import RawKerberosTest >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+from samba.tests.krb5.rfc4120_constants import ( >+ KDC_ERR_PREAUTH_REQUIRED, >+ NT_PRINCIPAL, >+ NT_SRV_INST >+) >+ >+global_asn1_print = False >+global_hexdump = False >+ >+@DynamicTestCase >+class AsReqKerberosTests(RawKerberosTest): >+ >+ @classmethod >+ def setUpDynamicTestCases(cls): >+ for (name, idx) in cls.etype_test_permutation_name_idx(): >+ for pac in [None, True, False]: >+ tname = "%s_pac_%s" % (name, pac) >+ targs = (idx, pac) >+ cls.generate_dynamic_test("test_as_req_no_preauth", tname, *targs) >+ return >+ >+ def setUp(self): >+ super(AsReqKerberosTests, self).setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def _test_as_req_nopreauth(self, >+ initial_etypes, >+ initial_padata=None, >+ initial_kdc_options=None): >+ client_creds = self.get_client_creds() >+ client_account = client_creds.get_username() >+ client_as_etypes = client_creds.get_as_krb5_etypes() >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_account = krbtgt_creds.get_username() >+ realm = krbtgt_creds.get_realm() >+ >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[client_account]) >+ sname = self.PrincipalName_create(name_type=NT_SRV_INST, >+ names=[krbtgt_account, realm]) >+ >+ expected_error_mode = KDC_ERR_PREAUTH_REQUIRED >+ expected_crealm = realm >+ expected_cname = cname >+ expected_srealm = realm >+ expected_sname = sname >+ expected_salt = client_creds.get_forced_salt() >+ >+ def _generate_padata_copy(_kdc_exchange_dict, >+ _callback_dict, >+ req_body): >+ return initial_padata, req_body >+ >+ kdc_exchange_dict = self.as_exchange_dict( >+ expected_crealm=expected_crealm, >+ expected_cname=expected_cname, >+ expected_srealm=expected_srealm, >+ expected_sname=expected_sname, >+ generate_padata_fn=_generate_padata_copy, >+ check_error_fn=self.generic_check_as_error, >+ check_rep_fn=self.generic_check_kdc_rep, >+ expected_error_mode=expected_error_mode, >+ client_as_etypes=client_as_etypes, >+ expected_salt=expected_salt) >+ >+ rep = self._generic_kdc_exchange(kdc_exchange_dict, >+ kdc_options=str(initial_kdc_options), >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ etypes=initial_etypes) >+ >+ return kdc_exchange_dict['preauth_etype_info2'] >+ >+ def _test_as_req_no_preauth_with_args(self, etype_idx, pac): >+ name, etypes = self.etype_test_permutation_by_idx(etype_idx) >+ if pac is None: >+ padata = None >+ else: >+ pa_pac = self.KERB_PA_PAC_REQUEST_create(pac) >+ padata = [pa_pac] >+ return self._test_as_req_nopreauth( >+ initial_padata=padata, >+ initial_etypes=etypes, >+ initial_kdc_options=krb5_asn1.KDCOptions('forwardable')) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = True >+ global_hexdump = True >+ import unittest >+ unittest.main() >+ >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index ad13012c9bb..db46705cdb4 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -98,6 +98,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/test_rpc.py', > 'python/samba/tests/krb5/test_smb.py', > 'python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py', >+ 'python/samba/tests/krb5/as_req_tests.py', > } > > >-- >2.25.1 > > >From 5437abd197eff0a50e9b4d9345ac460aa9743c7b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 21 Apr 2020 11:07:45 +0200 >Subject: [PATCH 100/686] selftest: run new as_req_tests against fl2008r2dc and > fl2003dc > >There are a lot of things we should improve in our KDC >in order to work like a Windows KDC. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d91665d33130aed11fa82d8d2796ab1627e04dc4) > >[jsutton@samba.org Fixed conflict from > 0dbb923881a66b1e6b499b5b59103aea58ae0be6 not being applied] >--- > .../knownfail.d/samba.tests.krb5.as_req_tests | 276 +++++++++++++ > selftest/knownfail_mit_kdc | 389 +++++++++++++++++- > selftest/selftest.pl | 1 + > selftest/target/Samba4.pm | 6 +- > source4/selftest/tests.py | 10 + > 5 files changed, 680 insertions(+), 2 deletions(-) > create mode 100644 selftest/knownfail.d/samba.tests.krb5.as_req_tests > >diff --git a/selftest/knownfail.d/samba.tests.krb5.as_req_tests b/selftest/knownfail.d/samba.tests.krb5.as_req_tests >new file mode 100644 >index 00000000000..390d6cd0ab6 >--- /dev/null >+++ b/selftest/knownfail.d/samba.tests.krb5.as_req_tests >@@ -0,0 +1,276 @@ >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2003dc >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 2c2a643944c..b610929a8dd 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -290,4 +290,391 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_b > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c >- >+# >+# MIT currently fails some as_req_no_preauth tests. >+# >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_False >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_False.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_None.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_True.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_True.fl2008r2dc >diff --git a/selftest/selftest.pl b/selftest/selftest.pl >index f2968139cfd..2fe7fb27d05 100755 >--- a/selftest/selftest.pl >+++ b/selftest/selftest.pl >@@ -821,6 +821,7 @@ my @exported_envvars = ( > "DNSNAME", > "REALM", > "DOMSID", >+ "SUPPORTED_ENCTYPE_BITS", > > # stuff related to a trusted domain > "TRUST_SERVER", >diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm >index aa12e823ae5..02b43e2821c 100755 >--- a/selftest/target/Samba4.pm >+++ b/selftest/target/Samba4.pm >@@ -581,7 +581,10 @@ sub provision_raw_prepare($$$$$$$$$$$$) > $ctx->{kdc_ipv6} = $kdc_ipv6; > $ctx->{krb5_ccname} = "$prefix_abs/krb5cc_%{uid}"; > if ($functional_level eq "2000") { >- $ctx->{supported_enctypes} = "arcfour-hmac-md5 des-cbc-md5 des-cbc-crc" >+ $ctx->{supported_enctypes} = "arcfour-hmac-md5 des-cbc-md5 des-cbc-crc"; >+ $ctx->{supported_enctypes_bits} = "4"; >+ } else { >+ $ctx->{supported_enctypes_bits} = "28"; > } > > # >@@ -878,6 +881,7 @@ nogroup:x:65534:nobody > KRB5_CONFIG => $ctx->{krb5_conf}, > KRB5_CCACHE => $ctx->{krb5_ccache}, > MITKDC_CONFIG => $ctx->{mitkdc_conf}, >+ SUPPORTED_ENCTYPE_BITS => $ctx->{supported_enctypes_bits}, > PIDDIR => $ctx->{piddir}, > SERVER => $ctx->{hostname}, > SERVER_IP => $ctx->{ipv4}, >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 68a51813e4f..b6ec53904a6 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1217,6 +1217,16 @@ plansmbtorture4testsuite('krb5.kdc', env, ['ncacn_np:$SERVER_IP', "-k", "yes", ' > '--option=torture:krb5-hostname=testupnspn.$DNSNAME', > '--option=torture:krb5-service=http'], > "samba4.krb5.kdc with account having identical UPN and SPN") >+for env in ["fl2008r2dc", "fl2003dc"]: >+ planoldpythontestsuite(env, "samba.tests.krb5.as_req_tests", >+ environ={ >+ 'CLIENT_USERNAME': '$USERNAME', >+ 'CLIENT_PASSWORD': '$PASSWORD', >+ 'CLIENT_AS_SUPPORTED_ENCTYPES': '$SUPPORTED_ENCTYPE_BITS', >+ 'SERVER_USERNAME': '$SERVER', >+ 'SERVER_PASSWORD': 'machine$PASSWORD', >+ 'STRICT_CHECKING': '0', >+ }) > > > for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: >-- >2.25.1 > > >From a8f3c4c30effea0b0da7adee81abd7b52e2cabc7 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 15:38:28 +1200 >Subject: [PATCH 101/686] tests/krb5/kdc_base_test.py: Defer account deletion > until tearDownClass() is called > >This allows accounts created for permutation tests to be reused, rather >than having to be recreated for every test. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 5412bffb9b4fc13023e650bbc9436a79b60b6fa2) >--- > python/samba/tests/krb5/kdc_base_test.py | 24 +++++++++++++++--------- > 1 file changed, 15 insertions(+), 9 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index e345f739e1c..578736574ae 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -99,21 +99,27 @@ class KDCBaseTest(RawKerberosTest): > base="", expression="", scope=SCOPE_BASE, attrs=["dnsHostName"]) > cls.dns_host_name = str(res[0]['dnsHostName']) > >+ # A set containing DNs of accounts created as part of testing. >+ cls.accounts = set() >+ >+ @classmethod >+ def tearDownClass(cls): >+ # Clean up any accounts created by create_account. This is >+ # done in tearDownClass() rather than tearDown(), so that >+ # accounts need only be created once for permutation tests. >+ for dn in cls.accounts: >+ delete_force(cls.ldb, dn) >+ super().tearDownClass() >+ > def setUp(self): > super().setUp() > self.do_asn1_print = global_asn1_print > self.do_hexdump = global_hexdump >- self.accounts = [] >- >- def tearDown(self): >- # Clean up any accounts created by create_account >- for dn in self.accounts: >- delete_force(self.ldb, dn) > > def create_account(self, name, machine_account=False, spn=None, upn=None): > '''Create an account for testing. > The dn of the created account is added to self.accounts, >- which is used by tearDown to clean up the created accounts. >+ which is used by tearDownClass to clean up the created accounts. > ''' > dn = "cn=%s,%s" % (name, self.ldb.domain_dn()) > >@@ -153,8 +159,8 @@ class KDCBaseTest(RawKerberosTest): > if machine_account: > creds.set_workstation(name) > # >- # Save the account name so it can be deleted in the tearDown >- self.accounts.append(dn) >+ # Save the account name so it can be deleted in tearDownClass >+ self.accounts.add(dn) > > return (creds, dn) > >-- >2.25.1 > > >From 087d03fb2d6549eca5c1be96deebe2b6bd05249b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 13:14:33 +1200 >Subject: [PATCH 102/686] tests/krb5/raw_testcase.py: Add get_admin_creds() > >This method allows obtaining credentials that can be used for >administrative tasks such as creating accounts. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 5afae39da0ab408bb36dde3a7801634bd9cc24f6) >--- > python/samba/tests/krb5/raw_testcase.py | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 8c8926b0ad2..7e41245f706 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -526,6 +526,11 @@ class RawKerberosTest(TestCaseInTempDir): > allow_missing_password=allow_missing_password) > return c > >+ def get_admin_creds(self, allow_missing_password=False): >+ c = self._get_krb5_creds(prefix='ADMIN', >+ allow_missing_password=allow_missing_password) >+ return c >+ > def get_krbtgt_creds(self, require_strongest_key=False): > c = self._get_krb5_creds(prefix='KRBTGT', > default_username='krbtgt', >-- >2.25.1 > > >From a7ab6e0e051a07045c506416ff9515b996f0ed1a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 16 Jun 2021 11:04:00 +1200 >Subject: [PATCH 103/686] tests/krb5/kdc_base_test.py: Create database > connection only when needed > >Now the database connection is only created on its first use, which >means database credentials are no longer required for tests that don't >make use of it. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 4f5566be4839838e0e3e501a030bcf6e85ff5159) >--- > python/samba/tests/krb5/kdc_base_test.py | 56 +++++++------ > python/samba/tests/krb5/kdc_tgs_tests.py | 17 ++-- > .../ms_kile_client_principal_lookup_tests.py | 84 +++++++++++-------- > python/samba/tests/krb5/test_ccache.py | 15 ++-- > python/samba/tests/krb5/test_ldap.py | 12 +-- > python/samba/tests/krb5/test_rpc.py | 6 +- > python/samba/tests/krb5/test_smb.py | 12 +-- > 7 files changed, 116 insertions(+), 86 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 578736574ae..b191f905366 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -89,15 +89,7 @@ class KDCBaseTest(RawKerberosTest): > > cls.credentials = c > >- cls.session = system_session() >- cls.ldb = SamDB(url="ldap://%s" % cls.host, >- session_info=cls.session, >- credentials=cls.credentials, >- lp=cls.lp) >- # fetch the dnsHostName from the RootDse >- res = cls.ldb.search( >- base="", expression="", scope=SCOPE_BASE, attrs=["dnsHostName"]) >- cls.dns_host_name = str(res[0]['dnsHostName']) >+ cls._ldb = None > > # A set containing DNs of accounts created as part of testing. > cls.accounts = set() >@@ -107,8 +99,9 @@ class KDCBaseTest(RawKerberosTest): > # Clean up any accounts created by create_account. This is > # done in tearDownClass() rather than tearDown(), so that > # accounts need only be created once for permutation tests. >- for dn in cls.accounts: >- delete_force(cls.ldb, dn) >+ if cls._ldb is not None: >+ for dn in cls.accounts: >+ delete_force(cls._ldb, dn) > super().tearDownClass() > > def setUp(self): >@@ -116,16 +109,27 @@ class KDCBaseTest(RawKerberosTest): > self.do_asn1_print = global_asn1_print > self.do_hexdump = global_hexdump > >- def create_account(self, name, machine_account=False, spn=None, upn=None): >+ def get_samdb(self): >+ if self._ldb is None: >+ session = system_session() >+ type(self)._ldb = SamDB(url="ldap://%s" % self.host, >+ session_info=session, >+ credentials=self.credentials, >+ lp=self.lp) >+ >+ return self._ldb >+ >+ def create_account(self, ldb, name, machine_account=False, >+ spn=None, upn=None): > '''Create an account for testing. > The dn of the created account is added to self.accounts, > which is used by tearDownClass to clean up the created accounts. > ''' >- dn = "cn=%s,%s" % (name, self.ldb.domain_dn()) >+ dn = "cn=%s,%s" % (name, ldb.domain_dn()) > > # remove the account if it exists, this will happen if a previous test > # run failed >- delete_force(self.ldb, dn) >+ delete_force(ldb, dn) > if machine_account: > object_class = "computer" > account_name = "%s$" % name >@@ -148,12 +152,12 @@ class KDCBaseTest(RawKerberosTest): > details["servicePrincipalName"] = spn > if upn is not None: > details["userPrincipalName"] = upn >- self.ldb.add(details) >+ ldb.add(details) > > creds = Credentials() > creds.guess(self.lp) >- creds.set_realm(self.ldb.domain_dns_name().upper()) >- creds.set_domain(self.ldb.domain_netbios_name().upper()) >+ creds.set_realm(ldb.domain_dns_name().upper()) >+ creds.set_domain(ldb.domain_netbios_name().upper()) > creds.set_password(password) > creds.set_username(account_name) > if machine_account: >@@ -425,38 +429,38 @@ class KDCBaseTest(RawKerberosTest): > enc_part, asn1Spec=krb5_asn1.EncTicketPart()) > return enc_ticket_part > >- def get_objectSid(self, dn): >+ def get_objectSid(self, samdb, dn): > ''' Get the objectSID for a DN > Note: performs an Ldb query. > ''' >- res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=["objectSID"]) >+ res = samdb.search(dn, scope=SCOPE_BASE, attrs=["objectSID"]) > self.assertTrue(len(res) == 1, "did not get objectSid for %s" % dn) >- sid = self.ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) >+ sid = samdb.schema_format_value("objectSID", res[0]["objectSID"][0]) > return sid.decode('utf8') > >- def add_attribute(self, dn_str, name, value): >+ def add_attribute(self, samdb, dn_str, name, value): > if isinstance(value, list): > values = value > else: > values = [value] > flag = ldb.FLAG_MOD_ADD > >- dn = ldb.Dn(self.ldb, dn_str) >+ dn = ldb.Dn(samdb, dn_str) > msg = ldb.Message(dn) > msg[name] = ldb.MessageElement(values, flag, name) >- self.ldb.modify(msg) >+ samdb.modify(msg) > >- def modify_attribute(self, dn_str, name, value): >+ def modify_attribute(self, samdb, dn_str, name, value): > if isinstance(value, list): > values = value > else: > values = [value] > flag = ldb.FLAG_MOD_REPLACE > >- dn = ldb.Dn(self.ldb, dn_str) >+ dn = ldb.Dn(samdb, dn_str) > msg = ldb.Message(dn) > msg[name] = ldb.MessageElement(values, flag, name) >- self.ldb.modify(msg) >+ samdb.modify(msg) > > def create_ccache(self, cname, ticket, enc_part): > """ Lay out a version 4 on-disk credentials cache, to be read using the >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 23a1d868a79..0c757bd5e5f 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -49,8 +49,9 @@ class KdcTgsTests(KDCBaseTest): > that differs from that provided to the krbtgt > ''' > # Create the user account >+ samdb = self.get_samdb() > user_name = "tsttktusr" >- (uc, _) = self.create_account(user_name) >+ (uc, _) = self.create_account(samdb, user_name) > realm = uc.get_realm().lower() > > # Do the initial AS-REQ, should get a pre-authentication required >@@ -81,7 +82,7 @@ class KdcTgsTests(KDCBaseTest): > names=["Administrator"]) > sname = self.PrincipalName_create( > name_type=NT_PRINCIPAL, >- names=["host", self.dns_host_name]) >+ names=["host", samdb.host_dns_name()]) > > (rep, enc_part) = self.tgs_req(cname, sname, realm, ticket, key, etype) > >@@ -98,8 +99,9 @@ class KdcTgsTests(KDCBaseTest): > '''Get a ticket to the ldap service > ''' > # Create the user account >+ samdb = self.get_samdb() > user_name = "tsttktusr" >- (uc, _) = self.create_account(user_name) >+ (uc, _) = self.create_account(samdb, user_name) > realm = uc.get_realm().lower() > > # Do the initial AS-REQ, should get a pre-authentication required >@@ -126,7 +128,7 @@ class KdcTgsTests(KDCBaseTest): > # Request a ticket to the ldap service > sname = self.PrincipalName_create( > name_type=NT_SRV_INST, >- names=["ldap", self.dns_host_name]) >+ names=["ldap", samdb.host_dns_name()]) > > (rep, _) = self.tgs_req( > cname, sname, uc.get_realm(), ticket, key, etype) >@@ -137,9 +139,10 @@ class KdcTgsTests(KDCBaseTest): > > # Create a user and machine account for the test. > # >+ samdb = self.get_samdb() > user_name = "tsttktusr" >- (uc, dn) = self.create_account(user_name) >- (mc, _) = self.create_account("tsttktmac", machine_account=True) >+ (uc, dn) = self.create_account(samdb, user_name) >+ (mc, _) = self.create_account(samdb, "tsttktmac", machine_account=True) > realm = uc.get_realm().lower() > > # Do the initial AS-REQ, should get a pre-authentication required >@@ -179,7 +182,7 @@ class KdcTgsTests(KDCBaseTest): > enc_part = self.decode_service_ticket(mc, ticket) > > pac_data = self.get_pac_data(enc_part['authorization-data']) >- sid = self.get_objectSid(dn) >+ sid = self.get_objectSid(samdb, dn) > upn = "%s@%s" % (uc.get_username(), realm) > self.assertEqual( > uc.get_username(), >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index 356a25f8e18..63f67b09c4c 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -49,10 +49,10 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.do_asn1_print = global_asn1_print > self.do_hexdump = global_hexdump > >- def check_pac(self, auth_data, dn, uc, name, upn=None): >+ def check_pac(self, samdb, auth_data, dn, uc, name, upn=None): > > pac_data = self.get_pac_data(auth_data) >- sid = self.get_objectSid(dn) >+ sid = self.get_objectSid(samdb, dn) > if upn is None: > upn = "%s@%s" % (name, uc.get_realm().lower()) > if name.endswith('$'): >@@ -89,12 +89,13 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > # Create user and machine accounts for the test. > # >+ samdb = self.get_samdb() > user_name = "mskileusr" >- (uc, dn) = self.create_account(user_name) >+ (uc, dn) = self.create_account(samdb, user_name) > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, _) = self.create_account(mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, machine_account=True) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -131,7 +132,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # Check the contents of the pac, and the ticket > ticket = rep['ticket'] > enc_part = self.decode_service_ticket(mc, ticket) >- self.check_pac(enc_part['authorization-data'], dn, uc, user_name) >+ self.check_pac(samdb, enc_part['authorization-data'], dn, uc, user_name) > # check the crealm and cname > cname = enc_part['cname'] > self.assertEqual(NT_PRINCIPAL, cname['name-type']) >@@ -147,12 +148,13 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > # Create a machine account for the test. > # >+ samdb = self.get_samdb() > user_name = "mskilemac" >- (mc, dn) = self.create_account(user_name, machine_account=True) >+ (mc, dn) = self.create_account(samdb, user_name, machine_account=True) > realm = mc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, _) = self.create_account(mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, machine_account=True) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -189,7 +191,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # Check the contents of the pac, and the ticket > ticket = rep['ticket'] > enc_part = self.decode_service_ticket(mc, ticket) >- self.check_pac(enc_part['authorization-data'], dn, mc, mach_name + '$') >+ self.check_pac(samdb, enc_part['authorization-data'], dn, mc, mach_name + '$') > # check the crealm and cname > cname = enc_part['cname'] > self.assertEqual(NT_PRINCIPAL, cname['name-type']) >@@ -206,14 +208,15 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > ''' > # Create a user account for the test. > # >+ samdb = self.get_samdb() > user_name = "mskileusr" > upn_name = "mskileupn" > upn = upn_name + "@" + self.credentials.get_realm().lower() >- (uc, dn) = self.create_account(user_name, upn=upn) >+ (uc, dn) = self.create_account(samdb, user_name, upn=upn) > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, _) = self.create_account(mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, machine_account=True) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -250,7 +253,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # Check the contents of the service ticket > ticket = rep['ticket'] > enc_part = self.decode_service_ticket(mc, ticket) >- self.check_pac(enc_part['authorization-data'], dn, uc, upn_name) >+ self.check_pac(samdb, enc_part['authorization-data'], dn, uc, upn_name) > # check the crealm and cname > cname = enc_part['cname'] > self.assertEqual(NT_PRINCIPAL, cname['name-type']) >@@ -273,19 +276,21 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # setting UF_DONT_REQUIRE_PREAUTH seems to be the only way > # to trigger the no pre-auth step > >+ samdb = self.get_samdb() > user_name = "mskileusr" > alt_name = "mskilealtsec" >- (uc, dn) = self.create_account(user_name) >+ (uc, dn) = self.create_account(samdb, user_name) > realm = uc.get_realm().lower() > alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >- self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > self.modify_attribute( >+ samdb, > dn, > "userAccountControl", > str(UF_NORMAL_ACCOUNT | UF_DONT_REQUIRE_PREAUTH)) > > mach_name = "mskilemac" >- (mc, _) = self.create_account(mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, machine_account=True) > > # Do the initial AS-REQ, as we've set UF_DONT_REQUIRE_PREAUTH > # we should get a valid AS-RESP >@@ -340,15 +345,16 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > # Create user and machine accounts for the test. > # >+ samdb = self.get_samdb() > user_name = "mskileusr" > alt_name = "mskilealtsec" >- (uc, dn) = self.create_account(user_name) >+ (uc, dn) = self.create_account(samdb, user_name) > realm = uc.get_realm().lower() > alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >- self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > > mach_name = "mskilemac" >- (mc, _) = self.create_account(mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, machine_account=True) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -406,15 +412,16 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > # Create user and machine accounts for the test. > # >+ samdb = self.get_samdb() > user_name = "mskileusr" > alt_name = "mskilealtsec" >- (uc, dn) = self.create_account(user_name) >+ (uc, dn) = self.create_account(samdb, user_name) > realm = uc.get_realm().lower() > alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >- self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > > mach_name = "mskilemac" >- (mc, _) = self.create_account(mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, machine_account=True) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -445,14 +452,15 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > # Create a user account for the test. > # >+ samdb = self.get_samdb() > user_name = "mskileusr" > upn_name = "mskileupn" > upn = upn_name + "@" + self.credentials.get_realm().lower() >- (uc, dn) = self.create_account(user_name, upn=upn) >+ (uc, dn) = self.create_account(samdb, user_name, upn=upn) > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, _) = self.create_account(mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, machine_account=True) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -508,13 +516,14 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > # Create a user account for the test. > # >+ samdb = self.get_samdb() > user_name = "mskileusr" >- (uc, dn) = self.create_account(user_name) >+ (uc, dn) = self.create_account(samdb, user_name) > realm = uc.get_realm().lower() > ename = user_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, machine_account=True) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -570,12 +579,13 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > # Create a user account for the test. > # >+ samdb = self.get_samdb() > user_name = "mskileusr" >- (uc, _) = self.create_account(user_name) >+ (uc, _) = self.create_account(samdb, user_name) > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, dn) = self.create_account(mach_name, machine_account=True) >+ (mc, dn) = self.create_account(samdb, mach_name, machine_account=True) > ename = mach_name + "@" + realm > uname = mach_name + "$@" + realm > >@@ -638,20 +648,22 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # setting UF_DONT_REQUIRE_PREAUTH seems to be the only way > # to trigger the no pre-auth step > >+ samdb = self.get_samdb() > user_name = "mskileusr" > alt_name = "mskilealtsec" >- (uc, dn) = self.create_account(user_name) >+ (uc, dn) = self.create_account(samdb, user_name) > realm = uc.get_realm().lower() > alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >- self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > self.modify_attribute( >+ samdb, > dn, > "userAccountControl", > str(UF_NORMAL_ACCOUNT | UF_DONT_REQUIRE_PREAUTH)) > ename = alt_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, machine_account=True) > > # Do the initial AS-REQ, as we've set UF_DONT_REQUIRE_PREAUTH > # we should get a valid AS-RESP >@@ -706,17 +718,18 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > # Create user and machine accounts for the test. > # >+ samdb = self.get_samdb() > user_name = "mskileusr" > alt_name = "mskilealtsec" >- (uc, dn) = self.create_account(user_name) >+ (uc, dn) = self.create_account(samdb, user_name) > realm = uc.get_realm().lower() > alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >- self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > ename = alt_name + "@" + realm > uname = user_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, machine_account=True) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -775,16 +788,17 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > # Create user and machine accounts for the test. > # >+ samdb = self.get_samdb() > user_name = "mskileusr" > alt_name = "mskilealtsec" >- (uc, dn) = self.create_account(user_name) >+ (uc, dn) = self.create_account(samdb, user_name) > realm = uc.get_realm().lower() > alt_sec = "Kerberos:%s@%s" % (alt_name, realm) >- self.add_attribute(dn, "altSecurityIdentities", alt_sec) >+ self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > ename = alt_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, machine_account=True) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >index 32c9e3cce6b..c7857a6cf0e 100755 >--- a/python/samba/tests/krb5/test_ccache.py >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -49,11 +49,14 @@ class CcacheTests(KDCBaseTest): > mach_name = "ccachemac" > service = "host" > >+ samdb = self.get_samdb() >+ > # Create the user account. >- (user_credentials, _) = self.create_account(user_name) >+ (user_credentials, _) = self.create_account(samdb, user_name) > > # Create the machine account. >- (mach_credentials, _) = self.create_account(mach_name, >+ (mach_credentials, _) = self.create_account(samdb, >+ mach_name, > machine_account=True, > spn="%s/%s" % (service, > mach_name)) >@@ -77,7 +80,7 @@ class CcacheTests(KDCBaseTest): > gensec_client.want_feature(gensec.FEATURE_SEAL) > gensec_client.start_mech_by_sasl_name("GSSAPI") > >- auth_context = AuthContext(lp_ctx=self.lp, ldb=self.ldb, methods=[]) >+ auth_context = AuthContext(lp_ctx=self.lp, ldb=samdb, methods=[]) > > gensec_server = gensec.Security.start_server(settings, auth_context) > gensec_server.set_credentials(mach_credentials) >@@ -104,9 +107,9 @@ class CcacheTests(KDCBaseTest): > # token is the SID of the user we created. > > # Retrieve the user account's SID. >- ldb_res = self.ldb.search(scope=SCOPE_SUBTREE, >- expression="(sAMAccountName=%s)" % user_name, >- attrs=["objectSid"]) >+ ldb_res = samdb.search(scope=SCOPE_SUBTREE, >+ expression="(sAMAccountName=%s)" % user_name, >+ attrs=["objectSid"]) > self.assertEqual(1, len(ldb_res)) > sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) > >diff --git a/python/samba/tests/krb5/test_ldap.py b/python/samba/tests/krb5/test_ldap.py >index 6a4bf52d77f..7e9405a8a92 100755 >--- a/python/samba/tests/krb5/test_ldap.py >+++ b/python/samba/tests/krb5/test_ldap.py >@@ -44,12 +44,14 @@ class LdapTests(KDCBaseTest): > # credentials cache file where the service ticket authenticating the > # user are stored. > >+ samdb = self.get_samdb() >+ > user_name = "ldapusr" >- mach_name = self.dns_host_name >+ mach_name = samdb.host_dns_name() > service = "ldap" > > # Create the user account. >- (user_credentials, _) = self.create_account(user_name) >+ (user_credentials, _) = self.create_account(samdb, user_name) > > # Talk to the KDC to obtain the service ticket, which gets placed into > # the cache. The machine account name has to match the name in the >@@ -63,9 +65,9 @@ class LdapTests(KDCBaseTest): > # cached credentials. > > # Retrieve the user account's SID. >- ldb_res = self.ldb.search(scope=SCOPE_SUBTREE, >- expression="(sAMAccountName=%s)" % user_name, >- attrs=["objectSid"]) >+ ldb_res = samdb.search(scope=SCOPE_SUBTREE, >+ expression="(sAMAccountName=%s)" % user_name, >+ attrs=["objectSid"]) > self.assertEqual(1, len(ldb_res)) > sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) > >diff --git a/python/samba/tests/krb5/test_rpc.py b/python/samba/tests/krb5/test_rpc.py >index da1c4eb88ac..c474e479d81 100755 >--- a/python/samba/tests/krb5/test_rpc.py >+++ b/python/samba/tests/krb5/test_rpc.py >@@ -41,12 +41,14 @@ class RpcTests(KDCBaseTest): > # credentials cache file where the service ticket authenticating the > # user are stored. > >+ samdb = self.get_samdb() >+ > user_name = "rpcusr" >- mach_name = self.dns_host_name >+ mach_name = samdb.host_dns_name() > service = "cifs" > > # Create the user account. >- (user_credentials, _) = self.create_account(user_name) >+ (user_credentials, _) = self.create_account(samdb, user_name) > > # Talk to the KDC to obtain the service ticket, which gets placed into > # the cache. The machine account name has to match the name in the >diff --git a/python/samba/tests/krb5/test_smb.py b/python/samba/tests/krb5/test_smb.py >index 0262a37ebb5..8f76e78afe3 100755 >--- a/python/samba/tests/krb5/test_smb.py >+++ b/python/samba/tests/krb5/test_smb.py >@@ -45,13 +45,15 @@ class SmbTests(KDCBaseTest): > # credentials cache file where the service ticket authenticating the > # user are stored. > >+ samdb = self.get_samdb() >+ > user_name = "smbusr" >- mach_name = self.dns_host_name >+ mach_name = samdb.host_dns_name() > service = "cifs" > share = "tmp" > > # Create the user account. >- (user_credentials, _) = self.create_account(user_name) >+ (user_credentials, _) = self.create_account(samdb, user_name) > > # Talk to the KDC to obtain the service ticket, which gets placed into > # the cache. The machine account name has to match the name in the >@@ -72,9 +74,9 @@ class SmbTests(KDCBaseTest): > # cached credentials. > > # Retrieve the user account's SID. >- ldb_res = self.ldb.search(scope=SCOPE_SUBTREE, >- expression="(sAMAccountName=%s)" % user_name, >- attrs=["objectSid"]) >+ ldb_res = samdb.search(scope=SCOPE_SUBTREE, >+ expression="(sAMAccountName=%s)" % user_name, >+ attrs=["objectSid"]) > self.assertEqual(1, len(ldb_res)) > sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) > >-- >2.25.1 > > >From c1363e3a6838dd4453e7f68309ab93bdad98ec55 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 16 Jun 2021 11:31:26 +1200 >Subject: [PATCH 104/686] tests/krb5/kdc_base_test.py: Remove 'credentials' > class attribute > >Credentials for tests are now obtained using the get_user_creds() >method. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 364f1ce8d8221cb8926635fc864db782cee61cf9) >--- > python/samba/tests/krb5/kdc_base_test.py | 24 +++---------------- > .../ms_kile_client_principal_lookup_tests.py | 4 ++-- > 2 files changed, 5 insertions(+), 23 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index b191f905366..f3c6b37d29f 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -67,28 +67,8 @@ class KDCBaseTest(RawKerberosTest): > @classmethod > def setUpClass(cls): > cls.lp = cls.get_loadparm(cls) >- cls.username = os.environ["USERNAME"] >- cls.password = os.environ["PASSWORD"] > cls.host = os.environ["SERVER"] > >- c = Credentials() >- c.set_username(cls.username) >- c.set_password(cls.password) >- try: >- realm = os.environ["REALM"] >- c.set_realm(realm) >- except KeyError: >- pass >- try: >- domain = os.environ["DOMAIN"] >- c.set_domain(domain) >- except KeyError: >- pass >- >- c.guess() >- >- cls.credentials = c >- > cls._ldb = None > > # A set containing DNs of accounts created as part of testing. >@@ -111,10 +91,12 @@ class KDCBaseTest(RawKerberosTest): > > def get_samdb(self): > if self._ldb is None: >+ creds = self.get_user_creds() >+ > session = system_session() > type(self)._ldb = SamDB(url="ldap://%s" % self.host, > session_info=session, >- credentials=self.credentials, >+ credentials=creds, > lp=self.lp) > > return self._ldb >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index 63f67b09c4c..e9d251e72f6 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -211,7 +211,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > samdb = self.get_samdb() > user_name = "mskileusr" > upn_name = "mskileupn" >- upn = upn_name + "@" + self.credentials.get_realm().lower() >+ upn = upn_name + "@" + self.get_user_creds().get_realm().lower() > (uc, dn) = self.create_account(samdb, user_name, upn=upn) > realm = uc.get_realm().lower() > >@@ -455,7 +455,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > samdb = self.get_samdb() > user_name = "mskileusr" > upn_name = "mskileupn" >- upn = upn_name + "@" + self.credentials.get_realm().lower() >+ upn = upn_name + "@" + self.get_user_creds().get_realm().lower() > (uc, dn) = self.create_account(samdb, user_name, upn=upn) > realm = uc.get_realm().lower() > >-- >2.25.1 > > >From 8806afe9851b4cafe3936d761126394f04ca3182 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 16 Jun 2021 11:40:41 +1200 >Subject: [PATCH 105/686] tests/krb5/kdc_base_test.py: Create loadparm only > when needed > >Now the .conf file is only loaded on its first use, which means that >SMB_CONF_PATH need not be defined for tests that don't make use of it. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 210e544016a3a4de1cdb76ce28a2148811ff07eb) >--- > python/samba/tests/krb5/kdc_base_test.py | 15 +++++++++++---- > python/samba/tests/krb5/test_ccache.py | 6 ++++-- > python/samba/tests/krb5/test_ldap.py | 2 +- > python/samba/tests/krb5/test_rpc.py | 2 +- > python/samba/tests/krb5/test_smb.py | 2 +- > 5 files changed, 18 insertions(+), 9 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index f3c6b37d29f..59ce546a181 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -66,7 +66,7 @@ class KDCBaseTest(RawKerberosTest): > > @classmethod > def setUpClass(cls): >- cls.lp = cls.get_loadparm(cls) >+ cls._lp = None > cls.host = os.environ["SERVER"] > > cls._ldb = None >@@ -89,15 +89,22 @@ class KDCBaseTest(RawKerberosTest): > self.do_asn1_print = global_asn1_print > self.do_hexdump = global_hexdump > >+ def get_lp(self): >+ if self._lp is None: >+ type(self)._lp = self.get_loadparm() >+ >+ return self._lp >+ > def get_samdb(self): > if self._ldb is None: > creds = self.get_user_creds() >+ lp = self.get_lp() > > session = system_session() > type(self)._ldb = SamDB(url="ldap://%s" % self.host, > session_info=session, > credentials=creds, >- lp=self.lp) >+ lp=lp) > > return self._ldb > >@@ -137,7 +144,7 @@ class KDCBaseTest(RawKerberosTest): > ldb.add(details) > > creds = Credentials() >- creds.guess(self.lp) >+ creds.guess(self.get_lp()) > creds.set_realm(ldb.domain_dns_name().upper()) > creds.set_domain(ldb.domain_netbios_name().upper()) > creds.set_password(password) >@@ -607,7 +614,7 @@ class KDCBaseTest(RawKerberosTest): > creds.set_kerberos_state(MUST_USE_KERBEROS) > creds.set_username(user_name, SPECIFIED) > creds.set_realm(realm) >- creds.set_named_ccache(cachefile.name, SPECIFIED, self.lp) >+ creds.set_named_ccache(cachefile.name, SPECIFIED, self.get_lp()) > > # Return the credentials along with the cache file. > return (creds, cachefile) >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >index c7857a6cf0e..feb7a7bd9be 100755 >--- a/python/samba/tests/krb5/test_ccache.py >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -71,8 +71,10 @@ class CcacheTests(KDCBaseTest): > # Authenticate in-process to the machine account using the user's > # cached credentials. > >+ lp = self.get_lp() >+ > settings = {} >- settings["lp_ctx"] = self.lp >+ settings["lp_ctx"] = lp > settings["target_hostname"] = mach_name > > gensec_client = gensec.Security.start_client(settings) >@@ -80,7 +82,7 @@ class CcacheTests(KDCBaseTest): > gensec_client.want_feature(gensec.FEATURE_SEAL) > gensec_client.start_mech_by_sasl_name("GSSAPI") > >- auth_context = AuthContext(lp_ctx=self.lp, ldb=samdb, methods=[]) >+ auth_context = AuthContext(lp_ctx=lp, ldb=samdb, methods=[]) > > gensec_server = gensec.Security.start_server(settings, auth_context) > gensec_server.set_credentials(mach_credentials) >diff --git a/python/samba/tests/krb5/test_ldap.py b/python/samba/tests/krb5/test_ldap.py >index 7e9405a8a92..d304fb9d71e 100755 >--- a/python/samba/tests/krb5/test_ldap.py >+++ b/python/samba/tests/krb5/test_ldap.py >@@ -74,7 +74,7 @@ class LdapTests(KDCBaseTest): > # Connect to the machine account and retrieve the user SID. > ldb_as_user = SamDB(url="ldap://%s" % mach_name, > credentials=creds, >- lp=self.lp) >+ lp=self.get_lp()) > ldb_res = ldb_as_user.search('', > scope=SCOPE_BASE, > attrs=["tokenGroups"]) >diff --git a/python/samba/tests/krb5/test_rpc.py b/python/samba/tests/krb5/test_rpc.py >index c474e479d81..324b57f2847 100755 >--- a/python/samba/tests/krb5/test_rpc.py >+++ b/python/samba/tests/krb5/test_rpc.py >@@ -62,7 +62,7 @@ class RpcTests(KDCBaseTest): > # cached credentials. > > binding_str = "ncacn_np:%s[\\pipe\\lsarpc]" % mach_name >- conn = lsa.lsarpc(binding_str, self.lp, creds) >+ conn = lsa.lsarpc(binding_str, self.get_lp(), creds) > > (account_name, _) = conn.GetUserName(None, None, None) > >diff --git a/python/samba/tests/krb5/test_smb.py b/python/samba/tests/krb5/test_smb.py >index 8f76e78afe3..45d4fe5e0c1 100755 >--- a/python/samba/tests/krb5/test_smb.py >+++ b/python/samba/tests/krb5/test_smb.py >@@ -82,7 +82,7 @@ class SmbTests(KDCBaseTest): > > # Connect to a share and retrieve the user SID. > s3_lp = s3param.get_context() >- s3_lp.load(self.lp.configfile) >+ s3_lp.load(self.get_lp().configfile) > > min_protocol = s3_lp.get("client min protocol") > self.addCleanup(s3_lp.set, "client min protocol", min_protocol) >-- >2.25.1 > > >From f1fb0f0676d62ad25d4f5701e580dd3a900242f9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 15:12:38 +1200 >Subject: [PATCH 106/686] tests/krb5/kdc_base_test.py: Add methods to determine > supported encryption types > >This is done based on the domain functional level, which corresponds to >the logic Samba uses to decide whether or not to generate a >Primary:Kerberos-Newer-Keys element for the supplementalCredentials >attribute. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 7d4a0ed21be49d13c2b815582f2d04f0c058bf3a) >--- > python/samba/tests/krb5/kdc_base_test.py | 38 ++++++++++++++++++++++-- > 1 file changed, 36 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 59ce546a181..e1b73dd8ff7 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -29,8 +29,13 @@ from ldb import SCOPE_BASE > from samba import generate_random_password > from samba.auth import system_session > from samba.credentials import Credentials, SPECIFIED, MUST_USE_KERBEROS >-from samba.dcerpc import krb5pac, krb5ccache >-from samba.dsdb import UF_WORKSTATION_TRUST_ACCOUNT, UF_NORMAL_ACCOUNT >+from samba.dcerpc import krb5pac, krb5ccache, security >+from samba.dsdb import ( >+ DS_DOMAIN_FUNCTION_2000, >+ DS_DOMAIN_FUNCTION_2008, >+ UF_WORKSTATION_TRUST_ACCOUNT, >+ UF_NORMAL_ACCOUNT >+) > from samba.ndr import ndr_pack, ndr_unpack > from samba.samdb import SamDB > >@@ -71,6 +76,8 @@ class KDCBaseTest(RawKerberosTest): > > cls._ldb = None > >+ cls._functional_level = None >+ > # A set containing DNs of accounts created as part of testing. > cls.accounts = set() > >@@ -108,6 +115,33 @@ class KDCBaseTest(RawKerberosTest): > > return self._ldb > >+ def get_domain_functional_level(self, ldb): >+ if self._functional_level is None: >+ res = ldb.search(base='', >+ scope=SCOPE_BASE, >+ attrs=['domainFunctionality']) >+ try: >+ functional_level = int(res[0]['domainFunctionality'][0]) >+ except KeyError: >+ functional_level = DS_DOMAIN_FUNCTION_2000 >+ >+ type(self)._functional_level = functional_level >+ >+ return self._functional_level >+ >+ def get_default_enctypes(self): >+ samdb = self.get_samdb() >+ functional_level = self.get_domain_functional_level(samdb) >+ >+ # RC4 should always be supported >+ default_enctypes = security.KERB_ENCTYPE_RC4_HMAC_MD5 >+ if functional_level >= DS_DOMAIN_FUNCTION_2008: >+ # AES is only supported at functional level 2008 or higher >+ default_enctypes |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 >+ default_enctypes |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 >+ >+ return default_enctypes >+ > def create_account(self, ldb, name, machine_account=False, > spn=None, upn=None): > '''Create an account for testing. >-- >2.25.1 > > >From 088441227b0fa9cbd199bee6b039a0f0e3ac53b6 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 13:15:10 +1200 >Subject: [PATCH 107/686] tests/krb5/raw_testcase.py: Add method to obtain > Kerberos keys over DRS > >This requires admin credentials, and removes the need to pass these keys >as environment variables. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 1f2ddd3c97e3ff243c8bd0c17299f27b761f5e7f) >--- > python/samba/tests/krb5/kdc_base_test.py | 100 ++++++++++++++++++++++- > 1 file changed, 99 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index e1b73dd8ff7..7ae22bc5929 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -20,6 +20,8 @@ import sys > import os > from datetime import datetime, timezone > import tempfile >+import binascii >+import struct > > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" >@@ -29,7 +31,8 @@ from ldb import SCOPE_BASE > from samba import generate_random_password > from samba.auth import system_session > from samba.credentials import Credentials, SPECIFIED, MUST_USE_KERBEROS >-from samba.dcerpc import krb5pac, krb5ccache, security >+from samba.dcerpc import drsblobs, drsuapi, misc, krb5pac, krb5ccache, security >+from samba.drs_utils import drsuapi_connect > from samba.dsdb import ( > DS_DOMAIN_FUNCTION_2000, > DS_DOMAIN_FUNCTION_2008, >@@ -37,6 +40,7 @@ from samba.dsdb import ( > UF_NORMAL_ACCOUNT > ) > from samba.ndr import ndr_pack, ndr_unpack >+from samba import net > from samba.samdb import SamDB > > from samba.tests import delete_force >@@ -191,6 +195,100 @@ class KDCBaseTest(RawKerberosTest): > > return (creds, dn) > >+ def get_keys(self, samdb, dn): >+ admin_creds = self.get_admin_creds() >+ >+ dns_hostname = samdb.host_dns_name() >+ (bind, handle, _) = drsuapi_connect(dns_hostname, >+ self.get_lp(), >+ admin_creds) >+ >+ destination_dsa_guid = misc.GUID(samdb.get_ntds_GUID()) >+ >+ req = drsuapi.DsGetNCChangesRequest8() >+ >+ req.destination_dsa_guid = destination_dsa_guid >+ req.source_dsa_invocation_id = misc.GUID() >+ >+ naming_context = drsuapi.DsReplicaObjectIdentifier() >+ naming_context.dn = str(dn) >+ >+ req.naming_context = naming_context >+ >+ hwm = drsuapi.DsReplicaHighWaterMark() >+ hwm.tmp_highest_usn = 0 >+ hwm.reserved_usn = 0 >+ hwm.highest_usn = 0 >+ >+ req.highwatermark = hwm >+ req.uptodateness_vector = None >+ >+ req.replica_flags = 0 >+ >+ req.max_object_count = 1 >+ req.max_ndr_size = 402116 >+ req.extended_op = drsuapi.DRSUAPI_EXOP_REPL_SECRET >+ >+ attids = [drsuapi.DRSUAPI_ATTID_supplementalCredentials, >+ drsuapi.DRSUAPI_ATTID_unicodePwd] >+ >+ partial_attribute_set = drsuapi.DsPartialAttributeSet() >+ partial_attribute_set.version = 1 >+ partial_attribute_set.attids = attids >+ partial_attribute_set.num_attids = len(attids) >+ >+ req.partial_attribute_set = partial_attribute_set >+ >+ req.partial_attribute_set_ex = None >+ req.mapping_ctr.num_mappings = 0 >+ req.mapping_ctr.mappings = None >+ >+ _, ctr = bind.DsGetNCChanges(handle, 8, req) >+ identifier = ctr.first_object.object.identifier >+ attributes = ctr.first_object.object.attribute_ctr.attributes >+ >+ rid = identifier.sid.split()[1] >+ >+ forced_keys = dict() >+ >+ net_ctx = net.Net(admin_creds) >+ >+ keys = {} >+ >+ for attr in attributes: >+ if attr.attid == drsuapi.DRSUAPI_ATTID_supplementalCredentials: >+ net_ctx.replicate_decrypt(bind, attr, rid) >+ attr_val = attr.value_ctr.values[0].blob >+ >+ spl = ndr_unpack(drsblobs.supplementalCredentialsBlob, >+ attr_val) >+ for pkg in spl.sub.packages: >+ if pkg.name == 'Primary:Kerberos-Newer-Keys': >+ krb5_new_keys_raw = binascii.a2b_hex(pkg.data) >+ krb5_new_keys = ndr_unpack( >+ drsblobs.package_PrimaryKerberosBlob, >+ krb5_new_keys_raw) >+ for key in krb5_new_keys.ctr.keys: >+ keytype = key.keytype >+ if keytype in (kcrypto.Enctype.AES256, >+ kcrypto.Enctype.AES128): >+ keys[keytype] = key.value.hex() >+ elif attr.attid == drsuapi.DRSUAPI_ATTID_unicodePwd: >+ net_ctx.replicate_decrypt(bind, attr, rid) >+ pwd = attr.value_ctr.values[0].blob >+ keys[kcrypto.Enctype.RC4] = pwd.hex() >+ >+ default_enctypes = self.get_default_enctypes() >+ >+ if default_enctypes & security.KERB_ENCTYPE_RC4_HMAC_MD5: >+ self.assertIn(kcrypto.Enctype.RC4, keys) >+ if default_enctypes & security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96: >+ self.assertIn(kcrypto.Enctype.AES256, keys) >+ if default_enctypes & security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96: >+ self.assertIn(kcrypto.Enctype.AES128, keys) >+ >+ return keys >+ > def as_req(self, cname, sname, realm, etypes, padata=None): > '''Send a Kerberos AS_REQ, returns the undecoded response > ''' >-- >2.25.1 > > >From cc18a3819bc74120c0243e5cf84af169d9a69c0d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 15:59:11 +1200 >Subject: [PATCH 108/686] tests/krb5/raw_testcase.py: Make env_get_var() a > standalone method > >This allows it to be used elsewhere in the tests. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 948bbc9cecbfc1b33a338891d26a4a706864b9c6) >--- > python/samba/tests/krb5/raw_testcase.py | 80 +++++++++++++------------ > 1 file changed, 41 insertions(+), 39 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 7e41245f706..7d9f0cd94f9 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -424,6 +424,23 @@ class RawKerberosTest(TestCaseInTempDir): > sys.stderr.write("connected[%s]\n" % self.host) > return > >+ def env_get_var(self, varname, prefix, >+ fallback_default=True, >+ allow_missing=False): >+ val = None >+ if prefix is not None: >+ allow_missing_prefix = allow_missing >+ if fallback_default: >+ allow_missing_prefix = True >+ val = samba.tests.env_get_var_value('%s_%s' % (prefix, varname), >+ allow_missing=allow_missing_prefix) >+ else: >+ fallback_default = True >+ if val is None and fallback_default: >+ val = samba.tests.env_get_var_value(varname, >+ allow_missing=allow_missing) >+ return val >+ > def _get_krb5_creds(self, prefix, > default_username=None, > allow_missing_password=False, >@@ -431,49 +448,34 @@ class RawKerberosTest(TestCaseInTempDir): > c = KerberosCredentials() > c.guess() > >- def env_get_var(varname, prefix, fallback_default=True, allow_missing=False): >- val = None >- if prefix is not None: >- allow_missing_prefix = allow_missing >- if fallback_default: >- allow_missing_prefix = True >- val = samba.tests.env_get_var_value('%s_%s' % (prefix, varname), >- allow_missing=allow_missing_prefix) >- else: >- fallback_default = True >- if val is None and fallback_default: >- val = samba.tests.env_get_var_value(varname, >- allow_missing=allow_missing) >- return val >- >- domain = env_get_var('DOMAIN', prefix) >- realm = env_get_var('REALM', prefix) >+ domain = self.env_get_var('DOMAIN', prefix) >+ realm = self.env_get_var('REALM', prefix) > allow_missing_username = False > if default_username is not None: > allow_missing_username = True >- username = env_get_var('USERNAME', prefix, >- fallback_default=False, >- allow_missing=allow_missing_username) >+ username = self.env_get_var('USERNAME', prefix, >+ fallback_default=False, >+ allow_missing=allow_missing_username) > if username is None: > username = default_username >- password = env_get_var('PASSWORD', prefix, >- fallback_default=False, >- allow_missing=allow_missing_password) >+ password = self.env_get_var('PASSWORD', prefix, >+ fallback_default=False, >+ allow_missing=allow_missing_password) > c.set_domain(domain) > c.set_realm(realm) > c.set_username(username) > if password is not None: > c.set_password(password) >- as_supported_enctypes = env_get_var('AS_SUPPORTED_ENCTYPES', >- prefix, allow_missing=True) >+ as_supported_enctypes = self.env_get_var('AS_SUPPORTED_ENCTYPES', >+ prefix, allow_missing=True) > if as_supported_enctypes is not None: > c.set_as_supported_enctypes(as_supported_enctypes) >- tgs_supported_enctypes = env_get_var('TGS_SUPPORTED_ENCTYPES', >- prefix, allow_missing=True) >+ tgs_supported_enctypes = self.env_get_var('TGS_SUPPORTED_ENCTYPES', >+ prefix, allow_missing=True) > if tgs_supported_enctypes is not None: > c.set_tgs_supported_enctypes(tgs_supported_enctypes) >- ap_supported_enctypes = env_get_var('AP_SUPPORTED_ENCTYPES', >- prefix, allow_missing=True) >+ ap_supported_enctypes = self.env_get_var('AP_SUPPORTED_ENCTYPES', >+ prefix, allow_missing=True) > if ap_supported_enctypes is not None: > c.set_ap_supported_enctypes(ap_supported_enctypes) > >@@ -486,22 +488,22 @@ class RawKerberosTest(TestCaseInTempDir): > else: > kvno_allow_missing = True > aes256_allow_missing = True >- kvno = env_get_var('KVNO', prefix, >- fallback_default=False, >- allow_missing=kvno_allow_missing) >+ kvno = self.env_get_var('KVNO', prefix, >+ fallback_default=False, >+ allow_missing=kvno_allow_missing) > if kvno is not None: > c.set_kvno(kvno) >- aes256_key = env_get_var('AES256_KEY_HEX', prefix, >- fallback_default=False, >- allow_missing=aes256_allow_missing) >+ aes256_key = self.env_get_var('AES256_KEY_HEX', prefix, >+ fallback_default=False, >+ allow_missing=aes256_allow_missing) > if aes256_key is not None: > c.set_forced_key(kcrypto.Enctype.AES256, aes256_key) >- aes128_key = env_get_var('AES128_KEY_HEX', prefix, >- fallback_default=False, allow_missing=True) >+ aes128_key = self.env_get_var('AES128_KEY_HEX', prefix, >+ fallback_default=False, allow_missing=True) > if aes128_key is not None: > c.set_forced_key(kcrypto.Enctype.AES128, aes128_key) >- rc4_key = env_get_var('RC4_KEY_HEX', prefix, >- fallback_default=False, allow_missing=True) >+ rc4_key = self.env_get_var('RC4_KEY_HEX', prefix, >+ fallback_default=False, allow_missing=True) > if rc4_key is not None: > c.set_forced_key(kcrypto.Enctype.RC4, rc4_key) > return c >-- >2.25.1 > > >From df675c647dba61b1b48bdfdf008ca3cc2cfd207b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 16:55:02 +1200 >Subject: [PATCH 109/686] tests/krb5/raw_testcase.py: Add allow_missing_keys > parameter for getting creds > >This allows us to require encryption keys in the case that a password >would not be required, such as for the krbtgt account. > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 6a77c2b93315503008627ce786388f281bd6bb87) >--- > python/samba/tests/krb5/as_req_tests.py | 2 +- > python/samba/tests/krb5/raw_testcase.py | 53 +++++++++++++++++++------ > python/samba/tests/krb5/simple_tests.py | 2 +- > 3 files changed, 42 insertions(+), 15 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 3ad37c6bdf2..3099c224c18 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -58,7 +58,7 @@ class AsReqKerberosTests(RawKerberosTest): > client_creds = self.get_client_creds() > client_account = client_creds.get_username() > client_as_etypes = client_creds.get_as_krb5_etypes() >- krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_creds = self.get_krbtgt_creds(require_keys=False) > krbtgt_account = krbtgt_creds.get_username() > realm = krbtgt_creds.get_realm() > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 7d9f0cd94f9..9c0f5800b42 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -444,6 +444,7 @@ class RawKerberosTest(TestCaseInTempDir): > def _get_krb5_creds(self, prefix, > default_username=None, > allow_missing_password=False, >+ allow_missing_keys=True, > require_strongest_key=False): > c = KerberosCredentials() > c.guess() >@@ -486,8 +487,8 @@ class RawKerberosTest(TestCaseInTempDir): > else: > aes256_allow_missing = True > else: >- kvno_allow_missing = True >- aes256_allow_missing = True >+ kvno_allow_missing = allow_missing_keys >+ aes256_allow_missing = allow_missing_keys > kvno = self.env_get_var('KVNO', prefix, > fallback_default=False, > allow_missing=kvno_allow_missing) >@@ -506,37 +507,63 @@ class RawKerberosTest(TestCaseInTempDir): > fallback_default=False, allow_missing=True) > if rc4_key is not None: > c.set_forced_key(kcrypto.Enctype.RC4, rc4_key) >+ >+ if not allow_missing_keys: >+ self.assertTrue(c.forced_keys, >+ 'Please supply %s encryption keys ' >+ 'in environment' % prefix) >+ > return c > >- def get_user_creds(self, allow_missing_password=False): >+ def get_user_creds(self, >+ allow_missing_password=False, >+ allow_missing_keys=True): > c = self._get_krb5_creds(prefix=None, >- allow_missing_password=allow_missing_password) >+ allow_missing_password=allow_missing_password, >+ allow_missing_keys=allow_missing_keys) > return c > >- def get_service_creds(self, allow_missing_password=False): >+ def get_service_creds(self, >+ allow_missing_password=False, >+ allow_missing_keys=True): > c = self._get_krb5_creds(prefix='SERVICE', >- allow_missing_password=allow_missing_password) >+ allow_missing_password=allow_missing_password, >+ allow_missing_keys=allow_missing_keys) > return c > >- def get_client_creds(self, allow_missing_password=False): >+ def get_client_creds(self, >+ allow_missing_password=False, >+ allow_missing_keys=True): > c = self._get_krb5_creds(prefix='CLIENT', >- allow_missing_password=allow_missing_password) >+ allow_missing_password=allow_missing_password, >+ allow_missing_keys=allow_missing_keys) > return c > >- def get_server_creds(self, allow_missing_password=False): >+ def get_server_creds(self, >+ allow_missing_password=False, >+ allow_missing_keys=True): > c = self._get_krb5_creds(prefix='SERVER', >- allow_missing_password=allow_missing_password) >+ allow_missing_password=allow_missing_password, >+ allow_missing_keys=allow_missing_keys) > return c > >- def get_admin_creds(self, allow_missing_password=False): >+ def get_admin_creds(self, >+ allow_missing_password=False, >+ allow_missing_keys=True): > c = self._get_krb5_creds(prefix='ADMIN', >- allow_missing_password=allow_missing_password) >+ allow_missing_password=allow_missing_password, >+ allow_missing_keys=allow_missing_keys) > return c > >- def get_krbtgt_creds(self, require_strongest_key=False): >+ def get_krbtgt_creds(self, >+ require_keys=True, >+ require_strongest_key=False): >+ if require_strongest_key: >+ self.assertTrue(require_keys) > c = self._get_krb5_creds(prefix='KRBTGT', > default_username='krbtgt', > allow_missing_password=True, >+ allow_missing_keys=not require_keys, > require_strongest_key=require_strongest_key) > return c > >diff --git a/python/samba/tests/krb5/simple_tests.py b/python/samba/tests/krb5/simple_tests.py >index 2da76a3cf5e..9650702c6c6 100755 >--- a/python/samba/tests/krb5/simple_tests.py >+++ b/python/samba/tests/krb5/simple_tests.py >@@ -44,7 +44,7 @@ class SimpleKerberosTests(RawKerberosTest): > def test_simple(self): > user_creds = self.get_user_creds() > user = user_creds.get_username() >- krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_creds = self.get_krbtgt_creds(require_keys=False) > krbtgt_account = krbtgt_creds.get_username() > realm = krbtgt_creds.get_realm() > >-- >2.25.1 > > >From 1a43fb0aa5a7299b8ca0c2f6abc53463dc6bc3f4 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 17:10:44 +1200 >Subject: [PATCH 110/686] tests/krb5/raw_testcase.py: Cache obtained > credentials > >If credentials are used more than once, we can now use the credentials >that we already obtained and so avoid fetching them again. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 22a90aea82ba6ef86bde835f2369daa6e23ed2fd) >--- > python/samba/tests/krb5/kdc_base_test.py | 1 + > python/samba/tests/krb5/raw_testcase.py | 38 ++++++++++++++++++++---- > 2 files changed, 34 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 7ae22bc5929..120084616e9 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -75,6 +75,7 @@ class KDCBaseTest(RawKerberosTest): > > @classmethod > def setUpClass(cls): >+ super().setUpClass() > cls._lp = None > cls.host = os.environ["SERVER"] > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 9c0f5800b42..5b59eede806 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -371,6 +371,14 @@ class RawKerberosTest(TestCaseInTempDir): > e = self.etype_test_permutations[idx] > return (e['name'], e['etypes']) > >+ @classmethod >+ def setUpClass(cls): >+ super().setUpClass() >+ >+ # A dictionary containing credentials that have already been >+ # obtained. >+ cls.creds_dict = {} >+ > def setUp(self): > super().setUp() > self.do_asn1_print = False >@@ -441,11 +449,11 @@ class RawKerberosTest(TestCaseInTempDir): > allow_missing=allow_missing) > return val > >- def _get_krb5_creds(self, prefix, >- default_username=None, >- allow_missing_password=False, >- allow_missing_keys=True, >- require_strongest_key=False): >+ def _get_krb5_creds_from_env(self, prefix, >+ default_username=None, >+ allow_missing_password=False, >+ allow_missing_keys=True, >+ require_strongest_key=False): > c = KerberosCredentials() > c.guess() > >@@ -515,6 +523,26 @@ class RawKerberosTest(TestCaseInTempDir): > > return c > >+ def _get_krb5_creds(self, >+ prefix, >+ default_username=None, >+ allow_missing_password=False, >+ allow_missing_keys=True, >+ require_strongest_key=False): >+ if prefix not in self.creds_dict: >+ # We don't have the credentials already >+ creds = self._get_krb5_creds_from_env(prefix, >+ default_username=default_username, >+ allow_missing_password=allow_missing_password, >+ allow_missing_keys=allow_missing_keys, >+ require_strongest_key=require_strongest_key) >+ self.assertIsNotNone(creds) >+ >+ # Save the obtained credentials >+ self.creds_dict[prefix] = creds >+ >+ return self.creds_dict[prefix] >+ > def get_user_creds(self, > allow_missing_password=False, > allow_missing_keys=True): >-- >2.25.1 > > >From 38cae29db7e20770281eda64dd2b35b6e6211686 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 17:12:39 +1200 >Subject: [PATCH 111/686] tests/krb5/raw_testcase.py: Allow specifying a > fallback credentials function > >This allows us to use other methods of obtaining credentials if getting >them from the environment fails. > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit e1601f2b56f09a944c5cfb119502fdcf49a03c99) >--- > python/samba/tests/krb5/raw_testcase.py | 39 +++++++++++++++++++++---- > 1 file changed, 33 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 5b59eede806..ade980cb46d 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -528,20 +528,47 @@ class RawKerberosTest(TestCaseInTempDir): > default_username=None, > allow_missing_password=False, > allow_missing_keys=True, >- require_strongest_key=False): >- if prefix not in self.creds_dict: >- # We don't have the credentials already >+ require_strongest_key=False, >+ fallback_creds_fn=None): >+ if prefix in self.creds_dict: >+ return self.creds_dict[prefix] >+ >+ # We don't have the credentials already >+ creds = None >+ env_err = None >+ try: >+ # Try to obtain them from the environment > creds = self._get_krb5_creds_from_env(prefix, > default_username=default_username, > allow_missing_password=allow_missing_password, > allow_missing_keys=allow_missing_keys, > require_strongest_key=require_strongest_key) >+ except Exception as err: >+ # An error occurred, so save it for later >+ env_err = err >+ else: > self.assertIsNotNone(creds) >- > # Save the obtained credentials > self.creds_dict[prefix] = creds >- >- return self.creds_dict[prefix] >+ return creds >+ >+ if fallback_creds_fn is not None: >+ try: >+ # Try to use the fallback method >+ creds = fallback_creds_fn() >+ except Exception as err: >+ print("ERROR FROM ENV: %r" % (env_err)) >+ print("FALLBACK-FN: %s" % (fallback_creds_fn)) >+ print("FALLBACK-ERROR: %r" % (err)) >+ else: >+ self.assertIsNotNone(creds) >+ # Save the obtained credentials >+ self.creds_dict[prefix] = creds >+ return creds >+ >+ # Both methods failed, so raise the exception from the >+ # environment method >+ raise env_err > > def get_user_creds(self, > allow_missing_password=False, >-- >2.25.1 > > >From 96f8ec0c1de1e5985b6aa2cb9545a47621bac6db Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 15:55:17 +1200 >Subject: [PATCH 112/686] tests/krb5/raw_testcase.py: Simplify conditionals > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit ec5c2b040b63d06a17bcd7bd133c2d68d07df587) >--- > python/samba/tests/krb5/raw_testcase.py | 8 ++------ > 1 file changed, 2 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index ade980cb46d..0e08f0ef7d2 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -437,9 +437,7 @@ class RawKerberosTest(TestCaseInTempDir): > allow_missing=False): > val = None > if prefix is not None: >- allow_missing_prefix = allow_missing >- if fallback_default: >- allow_missing_prefix = True >+ allow_missing_prefix = allow_missing or fallback_default > val = samba.tests.env_get_var_value('%s_%s' % (prefix, varname), > allow_missing=allow_missing_prefix) > else: >@@ -459,9 +457,7 @@ class RawKerberosTest(TestCaseInTempDir): > > domain = self.env_get_var('DOMAIN', prefix) > realm = self.env_get_var('REALM', prefix) >- allow_missing_username = False >- if default_username is not None: >- allow_missing_username = True >+ allow_missing_username = default_username is not None > username = self.env_get_var('USERNAME', prefix, > fallback_default=False, > allow_missing=allow_missing_username) >-- >2.25.1 > > >From 23a9bfff5650b8766e520d81d867c7db4371b2ea Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 16:07:16 +1200 >Subject: [PATCH 113/686] tests/krb5/kdc_base_test.py: Add fallback methods to > obtain client and krbtgt credentials > >Now if the client credentials are not supplied in the environment, we >can fall back to creating a new user account. Similarly, if the krbtgt >credentials are not supplied, we can fetch the credentials of the >existing krbtgt account. > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit fd45bea7a88837cbe4f99adf3a6b3f69ce32f34c) >--- > python/samba/tests/krb5/kdc_base_test.py | 86 +++++++++++++++++++++++- > 1 file changed, 84 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 120084616e9..1f042aa78aa 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -44,7 +44,8 @@ from samba import net > from samba.samdb import SamDB > > from samba.tests import delete_force >-from samba.tests.krb5.raw_testcase import RawKerberosTest >+import samba.tests.krb5.kcrypto as kcrypto >+from samba.tests.krb5.raw_testcase import KerberosCredentials, RawKerberosTest > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > AD_IF_RELEVANT, >@@ -182,7 +183,7 @@ class KDCBaseTest(RawKerberosTest): > details["userPrincipalName"] = upn > ldb.add(details) > >- creds = Credentials() >+ creds = KerberosCredentials() > creds.guess(self.get_lp()) > creds.set_realm(ldb.domain_dns_name().upper()) > creds.set_domain(ldb.domain_netbios_name().upper()) >@@ -290,6 +291,87 @@ class KDCBaseTest(RawKerberosTest): > > return keys > >+ def creds_set_keys(self, creds, keys): >+ if keys is not None: >+ for enctype, key in keys.items(): >+ creds.set_forced_key(enctype, key) >+ >+ supported_enctypes = 0 >+ if kcrypto.Enctype.AES256 in keys: >+ supported_enctypes |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 >+ if kcrypto.Enctype.AES128 in keys: >+ supported_enctypes |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 >+ if kcrypto.Enctype.RC4 in keys: >+ supported_enctypes |= security.KERB_ENCTYPE_RC4_HMAC_MD5 >+ >+ creds.set_as_supported_enctypes(supported_enctypes) >+ creds.set_tgs_supported_enctypes(supported_enctypes) >+ creds.set_ap_supported_enctypes(supported_enctypes) >+ >+ def get_client_creds(self, >+ allow_missing_password=False, >+ allow_missing_keys=True): >+ def create_client_account(): >+ samdb = self.get_samdb() >+ >+ creds, dn = self.create_account(samdb, 'kdctestclient') >+ >+ res = samdb.search(base=dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KeyVersionNumber']) >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ creds.set_kvno(kvno) >+ >+ keys = self.get_keys(samdb, dn) >+ self.creds_set_keys(creds, keys) >+ >+ return creds >+ >+ c = self._get_krb5_creds(prefix='CLIENT', >+ allow_missing_password=allow_missing_password, >+ allow_missing_keys=allow_missing_keys, >+ fallback_creds_fn=create_client_account) >+ return c >+ >+ def get_krbtgt_creds(self, >+ require_keys=True, >+ require_strongest_key=False): >+ if require_strongest_key: >+ self.assertTrue(require_keys) >+ def download_krbtgt_creds(): >+ samdb = self.get_samdb() >+ >+ krbtgt_rid = 502 >+ krbtgt_sid = '%s-%d' % (samdb.get_domain_sid(), krbtgt_rid) >+ >+ res = samdb.search(base='<SID=%s>' % krbtgt_sid, >+ scope=ldb.SCOPE_BASE, >+ attrs=['sAMAccountName', >+ 'msDS-KeyVersionNumber']) >+ dn = res[0].dn >+ username = str(res[0]['sAMAccountName']) >+ >+ creds = KerberosCredentials() >+ creds.set_domain(self.env_get_var('DOMAIN', 'KRBTGT')) >+ creds.set_realm(self.env_get_var('REALM', 'KRBTGT')) >+ creds.set_username(username) >+ >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ creds.set_kvno(kvno) >+ >+ keys = self.get_keys(samdb, dn) >+ self.creds_set_keys(creds, keys) >+ >+ return creds >+ >+ c = self._get_krb5_creds(prefix='KRBTGT', >+ default_username='krbtgt', >+ allow_missing_password=True, >+ allow_missing_keys=not require_keys, >+ require_strongest_key=require_strongest_key, >+ fallback_creds_fn=download_krbtgt_creds) >+ return c >+ > def as_req(self, cname, sname, realm, etypes, padata=None): > '''Send a Kerberos AS_REQ, returns the undecoded response > ''' >-- >2.25.1 > > >From 80d0a31c2ec0f14b5e11c128924aad7601d2090e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 16 Jun 2021 14:51:22 +1200 >Subject: [PATCH 114/686] tests/krb5/as_req_tests.py: Automatically obtain > credentials > >The credentials for the client and krbtgt accounts are now fetched >automatically rather than using environment variables, and the client >account is now automatically created. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 0fd71ed3c37c8cf326f9f676b7fddda3d2d24072) > >[jsutton@samba.org Fixed conflict from > 0dbb923881a66b1e6b499b5b59103aea58ae0be6 not being applied] >--- > python/samba/tests/krb5/as_req_tests.py | 4 +- > .../knownfail.d/samba.tests.krb5.as_req_tests | 180 ------------------ > selftest/knownfail_mit_kdc | 42 ---- > selftest/selftest.pl | 1 - > selftest/target/Samba4.pm | 4 - > source4/selftest/tests.py | 7 +- > 6 files changed, 4 insertions(+), 234 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 3099c224c18..e8c2a29221d 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -23,7 +23,7 @@ sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > > from samba.tests import DynamicTestCase >-from samba.tests.krb5.raw_testcase import RawKerberosTest >+from samba.tests.krb5.kdc_base_test import KDCBaseTest > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_PREAUTH_REQUIRED, >@@ -35,7 +35,7 @@ global_asn1_print = False > global_hexdump = False > > @DynamicTestCase >-class AsReqKerberosTests(RawKerberosTest): >+class AsReqKerberosTests(KDCBaseTest): > > @classmethod > def setUpDynamicTestCases(cls): >diff --git a/selftest/knownfail.d/samba.tests.krb5.as_req_tests b/selftest/knownfail.d/samba.tests.krb5.as_req_tests >index 390d6cd0ab6..f395bdc553b 100644 >--- a/selftest/knownfail.d/samba.tests.krb5.as_req_tests >+++ b/selftest/knownfail.d/samba.tests.krb5.as_req_tests >@@ -94,183 +94,3 @@ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2003dc >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index b610929a8dd..776148314d1 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -294,11 +294,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > # MIT currently fails some as_req_no_preauth tests. > # > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_False > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_False.fl2003dc >@@ -306,11 +303,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_False.fl2008r2dc >@@ -324,11 +318,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_False.fl2008r2dc >@@ -336,11 +327,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_False.fl2008r2dc >@@ -354,11 +342,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_False.fl2003dc >@@ -391,11 +376,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_False.fl2008r2dc >@@ -403,11 +385,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_False.fl2003dc >@@ -422,11 +401,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_False.fl2008r2dc >@@ -434,11 +410,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_False.fl2008r2dc >@@ -452,11 +425,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_False.fl2008r2dc >@@ -488,11 +458,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_False.fl2008r2dc >@@ -500,11 +467,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_False.fl2008r2dc >@@ -518,11 +482,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_False.fl2008r2dc >@@ -530,11 +491,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_None.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_False.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_False.fl2008r2dc >diff --git a/selftest/selftest.pl b/selftest/selftest.pl >index 2fe7fb27d05..f2968139cfd 100755 >--- a/selftest/selftest.pl >+++ b/selftest/selftest.pl >@@ -821,7 +821,6 @@ my @exported_envvars = ( > "DNSNAME", > "REALM", > "DOMSID", >- "SUPPORTED_ENCTYPE_BITS", > > # stuff related to a trusted domain > "TRUST_SERVER", >diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm >index 02b43e2821c..ae84a3ca89a 100755 >--- a/selftest/target/Samba4.pm >+++ b/selftest/target/Samba4.pm >@@ -582,9 +582,6 @@ sub provision_raw_prepare($$$$$$$$$$$$) > $ctx->{krb5_ccname} = "$prefix_abs/krb5cc_%{uid}"; > if ($functional_level eq "2000") { > $ctx->{supported_enctypes} = "arcfour-hmac-md5 des-cbc-md5 des-cbc-crc"; >- $ctx->{supported_enctypes_bits} = "4"; >- } else { >- $ctx->{supported_enctypes_bits} = "28"; > } > > # >@@ -881,7 +878,6 @@ nogroup:x:65534:nobody > KRB5_CONFIG => $ctx->{krb5_conf}, > KRB5_CCACHE => $ctx->{krb5_ccache}, > MITKDC_CONFIG => $ctx->{mitkdc_conf}, >- SUPPORTED_ENCTYPE_BITS => $ctx->{supported_enctypes_bits}, > PIDDIR => $ctx->{piddir}, > SERVER => $ctx->{hostname}, > SERVER_IP => $ctx->{ipv4}, >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index b6ec53904a6..6873746f389 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1220,11 +1220,8 @@ plansmbtorture4testsuite('krb5.kdc', env, ['ncacn_np:$SERVER_IP', "-k", "yes", ' > for env in ["fl2008r2dc", "fl2003dc"]: > planoldpythontestsuite(env, "samba.tests.krb5.as_req_tests", > environ={ >- 'CLIENT_USERNAME': '$USERNAME', >- 'CLIENT_PASSWORD': '$PASSWORD', >- 'CLIENT_AS_SUPPORTED_ENCTYPES': '$SUPPORTED_ENCTYPE_BITS', >- 'SERVER_USERNAME': '$SERVER', >- 'SERVER_PASSWORD': 'machine$PASSWORD', >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > }) > >-- >2.25.1 > > >From f1a6c62828f924c81efc960129a33312f5033568 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 21 Apr 2020 11:07:45 +0200 >Subject: [PATCH 115/686] tests/krb5/as_req_tests.py: add simple > test_as_req_enc_timestamp test > >Example commands: > >Windows 2012R2: >SERVER=172.31.9.188 SMB_CONF_PATH=/dev/null STRICT_CHECKING=1 DOMAIN=W2012R2-L6 REALM=W2012R2-L6.BASE CLIENT_USERNAME=ldaptestuser CLIENT_PASSWORD=a1B2c3D4 CLIENT_AS_SUPPORTED_ENCTYPES=28 KRBTGT_KVNO=2 KRBTGT_AES256_KEY_HEX=2eb6d146a2653d333cdbfb641a4efbc3de81af49e878e112bb4f6cbdd73fca52 KRBTGT_RC4_KEY_HEX=4e6d99c30e5fab901ea71f8894289d3b python/samba/tests/krb5/as_req_tests.py AsReqKerberosTests >SERVER=172.31.9.188 SMB_CONF_PATH=/dev/null STRICT_CHECKING=1 DOMAIN=W2012R2-L6 REALM=W2012R2-L6.BASE CLIENT_USERNAME=administrator CLIENT_PASSWORD=A1b2C3d4 CLIENT_AS_SUPPORTED_ENCTYPES=4 KRBTGT_KVNO=2 KRBTGT_AES256_KEY_HEX=2eb6d146a2653d333cdbfb641a4efbc3de81af49e878e112bb4f6cbdd73fca52 KRBTGT_RC4_KEY_HEX=4e6d99c30e5fab901ea71f8894289d3b python/samba/tests/krb5/as_req_tests.py AsReqKerberosTests >SERVER=172.31.9.188 SMB_CONF_PATH=/dev/null STRICT_CHECKING=1 DOMAIN=W2012R2-L6 REALM=W2012R2-L6.BASE ADMIN_USERNAME=administrator ADMIN_PASSWORD=A1b2C3d4 python/samba/tests/krb5/as_req_tests.py >SERVER=172.31.9.188 SMB_CONF_PATH=/dev/null STRICT_CHECKING=1 DOMAIN=W2012R2-L6 REALM=W2012R2-L6.BASE ADMIN_USERNAME=administrator ADMIN_PASSWORD=A1b2C3d4 CLIENT_USERNAME=administrator CLIENT_PASSWORD=A1b2C3d4 CLIENT_AS_SUPPORTED_ENCTYPES=4 CLIENT_KVNO=1 python/samba/tests/krb5/as_req_tests.py >SERVER=172.31.9.188 SMB_CONF_PATH=/dev/null STRICT_CHECKING=1 DOMAIN=W2012R2-L6 REALM=W2012R2-L6.BASE ADMIN_USERNAME=administrator ADMIN_PASSWORD=A1b2C3d4 CLIENT_USERNAME=ldaptestuser CLIENT_PASSWORD=a1B2c3D4 CLIENT_AS_SUPPORTED_ENCTYPES=28 CLIENT_KVNO=4 python/samba/tests/krb5/as_req_tests.py > >Windows 2008R2: >SERVER=172.31.9.133 SMB_CONF_PATH=/dev/null STRICT_CHECKING=1 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE CLIENT_USERNAME=cifsmount CLIENT_PASSWORD=A1b2C3d4-08 CLIENT_AS_SUPPORTED_ENCTYPES=28 CLIENT_KVNO=17 KRBTGT_KVNO=2 KRBTGT_AES256_KEY_HEX=550aea2ea2719cb81c87692569796d1b3a099d433a93438f53bee798cc2f83be KRBTGT_RC4_KEY_HEX=dbc0d1feaaca3d5abc6794857b7f6fe0 python/samba/tests/krb5/as_req_tests.py >SERVER=172.31.9.133 SMB_CONF_PATH=/dev/null STRICT_CHECKING=1 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE CLIENT_USERNAME=administrator CLIENT_PASSWORD=A1b2C3d4 CLIENT_AS_SUPPORTED_ENCTYPES=4 CLIENT_KVNO=1 KRBTGT_KVNO=2 KRBTGT_AES256_KEY_HEX=550aea2ea2719cb81c87692569796d1b3a099d433a93438f53bee798cc2f83be KRBTGT_RC4_KEY_HEX=dbc0d1feaaca3d5abc6794857b7f6fe0 python/samba/tests/krb5/as_req_tests.py >SERVER=172.31.9.133 SMB_CONF_PATH=/dev/null STRICT_CHECKING=1 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE ADMIN_USERNAME=administrator ADMIN_PASSWORD=A1b2C3d4 CLIENT_USERNAME=administrator CLIENT_PASSWORD=A1b2C3d4 CLIENT_AS_SUPPORTED_ENCTYPES=4 CLIENT_KVNO=1 python/samba/tests/krb5/as_req_tests.py >SERVER=172.31.9.133 SMB_CONF_PATH=/dev/null STRICT_CHECKING=1 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE ADMIN_USERNAME=administrator ADMIN_PASSWORD=A1b2C3d4 CLIENT_USERNAME=cifsmount CLIENT_PASSWORD=A1b2C3d4-08 CLIENT_AS_SUPPORTED_ENCTYPES=28 CLIENT_KVNO=17 python/samba/tests/krb5/as_req_tests.py >SERVER=172.31.9.133 SMB_CONF_PATH=/dev/null STRICT_CHECKING=1 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE ADMIN_USERNAME=administrator ADMIN_PASSWORD=A1b2C3d4 python/samba/tests/krb5/as_req_tests.py > >Samba: >SERVER=172.31.9.163 SMB_CONF_PATH=/dev/null STRICT_CHECKING=0 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE CLIENT_USERNAME=cifsmount CLIENT_PASSWORD=A1b2C3d4-08 CLIENT_AS_SUPPORTED_ENCTYPES=28 CLIENT_KVNO=17 KRBTGT_KVNO=2 KRBTGT_AES256_KEY_HEX=550aea2ea2719cb81c87692569796d1b3a099d433a93438f53bee798cc2f83be KRBTGT_RC4_KEY_HEX=dbc0d1feaaca3d5abc6794857b7f6fe0 python/samba/tests/krb5/as_req_tests.py >SERVER=172.31.9.163 SMB_CONF_PATH=/dev/null STRICT_CHECKING=0 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE CLIENT_USERNAME=administrator CLIENT_PASSWORD=A1b2C3d4 CLIENT_AS_SUPPORTED_ENCTYPES=4 CLIENT_KVNO=1 KRBTGT_KVNO=2 KRBTGT_AES256_KEY_HEX=550aea2ea2719cb81c87692569796d1b3a099d433a93438f53bee798cc2f83be KRBTGT_RC4_KEY_HEX=dbc0d1feaaca3d5abc6794857b7f6fe0 python/samba/tests/krb5/as_req_tests.py >SERVER=172.31.9.163 SMB_CONF_PATH=/dev/null STRICT_CHECKING=0 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE ADMIN_USERNAME=administrator ADMIN_PASSWORD=A1b2C3d4 CLIENT_USERNAME=administrator CLIENT_PASSWORD=A1b2C3d4 CLIENT_AS_SUPPORTED_ENCTYPES=4 CLIENT_KVNO=1 python/samba/tests/krb5/as_req_tests.py >SERVER=172.31.9.163 SMB_CONF_PATH=/dev/null STRICT_CHECKING=0 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE ADMIN_USERNAME=administrator ADMIN_PASSWORD=A1b2C3d4 CLIENT_USERNAME=cifsmount CLIENT_PASSWORD=A1b2C3d4-08 CLIENT_AS_SUPPORTED_ENCTYPES=28 CLIENT_KVNO=17 python/samba/tests/krb5/as_req_tests.py >SERVER=172.31.9.163 SMB_CONF_PATH=/dev/null STRICT_CHECKING=0 DOMAIN=W4EDOM-L4 REALM=W4EDOM-L4.BASE ADMIN_USERNAME=administrator ADMIN_PASSWORD=A1b2C3d4 python/samba/tests/krb5/as_req_tests.py > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d5e350a4a490fecf570f1c248c9dde1466796166) >--- > python/samba/tests/krb5/as_req_tests.py | 85 ++++++++++++++++++++++++- > selftest/knownfail_mit_kdc | 5 ++ > 2 files changed, 89 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index e8c2a29221d..be33748dfb6 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -27,8 +27,10 @@ from samba.tests.krb5.kdc_base_test import KDCBaseTest > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_PREAUTH_REQUIRED, >+ KU_PA_ENC_TIMESTAMP, > NT_PRINCIPAL, >- NT_SRV_INST >+ NT_SRV_INST, >+ PADATA_ENC_TIMESTAMP > ) > > global_asn1_print = False >@@ -112,6 +114,87 @@ class AsReqKerberosTests(KDCBaseTest): > initial_etypes=etypes, > initial_kdc_options=krb5_asn1.KDCOptions('forwardable')) > >+ def test_as_req_enc_timestamp(self): >+ client_creds = self.get_client_creds() >+ client_account = client_creds.get_username() >+ client_as_etypes = client_creds.get_as_krb5_etypes() >+ krbtgt_creds = self.get_krbtgt_creds(require_strongest_key=True) >+ krbtgt_account = krbtgt_creds.get_username() >+ realm = krbtgt_creds.get_realm() >+ >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[client_account]) >+ sname = self.PrincipalName_create(name_type=NT_SRV_INST, >+ names=[krbtgt_account, realm]) >+ >+ expected_crealm = realm >+ expected_cname = cname >+ expected_srealm = realm >+ expected_sname = sname >+ expected_salt = client_creds.get_forced_salt() >+ >+ till = self.get_KerberosTime(offset=36000) >+ >+ pa_pac = self.KERB_PA_PAC_REQUEST_create(True) >+ initial_padata = [pa_pac] >+ initial_etypes = client_as_etypes >+ initial_kdc_options = krb5_asn1.KDCOptions('forwardable') >+ initial_error_mode = KDC_ERR_PREAUTH_REQUIRED >+ >+ etype_info2 = self._test_as_exchange(cname, >+ realm, >+ sname, >+ till, >+ client_as_etypes, >+ initial_error_mode, >+ expected_crealm, >+ expected_cname, >+ expected_srealm, >+ expected_sname, >+ expected_salt, >+ initial_etypes, >+ initial_padata, >+ initial_kdc_options) >+ self.assertIsNotNone(etype_info2) >+ >+ preauth_key = self.PasswordKey_from_etype_info2(client_creds, etype_info2[0], kvno=0) >+ >+ (patime, pausec) = self.get_KerberosTimeWithUsec() >+ pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) >+ >+ enc_pa_ts_usage = KU_PA_ENC_TIMESTAMP >+ pa_ts = self.EncryptedData_create(preauth_key, enc_pa_ts_usage, pa_ts) >+ pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData()) >+ >+ pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts) >+ >+ preauth_padata = [pa_ts, pa_pac] >+ preauth_etypes = client_as_etypes >+ preauth_kdc_options = krb5_asn1.KDCOptions('forwardable') >+ preauth_error_mode = 0 # AS-REP >+ >+ krbtgt_decryption_key = ( >+ self.TicketDecryptionKey_from_creds(krbtgt_creds)) >+ >+ as_rep = self._test_as_exchange(cname, >+ realm, >+ sname, >+ till, >+ client_as_etypes, >+ preauth_error_mode, >+ expected_crealm, >+ expected_cname, >+ expected_srealm, >+ expected_sname, >+ expected_salt, >+ preauth_etypes, >+ preauth_padata, >+ preauth_kdc_options, >+ preauth_key=preauth_key, >+ ticket_decryption_key=krbtgt_decryption_key) >+ self.assertIsNotNone(as_rep) >+ return > > if __name__ == "__main__": > global_asn1_print = True >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 776148314d1..db40b0614fa 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -291,6 +291,11 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c > # >+# MIT currently fails the test_as_req_enc_timestamp test. >+# >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_enc_timestamp.fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_enc_timestamp.fl2008r2dc >+# > # MIT currently fails some as_req_no_preauth tests. > # > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256.fl2008r2dc >-- >2.25.1 > > >From c3216735cf8ceef6221433442b8be8b8b4f1fdd6 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 13:24:22 +1200 >Subject: [PATCH 116/686] tests/krb5/as_req_tests.py: Check the client kvno > >Ensure we have the correct kvno for the client, rather than an 'unknown' >value. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d4c38678e0cc782965edfe40a0423fafb7d5a5ff) >--- > python/samba/tests/krb5/as_req_tests.py | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index be33748dfb6..10e7b603609 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -118,6 +118,7 @@ class AsReqKerberosTests(KDCBaseTest): > client_creds = self.get_client_creds() > client_account = client_creds.get_username() > client_as_etypes = client_creds.get_as_krb5_etypes() >+ client_kvno = client_creds.get_kvno() > krbtgt_creds = self.get_krbtgt_creds(require_strongest_key=True) > krbtgt_account = krbtgt_creds.get_username() > realm = krbtgt_creds.get_realm() >@@ -157,7 +158,9 @@ class AsReqKerberosTests(KDCBaseTest): > initial_kdc_options) > self.assertIsNotNone(etype_info2) > >- preauth_key = self.PasswordKey_from_etype_info2(client_creds, etype_info2[0], kvno=0) >+ preauth_key = self.PasswordKey_from_etype_info2(client_creds, >+ etype_info2[0], >+ kvno=client_kvno) > > (patime, pausec) = self.get_KerberosTimeWithUsec() > pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec) >-- >2.25.1 > > >From 7b70704352844859c2a6f0b35ddf243bf7bb97cc Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 15 Jun 2021 13:25:34 +1200 >Subject: [PATCH 117/686] tests/krb5/raw_testcase.py: Check for an explicit > 'unspecified kvno' value > >This is clearer than using the constant zero, which could be mistaken >for a valid kvno value. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 381223117e0bae4c348d538bffaa8227b18ef3d1) >--- > python/samba/tests/krb5/raw_testcase.py | 15 +++++++++------ > 1 file changed, 9 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 0e08f0ef7d2..b7044546cbd 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -393,6 +393,8 @@ class RawKerberosTest(TestCaseInTempDir): > > self.s = None > >+ self.unspecified_kvno = object() >+ > def tearDown(self): > self._disconnect("tearDown") > super().tearDown() >@@ -861,10 +863,11 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(v) > # The value on the wire should never be 0 > self.assertNotEqual(v, 0) >- # value == 0 means we don't know the kvno >- # but enforce at any value != 0 is present >- value = int(value) >- if value != 0: >+ # unspecified_kvno means we don't know the kvno, >+ # but want to enforce its presense >+ if value is not self.unspecified_kvno: >+ value = int(value) >+ self.assertNotEqual(value, 0) > self.assertEqual(v, value) > else: > self.assertIsNone(v) >@@ -1584,8 +1587,8 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_encpart = self.getElementValue(ticket, 'enc-part') > if ticket_encpart is not None: # Never None, but gives indentation > self.assertElementPresent(ticket_encpart, 'etype') >- # 0 means present, with any value != 0 >- self.assertElementKVNO(ticket_encpart, 'kvno', 0) >+ # 'unspecified' means present, with any value != 0 >+ self.assertElementKVNO(ticket_encpart, 'kvno', self.unspecified_kvno) > self.assertElementPresent(ticket_encpart, 'cipher') > ticket_cipher = self.getElementValue(ticket_encpart, 'cipher') > self.assertElementPresent(rep, 'enc-part') >-- >2.25.1 > > >From 16173a94030e3eb1e8c5cfe4cdf44eec092819ab Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 16 Jun 2021 11:01:50 +1200 >Subject: [PATCH 118/686] tests/krb5: Deduplicate 'host' attribute > initialisation > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 3e621dcb6966f75034bb948a2705358d43454202) >--- > python/samba/tests/krb5/kdc_base_test.py | 1 - > python/samba/tests/krb5/raw_testcase.py | 4 ++-- > 2 files changed, 2 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 1f042aa78aa..89d374fc5cc 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -78,7 +78,6 @@ class KDCBaseTest(RawKerberosTest): > def setUpClass(cls): > super().setUpClass() > cls._lp = None >- cls.host = os.environ["SERVER"] > > cls._ldb = None > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b7044546cbd..b9bc08d1fa9 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -375,6 +375,8 @@ class RawKerberosTest(TestCaseInTempDir): > def setUpClass(cls): > super().setUpClass() > >+ cls.host = samba.tests.env_get_var_value('SERVER') >+ > # A dictionary containing credentials that have already been > # obtained. > cls.creds_dict = {} >@@ -389,8 +391,6 @@ class RawKerberosTest(TestCaseInTempDir): > strict_checking = '1' > self.strict_checking = bool(int(strict_checking)) > >- self.host = samba.tests.env_get_var_value('SERVER') >- > self.s = None > > self.unspecified_kvno = object() >-- >2.25.1 > > >From db1d30053eaae8b0570fae2c6f1f553805d8029f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 16 Jun 2021 11:49:05 +1200 >Subject: [PATCH 119/686] tests/krb5/as_canonicalization_tests.py: Refactor > account creation > >Making this test a subclass of KDCBaseTest allows us to make use of its >methods for obtaining credentials and creating accounts, which helps to >eliminate some duplicated code. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit fc857ea60e2a66d20d4174cb121e0a6949f8a0c1) >--- > .../tests/krb5/as_canonicalization_tests.py | 136 ++++-------------- > 1 file changed, 25 insertions(+), 111 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index 43f532dc483..abb3f96a1e6 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -25,20 +25,11 @@ import pyasn1 > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > >-from samba.tests.krb5.raw_testcase import RawKerberosTest >+from samba.tests.krb5.kdc_base_test import KDCBaseTest > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >-import samba >-from samba.auth import system_session >-from samba.credentials import ( >- Credentials, >- DONT_USE_KERBEROS) >+from samba.credentials import DONT_USE_KERBEROS > from samba.dcerpc.misc import SEC_CHAN_WKSTA >-from samba.dsdb import ( >- UF_WORKSTATION_TRUST_ACCOUNT, >- UF_PASSWD_NOTREQD, >- UF_NORMAL_ACCOUNT) >-from samba.samdb import SamDB >-from samba.tests import delete_force, DynamicTestCase >+from samba.tests import DynamicTestCase > from samba.tests.krb5.rfc4120_constants import ( > AES256_CTS_HMAC_SHA1_96, > AES128_CTS_HMAC_SHA1_96, >@@ -96,12 +87,12 @@ class TestData: > else: > client_name_type = NT_PRINCIPAL > >- self.cname = RawKerberosTest.PrincipalName_create( >+ self.cname = KDCBaseTest.PrincipalName_create( > name_type=client_name_type, names=[self.user_name]) > if TestOptions.AsReqSelf.is_set(options): > self.sname = self.cname > else: >- self.sname = RawKerberosTest.PrincipalName_create( >+ self.sname = KDCBaseTest.PrincipalName_create( > name_type=NT_SRV_INST, names=["krbtgt", self.realm]) > self.canonicalize = TestOptions.Canonicalize.is_set(options) > >@@ -141,7 +132,7 @@ USER_NAME = "tstkrb5cnnusr" > > > @DynamicTestCase >-class KerberosASCanonicalizationTests(RawKerberosTest): >+class KerberosASCanonicalizationTests(KDCBaseTest): > > @classmethod > def setUpDynamicTestCases(cls): >@@ -170,114 +161,37 @@ class KerberosASCanonicalizationTests(RawKerberosTest): > name = build_test_name(ct, x) > cls.generate_dynamic_test("test", name, x, ct) > >- @classmethod >- def setUpClass(cls): >- cls.lp = cls.get_loadparm(cls) >- cls.username = os.environ["USERNAME"] >- cls.password = os.environ["PASSWORD"] >- cls.host = os.environ["SERVER"] >- >- c = Credentials() >- c.set_username(cls.username) >- c.set_password(cls.password) >- try: >- realm = os.environ["REALM"] >- c.set_realm(realm) >- except KeyError: >- pass >- try: >- domain = os.environ["DOMAIN"] >- c.set_domain(domain) >- except KeyError: >- pass >+ def user_account_creds(self): >+ if self.user_creds is None: >+ samdb = self.get_samdb() >+ self.user_creds, _ = self.create_account(samdb, USER_NAME) > >- c.guess() >+ return self.user_creds > >- cls.credentials = c >+ def machine_account_creds(self): >+ if self.machine_creds is None: >+ samdb = self.get_samdb() >+ self.machine_creds, _ = self.create_account(samdb, >+ MACHINE_NAME, >+ machine_account=True) >+ self.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) >+ self.machine_creds.set_kerberos_state(DONT_USE_KERBEROS) > >- cls.session = system_session() >- cls.ldb = SamDB(url="ldap://%s" % cls.host, >- session_info=cls.session, >- credentials=cls.credentials, >- lp=cls.lp) >- cls.create_machine_account() >- cls.create_user_account() >- >- @classmethod >- def tearDownClass(cls): >- super(KerberosASCanonicalizationTests, cls).tearDownClass() >- delete_force(cls.ldb, cls.machine_dn) >- delete_force(cls.ldb, cls.user_dn) >+ return self.machine_creds > > def setUp(self): >- super(KerberosASCanonicalizationTests, self).setUp() >+ super().setUp() > self.do_asn1_print = global_asn1_print > self.do_hexdump = global_hexdump > >- # >- # Create a test user account >- @classmethod >- def create_user_account(cls): >- cls.user_pass = samba.generate_random_password(32, 32) >- cls.user_name = USER_NAME >- cls.user_dn = "cn=%s,%s" % (cls.user_name, cls.ldb.domain_dn()) >- >- # remove the account if it exists, this will happen if a previous test >- # run failed >- delete_force(cls.ldb, cls.user_dn) >- >- utf16pw = ('"%s"' % cls.user_pass).encode('utf-16-le') >- cls.ldb.add({ >- "dn": cls.user_dn, >- "objectclass": "user", >- "sAMAccountName": "%s" % cls.user_name, >- "userAccountControl": str(UF_NORMAL_ACCOUNT), >- "unicodePwd": utf16pw}) >- >- cls.user_creds = Credentials() >- cls.user_creds.guess(cls.lp) >- cls.user_creds.set_realm(cls.ldb.domain_dns_name().upper()) >- cls.user_creds.set_domain(cls.ldb.domain_netbios_name().upper()) >- cls.user_creds.set_password(cls.user_pass) >- cls.user_creds.set_username(cls.user_name) >- cls.user_creds.set_workstation(cls.machine_name) >- >- # >- # Create the machine account >- @classmethod >- def create_machine_account(cls): >- cls.machine_pass = samba.generate_random_password(32, 32) >- cls.machine_name = MACHINE_NAME >- cls.machine_dn = "cn=%s,%s" % (cls.machine_name, cls.ldb.domain_dn()) >- >- # remove the account if it exists, this will happen if a previous test >- # run failed >- delete_force(cls.ldb, cls.machine_dn) >- >- utf16pw = ('"%s"' % cls.machine_pass).encode('utf-16-le') >- cls.ldb.add({ >- "dn": cls.machine_dn, >- "objectclass": "computer", >- "sAMAccountName": "%s$" % cls.machine_name, >- "userAccountControl": >- str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), >- "unicodePwd": utf16pw}) >- >- cls.machine_creds = Credentials() >- cls.machine_creds.guess(cls.lp) >- cls.machine_creds.set_realm(cls.ldb.domain_dns_name().upper()) >- cls.machine_creds.set_domain(cls.ldb.domain_netbios_name().upper()) >- cls.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) >- cls.machine_creds.set_kerberos_state(DONT_USE_KERBEROS) >- cls.machine_creds.set_password(cls.machine_pass) >- cls.machine_creds.set_username(cls.machine_name + "$") >- cls.machine_creds.set_workstation(cls.machine_name) >+ self.user_creds = None >+ self.machine_creds = None > > def _test_with_args(self, x, ct): > if ct == CredentialsType.User: >- creds = self.user_creds >+ creds = self.user_account_creds() > elif ct == CredentialsType.Machine: >- creds = self.machine_creds >+ creds = self.machine_account_creds() > else: > raise Exception("Unexpected credential type") > data = TestData(x, creds) >-- >2.25.1 > > >From 8c1445c4f5e83385b9250358c3df04730cb0142b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 16 Jun 2021 12:52:11 +1200 >Subject: [PATCH 120/686] tests/krb5: Use admin creds for SamDB rather than > user creds > >This makes the purpose of each set of credentials more consistent, and >makes some tests more convenient to run standalone as they no longer >require user credentials. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit ab221c1b3e24696aa0eed6aa970f310447657069) >--- > python/samba/tests/krb5/kdc_base_test.py | 2 +- > source4/selftest/tests.py | 42 ++++++++++++++++++++---- > 2 files changed, 36 insertions(+), 8 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 89d374fc5cc..0f5238a3de9 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -109,7 +109,7 @@ class KDCBaseTest(RawKerberosTest): > > def get_samdb(self): > if self._ldb is None: >- creds = self.get_user_creds() >+ creds = self.get_admin_creds() > lp = self.get_lp() > > session = system_session() >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 6873746f389..62e2bc33754 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -723,10 +723,26 @@ planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", > > planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests") > >-planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache") >-planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap") >-planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_rpc") >-planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb") >+planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD' >+ }) >+planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD' >+ }) >+planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_rpc", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD' >+ }) >+planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD' >+ }) > > for env in ["ad_dc", smbv1_disabled_testenv]: > planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) >@@ -1240,15 +1256,27 @@ for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: > '--option=torture:expect_machine_account=true'] + extra_options, > "samba4.krb5.kdc with machine account") > >-planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests") >+planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD' >+ }) > planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests") > planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests") > planpythontestsuite( > "ad_dc", >- "samba.tests.krb5.kdc_tgs_tests") >+ "samba.tests.krb5.kdc_tgs_tests", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD' >+ }) > planpythontestsuite( > "ad_dc", >- "samba.tests.krb5.ms_kile_client_principal_lookup_tests") >+ "samba.tests.krb5.ms_kile_client_principal_lookup_tests", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD' >+ }) > > for env in [ > 'vampire_dc', >-- >2.25.1 > > >From fe795242d300ec8a60a6a98d997486f028571e5e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 21 Jun 2021 14:14:48 +1200 >Subject: [PATCH 121/686] s4:torture/krb5/kdc-heimdal: Automatically determine > AS-REP enctype to check against > >This enables us to more easily switch to a different algorithm to find >the strongest key in _kdc_find_etype(). > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit bf71fa038e9b97f770e06e88226e885d67342d47) >--- > selftest/knownfail | 6 +- > selftest/knownfail_mit_kdc | 6 ++ > source4/torture/krb5/kdc-heimdal.c | 104 +++++++++++++++++++++++++++-- > 3 files changed, 104 insertions(+), 12 deletions(-) > >diff --git a/selftest/knownfail b/selftest/knownfail >index 3a851b06e8e..740902b571f 100644 >--- a/selftest/knownfail >+++ b/selftest/knownfail >@@ -262,10 +262,6 @@ > ^samba4.winbind.struct.lookup_name_sid\(ad_member:local\) > ^samba4.winbind.struct.getdcname\(nt4_member:local\) # Works in other modes, just not against the classic/NT4 DC > # >-# Differences in our KDC compared to windows >-# >-^samba4.krb5.kdc .*.as-req-pac-request # We should reply to a request for a PAC over UDP with KRB5KRB_ERR_RESPONSE_TOO_BIG unconditionally >-# > # This will fail against the classic DC, because it requires kerberos > # > ^samba4.winbind.pac.*\(nt4_member:local\) # No KDC on a classic DC >@@ -304,7 +300,7 @@ > # > ^samba4.smb.signing.*disabled.*signing=off.*\(ad_dc\) > # fl2000dc doesn't support AES >-^samba4.krb5.kdc.*as-req-aes.*fl2000dc >+^samba4.krb5.kdc.*as-req-aes.fl2000dc > # nt4_member and ad_member don't support ntlmv1 (not even over SMB1) > ^samba3.blackbox.smbclient_auth.plain.*_member.*option=clientntlmv2auth=no.member.creds.*as.user > ^samba3.blackbox.smbclient_auth.plain.*_member.*option=clientntlmv2auth=no.*mNT1.member.creds.*as.user >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index db40b0614fa..fffa5c3cd7e 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -641,3 +641,9 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_True.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_True.fl2008r2dc >+# Differences in our KDC compared to windows >+# >+^samba4.krb5.kdc .*.as-req-pac-request # We should reply to a request for a PAC over UDP with KRB5KRB_ERR_RESPONSE_TOO_BIG unconditionally >+# >+# fl2000dc doesn't support AES >+^samba4.krb5.kdc.*as-req-aes.*fl2000dc >diff --git a/source4/torture/krb5/kdc-heimdal.c b/source4/torture/krb5/kdc-heimdal.c >index cc70c9eda67..ccd9919b33a 100644 >--- a/source4/torture/krb5/kdc-heimdal.c >+++ b/source4/torture/krb5/kdc-heimdal.c >@@ -204,11 +204,12 @@ static bool torture_check_krb5_error(struct torture_krb5_context *test_context, > > static bool torture_check_krb5_as_rep_enctype(struct torture_krb5_context *test_context, > const krb5_data *reply, >- krb5_enctype expected_enctype) >+ const krb5_enctype* allowed_enctypes) > { > ENCTYPE reply_enctype = { 0 }; > size_t used = 0; > int rc; >+ int expected_enctype = ETYPE_NULL; > > rc = decode_AS_REP(reply->data, > reply->length, >@@ -230,8 +231,84 @@ static bool torture_check_krb5_as_rep_enctype(struct torture_krb5_context *test_ > test_context->as_rep.ticket.enc_part.kvno, > "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno"); > >- reply_enctype = test_context->as_rep.enc_part.etype; >+ if (test_context->as_req.padata) { >+ /* >+ * If the AS-REQ contains a PA-ENC-TIMESTAMP, then >+ * that encryption type is used to determine the reply >+ * enctype. >+ */ >+ int i = 0; >+ const PA_DATA *pa = krb5_find_padata(test_context->as_req.padata->val, >+ test_context->as_req.padata->len, >+ KRB5_PADATA_ENC_TIMESTAMP, >+ &i); >+ if (pa) { >+ EncryptedData ed; >+ size_t len; >+ krb5_error_code ret = decode_EncryptedData(pa->padata_value.data, >+ pa->padata_value.length, >+ &ed, &len); >+ torture_assert_int_equal(test_context->tctx, >+ ret, >+ 0, >+ "decode_EncryptedData failed"); >+ expected_enctype = ed.etype; >+ free_EncryptedData(&ed); >+ } >+ } >+ if (expected_enctype == ETYPE_NULL) { >+ /* >+ * Otherwise, find the strongest enctype contained in >+ * the AS-REQ supported enctypes list. >+ */ >+ const krb5_enctype *p = NULL; >+ >+ for (p = krb5_kerberos_enctypes(NULL); *p != (krb5_enctype)ETYPE_NULL; ++p) { >+ int j; >+ >+ if ((*p == (krb5_enctype)ETYPE_AES256_CTS_HMAC_SHA1_96 || >+ *p == (krb5_enctype)ETYPE_AES128_CTS_HMAC_SHA1_96) && >+ !test_context->as_req.req_body.kdc_options.canonicalize) >+ { >+ /* >+ * AES encryption types are only used here when >+ * we set the canonicalize flag, as the salt >+ * needs to match. >+ */ >+ continue; >+ } >+ >+ for (j = 0; j < test_context->as_req.req_body.etype.len; ++j) { >+ krb5_enctype etype = test_context->as_req.req_body.etype.val[j]; >+ if (*p == etype) { >+ expected_enctype = etype; >+ break; >+ } >+ } >+ >+ if (expected_enctype != (krb5_enctype)ETYPE_NULL) { >+ break; >+ } >+ } >+ } >+ >+ { >+ /* Ensure the enctype to check against is an expected type. */ >+ const krb5_enctype *p = NULL; >+ bool found = false; >+ for (p = allowed_enctypes; *p != (krb5_enctype)ETYPE_NULL; ++p) { >+ if (*p == expected_enctype) { >+ found = true; >+ break; >+ } >+ } > >+ torture_assert(test_context->tctx, >+ found, >+ "Calculated enctype not in allowed list"); >+ } >+ >+ reply_enctype = test_context->as_rep.enc_part.etype; > torture_assert_int_equal(test_context->tctx, > reply_enctype, expected_enctype, > "Ticket encrypted with invalid algorithm"); >@@ -310,7 +387,7 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex > if (test_context->packet_count == 0) { > ok = torture_check_krb5_error(test_context, > recv_buf, >- KRB5KRB_ERR_RESPONSE_TOO_BIG, >+ KRB5KDC_ERR_PREAUTH_REQUIRED, > false); > torture_assert(test_context->tctx, > ok, >@@ -318,7 +395,7 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex > } else if (test_context->packet_count == 1) { > ok = torture_check_krb5_error(test_context, > recv_buf, >- KRB5KDC_ERR_PREAUTH_REQUIRED, >+ KRB5KRB_ERR_RESPONSE_TOO_BIG, > false); > torture_assert(test_context->tctx, > ok, >@@ -411,9 +488,13 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex > ok, > "torture_check_krb5_error failed"); > } else { >+ const krb5_enctype allowed_enctypes[] = { >+ KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96, >+ ETYPE_NULL >+ }; > ok = torture_check_krb5_as_rep_enctype(test_context, > recv_buf, >- KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96); >+ allowed_enctypes); > torture_assert(test_context->tctx, > ok, > "torture_check_krb5_as_rep_enctype failed"); >@@ -443,9 +524,13 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex > ok, > "torture_check_krb5_error failed"); > } else { >+ const krb5_enctype allowed_enctypes[] = { >+ KRB5_ENCTYPE_ARCFOUR_HMAC_MD5, >+ ETYPE_NULL >+ }; > ok = torture_check_krb5_as_rep_enctype(test_context, > recv_buf, >- KRB5_ENCTYPE_ARCFOUR_HMAC_MD5); >+ allowed_enctypes); > torture_assert(test_context->tctx, > ok, > "torture_check_krb5_as_rep_enctype failed"); >@@ -475,9 +560,14 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex > ok, > "torture_check_krb5_error failed"); > } else { >+ const krb5_enctype allowed_enctypes[] = { >+ KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96, >+ KRB5_ENCTYPE_ARCFOUR_HMAC_MD5, >+ ETYPE_NULL >+ }; > ok = torture_check_krb5_as_rep_enctype(test_context, > recv_buf, >- KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96); >+ allowed_enctypes); > torture_assert(test_context->tctx, > ok, > "torture_check_krb5_as_rep_enctype failed"); >-- >2.25.1 > > >From 5a2867682b5bd11dc4728e11ab2df9f8e2dd73eb Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 7 Sep 2021 09:08:58 +1200 >Subject: [PATCH 122/686] selftest: add space after --list in output of > selftesthelpers.py > >Selected and backported from: > >commit b113a3bbcd03ab6a62883fbca85ee8749e038887 >Author: Volker Lendecke <vl@samba.org> >Date: Mon Apr 19 16:04:00 2021 +0200 > > torture: Show sddl_decode() failure for "GWFX" access mask > > Signed-off-by: Volker Lendecke <vl@samba.org> > Reviewed-by: Jeremy Allison <jra@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >(This allows subsequent patches to be cherry-picked cleanly) > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/selftesthelpers.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/selftest/selftesthelpers.py b/selftest/selftesthelpers.py >index 39b8a1782c6..800c386f9c9 100644 >--- a/selftest/selftesthelpers.py >+++ b/selftest/selftesthelpers.py >@@ -110,7 +110,7 @@ def plantestsuite_loadlist(name, env, cmdline): > raise AssertionError("loadlist test %s does not support not --list" % name) > if "$LOADLIST" not in cmdline: > raise AssertionError("loadlist test %s does not support --load-list" % name) >- print(("%s | %s" % (cmdline.replace("$LOADLIST", ""), add_prefix(name, env, support_list))).replace("$LISTOPT", "--list")) >+ print(("%s | %s" % (cmdline.replace("$LOADLIST", ""), add_prefix(name, env, support_list))).replace("$LISTOPT", "--list ")) > print(cmdline.replace("$LISTOPT", "") + " 2>&1 " + " | " + add_prefix(name, env, False)) > > >-- >2.25.1 > > >From fcccdf881c24a10fcf52ca8ac6a56c5121dcd629 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Tue, 27 Jul 2021 08:50:54 +0200 >Subject: [PATCH 123/686] selftest: Re-format long lines in selftesthelpers.py > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 18976a9568b23759060377d09304e9d7badb143a) >--- > selftest/selftesthelpers.py | 18 +++++++++++++----- > 1 file changed, 13 insertions(+), 5 deletions(-) > >diff --git a/selftest/selftesthelpers.py b/selftest/selftesthelpers.py >index 800c386f9c9..d53f98b648f 100644 >--- a/selftest/selftesthelpers.py >+++ b/selftest/selftesthelpers.py >@@ -1,4 +1,5 @@ >-#!/usr/bin/python >+#!/usr/bin/env python3 >+# > # This script generates a list of testsuites that should be run as part of > # the Samba 4 test suite. > >@@ -25,7 +26,8 @@ import sys > > > def srcdir(): >- return os.path.normpath(os.getenv("SRCDIR", os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))) >+ alternate_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") >+ return os.path.normpath(os.getenv("SRCDIR", alternate_path)) > > > def source4dir(): >@@ -92,7 +94,8 @@ def add_prefix(prefix, env, support_list=False): > listopt = "$LISTOPT " > else: > listopt = "" >- return "%s %s/selftest/filter-subunit %s--fail-on-empty --prefix=\"%s.\" --suffix=\"(%s)\"" % (python, srcdir(), listopt, prefix, env) >+ return ("%s %s/selftest/filter-subunit %s--fail-on-empty --prefix=\"%s.\" --suffix=\"(%s)\"" % >+ (python, srcdir(), listopt, prefix, env)) > > > def plantestsuite_loadlist(name, env, cmdline): >@@ -110,7 +113,9 @@ def plantestsuite_loadlist(name, env, cmdline): > raise AssertionError("loadlist test %s does not support not --list" % name) > if "$LOADLIST" not in cmdline: > raise AssertionError("loadlist test %s does not support --load-list" % name) >- print(("%s | %s" % (cmdline.replace("$LOADLIST", ""), add_prefix(name, env, support_list))).replace("$LISTOPT", "--list ")) >+ print(("%s | %s" % >+ (cmdline.replace("$LOADLIST", ""), >+ add_prefix(name, env, support_list))).replace("$LISTOPT", "--list ")) > print(cmdline.replace("$LISTOPT", "") + " 2>&1 " + " | " + add_prefix(name, env, False)) > > >@@ -169,7 +174,10 @@ bbdir = os.path.join(srcdir(), "testprogs/blackbox") > configuration = "--configfile=$SMB_CONF_PATH" > > smbtorture4 = binpath("smbtorture") >-smbtorture4_testsuite_list = subprocess.Popen([smbtorture4, "--list-suites"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate("")[0].decode('utf8').splitlines() >+smbtorture4_testsuite_list = subprocess.Popen( >+ [smbtorture4, "--list-suites"], >+ stdout=subprocess.PIPE, >+ stderr=subprocess.PIPE).communicate("")[0].decode('utf8').splitlines() > > smbtorture4_options = [ > configuration, >-- >2.25.1 > > >From 6eb4b998caafb45b066107894fb46180807d2404 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Tue, 27 Jul 2021 13:25:59 +0200 >Subject: [PATCH 124/686] selftest: Add support for setting ENV variables in > plansmbtorture4testsuite() > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 3db299e586fd9464b6e1b145f29b10c8ae325d3a) >--- > selftest/selftesthelpers.py | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > >diff --git a/selftest/selftesthelpers.py b/selftest/selftesthelpers.py >index d53f98b648f..cbe840c9a6a 100644 >--- a/selftest/selftesthelpers.py >+++ b/selftest/selftesthelpers.py >@@ -188,13 +188,14 @@ smbtorture4_options = [ > ] + get_env_torture_options() > > >-def plansmbtorture4testsuite(name, env, options, target, modname=None): >+def plansmbtorture4testsuite(name, env, options, target, environ={}, modname=None): > if modname is None: > modname = "samba4.%s" % name > if isinstance(options, list): > options = " ".join(options) > options = " ".join(smbtorture4_options + ["--target=%s" % target]) + " " + options >- cmdline = "%s $LISTOPT $LOADLIST %s %s" % (valgrindify(smbtorture4), options, name) >+ cmdline = ["%s=%s" % item for item in environ.items()] >+ cmdline += "%s $LISTOPT $LOADLIST %s %s" % (valgrindify(smbtorture4), options, name) > plantestsuite_loadlist(modname, env, cmdline) > > >-- >2.25.1 > > >From d3588db9cd42f6a9926761ee5b779cf4c7a1c227 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Tue, 27 Jul 2021 13:45:03 +0200 >Subject: [PATCH 125/686] selftest: Add support for setting ENV variables in > plantestsuite() > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 48289b6964d28e153fec885aceca02c6a9b436ef) >--- > selftest/selftesthelpers.py | 25 +++++++++++++++++++------ > 1 file changed, 19 insertions(+), 6 deletions(-) > >diff --git a/selftest/selftesthelpers.py b/selftest/selftesthelpers.py >index cbe840c9a6a..3a179b9f625 100644 >--- a/selftest/selftesthelpers.py >+++ b/selftest/selftesthelpers.py >@@ -68,7 +68,7 @@ def valgrindify(cmdline): > return valgrind + " " + cmdline > > >-def plantestsuite(name, env, cmdline): >+def plantestsuite(name, env, cmd, environ={}): > """Plan a test suite. > > :param name: Testsuite name >@@ -82,8 +82,18 @@ def plantestsuite(name, env, cmdline): > fullname = "%s(%s)" % (name, env) > print(fullname) > print(env) >- if isinstance(cmdline, list): >- cmdline = " ".join(cmdline) >+ >+ cmdline = "" >+ if environ: >+ environ = dict(environ) >+ cmdline_env = ["%s=%s" % item for item in environ.items()] >+ cmdline = " ".join(cmdline_env) + " " >+ >+ if isinstance(cmd, list): >+ cmdline += " ".join(cmd) >+ else: >+ cmdline += cmd >+ > if "$LISTOPT" in cmdline: > raise AssertionError("test %s supports --list, but not --load-list" % name) > print(cmdline + " 2>&1 " + " | " + add_prefix(name, env)) >@@ -188,14 +198,17 @@ smbtorture4_options = [ > ] + get_env_torture_options() > > >-def plansmbtorture4testsuite(name, env, options, target, environ={}, modname=None): >+def plansmbtorture4testsuite(name, env, options, target, modname=None, environ={}): > if modname is None: > modname = "samba4.%s" % name > if isinstance(options, list): > options = " ".join(options) > options = " ".join(smbtorture4_options + ["--target=%s" % target]) + " " + options >- cmdline = ["%s=%s" % item for item in environ.items()] >- cmdline += "%s $LISTOPT $LOADLIST %s %s" % (valgrindify(smbtorture4), options, name) >+ cmdline = "" >+ if environ: >+ environ = dict(environ) >+ cmdline = ["%s=%s" % item for item in environ.items()] >+ cmdline += " %s $LISTOPT $LOADLIST %s %s" % (valgrindify(smbtorture4), options, name) > plantestsuite_loadlist(modname, env, cmdline) > > >-- >2.25.1 > > >From 980b2c251da45a80474db892910a226817d92560 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Bj=C3=B6rn=20Baumbach?= <bb@sernet.de> >Date: Fri, 24 Jul 2020 12:18:11 +0200 >Subject: [PATCH 126/686] selftest: add option to pass args to tests to > planpythontestsuite() >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >The logic is basically a copy from planoldpythontestsuite(). > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Björn Baumbach <bb@sernet.de> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 3e9f0e97255de1b4235c4dca6912635386328746) > >[jsutton@samba.org Adapted to account for py3_compatible parameter] >--- > selftest/selftesthelpers.py | 21 ++++++++++++--------- > 1 file changed, 12 insertions(+), 9 deletions(-) > >diff --git a/selftest/selftesthelpers.py b/selftest/selftesthelpers.py >index 3a179b9f625..9c7f2e65c0e 100644 >--- a/selftest/selftesthelpers.py >+++ b/selftest/selftesthelpers.py >@@ -151,22 +151,25 @@ def planperltestsuite(name, path): > skiptestsuite(name, "Test::More not available") > > >-def planpythontestsuite(env, module, name=None, extra_path=None, >+def planpythontestsuite(env, module, name=None, extra_path=[], environ={}, extra_args=[], > py3_compatible=False): >+ environ = dict(environ) >+ py_path = list(extra_path) >+ if py_path is not None: >+ environ["PYTHONPATH"] = ":".join(["$PYTHONPATH"] + py_path) >+ args = ["%s=%s" % item for item in environ.items()] >+ python_index = len(args) >+ args += [python, "-m", "samba.subunit.run", "$LISTOPT", "$LOADLIST", module] >+ args += extra_args > if name is None: > name = module >- args = [python, "-m", "samba.subunit.run", "$LISTOPT", "$LOADLIST", module] >- if extra_path: >- pypath = ["PYTHONPATH=$PYTHONPATH:%s" % ":".join(extra_path)] >- else: >- pypath = [] > >- plantestsuite_loadlist(name, env, pypath + args) >+ plantestsuite_loadlist(name, env, args) > if py3_compatible and extra_python is not None: > # Plan one more test for Python 3 compatible module >- args[0] = extra_python >+ args[python_index] = extra_python > python_name = os.path.basename(extra_python) >- plantestsuite_loadlist(name + "." + python_name, env, pypath + args) >+ plantestsuite_loadlist(name + "." + python_name, env, args) > > > def get_env_torture_options(): >-- >2.25.1 > > >From d370553271a04ce62e08a6dac12c57dff70d871c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 19 Jul 2021 17:29:39 +1200 >Subject: [PATCH 127/686] pygensec: Fix memory leaks > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 814df05f8c10e9d82e6082d42ece1df569db4385) >--- > source4/auth/gensec/pygensec.c | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > >diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c >index 9ede11c9d8d..c456b680574 100644 >--- a/source4/auth/gensec/pygensec.c >+++ b/source4/auth/gensec/pygensec.c >@@ -299,9 +299,13 @@ static PyObject *py_gensec_session_info(PyObject *self) > return NULL; > } > mem_ctx = talloc_new(NULL); >+ if (mem_ctx == NULL) { >+ return PyErr_NoMemory(); >+ } > > status = gensec_session_info(security, mem_ctx, &info); > if (NT_STATUS_IS_ERR(status)) { >+ talloc_free(mem_ctx); > PyErr_SetNTSTATUS(status); > return NULL; > } >@@ -325,6 +329,9 @@ static PyObject *py_gensec_session_key(PyObject *self) > return NULL; > } > mem_ctx = talloc_new(NULL); >+ if (mem_ctx == NULL) { >+ return PyErr_NoMemory(); >+ } > > status = gensec_session_key(security, mem_ctx, &session_key); > if (!NT_STATUS_IS_OK(status)) { >@@ -453,7 +460,12 @@ static PyObject *py_gensec_update(PyObject *self, PyObject *args) > return NULL; > > mem_ctx = talloc_new(NULL); >+ if (mem_ctx == NULL) { >+ return PyErr_NoMemory(); >+ } >+ > if (!PyBytes_Check(py_in)) { >+ talloc_free(mem_ctx); > PyErr_Format(PyExc_TypeError, "bytes expected"); > return NULL; > } >@@ -494,8 +506,12 @@ static PyObject *py_gensec_wrap(PyObject *self, PyObject *args) > return NULL; > > mem_ctx = talloc_new(NULL); >+ if (mem_ctx == NULL) { >+ return PyErr_NoMemory(); >+ } > > if (!PyBytes_Check(py_in)) { >+ talloc_free(mem_ctx); > PyErr_Format(PyExc_TypeError, "bytes expected"); > return NULL; > } >@@ -529,8 +545,12 @@ static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args) > return NULL; > > mem_ctx = talloc_new(NULL); >+ if (mem_ctx == NULL) { >+ return PyErr_NoMemory(); >+ } > > if (!PyBytes_Check(py_in)) { >+ talloc_free(mem_ctx); > PyErr_Format(PyExc_TypeError, "bytes expected"); > return NULL; > } >@@ -583,6 +603,9 @@ static PyObject *py_gensec_sign_packet(PyObject *self, PyObject *args) > pdu.length = pdu_length; > > mem_ctx = talloc_new(NULL); >+ if (mem_ctx == NULL) { >+ return PyErr_NoMemory(); >+ } > > status = gensec_sign_packet(security, mem_ctx, > data.data, data.length, >-- >2.25.1 > > >From a11c1ad0c5ead9bdaa365ac1e5032ff308a49b7c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 20 Jul 2021 10:48:41 +1200 >Subject: [PATCH 128/686] pygensec: Don't modify Python bytes objects > >gensec_update() and gensec_unwrap() can both modify their input buffers >(for example, during the inplace RRC operation on GSSAPI tokens). >However, buffers obtained from Python bytes objects must not be modified >in any way. Create a copy of the input buffer so the original isn't >modified. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 6818d204897d0b7946dcfbedf79cd53fb9b3f159) >--- > source4/auth/gensec/gensec_gssapi.c | 4 ++++ > source4/auth/gensec/pygensec.c | 36 ++++++++++++++++++++++------- > 2 files changed, 32 insertions(+), 8 deletions(-) > >diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c >index 045a0225741..4ac20575b01 100644 >--- a/source4/auth/gensec/gensec_gssapi.c >+++ b/source4/auth/gensec/gensec_gssapi.c >@@ -1167,6 +1167,10 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, > } > } > >+ /* >+ * FIXME: input_message_buffer is marked const, but gss_unwrap() may >+ * modify it (see calls to rrc_rotate() in _gssapi_unwrap_cfx()). >+ */ > maj_stat = gss_unwrap(&min_stat, > gensec_gssapi_state->gssapi_context, > &input_token, >diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c >index c456b680574..fe4472b8ed0 100644 >--- a/source4/auth/gensec/pygensec.c >+++ b/source4/auth/gensec/pygensec.c >@@ -455,6 +455,9 @@ static PyObject *py_gensec_update(PyObject *self, PyObject *args) > PyObject *ret, *py_in; > struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); > PyObject *finished_processing; >+ char *data = NULL; >+ Py_ssize_t len; >+ int err; > > if (!PyArg_ParseTuple(args, "O", &py_in)) > return NULL; >@@ -464,14 +467,21 @@ static PyObject *py_gensec_update(PyObject *self, PyObject *args) > return PyErr_NoMemory(); > } > >- if (!PyBytes_Check(py_in)) { >+ err = PyBytes_AsStringAndSize(py_in, &data, &len); >+ if (err) { > talloc_free(mem_ctx); >- PyErr_Format(PyExc_TypeError, "bytes expected"); > return NULL; > } > >- in.data = (uint8_t *)PyBytes_AsString(py_in); >- in.length = PyBytes_Size(py_in); >+ /* >+ * Make a copy of the input buffer, as gensec_update may modify its >+ * input argument. >+ */ >+ in = data_blob_talloc(mem_ctx, data, len); >+ if (!in.data) { >+ talloc_free(mem_ctx); >+ return PyErr_NoMemory(); >+ } > > status = gensec_update(security, mem_ctx, in, &out); > >@@ -540,6 +550,9 @@ static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args) > DATA_BLOB in, out; > PyObject *ret, *py_in; > struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); >+ char *data = NULL; >+ Py_ssize_t len; >+ int err; > > if (!PyArg_ParseTuple(args, "O", &py_in)) > return NULL; >@@ -549,14 +562,21 @@ static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args) > return PyErr_NoMemory(); > } > >- if (!PyBytes_Check(py_in)) { >+ err = PyBytes_AsStringAndSize(py_in, &data, &len); >+ if (err) { > talloc_free(mem_ctx); >- PyErr_Format(PyExc_TypeError, "bytes expected"); > return NULL; > } > >- in.data = (uint8_t *)PyBytes_AsString(py_in); >- in.length = PyBytes_Size(py_in); >+ /* >+ * Make a copy of the input buffer, as gensec_unwrap may modify its >+ * input argument. >+ */ >+ in = data_blob_talloc(mem_ctx, data, len); >+ if (!in.data) { >+ talloc_free(mem_ctx); >+ return PyErr_NoMemory(); >+ } > > status = gensec_unwrap(security, mem_ctx, &in, &out); > >-- >2.25.1 > > >From a79749daf3df83013a7612f440651eb8decc157d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 26 Jul 2021 17:15:23 +1200 >Subject: [PATCH 129/686] tests/krb5: Fix ms_kile_client_principal_lookup_test > errors > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 4797ced89095155c01e44727cf8b66ee4fb39710) >--- > .../krb5/ms_kile_client_principal_lookup_tests.py | 11 ++++++----- > 1 file changed, 6 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index e9d251e72f6..1598959a18c 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -395,7 +395,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # Check the contents of the pac, and the ticket > ticket = rep['ticket'] > enc_part = self.decode_service_ticket(mc, ticket) >- self.check_pac(enc_part['authorization-data'], dn, uc, user_name) >+ self.check_pac(samdb, >+ enc_part['authorization-data'], dn, uc, user_name) > # check the crealm and cname > cname = enc_part['cname'] > self.assertEqual(NT_PRINCIPAL, cname['name-type']) >@@ -497,7 +498,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > ticket = rep['ticket'] > enc_part = self.decode_service_ticket(mc, ticket) > self.check_pac( >- enc_part['authorization-data'], dn, uc, upn, upn=upn) >+ samdb, enc_part['authorization-data'], dn, uc, upn, upn=upn) > # check the crealm and cname > cname = enc_part['cname'] > crealm = enc_part['crealm'] >@@ -560,7 +561,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > ticket = rep['ticket'] > enc_part = self.decode_service_ticket(mc, ticket) > self.check_pac( >- enc_part['authorization-data'], dn, uc, ename, upn=ename) >+ samdb, enc_part['authorization-data'], dn, uc, ename, upn=ename) > # check the crealm and cname > cname = enc_part['cname'] > crealm = enc_part['crealm'] >@@ -624,7 +625,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > ticket = rep['ticket'] > enc_part = self.decode_service_ticket(mc, ticket) > self.check_pac( >- enc_part['authorization-data'], dn, mc, ename, upn=uname) >+ samdb, enc_part['authorization-data'], dn, mc, ename, upn=uname) > # check the crealm and cname > cname = enc_part['cname'] > crealm = enc_part['crealm'] >@@ -771,7 +772,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > ticket = rep['ticket'] > enc_part = self.decode_service_ticket(mc, ticket) > self.check_pac( >- enc_part['authorization-data'], dn, uc, uname, upn=uname) >+ samdb, enc_part['authorization-data'], dn, uc, uname, upn=uname) > # check the crealm and cname > cname = enc_part['cname'] > self.assertEqual(NT_ENTERPRISE_PRINCIPAL, cname['name-type']) >-- >2.25.1 > > >From 2618eb9ebfe32c682a1959c183b160f7a3526ae5 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 22 Jul 2021 16:26:17 +1200 >Subject: [PATCH 130/686] tests/krb5: Fix comment typo > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 9eb4c4b7b1c2e8d124456e6a57262dc9c02d67d4) >--- > python/samba/tests/krb5/raw_testcase.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b9bc08d1fa9..9c090e4d005 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -864,7 +864,7 @@ class RawKerberosTest(TestCaseInTempDir): > # The value on the wire should never be 0 > self.assertNotEqual(v, 0) > # unspecified_kvno means we don't know the kvno, >- # but want to enforce its presense >+ # but want to enforce its presence > if value is not self.unspecified_kvno: > value = int(value) > self.assertNotEqual(value, 0) >-- >2.25.1 > > >From bea90874a7a267fc561faeed80570e8b064c3c00 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 6 Jul 2021 10:17:52 +1200 >Subject: [PATCH 131/686] tests/krb5: Fix method name typo > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 7013a8edd1f628b8659f0836f3b37ccf13156ae2) >--- > python/samba/tests/krb5/kdc_base_test.py | 4 ++-- > python/samba/tests/krb5/kdc_tgs_tests.py | 6 +++--- > .../ms_kile_client_principal_lookup_tests.py | 20 +++++++++---------- > 3 files changed, 15 insertions(+), 15 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 0f5238a3de9..4bd856b217e 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -444,7 +444,7 @@ class KDCBaseTest(RawKerberosTest): > > return enc_part > >- def check_pre_authenication(self, rep): >+ def check_pre_authentication(self, rep): > """ Check that the kdc response was pre-authentication required > """ > self.check_error_rep(rep, KDC_ERR_PREAUTH_REQUIRED) >@@ -794,7 +794,7 @@ class KDCBaseTest(RawKerberosTest): > names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(user_credentials, rep) >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 0c757bd5e5f..25a1f5f3ed8 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -63,7 +63,7 @@ class KdcTgsTests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(uc, rep) >@@ -113,7 +113,7 @@ class KdcTgsTests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(uc, rep) >@@ -154,7 +154,7 @@ class KdcTgsTests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(uc, rep) >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index 1598959a18c..e42b643b357 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -106,7 +106,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(uc, rep) >@@ -165,7 +165,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(mc, rep) >@@ -227,7 +227,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(uc, rep) >@@ -365,7 +365,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(uc, rep) >@@ -433,7 +433,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(uc, rep) >@@ -472,7 +472,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(uc, rep) >@@ -535,7 +535,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(uc, rep) >@@ -599,7 +599,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(mc, rep) >@@ -741,7 +741,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(uc, rep) >@@ -810,7 +810,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=["krbtgt", realm]) > > rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authenication(rep) >+ self.check_pre_authentication(rep) > > # Do the next AS-REQ > padata = self.get_pa_data(uc, rep) >-- >2.25.1 > > >From 0fe1dd935c76f0a53c7054a9bd51bf665e45339a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 2 Aug 2021 17:00:09 +1200 >Subject: [PATCH 132/686] tests/krb5: formatting > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit df6623363a7ec1a13af48a09e1d29fa8784e825c) >--- > python/samba/tests/krb5/as_req_tests.py | 20 +- > python/samba/tests/krb5/kdc_base_test.py | 22 +- > python/samba/tests/krb5/raw_testcase.py | 323 +++++++++++++---------- > 3 files changed, 209 insertions(+), 156 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 10e7b603609..09cfc9e1fc8 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -82,16 +82,16 @@ class AsReqKerberosTests(KDCBaseTest): > return initial_padata, req_body > > kdc_exchange_dict = self.as_exchange_dict( >- expected_crealm=expected_crealm, >- expected_cname=expected_cname, >- expected_srealm=expected_srealm, >- expected_sname=expected_sname, >- generate_padata_fn=_generate_padata_copy, >- check_error_fn=self.generic_check_as_error, >- check_rep_fn=self.generic_check_kdc_rep, >- expected_error_mode=expected_error_mode, >- client_as_etypes=client_as_etypes, >- expected_salt=expected_salt) >+ expected_crealm=expected_crealm, >+ expected_cname=expected_cname, >+ expected_srealm=expected_srealm, >+ expected_sname=expected_sname, >+ generate_padata_fn=_generate_padata_copy, >+ check_error_fn=self.generic_check_as_error, >+ check_rep_fn=self.generic_check_kdc_rep, >+ expected_error_mode=expected_error_mode, >+ client_as_etypes=client_as_etypes, >+ expected_salt=expected_salt) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, > kdc_options=str(initial_kdc_options), >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 4bd856b217e..c23c71e1d74 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -21,10 +21,7 @@ import os > from datetime import datetime, timezone > import tempfile > import binascii >-import struct > >-sys.path.insert(0, "bin/python") >-os.environ["PYTHONUNBUFFERED"] = "1" > from collections import namedtuple > import ldb > from ldb import SCOPE_BASE >@@ -66,6 +63,9 @@ from samba.tests.krb5.rfc4120_constants import ( > PADATA_ETYPE_INFO2, > ) > >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ > global_asn1_print = False > global_hexdump = False > >@@ -114,9 +114,9 @@ class KDCBaseTest(RawKerberosTest): > > session = system_session() > type(self)._ldb = SamDB(url="ldap://%s" % self.host, >- session_info=session, >- credentials=creds, >- lp=lp) >+ session_info=session, >+ credentials=creds, >+ lp=lp) > > return self._ldb > >@@ -337,6 +337,7 @@ class KDCBaseTest(RawKerberosTest): > require_strongest_key=False): > if require_strongest_key: > self.assertTrue(require_keys) >+ > def download_krbtgt_creds(): > samdb = self.get_samdb() > >@@ -742,15 +743,16 @@ class KDCBaseTest(RawKerberosTest): > .replace(tzinfo=timezone.utc).timestamp()) > > # Account for clock skew of up to five minutes. >- self.assertLess(cred.authtime - 5*60, >+ self.assertLess(cred.authtime - 5 * 60, > datetime.now(timezone.utc).timestamp(), > "Ticket not yet valid - clocks may be out of sync.") >- self.assertLess(cred.starttime - 5*60, >+ self.assertLess(cred.starttime - 5 * 60, > datetime.now(timezone.utc).timestamp(), > "Ticket not yet valid - clocks may be out of sync.") >- self.assertGreater(cred.endtime - 60*60, >+ self.assertGreater(cred.endtime - 60 * 60, > datetime.now(timezone.utc).timestamp(), >- "Ticket already expired/about to expire - clocks may be out of sync.") >+ "Ticket already expired/about to expire - " >+ "clocks may be out of sync.") > > cred.renew_till = cred.endtime > cred.is_skey = 0 >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 9c090e4d005..de9c25751d2 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -24,11 +24,19 @@ import datetime > import random > import binascii > import itertools >+from pyasn1.codec.der.decoder import decode as pyasn1_der_decode >+from pyasn1.codec.der.encoder import encode as pyasn1_der_encode >+from pyasn1.codec.native.decoder import decode as pyasn1_native_decode >+from pyasn1.codec.native.encoder import encode as pyasn1_native_encode >+ >+from pyasn1.codec.ber.encoder import BitStringEncoder > >-import samba.tests > from samba.credentials import Credentials >-from samba.tests import TestCaseInTempDir > from samba.dcerpc import security >+ >+import samba.tests >+from samba.tests import TestCaseInTempDir >+ > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_ETYPE_NOSUPP, >@@ -53,13 +61,6 @@ from samba.tests.krb5.rfc4120_constants import ( > ) > import samba.tests.krb5.kcrypto as kcrypto > >-from pyasn1.codec.der.decoder import decode as pyasn1_der_decode >-from pyasn1.codec.der.encoder import encode as pyasn1_der_encode >-from pyasn1.codec.native.decoder import decode as pyasn1_native_decode >-from pyasn1.codec.native.encoder import encode as pyasn1_native_encode >- >-from pyasn1.codec.ber.encoder import BitStringEncoder as BitStringEncoder >- > > def BitStringEncoder_encodeValue32( > self, value, asn1Spec, encodeFun, **options): >@@ -217,6 +218,7 @@ class Krb5EncryptionKey(object): > } > return EncryptionKey_obj > >+ > class KerberosCredentials(Credentials): > def __init__(self): > super(KerberosCredentials, self).__init__() >@@ -293,6 +295,7 @@ class KerberosCredentials(Credentials): > def get_forced_salt(self): > return self.forced_salt > >+ > class KerberosTicketCreds(object): > def __init__(self, ticket, session_key, > crealm=None, cname=None, >@@ -311,14 +314,15 @@ class KerberosTicketCreds(object): > self.encpart_private = encpart_private > return > >+ > class RawKerberosTest(TestCaseInTempDir): > """A raw Kerberos Test case.""" > > etypes_to_test = ( >- { "value": -1111, "name": "dummy", }, >- { "value": kcrypto.Enctype.AES256, "name": "aes128", }, >- { "value": kcrypto.Enctype.AES128, "name": "aes256", }, >- { "value": kcrypto.Enctype.RC4, "name": "rc4", }, >+ {"value": -1111, "name": "dummy", }, >+ {"value": kcrypto.Enctype.AES256, "name": "aes128", }, >+ {"value": kcrypto.Enctype.AES128, "name": "aes256", }, >+ {"value": kcrypto.Enctype.RC4, "name": "rc4", }, > ) > > setup_etype_test_permutations_done = False >@@ -332,7 +336,7 @@ class RawKerberosTest(TestCaseInTempDir): > > num_idxs = len(cls.etypes_to_test) > permutations = [] >- for num in range(1, num_idxs+1): >+ for num in range(1, num_idxs + 1): > chunk = list(itertools.permutations(range(num_idxs), num)) > for e in chunk: > el = list(e) >@@ -349,7 +353,7 @@ class RawKerberosTest(TestCaseInTempDir): > name += "_%s" % n > etypes += (cls.etypes_to_test[idx]["value"],) > >- r = { "name": name, "etypes": etypes, } >+ r = {"name": name, "etypes": etypes, } > res.append(r) > > cls.etype_test_permutations = res >@@ -386,7 +390,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.do_asn1_print = False > self.do_hexdump = False > >- strict_checking = samba.tests.env_get_var_value('STRICT_CHECKING', allow_missing=True) >+ strict_checking = samba.tests.env_get_var_value('STRICT_CHECKING', >+ allow_missing=True) > if strict_checking is None: > strict_checking = '1' > self.strict_checking = bool(int(strict_checking)) >@@ -440,8 +445,9 @@ class RawKerberosTest(TestCaseInTempDir): > val = None > if prefix is not None: > allow_missing_prefix = allow_missing or fallback_default >- val = samba.tests.env_get_var_value('%s_%s' % (prefix, varname), >- allow_missing=allow_missing_prefix) >+ val = samba.tests.env_get_var_value( >+ '%s_%s' % (prefix, varname), >+ allow_missing=allow_missing_prefix) > else: > fallback_default = True > if val is None and fallback_default: >@@ -506,7 +512,8 @@ class RawKerberosTest(TestCaseInTempDir): > if aes256_key is not None: > c.set_forced_key(kcrypto.Enctype.AES256, aes256_key) > aes128_key = self.env_get_var('AES128_KEY_HEX', prefix, >- fallback_default=False, allow_missing=True) >+ fallback_default=False, >+ allow_missing=True) > if aes128_key is not None: > c.set_forced_key(kcrypto.Enctype.AES128, aes128_key) > rc4_key = self.env_get_var('RC4_KEY_HEX', prefix, >@@ -536,11 +543,12 @@ class RawKerberosTest(TestCaseInTempDir): > env_err = None > try: > # Try to obtain them from the environment >- creds = self._get_krb5_creds_from_env(prefix, >- default_username=default_username, >- allow_missing_password=allow_missing_password, >- allow_missing_keys=allow_missing_keys, >- require_strongest_key=require_strongest_key) >+ creds = self._get_krb5_creds_from_env( >+ prefix, >+ default_username=default_username, >+ allow_missing_password=allow_missing_password, >+ allow_missing_keys=allow_missing_keys, >+ require_strongest_key=require_strongest_key) > except Exception as err: > # An error occurred, so save it for later > env_err = err >@@ -886,8 +894,8 @@ class RawKerberosTest(TestCaseInTempDir): > return s > > def get_Nonce(self): >- nonce_min=0x7f000000 >- nonce_max=0x7fffffff >+ nonce_min = 0x7f000000 >+ nonce_max = 0x7fffffff > v = random.randint(nonce_min, nonce_max) > return v > >@@ -936,15 +944,20 @@ class RawKerberosTest(TestCaseInTempDir): > if etype == kcrypto.Enctype.RC4: > nthash = creds.get_nt_hash() > self.assertIsNotNone(nthash, msg=fail_msg) >- return self.SessionKey_create(etype=etype, contents=nthash, kvno=kvno) >+ return self.SessionKey_create(etype=etype, >+ contents=nthash, >+ kvno=kvno) > > password = creds.get_password() > self.assertIsNotNone(password, msg=fail_msg) > salt = creds.get_forced_salt() > if salt is None: > salt = bytes("%s%s" % (creds.get_realm(), creds.get_username()), >- encoding='utf-8') >- return self.PasswordKey_create(etype=etype, pwd=password, salt=salt, kvno=kvno) >+ encoding='utf-8') >+ return self.PasswordKey_create(etype=etype, >+ pwd=password, >+ salt=salt, >+ kvno=kvno) > > def RandomKey(self, etype): > e = kcrypto._get_enctype_profile(etype) >@@ -1020,10 +1033,12 @@ class RawKerberosTest(TestCaseInTempDir): > return PA_ENC_TS_ENC_obj > > def KERB_PA_PAC_REQUEST_create(self, include_pac, pa_data_create=True): >- #KERB-PA-PAC-REQUEST ::= SEQUENCE { >- # include-pac[0] BOOLEAN --If TRUE, and no pac present, include PAC. >- # --If FALSE, and PAC present, remove PAC >- #} >+ # KERB-PA-PAC-REQUEST ::= SEQUENCE { >+ # include-pac[0] BOOLEAN --If TRUE, and no pac present, >+ # -- include PAC. >+ # --If FALSE, and PAC present, >+ # -- remove PAC. >+ # } > KERB_PA_PAC_REQUEST_obj = { > 'include-pac': include_pac, > } >@@ -1031,7 +1046,7 @@ class RawKerberosTest(TestCaseInTempDir): > return KERB_PA_PAC_REQUEST_obj > pa_pac = self.der_encode(KERB_PA_PAC_REQUEST_obj, > asn1Spec=krb5_asn1.KERB_PA_PAC_REQUEST()) >- pa_data = self.PA_DATA_create(128, pa_pac) # PA-PAC-REQUEST >+ pa_data = self.PA_DATA_create(128, pa_pac) # PA-PAC-REQUEST > return pa_data > > def KDC_REQ_BODY_create(self, >@@ -1327,11 +1342,14 @@ class RawKerberosTest(TestCaseInTempDir): > EncAuthorizationData=EncAuthorizationData, > EncAuthorizationData_key=EncAuthorizationData_key, > additional_tickets=additional_tickets) >- req_body_blob = self.der_encode(req_body, asn1Spec=krb5_asn1.KDC_REQ_BODY(), >+ req_body_blob = self.der_encode(req_body, >+ asn1Spec=krb5_asn1.KDC_REQ_BODY(), > asn1_print=asn1_print, hexdump=hexdump) > >- req_body_checksum = self.Checksum_create( >- ticket_session_key, 6, req_body_blob, ctype=body_checksum_type) >+ req_body_checksum = self.Checksum_create(ticket_session_key, >+ 6, >+ req_body_blob, >+ ctype=body_checksum_type) > > subkey_obj = None > if authenticator_subkey is not None: >@@ -1390,7 +1408,10 @@ class RawKerberosTest(TestCaseInTempDir): > cksum_data += n.encode() > cksum_data += realm.encode() > cksum_data += "Kerberos".encode() >- cksum = self.Checksum_create(tgt_session_key, 17, cksum_data, ctype) >+ cksum = self.Checksum_create(tgt_session_key, >+ 17, >+ cksum_data, >+ ctype) > > PA_S4U2Self_obj = { > 'name': name, >@@ -1403,20 +1424,20 @@ class RawKerberosTest(TestCaseInTempDir): > return self.PA_DATA_create(129, pa_s4u2self) > > def _generic_kdc_exchange(self, >- kdc_exchange_dict, # required >- kdc_options=None, # required >- cname=None, # optional >- realm=None, # required >- sname=None, # optional >- from_time=None, # optional >- till_time=None, # required >- renew_time=None, # optional >- nonce=None, # required >- etypes=None, # required >- addresses=None, # optional >- EncAuthorizationData=None, # optional >- EncAuthorizationData_key=None, # optional >- additional_tickets=None): # optional >+ kdc_exchange_dict, # required >+ kdc_options=None, # required >+ cname=None, # optional >+ realm=None, # required >+ sname=None, # optional >+ from_time=None, # optional >+ till_time=None, # required >+ renew_time=None, # optional >+ nonce=None, # required >+ etypes=None, # required >+ addresses=None, # optional >+ EncAuthorizationData=None, # optional >+ EncAuthorizationData_key=None, # optional >+ additional_tickets=None): # optional > > check_error_fn = kdc_exchange_dict['check_error_fn'] > check_rep_fn = kdc_exchange_dict['check_rep_fn'] >@@ -1431,19 +1452,20 @@ class RawKerberosTest(TestCaseInTempDir): > if nonce is None: > nonce = self.get_Nonce() > >- req_body = self.KDC_REQ_BODY_create(kdc_options=kdc_options, >- cname=cname, >- realm=realm, >- sname=sname, >- from_time=from_time, >- till_time=till_time, >- renew_time=renew_time, >- nonce=nonce, >- etypes=etypes, >- addresses=addresses, >- EncAuthorizationData=EncAuthorizationData, >- EncAuthorizationData_key=EncAuthorizationData_key, >- additional_tickets=additional_tickets) >+ req_body = self.KDC_REQ_BODY_create( >+ kdc_options=kdc_options, >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ from_time=from_time, >+ till_time=till_time, >+ renew_time=renew_time, >+ nonce=nonce, >+ etypes=etypes, >+ addresses=addresses, >+ EncAuthorizationData=EncAuthorizationData, >+ EncAuthorizationData_key=EncAuthorizationData_key, >+ additional_tickets=additional_tickets) > if generate_padata_fn is not None: > # This can alter req_body... > padata, req_body = generate_padata_fn(kdc_exchange_dict, >@@ -1455,10 +1477,10 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_exchange_dict['req_padata'] = padata > kdc_exchange_dict['req_body'] = req_body > >- req_obj,req_decoded = self.KDC_REQ_create(msg_type=req_msg_type, >- padata=padata, >- req_body=req_body, >- asn1Spec=req_asn1Spec()) >+ req_obj, req_decoded = self.KDC_REQ_create(msg_type=req_msg_type, >+ padata=padata, >+ req_body=req_body, >+ asn1Spec=req_asn1Spec()) > > rep = self.send_recv_transaction(req_decoded) > self.assertIsNotNone(rep) >@@ -1571,7 +1593,7 @@ class RawKerberosTest(TestCaseInTempDir): > rep_encpart_asn1Spec = kdc_exchange_dict['rep_encpart_asn1Spec'] > msg_type = kdc_exchange_dict['rep_msg_type'] > >- self.assertElementEqual(rep, 'msg-type', msg_type) # AS-REP | TGS-REP >+ self.assertElementEqual(rep, 'msg-type', msg_type) # AS-REP | TGS-REP > padata = self.getElementValue(rep, 'padata') > self.assertElementEqualUTF8(rep, 'crealm', expected_crealm) > self.assertElementEqualPrincipal(rep, 'cname', expected_cname) >@@ -1579,22 +1601,23 @@ class RawKerberosTest(TestCaseInTempDir): > ticket = self.getElementValue(rep, 'ticket') > ticket_encpart = None > ticket_cipher = None >- if ticket is not None: # Never None, but gives indentation >+ if ticket is not None: # Never None, but gives indentation > self.assertElementPresent(ticket, 'tkt-vno') > self.assertElementEqualUTF8(ticket, 'realm', expected_srealm) > self.assertElementEqualPrincipal(ticket, 'sname', expected_sname) > self.assertElementPresent(ticket, 'enc-part') > ticket_encpart = self.getElementValue(ticket, 'enc-part') >- if ticket_encpart is not None: # Never None, but gives indentation >+ if ticket_encpart is not None: # Never None, but gives indentation > self.assertElementPresent(ticket_encpart, 'etype') > # 'unspecified' means present, with any value != 0 >- self.assertElementKVNO(ticket_encpart, 'kvno', self.unspecified_kvno) >+ self.assertElementKVNO(ticket_encpart, 'kvno', >+ self.unspecified_kvno) > self.assertElementPresent(ticket_encpart, 'cipher') > ticket_cipher = self.getElementValue(ticket_encpart, 'cipher') > self.assertElementPresent(rep, 'enc-part') > encpart = self.getElementValue(rep, 'enc-part') > encpart_cipher = None >- if encpart is not None: # Never None, but gives indentation >+ if encpart is not None: # Never None, but gives indentation > self.assertElementPresent(encpart, 'etype') > self.assertElementKVNO(ticket_encpart, 'kvno', 'autodetect') > self.assertElementPresent(encpart, 'cipher') >@@ -1602,24 +1625,35 @@ class RawKerberosTest(TestCaseInTempDir): > > encpart_decryption_key = None > if check_padata_fn is not None: >- # See if get the decryption key from the preauth phase >- encpart_decryption_key,encpart_decryption_usage = \ >- check_padata_fn(kdc_exchange_dict, callback_dict, >- rep, padata) >+ # See if we can get the decryption key from the preauth phase >+ encpart_decryption_key, encpart_decryption_usage = ( >+ check_padata_fn(kdc_exchange_dict, callback_dict, >+ rep, padata)) > > ticket_private = None > if ticket_decryption_key is not None: >- self.assertElementEqual(ticket_encpart, 'etype', ticket_decryption_key.etype) >- self.assertElementKVNO(ticket_encpart, 'kvno', ticket_decryption_key.kvno) >- ticket_decpart = ticket_decryption_key.decrypt(KU_TICKET, ticket_cipher) >- ticket_private = self.der_decode(ticket_decpart, asn1Spec=krb5_asn1.EncTicketPart()) >+ self.assertElementEqual(ticket_encpart, 'etype', >+ ticket_decryption_key.etype) >+ self.assertElementKVNO(ticket_encpart, 'kvno', >+ ticket_decryption_key.kvno) >+ ticket_decpart = ticket_decryption_key.decrypt(KU_TICKET, >+ ticket_cipher) >+ ticket_private = self.der_decode( >+ ticket_decpart, >+ asn1Spec=krb5_asn1.EncTicketPart()) > > encpart_private = None > if encpart_decryption_key is not None: >- self.assertElementEqual(encpart, 'etype', encpart_decryption_key.etype) >- self.assertElementKVNO(encpart, 'kvno', encpart_decryption_key.kvno) >- rep_decpart = encpart_decryption_key.decrypt(encpart_decryption_usage, encpart_cipher) >- encpart_private = self.der_decode(rep_decpart, asn1Spec=rep_encpart_asn1Spec()) >+ self.assertElementEqual(encpart, 'etype', >+ encpart_decryption_key.etype) >+ self.assertElementKVNO(encpart, 'kvno', >+ encpart_decryption_key.kvno) >+ rep_decpart = encpart_decryption_key.decrypt( >+ encpart_decryption_usage, >+ encpart_cipher) >+ encpart_private = self.der_decode( >+ rep_decpart, >+ asn1Spec=rep_encpart_asn1Spec()) > > if check_kdc_private_fn is not None: > check_kdc_private_fn(kdc_exchange_dict, callback_dict, >@@ -1647,12 +1681,14 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(ticket_private, 'flags') > self.assertElementPresent(ticket_private, 'key') > ticket_key = self.getElementValue(ticket_private, 'key') >- if ticket_key is not None: # Never None, but gives indentation >+ if ticket_key is not None: # Never None, but gives indentation > self.assertElementPresent(ticket_key, 'keytype') > self.assertElementPresent(ticket_key, 'keyvalue') > ticket_session_key = self.EncryptionKey_import(ticket_key) >- self.assertElementEqualUTF8(ticket_private, 'crealm', expected_crealm) >- self.assertElementEqualPrincipal(ticket_private, 'cname', expected_cname) >+ self.assertElementEqualUTF8(ticket_private, 'crealm', >+ expected_crealm) >+ self.assertElementEqualPrincipal(ticket_private, 'cname', >+ expected_cname) > self.assertElementPresent(ticket_private, 'transited') > self.assertElementPresent(ticket_private, 'authtime') > if self.strict_checking: >@@ -1666,39 +1702,45 @@ class RawKerberosTest(TestCaseInTempDir): > if encpart_private is not None: > self.assertElementPresent(encpart_private, 'key') > encpart_key = self.getElementValue(encpart_private, 'key') >- if encpart_key is not None: # Never None, but gives indentation >+ if encpart_key is not None: # Never None, but gives indentation > self.assertElementPresent(encpart_key, 'keytype') > self.assertElementPresent(encpart_key, 'keyvalue') > encpart_session_key = self.EncryptionKey_import(encpart_key) > self.assertElementPresent(encpart_private, 'last-req') > self.assertElementPresent(encpart_private, 'nonce') >- # TODO self.assertElementPresent(encpart_private, 'key-expiration') >+ # TODO self.assertElementPresent(encpart_private, >+ # 'key-expiration') > self.assertElementPresent(encpart_private, 'flags') > self.assertElementPresent(encpart_private, 'authtime') > if self.strict_checking: > self.assertElementPresent(encpart_private, 'starttime') > self.assertElementPresent(encpart_private, 'endtime') > # TODO self.assertElementPresent(encpart_private, 'renew-till') >- self.assertElementEqualUTF8(encpart_private, 'srealm', expected_srealm) >- self.assertElementEqualPrincipal(encpart_private, 'sname', expected_sname) >+ self.assertElementEqualUTF8(encpart_private, 'srealm', >+ expected_srealm) >+ self.assertElementEqualPrincipal(encpart_private, 'sname', >+ expected_sname) > # TODO self.assertElementMissing(encpart_private, 'caddr') > > if ticket_session_key is not None and encpart_session_key is not None: >- self.assertEqual(ticket_session_key.etype, encpart_session_key.etype) >- self.assertEqual(ticket_session_key.key.contents, encpart_session_key.key.contents) >+ self.assertEqual(ticket_session_key.etype, >+ encpart_session_key.etype) >+ self.assertEqual(ticket_session_key.key.contents, >+ encpart_session_key.key.contents) > if encpart_session_key is not None: > session_key = encpart_session_key > else: > session_key = ticket_session_key >- ticket_creds = KerberosTicketCreds(ticket, >- session_key, >- crealm=expected_crealm, >- cname=expected_cname, >- srealm=expected_srealm, >- sname=expected_sname, >- decryption_key=ticket_decryption_key, >- ticket_private=ticket_private, >- encpart_private=encpart_private) >+ ticket_creds = KerberosTicketCreds( >+ ticket, >+ session_key, >+ crealm=expected_crealm, >+ cname=expected_cname, >+ srealm=expected_srealm, >+ sname=expected_sname, >+ decryption_key=ticket_decryption_key, >+ ticket_private=ticket_private, >+ encpart_private=encpart_private) > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > return >@@ -1728,11 +1770,11 @@ class RawKerberosTest(TestCaseInTempDir): > if kcrypto.Enctype.RC4 in proposed_etypes: > expect_etype_info = True > for etype in proposed_etypes: >- if etype in (kcrypto.Enctype.AES256,kcrypto.Enctype.AES128): >+ if etype in (kcrypto.Enctype.AES256, kcrypto.Enctype.AES128): > expect_etype_info = False > if etype not in client_as_etypes: > continue >- if etype in (kcrypto.Enctype.AES256,kcrypto.Enctype.AES128): >+ if etype in (kcrypto.Enctype.AES256, kcrypto.Enctype.AES128): > if etype > expected_aes_type: > expected_aes_type = etype > if etype in (kcrypto.Enctype.RC4,): >@@ -1779,14 +1821,17 @@ class RawKerberosTest(TestCaseInTempDir): > if self.strict_checking: > self.assertIsNotNone(edata) > if edata is not None: >- rep_padata = self.der_decode(edata, asn1Spec=krb5_asn1.METHOD_DATA()) >+ rep_padata = self.der_decode(edata, >+ asn1Spec=krb5_asn1.METHOD_DATA()) > self.assertGreater(len(rep_padata), 0) > else: > rep_padata = [] > > if self.strict_checking: > for i in range(0, len(expected_patypes)): >- self.assertElementEqual(rep_padata[i], 'padata-type', expected_patypes[i]) >+ self.assertElementEqual(rep_padata[i], >+ 'padata-type', >+ expected_patypes[i]) > self.assertEqual(len(rep_padata), len(expected_patypes)) > > etype_info2 = None >@@ -1799,11 +1844,13 @@ class RawKerberosTest(TestCaseInTempDir): > pavalue = self.getElementValue(pa, 'padata-value') > if patype == PADATA_ETYPE_INFO2: > self.assertIsNone(etype_info2) >- etype_info2 = self.der_decode(pavalue, asn1Spec=krb5_asn1.ETYPE_INFO2()) >+ etype_info2 = self.der_decode(pavalue, >+ asn1Spec=krb5_asn1.ETYPE_INFO2()) > continue > if patype == PADATA_ETYPE_INFO: > self.assertIsNone(etype_info) >- etype_info = self.der_decode(pavalue, asn1Spec=krb5_asn1.ETYPE_INFO()) >+ etype_info = self.der_decode(pavalue, >+ asn1Spec=krb5_asn1.ETYPE_INFO()) > continue > if patype == PADATA_ENC_TIMESTAMP: > self.assertIsNone(enc_timestamp) >@@ -1881,7 +1928,8 @@ class RawKerberosTest(TestCaseInTempDir): > authenticator_subkey = kdc_exchange_dict['authenticator_subkey'] > body_checksum_type = kdc_exchange_dict['body_checksum_type'] > >- req_body_blob = self.der_encode(req_body, asn1Spec=krb5_asn1.KDC_REQ_BODY()) >+ req_body_blob = self.der_encode(req_body, >+ asn1Spec=krb5_asn1.KDC_REQ_BODY()) > > req_body_checksum = self.Checksum_create(tgt.session_key, > KU_TGS_REQ_AUTH_CKSUM, >@@ -1893,15 +1941,18 @@ class RawKerberosTest(TestCaseInTempDir): > subkey_obj = authenticator_subkey.export_obj() > seq_number = random.randint(0, 0xfffffffe) > (ctime, cusec) = self.get_KerberosTimeWithUsec() >- authenticator_obj = self.Authenticator_create(crealm=tgt.crealm, >- cname=tgt.cname, >- cksum=req_body_checksum, >- cusec=cusec, >- ctime=ctime, >- subkey=subkey_obj, >- seq_number=seq_number, >- authorization_data=None) >- authenticator_blob = self.der_encode(authenticator_obj, asn1Spec=krb5_asn1.Authenticator()) >+ authenticator_obj = self.Authenticator_create( >+ crealm=tgt.crealm, >+ cname=tgt.cname, >+ cksum=req_body_checksum, >+ cusec=cusec, >+ ctime=ctime, >+ subkey=subkey_obj, >+ seq_number=seq_number, >+ authorization_data=None) >+ authenticator_blob = self.der_encode( >+ authenticator_obj, >+ asn1Spec=krb5_asn1.Authenticator()) > > authenticator = self.EncryptedData_create(tgt.session_key, > KU_TGS_REQ_AUTH, >@@ -1909,8 +1960,8 @@ class RawKerberosTest(TestCaseInTempDir): > > ap_options = krb5_asn1.APOptions('0') > ap_req_obj = self.AP_REQ_create(ap_options=str(ap_options), >- ticket=tgt.ticket, >- authenticator=authenticator) >+ ticket=tgt.ticket, >+ authenticator=authenticator) > ap_req = self.der_encode(ap_req_obj, asn1Spec=krb5_asn1.AP_REQ()) > pa_tgs_req = self.PA_DATA_create(PADATA_KDC_REQ, ap_req) > padata = [pa_tgs_req] >@@ -1964,19 +2015,19 @@ class RawKerberosTest(TestCaseInTempDir): > return preauth_key, as_rep_usage > > kdc_exchange_dict = self.as_exchange_dict( >- expected_crealm=expected_crealm, >- expected_cname=expected_cname, >- expected_srealm=expected_srealm, >- expected_sname=expected_sname, >- ticket_decryption_key=ticket_decryption_key, >- generate_padata_fn=_generate_padata_copy, >- check_error_fn=self.generic_check_as_error, >- check_rep_fn=self.generic_check_kdc_rep, >- check_padata_fn=_check_padata_preauth_key, >- check_kdc_private_fn=self.generic_check_kdc_private, >- expected_error_mode=expected_error_mode, >- client_as_etypes=client_as_etypes, >- expected_salt=expected_salt) >+ expected_crealm=expected_crealm, >+ expected_cname=expected_cname, >+ expected_srealm=expected_srealm, >+ expected_sname=expected_sname, >+ ticket_decryption_key=ticket_decryption_key, >+ generate_padata_fn=_generate_padata_copy, >+ check_error_fn=self.generic_check_as_error, >+ check_rep_fn=self.generic_check_kdc_rep, >+ check_padata_fn=_check_padata_preauth_key, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ expected_error_mode=expected_error_mode, >+ client_as_etypes=client_as_etypes, >+ expected_salt=expected_salt) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, > kdc_options=str(kdc_options), >@@ -1986,7 +2037,7 @@ class RawKerberosTest(TestCaseInTempDir): > till_time=till, > etypes=etypes) > >- if expected_error_mode == 0: # AS-REP >+ if expected_error_mode == 0: # AS-REP > return rep > > return kdc_exchange_dict['preauth_etype_info2'] >-- >2.25.1 > > >From edffb71c589a6f5e7b57ecda212d49dbadfbd99e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 2 Aug 2021 17:01:39 +1200 >Subject: [PATCH 133/686] tests/krb5: Remove unneeded statements > >A return statement is redundant as the last statement in a method, as >methods will otherwise return None. Also, code blocks consisting of a >single 'pass' statement can be safely omitted. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 1320ac0f91a9b0fc8156840ec498059ee10b5a2d) >--- > python/samba/tests/krb5/as_req_tests.py | 2 - > python/samba/tests/krb5/raw_testcase.py | 99 +++++++++---------------- > 2 files changed, 33 insertions(+), 68 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 09cfc9e1fc8..106c7489e9c 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -46,7 +46,6 @@ class AsReqKerberosTests(KDCBaseTest): > tname = "%s_pac_%s" % (name, pac) > targs = (idx, pac) > cls.generate_dynamic_test("test_as_req_no_preauth", tname, *targs) >- return > > def setUp(self): > super(AsReqKerberosTests, self).setUp() >@@ -197,7 +196,6 @@ class AsReqKerberosTests(KDCBaseTest): > preauth_key=preauth_key, > ticket_decryption_key=krbtgt_decryption_key) > self.assertIsNotNone(as_rep) >- return > > if __name__ == "__main__": > global_asn1_print = True >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index de9c25751d2..34eae177882 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -195,7 +195,6 @@ class Krb5EncryptionKey(object): > self.etype = key.enctype > self.ctype = EncTypeChecksum[self.etype] > self.kvno = kvno >- return > > def encrypt(self, usage, plaintext): > ciphertext = kcrypto.encrypt(self.key, usage, plaintext) >@@ -235,19 +234,15 @@ class KerberosCredentials(Credentials): > self.forced_keys = {} > > self.forced_salt = None >- return > > def set_as_supported_enctypes(self, value): > self.as_supported_enctypes = int(value) >- return > > def set_tgs_supported_enctypes(self, value): > self.tgs_supported_enctypes = int(value) >- return > > def set_ap_supported_enctypes(self, value): > self.ap_supported_enctypes = int(value) >- return > > def _get_krb5_etypes(self, supported_enctypes): > etypes = () >@@ -290,7 +285,6 @@ class KerberosCredentials(Credentials): > > def set_forced_salt(self, salt): > self.forced_salt = bytes(salt) >- return > > def get_forced_salt(self): > return self.forced_salt >@@ -312,7 +306,6 @@ class KerberosTicketCreds(object): > self.decryption_key = decryption_key > self.ticket_private = ticket_private > self.encpart_private = encpart_private >- return > > > class RawKerberosTest(TestCaseInTempDir): >@@ -358,7 +351,6 @@ class RawKerberosTest(TestCaseInTempDir): > > cls.etype_test_permutations = res > cls.setup_etype_test_permutations_done = True >- return > > @classmethod > def etype_test_permutation_name_idx(cls): >@@ -427,17 +419,12 @@ class RawKerberosTest(TestCaseInTempDir): > except IOError: > self.s.close() > raise >- except Exception: >- raise >- finally: >- pass > > def connect(self): > self.assertNotConnected() > self._connect_tcp() > if self.do_hexdump: > sys.stderr.write("connected[%s]\n" % self.host) >- return > > def env_get_var(self, varname, prefix, > fallback_default=True, >@@ -704,8 +691,6 @@ class RawKerberosTest(TestCaseInTempDir): > except IOError as e: > self._disconnect("send_pdu: %s" % e) > raise >- finally: >- pass > > def recv_raw(self, num_recv=0xffff, hexdump=None, timeout=None): > rep_pdu = None >@@ -721,57 +706,51 @@ class RawKerberosTest(TestCaseInTempDir): > except socket.timeout: > self.s.settimeout(10) > sys.stderr.write("recv_raw: TIMEOUT\n") >- pass > except socket.error as e: > self._disconnect("recv_raw: %s" % e) > raise > except IOError as e: > self._disconnect("recv_raw: %s" % e) > raise >- finally: >- pass > return rep_pdu > > def recv_pdu_raw(self, asn1_print=None, hexdump=None, timeout=None): > rep_pdu = None > rep = None >- try: >+ raw_pdu = self.recv_raw( >+ num_recv=4, hexdump=hexdump, timeout=timeout) >+ if raw_pdu is None: >+ return (None, None) >+ header = struct.unpack(">I", raw_pdu[0:4]) >+ k5_len = header[0] >+ if k5_len == 0: >+ return (None, "") >+ missing = k5_len >+ rep_pdu = b'' >+ while missing > 0: > raw_pdu = self.recv_raw( >- num_recv=4, hexdump=hexdump, timeout=timeout) >- if raw_pdu is None: >- return (None, None) >- header = struct.unpack(">I", raw_pdu[0:4]) >- k5_len = header[0] >- if k5_len == 0: >- return (None, "") >- missing = k5_len >- rep_pdu = b'' >- while missing > 0: >- raw_pdu = self.recv_raw( >- num_recv=missing, hexdump=hexdump, timeout=timeout) >- self.assertGreaterEqual(len(raw_pdu), 1) >- rep_pdu += raw_pdu >- missing = k5_len - len(rep_pdu) >- k5_raw = self.der_decode( >- rep_pdu, >- asn1Spec=None, >- native_encode=False, >- asn1_print=False, >- hexdump=False) >- pvno = k5_raw['field-0'] >- self.assertEqual(pvno, 5) >- msg_type = k5_raw['field-1'] >- self.assertIn(msg_type, [11, 13, 30]) >- if msg_type == 11: >- asn1Spec = krb5_asn1.AS_REP() >- elif msg_type == 13: >- asn1Spec = krb5_asn1.TGS_REP() >- elif msg_type == 30: >- asn1Spec = krb5_asn1.KRB_ERROR() >- rep = self.der_decode(rep_pdu, asn1Spec=asn1Spec, >- asn1_print=asn1_print, hexdump=False) >- finally: >- pass >+ num_recv=missing, hexdump=hexdump, timeout=timeout) >+ self.assertGreaterEqual(len(raw_pdu), 1) >+ rep_pdu += raw_pdu >+ missing = k5_len - len(rep_pdu) >+ k5_raw = self.der_decode( >+ rep_pdu, >+ asn1Spec=None, >+ native_encode=False, >+ asn1_print=False, >+ hexdump=False) >+ pvno = k5_raw['field-0'] >+ self.assertEqual(pvno, 5) >+ msg_type = k5_raw['field-1'] >+ self.assertIn(msg_type, [11, 13, 30]) >+ if msg_type == 11: >+ asn1Spec = krb5_asn1.AS_REP() >+ elif msg_type == 13: >+ asn1Spec = krb5_asn1.TGS_REP() >+ elif msg_type == 30: >+ asn1Spec = krb5_asn1.KRB_ERROR() >+ rep = self.der_decode(rep_pdu, asn1Spec=asn1Spec, >+ asn1_print=asn1_print, hexdump=False) > return (rep, rep_pdu) > > def recv_pdu(self, asn1_print=None, hexdump=None, timeout=None): >@@ -782,11 +761,9 @@ class RawKerberosTest(TestCaseInTempDir): > > def assertIsConnected(self): > self.assertIsNotNone(self.s, msg="Not connected") >- return > > def assertNotConnected(self): > self.assertIsNone(self.s, msg="Is connected") >- return > > def send_recv_transaction( > self, >@@ -807,11 +784,9 @@ class RawKerberosTest(TestCaseInTempDir): > > def assertNoValue(self, value): > self.assertTrue(value.isNoValue) >- return > > def assertHasValue(self, value): > self.assertIsNotNone(value) >- return > > def getElementValue(self, obj, elem): > v = None >@@ -824,24 +799,20 @@ class RawKerberosTest(TestCaseInTempDir): > def assertElementMissing(self, obj, elem): > v = self.getElementValue(obj, elem) > self.assertIsNone(v) >- return > > def assertElementPresent(self, obj, elem): > v = self.getElementValue(obj, elem) > self.assertIsNotNone(v) >- return > > def assertElementEqual(self, obj, elem, value): > v = self.getElementValue(obj, elem) > self.assertIsNotNone(v) > self.assertEqual(v, value) >- return > > def assertElementEqualUTF8(self, obj, elem, value): > v = self.getElementValue(obj, elem) > self.assertIsNotNone(v) > self.assertEqual(v, bytes(value, 'utf8')) >- return > > def assertPrincipalEqual(self, princ1, princ2): > self.assertEqual(princ1['name-type'], princ2['name-type']) >@@ -854,14 +825,12 @@ class RawKerberosTest(TestCaseInTempDir): > princ1['name-string'][idx], > princ2['name-string'][idx], > msg="princ1=%s != princ2=%s" % (princ1, princ2)) >- return > > def assertElementEqualPrincipal(self, obj, elem, value): > v = self.getElementValue(obj, elem) > self.assertIsNotNone(v) > v = pyasn1_native_decode(v, asn1Spec=krb5_asn1.PrincipalName()) > self.assertPrincipalEqual(v, value) >- return > > def assertElementKVNO(self, obj, elem, value): > v = self.getElementValue(obj, elem) >@@ -879,7 +848,6 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertEqual(v, value) > else: > self.assertIsNone(v) >- return > > def get_KerberosTimeWithUsec(self, epoch=None, offset=None): > if epoch is None: >@@ -1743,7 +1711,6 @@ class RawKerberosTest(TestCaseInTempDir): > encpart_private=encpart_private) > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds >- return > > def generic_check_as_error(self, > kdc_exchange_dict, >-- >2.25.1 > > >From 3da1f1d62c19eae550122f61fb99c92fd92cb404 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 2 Aug 2021 17:10:32 +1200 >Subject: [PATCH 134/686] tests/krb5: Use more compact dict lookup > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 38b3a361819c716adb773fb3b4507c28d7d26c0d) >--- > python/samba/tests/krb5/kdc_base_test.py | 5 +---- > python/samba/tests/krb5/raw_testcase.py | 18 ++++-------------- > 2 files changed, 5 insertions(+), 18 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index c23c71e1d74..79efc68254e 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -722,10 +722,7 @@ class KDCBaseTest(RawKerberosTest): > ticket_data = self.der_encode(ticket, asn1Spec=krb5_asn1.Ticket()) > > authtime = enc_part['authtime'] >- try: >- starttime = enc_part['starttime'] >- except KeyError: >- starttime = authtime >+ starttime = enc_part.get('starttime', authtime) > endtime = enc_part['endtime'] > > cred = krb5ccache.CREDENTIAL() >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 34eae177882..15bbd9ec999 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -279,9 +279,7 @@ class KerberosCredentials(Credentials): > > def get_forced_key(self, etype): > etype = int(etype) >- if etype in self.forced_keys: >- return self.forced_keys[etype] >- return None >+ return self.forced_keys.get(etype, None) > > def set_forced_salt(self, salt): > self.forced_salt = bytes(salt) >@@ -789,12 +787,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(value) > > def getElementValue(self, obj, elem): >- v = None >- try: >- v = obj[elem] >- except KeyError: >- pass >- return v >+ return obj.get(elem, None) > > def assertElementMissing(self, obj, elem): > v = self.getElementValue(obj, elem) >@@ -879,11 +872,8 @@ class RawKerberosTest(TestCaseInTempDir): > > def PasswordKey_from_etype_info2(self, creds, etype_info2, kvno=None): > e = etype_info2['etype'] >- salt = None >- try: >- salt = etype_info2['salt'] >- except Exception: >- pass >+ >+ salt = etype_info2.get('salt', None) > > if e == kcrypto.Enctype.RC4: > nthash = creds.get_nt_hash() >-- >2.25.1 > > >From 78d91831eff416a4fa53c94f6b2c756a049b870a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 3 Aug 2021 15:03:00 +1200 >Subject: [PATCH 135/686] tests/krb5: Simplify Python syntax > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 41c3e410344280d691e5a21fa5240ef52e71bd2d) >--- > python/samba/tests/krb5/raw_testcase.py | 12 +++++------- > 1 file changed, 5 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 15bbd9ec999..31731a6547c 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -184,7 +184,7 @@ krb5_asn1.KerbErrorDataType.prettyPrint =\ > Integer_NamedValues_prettyPrint > > >-class Krb5EncryptionKey(object): >+class Krb5EncryptionKey: > def __init__(self, key, kvno): > EncTypeChecksum = { > kcrypto.Enctype.AES256: kcrypto.Cksumtype.SHA1_AES256, >@@ -288,7 +288,7 @@ class KerberosCredentials(Credentials): > return self.forced_salt > > >-class KerberosTicketCreds(object): >+class KerberosTicketCreds: > def __init__(self, ticket, session_key, > crealm=None, cname=None, > srealm=None, sname=None, >@@ -956,7 +956,7 @@ class RawKerberosTest(TestCaseInTempDir): > return Checksum_obj > > @classmethod >- def PrincipalName_create(self, name_type, names): >+ def PrincipalName_create(cls, name_type, names): > # PrincipalName ::= SEQUENCE { > # name-type [0] Int32, > # name-string [1] SEQUENCE OF KerberosString >@@ -1785,10 +1785,8 @@ class RawKerberosTest(TestCaseInTempDir): > rep_padata = [] > > if self.strict_checking: >- for i in range(0, len(expected_patypes)): >- self.assertElementEqual(rep_padata[i], >- 'padata-type', >- expected_patypes[i]) >+ for i, patype in enumerate(expected_patypes): >+ self.assertElementEqual(rep_padata[i], 'padata-type', patype) > self.assertEqual(len(rep_padata), len(expected_patypes)) > > etype_info2 = None >-- >2.25.1 > > >From 87875dfd4569a5e4355ca784b36a0fe026d7bff5 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 13:49:27 +1200 >Subject: [PATCH 136/686] tests/krb5: Remove magic constants > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit a2b183c179e74634438c85a4b35518836ba59e47) >--- > python/samba/tests/krb5/raw_testcase.py | 30 +++++++++++--------- > python/samba/tests/krb5/rfc4120_constants.py | 7 +++++ > 2 files changed, 24 insertions(+), 13 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 31731a6547c..dfa6a71467a 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -41,12 +41,14 @@ import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_ETYPE_NOSUPP, > KDC_ERR_PREAUTH_REQUIRED, >+ KRB_AP_REQ, > KRB_AS_REP, > KRB_AS_REQ, > KRB_ERROR, > KRB_TGS_REP, > KRB_TGS_REQ, > KU_AS_REP_ENC_PART, >+ KU_NON_KERB_CKSUM_SALT, > KU_TGS_REP_ENC_PART_SESSION, > KU_TGS_REP_ENC_PART_SUB_KEY, > KU_TGS_REQ_AUTH, >@@ -55,7 +57,9 @@ from samba.tests.krb5.rfc4120_constants import ( > PADATA_ENC_TIMESTAMP, > PADATA_ETYPE_INFO, > PADATA_ETYPE_INFO2, >+ PADATA_FOR_USER, > PADATA_KDC_REQ, >+ PADATA_PAC_REQUEST, > PADATA_PK_AS_REQ, > PADATA_PK_AS_REP_19 > ) >@@ -740,12 +744,12 @@ class RawKerberosTest(TestCaseInTempDir): > pvno = k5_raw['field-0'] > self.assertEqual(pvno, 5) > msg_type = k5_raw['field-1'] >- self.assertIn(msg_type, [11, 13, 30]) >- if msg_type == 11: >+ self.assertIn(msg_type, [KRB_AS_REP, KRB_TGS_REP, KRB_ERROR]) >+ if msg_type == KRB_AS_REP: > asn1Spec = krb5_asn1.AS_REP() >- elif msg_type == 13: >+ elif msg_type == KRB_TGS_REP: > asn1Spec = krb5_asn1.TGS_REP() >- elif msg_type == 30: >+ elif msg_type == KRB_ERROR: > asn1Spec = krb5_asn1.KRB_ERROR() > rep = self.der_decode(rep_pdu, asn1Spec=asn1Spec, > asn1_print=asn1_print, hexdump=False) >@@ -1004,7 +1008,7 @@ class RawKerberosTest(TestCaseInTempDir): > return KERB_PA_PAC_REQUEST_obj > pa_pac = self.der_encode(KERB_PA_PAC_REQUEST_obj, > asn1Spec=krb5_asn1.KERB_PA_PAC_REQUEST()) >- pa_data = self.PA_DATA_create(128, pa_pac) # PA-PAC-REQUEST >+ pa_data = self.PA_DATA_create(PADATA_PAC_REQUEST, pa_pac) > return pa_data > > def KDC_REQ_BODY_create(self, >@@ -1172,7 +1176,7 @@ class RawKerberosTest(TestCaseInTempDir): > asn1_print=asn1_print, > hexdump=hexdump) > obj, decoded = self.KDC_REQ_create( >- msg_type=10, >+ msg_type=KRB_AS_REQ, > padata=padata, > req_body=KDC_REQ_BODY_obj, > asn1Spec=krb5_asn1.AS_REQ(), >@@ -1192,7 +1196,7 @@ class RawKerberosTest(TestCaseInTempDir): > # } > AP_REQ_obj = { > 'pvno': 5, >- 'msg-type': 14, >+ 'msg-type': KRB_AP_REQ, > 'ap-options': ap_options, > 'ticket': ticket, > 'authenticator': authenticator, >@@ -1305,7 +1309,7 @@ class RawKerberosTest(TestCaseInTempDir): > asn1_print=asn1_print, hexdump=hexdump) > > req_body_checksum = self.Checksum_create(ticket_session_key, >- 6, >+ KU_TGS_REQ_AUTH_CKSUM, > req_body_blob, > ctype=body_checksum_type) > >@@ -1329,7 +1333,7 @@ class RawKerberosTest(TestCaseInTempDir): > hexdump=hexdump) > > authenticator = self.EncryptedData_create( >- ticket_session_key, 7, authenticator) >+ ticket_session_key, KU_TGS_REQ_AUTH, authenticator) > > ap_options = krb5_asn1.APOptions('0') > ap_req = self.AP_REQ_create(ap_options=str(ap_options), >@@ -1337,14 +1341,14 @@ class RawKerberosTest(TestCaseInTempDir): > authenticator=authenticator) > ap_req = self.der_encode(ap_req, asn1Spec=krb5_asn1.AP_REQ(), > asn1_print=asn1_print, hexdump=hexdump) >- pa_tgs_req = self.PA_DATA_create(1, ap_req) >+ pa_tgs_req = self.PA_DATA_create(PADATA_KDC_REQ, ap_req) > if padata is not None: > padata.append(pa_tgs_req) > else: > padata = [pa_tgs_req] > > obj, decoded = self.KDC_REQ_create( >- msg_type=12, >+ msg_type=KRB_TGS_REQ, > padata=padata, > req_body=req_body, > asn1Spec=krb5_asn1.TGS_REQ(), >@@ -1367,7 +1371,7 @@ class RawKerberosTest(TestCaseInTempDir): > cksum_data += realm.encode() > cksum_data += "Kerberos".encode() > cksum = self.Checksum_create(tgt_session_key, >- 17, >+ KU_NON_KERB_CKSUM_SALT, > cksum_data, > ctype) > >@@ -1379,7 +1383,7 @@ class RawKerberosTest(TestCaseInTempDir): > } > pa_s4u2self = self.der_encode( > PA_S4U2Self_obj, asn1Spec=krb5_asn1.PA_S4U2Self()) >- return self.PA_DATA_create(129, pa_s4u2self) >+ return self.PA_DATA_create(PADATA_FOR_USER, pa_s4u2self) > > def _generic_kdc_exchange(self, > kdc_exchange_dict, # required >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index a4c5e079b66..adcc93e1d6b 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -27,6 +27,7 @@ ARCFOUR_HMAC_MD5 = int( > > # Message types > KRB_ERROR = int(krb5_asn1.MessageTypeValues('krb-error')) >+KRB_AP_REQ = int(krb5_asn1.MessageTypeValues('krb-ap-req')) > KRB_AS_REP = int(krb5_asn1.MessageTypeValues('krb-as-rep')) > KRB_AS_REQ = int(krb5_asn1.MessageTypeValues('krb-as-req')) > KRB_TGS_REP = int(krb5_asn1.MessageTypeValues('krb-tgs-rep')) >@@ -39,8 +40,12 @@ PADATA_ETYPE_INFO = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-ETYPE-INFO')) > PADATA_ETYPE_INFO2 = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-ETYPE-INFO2')) >+PADATA_FOR_USER = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-FOR-USER')) > PADATA_KDC_REQ = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-KDC-REQ')) >+PADATA_PAC_REQUEST = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-PA-PAC-REQUEST')) > PADATA_PK_AS_REQ = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-PK-AS-REQ')) > PADATA_PK_AS_REP_19 = int( >@@ -125,3 +130,5 @@ KU_KRB_CRED = 14 > KU_KRB_SAFE_CKSUM = 15 > ''' KRB-SAFE cksum, keyed with a key chosen by the application > (section 5.6.1) ''' >+KU_NON_KERB_SALT = 16 >+KU_NON_KERB_CKSUM_SALT = 17 >-- >2.25.1 > > >From 2ff3e02cc21564c0f7d4753022df3fbdf99b1367 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 26 Jul 2021 17:14:08 +1200 >Subject: [PATCH 137/686] tests/krb5: Fix including enc-authorization-data > >Remove the EncAuthorizationData parameters from AS_REQ_create(), since >it should only be present in the TGS-REQ form. Also, fix a call to >EncryptedData_create() to supply the key usage when creating >enc-authorization-data. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 67ff72395cec2e5170c0ebae8db416a1f226df72) >--- > .../tests/krb5/as_canonicalization_tests.py | 4 --- > .../samba/tests/krb5/compatability_tests.py | 4 --- > python/samba/tests/krb5/kdc_base_test.py | 2 -- > python/samba/tests/krb5/kdc_tests.py | 2 -- > python/samba/tests/krb5/raw_testcase.py | 31 +++++++++++++------ > python/samba/tests/krb5/s4u_tests.py | 4 --- > python/samba/tests/krb5/simple_tests.py | 4 --- > python/samba/tests/krb5/xrealm_tests.py | 4 --- > 8 files changed, 21 insertions(+), 34 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index abb3f96a1e6..29d8cf418f5 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -257,8 +257,6 @@ class KerberosASCanonicalizationTests(KDCBaseTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > self.assertIsNotNone(rep) >@@ -314,8 +312,6 @@ class KerberosASCanonicalizationTests(KDCBaseTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > self.assertIsNotNone(rep) >diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py >index 5a1ef02ef80..cd67549212a 100755 >--- a/python/samba/tests/krb5/compatability_tests.py >+++ b/python/samba/tests/krb5/compatability_tests.py >@@ -147,8 +147,6 @@ class SimpleKerberosTests(RawKerberosTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > >@@ -209,8 +207,6 @@ class SimpleKerberosTests(RawKerberosTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > self.assertIsNotNone(rep) >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 79efc68254e..7874562d32d 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -390,8 +390,6 @@ class KDCBaseTest(RawKerberosTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > return rep >diff --git a/python/samba/tests/krb5/kdc_tests.py b/python/samba/tests/krb5/kdc_tests.py >index c7c53953a86..930edd0a63e 100755 >--- a/python/samba/tests/krb5/kdc_tests.py >+++ b/python/samba/tests/krb5/kdc_tests.py >@@ -79,8 +79,6 @@ class KdcTests(RawKerberosTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > return rep >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index dfa6a71467a..f39656d5e03 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -53,6 +53,8 @@ from samba.tests.krb5.rfc4120_constants import ( > KU_TGS_REP_ENC_PART_SUB_KEY, > KU_TGS_REQ_AUTH, > KU_TGS_REQ_AUTH_CKSUM, >+ KU_TGS_REQ_AUTH_DAT_SESSION, >+ KU_TGS_REQ_AUTH_DAT_SUBKEY, > KU_TICKET, > PADATA_ENC_TIMESTAMP, > PADATA_ETYPE_INFO, >@@ -1022,9 +1024,10 @@ class RawKerberosTest(TestCaseInTempDir): > nonce, > etypes, > addresses, >+ additional_tickets, > EncAuthorizationData, > EncAuthorizationData_key, >- additional_tickets, >+ EncAuthorizationData_usage, > asn1_print=None, > hexdump=None): > # KDC-REQ-BODY ::= SEQUENCE { >@@ -1054,8 +1057,9 @@ class RawKerberosTest(TestCaseInTempDir): > asn1Spec=krb5_asn1.AuthorizationData(), > asn1_print=asn1_print, > hexdump=hexdump) >- enc_ad = self.EncryptedData_create( >- EncAuthorizationData_key, enc_ad_plain) >+ enc_ad = self.EncryptedData_create(EncAuthorizationData_key, >+ EncAuthorizationData_usage, >+ enc_ad_plain) > else: > enc_ad = None > KDC_REQ_BODY_obj = { >@@ -1123,8 +1127,6 @@ class RawKerberosTest(TestCaseInTempDir): > nonce, # required > etypes, # required > addresses, # optional >- EncAuthorizationData, >- EncAuthorizationData_key, > additional_tickets, > native_decoded_only=True, > asn1_print=None, >@@ -1170,9 +1172,10 @@ class RawKerberosTest(TestCaseInTempDir): > nonce, > etypes, > addresses, >- EncAuthorizationData, >- EncAuthorizationData_key, > additional_tickets, >+ EncAuthorizationData=None, >+ EncAuthorizationData_key=None, >+ EncAuthorizationData_usage=None, > asn1_print=asn1_print, > hexdump=hexdump) > obj, decoded = self.KDC_REQ_create( >@@ -1290,6 +1293,11 @@ class RawKerberosTest(TestCaseInTempDir): > # -- NOTE: not empty > # } > >+ if authenticator_subkey is not None: >+ EncAuthorizationData_usage = KU_TGS_REQ_AUTH_DAT_SUBKEY >+ else: >+ EncAuthorizationData_usage = KU_TGS_REQ_AUTH_DAT_SESSION >+ > req_body = self.KDC_REQ_BODY_create( > kdc_options=kdc_options, > cname=None, >@@ -1301,9 +1309,10 @@ class RawKerberosTest(TestCaseInTempDir): > nonce=nonce, > etypes=etypes, > addresses=addresses, >+ additional_tickets=additional_tickets, > EncAuthorizationData=EncAuthorizationData, > EncAuthorizationData_key=EncAuthorizationData_key, >- additional_tickets=additional_tickets) >+ EncAuthorizationData_usage=EncAuthorizationData_usage) > req_body_blob = self.der_encode(req_body, > asn1Spec=krb5_asn1.KDC_REQ_BODY(), > asn1_print=asn1_print, hexdump=hexdump) >@@ -1397,9 +1406,10 @@ class RawKerberosTest(TestCaseInTempDir): > nonce=None, # required > etypes=None, # required > addresses=None, # optional >+ additional_tickets=None, # optional > EncAuthorizationData=None, # optional > EncAuthorizationData_key=None, # optional >- additional_tickets=None): # optional >+ EncAuthorizationData_usage=None): # optional > > check_error_fn = kdc_exchange_dict['check_error_fn'] > check_rep_fn = kdc_exchange_dict['check_rep_fn'] >@@ -1425,9 +1435,10 @@ class RawKerberosTest(TestCaseInTempDir): > nonce=nonce, > etypes=etypes, > addresses=addresses, >+ additional_tickets=additional_tickets, > EncAuthorizationData=EncAuthorizationData, > EncAuthorizationData_key=EncAuthorizationData_key, >- additional_tickets=additional_tickets) >+ EncAuthorizationData_usage=EncAuthorizationData_usage) > if generate_padata_fn is not None: > # This can alter req_body... > padata, req_body = generate_padata_fn(kdc_exchange_dict, >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index 30a58d6345a..57575f0595d 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -69,8 +69,6 @@ class S4UKerberosTests(RawKerberosTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > self.assertIsNotNone(rep) >@@ -113,8 +111,6 @@ class S4UKerberosTests(RawKerberosTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > self.assertIsNotNone(rep) >diff --git a/python/samba/tests/krb5/simple_tests.py b/python/samba/tests/krb5/simple_tests.py >index 9650702c6c6..795d753b4f7 100755 >--- a/python/samba/tests/krb5/simple_tests.py >+++ b/python/samba/tests/krb5/simple_tests.py >@@ -69,8 +69,6 @@ class SimpleKerberosTests(RawKerberosTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > self.assertIsNotNone(rep) >@@ -113,8 +111,6 @@ class SimpleKerberosTests(RawKerberosTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > self.assertIsNotNone(rep) >diff --git a/python/samba/tests/krb5/xrealm_tests.py b/python/samba/tests/krb5/xrealm_tests.py >index efb953bdf7e..073cb755b46 100755 >--- a/python/samba/tests/krb5/xrealm_tests.py >+++ b/python/samba/tests/krb5/xrealm_tests.py >@@ -68,8 +68,6 @@ class XrealmKerberosTests(RawKerberosTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > self.assertIsNotNone(rep) >@@ -112,8 +110,6 @@ class XrealmKerberosTests(RawKerberosTest): > nonce=0x7fffffff, > etypes=etypes, > addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, > additional_tickets=None) > rep = self.send_recv_transaction(req) > self.assertIsNotNone(rep) >-- >2.25.1 > > >From 1622224688c44118dd292e27d7622960aa237bc2 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 11:12:34 +1200 >Subject: [PATCH 138/686] tests/krb5: Fix callback_dict parameter > >Items contained in a default-created callback_dict should not be carried >over between unrelated calls to {as,tgs}_as_exchange_dict(). > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit bad5f4ee5fdf64ca9d775233fec24975e0b510bf) >--- > python/samba/tests/krb5/raw_testcase.py | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index f39656d5e03..fc8e6990834 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1486,7 +1486,7 @@ class RawKerberosTest(TestCaseInTempDir): > check_rep_fn=None, > check_padata_fn=None, > check_kdc_private_fn=None, >- callback_dict=dict(), >+ callback_dict=None, > expected_error_mode=None, > client_as_etypes=None, > expected_salt=None): >@@ -1511,6 +1511,9 @@ class RawKerberosTest(TestCaseInTempDir): > 'client_as_etypes': client_as_etypes, > 'expected_salt': expected_salt, > } >+ if callback_dict is None: >+ callback_dict = {} >+ > return kdc_exchange_dict > > def tgs_exchange_dict(self, >@@ -1524,7 +1527,7 @@ class RawKerberosTest(TestCaseInTempDir): > check_rep_fn=None, > check_padata_fn=None, > check_kdc_private_fn=None, >- callback_dict=dict(), >+ callback_dict=None, > tgt=None, > authenticator_subkey=None, > body_checksum_type=None): >@@ -1549,6 +1552,9 @@ class RawKerberosTest(TestCaseInTempDir): > 'body_checksum_type': body_checksum_type, > 'authenticator_subkey': authenticator_subkey, > } >+ if callback_dict is None: >+ callback_dict = {} >+ > return kdc_exchange_dict > > def generic_check_kdc_rep(self, >-- >2.25.1 > > >From a6025c4dba632ceeff5d6063b98ac4341eb248fe Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:06:29 +1200 >Subject: [PATCH 139/686] tests/krb5: Fix encpart_decryption_key with MIT KDC > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit a0c6538a97126671f9c7bcf3b581f3d98cbc7fd1) >--- > python/samba/tests/krb5/raw_testcase.py | 13 ++++++++++--- > 1 file changed, 10 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index fc8e6990834..1c08b76061f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1630,9 +1630,16 @@ class RawKerberosTest(TestCaseInTempDir): > rep_decpart = encpart_decryption_key.decrypt( > encpart_decryption_usage, > encpart_cipher) >- encpart_private = self.der_decode( >- rep_decpart, >- asn1Spec=rep_encpart_asn1Spec()) >+ # MIT KDC encodes both EncASRepPart and EncTGSRepPart with >+ # application tag 26 >+ try: >+ encpart_private = self.der_decode( >+ rep_decpart, >+ asn1Spec=rep_encpart_asn1Spec()) >+ except Exception: >+ encpart_private = self.der_decode( >+ rep_decpart, >+ asn1Spec=krb5_asn1.EncTGSRepPart()) > > if check_kdc_private_fn is not None: > check_kdc_private_fn(kdc_exchange_dict, callback_dict, >-- >2.25.1 > > >From 17b2c5c6b94b38106e0e578e156fbe66f4ce5532 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Jul 2021 17:00:09 +1200 >Subject: [PATCH 140/686] tests/krb5: Expect e-data except when the error code > is KDC_ERR_GENERIC > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 8194b2a2611c6b1db2d29ec22c70e14decd1784b) >--- > python/samba/tests/krb5/raw_testcase.py | 3 ++- > python/samba/tests/krb5/rfc4120_constants.py | 1 + > 2 files changed, 3 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 1c08b76061f..c0e997a86a1 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -40,6 +40,7 @@ from samba.tests import TestCaseInTempDir > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_ETYPE_NOSUPP, >+ KDC_ERR_GENERIC, > KDC_ERR_PREAUTH_REQUIRED, > KRB_AP_REQ, > KRB_AS_REP, >@@ -1799,7 +1800,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementEqualPrincipal(rep, 'sname', expected_sname) > if self.strict_checking: > self.assertElementMissing(rep, 'e-text') >- if expected_error_mode != KDC_ERR_PREAUTH_REQUIRED: >+ if expected_error_mode == KDC_ERR_GENERIC: > self.assertElementMissing(rep, 'e-data') > return > edata = self.getElementValue(rep, 'e-data') >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index adcc93e1d6b..b00b8b48ae5 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -58,6 +58,7 @@ KDC_ERR_PREAUTH_FAILED = 24 > KDC_ERR_PREAUTH_REQUIRED = 25 > KDC_ERR_BADMATCH = 36 > KDC_ERR_SKEW = 37 >+KDC_ERR_GENERIC = 60 > > # Name types > NT_UNKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-UNKNOWN')) >-- >2.25.1 > > >From 84368a1544b88b4dce682572b7b3f625d71bb163 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 15:07:59 +1200 >Subject: [PATCH 141/686] tests/krb5: Check Kerberos protocol version number > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d6a242e20004217a0ce02dc4ef620a121e5944da) >--- > python/samba/tests/krb5/raw_testcase.py | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index c0e997a86a1..693f196940c 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1786,6 +1786,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_patypes += (PADATA_PK_AS_REQ,) > expected_patypes += (PADATA_PK_AS_REP_19,) > >+ self.assertElementEqual(rep, 'pvno', 5) > self.assertElementEqual(rep, 'msg-type', KRB_ERROR) > self.assertElementEqual(rep, 'error-code', expected_error) > self.assertElementMissing(rep, 'ctime') >-- >2.25.1 > > >From 3e7be91b243df1eae9d1aa4825a899bfbd772173 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 6 Jul 2021 11:28:37 +1200 >Subject: [PATCH 142/686] tests/krb5: Use credentials kvno when creating > password key > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 17d5a267298ccd7272e86fd24c2c608511cf46b7) >--- > python/samba/tests/krb5/kdc_base_test.py | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 7874562d32d..aa172640399 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -409,7 +409,8 @@ class KDCBaseTest(RawKerberosTest): > etype_info2 = self.der_decode( > padata_value, asn1Spec=krb5_asn1.ETYPE_INFO2()) > >- key = self.PasswordKey_from_etype_info2(creds, etype_info2[0]) >+ key = self.PasswordKey_from_etype_info2(creds, etype_info2[0], >+ creds.get_kvno()) > return key > > def get_pa_data(self, creds, rep, skew=0): >-- >2.25.1 > > >From 86d6d15f0009c1c9d82730286a00712535b2546f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 6 Jul 2021 10:24:52 +1200 >Subject: [PATCH 143/686] tests/krb5: Allow cf2 to automatically use the > enctype of the first key > >RFC6113 states: "Unless otherwise specified, the resulting enctype of >KRB-FX-CF2 is the enctype of k1." This change means the enctype no >longer has to be specified manually. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit a5e5f8fdfe8b6952592d7d682af893c79080826f) >--- > python/samba/tests/krb5/kcrypto.py | 12 +++++++----- > 1 file changed, 7 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/kcrypto.py b/python/samba/tests/krb5/kcrypto.py >index 23502d7bb62..c861e3cc96e 100755 >--- a/python/samba/tests/krb5/kcrypto.py >+++ b/python/samba/tests/krb5/kcrypto.py >@@ -653,9 +653,11 @@ def prfplus(key, pepper, ln): > return out[:ln] > > >-def cf2(enctype, key1, key2, pepper1, pepper2): >+def cf2(key1, key2, pepper1, pepper2, enctype=None): > # Combine two keys and two pepper strings to produce a result key > # of type enctype, using the RFC 6113 KRB-FX-CF2 function. >+ if enctype is None: >+ enctype = key1.enctype > e = _get_enctype_profile(enctype) > return e.random_to_key(_xorbytes(prfplus(key1, pepper1, e.seedsize), > prfplus(key2, pepper2, e.seedsize))) >@@ -748,7 +750,7 @@ class KcrytoTest(TestCase): > kb = h('97DF97E4B798B29EB31ED7280287A92A') > k1 = string_to_key(Enctype.AES128, b'key1', b'key1') > k2 = string_to_key(Enctype.AES128, b'key2', b'key2') >- k = cf2(Enctype.AES128, k1, k2, b'a', b'b') >+ k = cf2(k1, k2, b'a', b'b') > self.assertEqual(k.contents, kb) > > def test_aes256_cf2(self): >@@ -757,7 +759,7 @@ class KcrytoTest(TestCase): > 'E72B1C7B') > k1 = string_to_key(Enctype.AES256, b'key1', b'key1') > k2 = string_to_key(Enctype.AES256, b'key2', b'key2') >- k = cf2(Enctype.AES256, k1, k2, b'a', b'b') >+ k = cf2(k1, k2, b'a', b'b') > self.assertEqual(k.contents, kb) > > def test_des3_crypt(self): >@@ -794,7 +796,7 @@ class KcrytoTest(TestCase): > kb = h('E58F9EB643862C13AD38E529313462A7F73E62834FE54A01') > k1 = string_to_key(Enctype.DES3, b'key1', b'key1') > k2 = string_to_key(Enctype.DES3, b'key2', b'key2') >- k = cf2(Enctype.DES3, k1, k2, b'a', b'b') >+ k = cf2(k1, k2, b'a', b'b') > self.assertEqual(k.contents, kb) > > def test_rc4_crypt(self): >@@ -830,7 +832,7 @@ class KcrytoTest(TestCase): > kb = h('24D7F6B6BAE4E5C00D2082C5EBAB3672') > k1 = string_to_key(Enctype.RC4, b'key1', b'key1') > k2 = string_to_key(Enctype.RC4, b'key2', b'key2') >- k = cf2(Enctype.RC4, k1, k2, b'a', b'b') >+ k = cf2(k1, k2, b'a', b'b') > self.assertEqual(k.contents, kb) > > def _test_md5_unkeyed_checksum(self, etype, usage): >-- >2.25.1 > > >From 3d2a9d67413f0bbdabab58dc01059672e650889a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 6 Jul 2021 10:16:01 +1200 >Subject: [PATCH 144/686] tests/krb5: Refactor get_pa_data() > >The function now returns a single padata object rather than a list, >making it easier to combine multiple padata elements into a request. The >new name 'get_enc_timestamp_pa_data' also makes it clearer as to what >the method generates. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 2c80f7f851a7a4ffbcde2c42b2c383b683b67731) >--- > python/samba/tests/krb5/kdc_base_test.py | 8 ++-- > python/samba/tests/krb5/kdc_tests.py | 25 ++++++------ > python/samba/tests/krb5/kdc_tgs_tests.py | 12 +++--- > .../ms_kile_client_principal_lookup_tests.py | 40 +++++++++---------- > 4 files changed, 42 insertions(+), 43 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index aa172640399..7748eae6225 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -413,7 +413,7 @@ class KDCBaseTest(RawKerberosTest): > creds.get_kvno()) > return key > >- def get_pa_data(self, creds, rep, skew=0): >+ def get_enc_timestamp_pa_data(self, creds, rep, skew=0): > '''generate the pa_data data element for an AS-REQ > ''' > key = self.get_as_rep_key(creds, rep) >@@ -427,7 +427,7 @@ class KDCBaseTest(RawKerberosTest): > > padata = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, padata) > >- return [padata] >+ return padata > > def get_as_rep_enc_data(self, key, rep): > ''' Decrypt and Decode the encrypted data in an AS-REP >@@ -795,9 +795,9 @@ class KDCBaseTest(RawKerberosTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(user_credentials, rep) >+ padata = self.get_enc_timestamp_pa_data(user_credentials, rep) > key = self.get_as_rep_key(user_credentials, rep) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > # Request a ticket to the host service on the machine account >diff --git a/python/samba/tests/krb5/kdc_tests.py b/python/samba/tests/krb5/kdc_tests.py >index 930edd0a63e..928f3c25c0f 100755 >--- a/python/samba/tests/krb5/kdc_tests.py >+++ b/python/samba/tests/krb5/kdc_tests.py >@@ -83,7 +83,7 @@ class KdcTests(RawKerberosTest): > rep = self.send_recv_transaction(req) > return rep > >- def get_pa_data(self, creds, rep, skew=0): >+ def get_enc_timestamp_pa_data(self, creds, rep, skew=0): > rep_padata = self.der_decode( > rep['e-data'], > asn1Spec=krb5_asn1.METHOD_DATA()) >@@ -107,8 +107,7 @@ class KdcTests(RawKerberosTest): > > pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts) > >- padata = [pa_ts] >- return padata >+ return pa_ts > > def check_pre_authenication(self, rep): > """ Check that the kdc response was pre-authentication required >@@ -160,8 +159,8 @@ class KdcTests(RawKerberosTest): > rep = self.as_req(creds, etype) > self.check_pre_authenication(rep) > >- padata = self.get_pa_data(creds, rep) >- rep = self.as_req(creds, etype, padata=padata) >+ padata = self.get_enc_timestamp_pa_data(creds, rep) >+ rep = self.as_req(creds, etype, padata=[padata]) > self.check_as_reply(rep) > > etype = rep['enc-part']['etype'] >@@ -174,8 +173,8 @@ class KdcTests(RawKerberosTest): > rep = self.as_req(creds, etype) > self.check_pre_authenication(rep) > >- padata = self.get_pa_data(creds, rep) >- rep = self.as_req(creds, etype, padata=padata) >+ padata = self.get_enc_timestamp_pa_data(creds, rep) >+ rep = self.as_req(creds, etype, padata=[padata]) > self.check_as_reply(rep) > > etype = rep['enc-part']['etype'] >@@ -188,8 +187,8 @@ class KdcTests(RawKerberosTest): > rep = self.as_req(creds, etype) > self.check_pre_authenication(rep) > >- padata = self.get_pa_data(creds, rep) >- rep = self.as_req(creds, etype, padata=padata) >+ padata = self.get_enc_timestamp_pa_data(creds, rep) >+ rep = self.as_req(creds, etype, padata=[padata]) > self.check_as_reply(rep) > > etype = rep['enc-part']['etype'] >@@ -202,8 +201,8 @@ class KdcTests(RawKerberosTest): > rep = self.as_req(creds, etype) > self.check_pre_authenication(rep) > >- padata = self.get_pa_data(creds, rep, skew=3600) >- rep = self.as_req(creds, etype, padata=padata) >+ padata = self.get_enc_timestamp_pa_data(creds, rep, skew=3600) >+ rep = self.as_req(creds, etype, padata=[padata]) > > self.check_error_rep(rep, KDC_ERR_SKEW) > >@@ -216,8 +215,8 @@ class KdcTests(RawKerberosTest): > rep = self.as_req(creds, etype) > self.check_pre_authenication(rep) > >- padata = self.get_pa_data(creds, rep) >- rep = self.as_req(creds, etype, padata=padata) >+ padata = self.get_enc_timestamp_pa_data(creds, rep) >+ rep = self.as_req(creds, etype, padata=[padata]) > > self.check_error_rep(rep, KDC_ERR_PREAUTH_FAILED) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 25a1f5f3ed8..97f9dd41339 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -66,9 +66,9 @@ class KdcTgsTests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(uc, rep) >+ padata = self.get_enc_timestamp_pa_data(uc, rep) > key = self.get_as_rep_key(uc, rep) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > # Request a service ticket, but use a cname that does not match >@@ -116,9 +116,9 @@ class KdcTgsTests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(uc, rep) >+ padata = self.get_enc_timestamp_pa_data(uc, rep) > key = self.get_as_rep_key(uc, rep) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > enc_part2 = self.get_as_rep_enc_data(key, rep) >@@ -157,9 +157,9 @@ class KdcTgsTests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(uc, rep) >+ padata = self.get_enc_timestamp_pa_data(uc, rep) > key = self.get_as_rep_key(uc, rep) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > # Request a ticket to the host service on the machine account >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index e42b643b357..99c842701ea 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -109,9 +109,9 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(uc, rep) >+ padata = self.get_enc_timestamp_pa_data(uc, rep) > key = self.get_as_rep_key(uc, rep) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > # Request a ticket to the host service on the machine account >@@ -168,9 +168,9 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(mc, rep) >+ padata = self.get_enc_timestamp_pa_data(mc, rep) > key = self.get_as_rep_key(mc, rep) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > # Request a ticket to the host service on the machine account >@@ -230,9 +230,9 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(uc, rep) >+ padata = self.get_enc_timestamp_pa_data(uc, rep) > key = self.get_as_rep_key(uc, rep) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > # Request a ticket to the host service on the machine account >@@ -368,13 +368,13 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(uc, rep) >+ padata = self.get_enc_timestamp_pa_data(uc, rep) > key = self.get_as_rep_key(uc, rep) > # Note: although we used the alt security id for the pre-auth > # we need to use the username for the auth > cname = self.PrincipalName_create( > name_type=NT_PRINCIPAL, names=[user_name]) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > # Request a ticket to the host service on the machine account >@@ -436,12 +436,12 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(uc, rep) >+ padata = self.get_enc_timestamp_pa_data(uc, rep) > # Use the alternate security identifier > # this should fail > cname = self.PrincipalName_create( > name_type=NT_PRINCIPAL, names=[alt_sec]) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN) > > def test_enterprise_principal_step_1_3(self): >@@ -475,9 +475,9 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(uc, rep) >+ padata = self.get_enc_timestamp_pa_data(uc, rep) > key = self.get_as_rep_key(uc, rep) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > # Request a ticket to the host service on the machine account >@@ -538,9 +538,9 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(uc, rep) >+ padata = self.get_enc_timestamp_pa_data(uc, rep) > key = self.get_as_rep_key(uc, rep) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > # Request a ticket to the host service on the machine account >@@ -602,9 +602,9 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(mc, rep) >+ padata = self.get_enc_timestamp_pa_data(mc, rep) > key = self.get_as_rep_key(mc, rep) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > # Request a ticket to the host service on the machine account >@@ -744,13 +744,13 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(uc, rep) >+ padata = self.get_enc_timestamp_pa_data(uc, rep) > key = self.get_as_rep_key(uc, rep) > # Note: although we used the alt security id for the pre-auth > # we need to use the username for the auth > cname = self.PrincipalName_create( > name_type=NT_ENTERPRISE_PRINCIPAL, names=[uname]) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_as_reply(rep) > > # Request a ticket to the host service on the machine account >@@ -813,12 +813,12 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.check_pre_authentication(rep) > > # Do the next AS-REQ >- padata = self.get_pa_data(uc, rep) >+ padata = self.get_enc_timestamp_pa_data(uc, rep) > # Use the alternate security identifier > # this should fail > cname = self.PrincipalName_create( > name_type=NT_ENTERPRISE_PRINCIPAL, names=[ename]) >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ rep = self.as_req(cname, sname, realm, etype, padata=[padata]) > self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN) > > >-- >2.25.1 > > >From bbf24326bde0142ee1754f0a5bf80f1e9d1c7f54 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 26 Jul 2021 17:18:38 +1200 >Subject: [PATCH 145/686] tests/krb5: Add get_enc_timestamp_pa_data_from_key() > >This makes it easier to create encrypted timestamp padata when the key >has already been obtained. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit f5a906f74f9665a894db3c13722022f732180620) >--- > python/samba/tests/krb5/kdc_base_test.py | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 7748eae6225..64d9e627672 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -416,8 +416,12 @@ class KDCBaseTest(RawKerberosTest): > def get_enc_timestamp_pa_data(self, creds, rep, skew=0): > '''generate the pa_data data element for an AS-REQ > ''' >+ > key = self.get_as_rep_key(creds, rep) > >+ return self.get_enc_timestamp_pa_data_from_key(key, skew=skew) >+ >+ def get_enc_timestamp_pa_data_from_key(self, key, skew=0): > (patime, pausec) = self.get_KerberosTimeWithUsec(offset=skew) > padata = self.PA_ENC_TS_ENC_create(patime, pausec) > padata = self.der_encode(padata, asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) >-- >2.25.1 > > >From 1f0ccc3b26a5c4ba080f6c601c22b1a1dbda8ac9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 6 Jul 2021 12:51:54 +1200 >Subject: [PATCH 146/686] tests/krb5: Add method to return dict containing > padata elements > >This makes checking multiple padata elements easier. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit cb332d83008aa97a60eaca9e008054f641d514d6) >--- > python/samba/tests/krb5/raw_testcase.py | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 693f196940c..9b0b953e565 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -867,6 +867,18 @@ class RawKerberosTest(TestCaseInTempDir): > v = random.randint(nonce_min, nonce_max) > return v > >+ def get_pa_dict(self, pa_data): >+ pa_dict = {} >+ >+ if pa_data is not None: >+ for pa in pa_data: >+ pa_type = pa['padata-type'] >+ if pa_type in pa_dict: >+ raise RuntimeError(f'Duplicate type {pa_type}') >+ pa_dict[pa_type] = pa['padata-value'] >+ >+ return pa_dict >+ > def SessionKey_create(self, etype, contents, kvno=None): > key = kcrypto.Key(etype, contents) > return Krb5EncryptionKey(key, kvno) >-- >2.25.1 > > >From 8f53266b62f06487cae8b2053ae9026da26df374 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:27:47 +1200 >Subject: [PATCH 147/686] tests/krb5: Make _test_as_exchange() return value > more consistent > >Always return the reply and the kdc_exchange_dict so that the caller has >more potentially useful information. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit fe8912e4a85c5fd614ad3079b041c0e1975958e3) >--- > python/samba/tests/krb5/as_req_tests.py | 62 +++++++++++++------------ > python/samba/tests/krb5/raw_testcase.py | 5 +- > 2 files changed, 33 insertions(+), 34 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 106c7489e9c..3b7841243c5 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -141,20 +141,21 @@ class AsReqKerberosTests(KDCBaseTest): > initial_kdc_options = krb5_asn1.KDCOptions('forwardable') > initial_error_mode = KDC_ERR_PREAUTH_REQUIRED > >- etype_info2 = self._test_as_exchange(cname, >- realm, >- sname, >- till, >- client_as_etypes, >- initial_error_mode, >- expected_crealm, >- expected_cname, >- expected_srealm, >- expected_sname, >- expected_salt, >- initial_etypes, >- initial_padata, >- initial_kdc_options) >+ rep, kdc_exchange_dict = self._test_as_exchange(cname, >+ realm, >+ sname, >+ till, >+ client_as_etypes, >+ initial_error_mode, >+ expected_crealm, >+ expected_cname, >+ expected_srealm, >+ expected_sname, >+ expected_salt, >+ initial_etypes, >+ initial_padata, >+ initial_kdc_options) >+ etype_info2 = kdc_exchange_dict['preauth_etype_info2'] > self.assertIsNotNone(etype_info2) > > preauth_key = self.PasswordKey_from_etype_info2(client_creds, >@@ -179,22 +180,23 @@ class AsReqKerberosTests(KDCBaseTest): > krbtgt_decryption_key = ( > self.TicketDecryptionKey_from_creds(krbtgt_creds)) > >- as_rep = self._test_as_exchange(cname, >- realm, >- sname, >- till, >- client_as_etypes, >- preauth_error_mode, >- expected_crealm, >- expected_cname, >- expected_srealm, >- expected_sname, >- expected_salt, >- preauth_etypes, >- preauth_padata, >- preauth_kdc_options, >- preauth_key=preauth_key, >- ticket_decryption_key=krbtgt_decryption_key) >+ as_rep, kdc_exchange_dict = self._test_as_exchange( >+ cname, >+ realm, >+ sname, >+ till, >+ client_as_etypes, >+ preauth_error_mode, >+ expected_crealm, >+ expected_cname, >+ expected_srealm, >+ expected_sname, >+ expected_salt, >+ preauth_etypes, >+ preauth_padata, >+ preauth_kdc_options, >+ preauth_key=preauth_key, >+ ticket_decryption_key=krbtgt_decryption_key) > self.assertIsNotNone(as_rep) > > if __name__ == "__main__": >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 9b0b953e565..e9b4c6c9efa 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2034,7 +2034,4 @@ class RawKerberosTest(TestCaseInTempDir): > till_time=till, > etypes=etypes) > >- if expected_error_mode == 0: # AS-REP >- return rep >- >- return kdc_exchange_dict['preauth_etype_info2'] >+ return rep, kdc_exchange_dict >-- >2.25.1 > > >From 5f59f672ef220ab21772ef774897668226f2f689 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 22 Jul 2021 16:27:17 +1200 >Subject: [PATCH 148/686] tests/krb5: Add get_EpochFromKerberosTime() > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit bab7503e3043002b1422b00f40cd03a0a29538aa) >--- > python/samba/tests/krb5/kdc_base_test.py | 12 +++--------- > python/samba/tests/krb5/raw_testcase.py | 11 +++++++++++ > 2 files changed, 14 insertions(+), 9 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 64d9e627672..f0a9e7311a5 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -732,15 +732,9 @@ class KDCBaseTest(RawKerberosTest): > cred.client = cprincipal > cred.server = sprincipal > cred.keyblock = keyblock >- cred.authtime = int(datetime.strptime(authtime.decode(), >- "%Y%m%d%H%M%SZ") >- .replace(tzinfo=timezone.utc).timestamp()) >- cred.starttime = int(datetime.strptime(starttime.decode(), >- "%Y%m%d%H%M%SZ") >- .replace(tzinfo=timezone.utc).timestamp()) >- cred.endtime = int(datetime.strptime(endtime.decode(), >- "%Y%m%d%H%M%SZ") >- .replace(tzinfo=timezone.utc).timestamp()) >+ cred.authtime = self.get_EpochFromKerberosTime(authtime) >+ cred.starttime = self.get_EpochFromKerberosTime(starttime) >+ cred.endtime = self.get_EpochFromKerberosTime(endtime) > > # Account for clock skew of up to five minutes. > self.assertLess(cred.authtime - 5 * 60, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e9b4c6c9efa..3ab63cd01d0 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -861,6 +861,17 @@ class RawKerberosTest(TestCaseInTempDir): > (s, _) = self.get_KerberosTimeWithUsec(epoch=epoch, offset=offset) > return s > >+ def get_EpochFromKerberosTime(self, kerberos_time): >+ if isinstance(kerberos_time, bytes): >+ kerberos_time = kerberos_time.decode() >+ >+ epoch = datetime.datetime.strptime(kerberos_time, >+ '%Y%m%d%H%M%SZ') >+ epoch = epoch.replace(tzinfo=datetime.timezone.utc) >+ epoch = int(epoch.timestamp()) >+ >+ return epoch >+ > def get_Nonce(self): > nonce_min = 0x7f000000 > nonce_max = 0x7fffffff >-- >2.25.1 > > >From 6309508fbf6f2015c35db1c2a3a48abd9efdfbed Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 3 Aug 2021 15:58:19 +1200 >Subject: [PATCH 149/686] tests/krb5: Use encryption with admin credentials > >This ensures that account creation using admin credentials succeeds. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit ce379edf2e135b105b18d35e24d732389de94291) >--- > python/samba/tests/krb5/raw_testcase.py | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 3ab63cd01d0..e48d501ad19 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -33,6 +33,7 @@ from pyasn1.codec.ber.encoder import BitStringEncoder > > from samba.credentials import Credentials > from samba.dcerpc import security >+from samba.gensec import FEATURE_SEAL > > import samba.tests > from samba.tests import TestCaseInTempDir >@@ -606,6 +607,7 @@ class RawKerberosTest(TestCaseInTempDir): > c = self._get_krb5_creds(prefix='ADMIN', > allow_missing_password=allow_missing_password, > allow_missing_keys=allow_missing_keys) >+ c.set_gensec_features(c.get_gensec_features() | FEATURE_SEAL) > return c > > def get_krbtgt_creds(self, >-- >2.25.1 > > >From 4a5abf6267dd9e9201762b1b7223169b6993c474 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 6 Jul 2021 11:25:55 +1200 >Subject: [PATCH 150/686] tests/krb5: Allow specifying additional details when > creating an account > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 4790b6b04ae145a2ebb418dd734487a6ba28a30c) >--- > python/samba/tests/krb5/kdc_base_test.py | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index f0a9e7311a5..279e15c13ce 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -148,7 +148,7 @@ class KDCBaseTest(RawKerberosTest): > return default_enctypes > > def create_account(self, ldb, name, machine_account=False, >- spn=None, upn=None): >+ spn=None, upn=None, additional_details=None): > '''Create an account for testing. > The dn of the created account is added to self.accounts, > which is used by tearDownClass to clean up the created accounts. >@@ -180,6 +180,8 @@ class KDCBaseTest(RawKerberosTest): > details["servicePrincipalName"] = spn > if upn is not None: > details["userPrincipalName"] = upn >+ if additional_details is not None: >+ details.update(additional_details) > ldb.add(details) > > creds = KerberosCredentials() >-- >2.25.1 > > >From 513a3f6fcc6877799fb72acee9c4e9ae628d63d9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 6 Jul 2021 10:19:57 +1200 >Subject: [PATCH 151/686] tests/krb5: Add more methods for obtaining machine > and service credentials > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 50d743bafc7aa9f7b4688bae652a501001e9fdbb) >--- > python/samba/tests/krb5/kdc_base_test.py | 74 ++++++++++++++++++++++++ > 1 file changed, 74 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 279e15c13ce..21e2c04cea1 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -334,6 +334,80 @@ class KDCBaseTest(RawKerberosTest): > fallback_creds_fn=create_client_account) > return c > >+ def get_mach_creds(self, >+ allow_missing_password=False, >+ allow_missing_keys=True): >+ def create_mach_account(): >+ samdb = self.get_samdb() >+ >+ mach_name = 'kdctestmac' >+ details = { >+ 'msDS-SupportedEncryptionTypes': str( >+ security.KERB_ENCTYPE_FAST_SUPPORTED | >+ security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >+ security.KERB_ENCTYPE_CLAIMS_SUPPORTED >+ ) >+ } >+ >+ creds, dn = self.create_account(samdb, mach_name, >+ machine_account=True, >+ spn='host/' + mach_name, >+ additional_details=details) >+ >+ res = samdb.search(base=dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KeyVersionNumber']) >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ creds.set_kvno(kvno) >+ >+ keys = self.get_keys(samdb, dn) >+ self.creds_set_keys(creds, keys) >+ >+ return creds >+ >+ c = self._get_krb5_creds(prefix='MAC', >+ allow_missing_password=allow_missing_password, >+ allow_missing_keys=allow_missing_keys, >+ fallback_creds_fn=create_mach_account) >+ return c >+ >+ def get_service_creds(self, >+ allow_missing_password=False, >+ allow_missing_keys=True): >+ def create_service_account(): >+ samdb = self.get_samdb() >+ >+ mach_name = 'kdctestservice' >+ details = { >+ 'msDS-SupportedEncryptionTypes': str( >+ security.KERB_ENCTYPE_FAST_SUPPORTED | >+ security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >+ security.KERB_ENCTYPE_CLAIMS_SUPPORTED >+ ) >+ } >+ >+ creds, dn = self.create_account(samdb, mach_name, >+ machine_account=True, >+ spn='host/' + mach_name, >+ additional_details=details) >+ >+ res = samdb.search(base=dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KeyVersionNumber']) >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ creds.set_kvno(kvno) >+ >+ keys = self.get_keys(samdb, dn) >+ self.creds_set_keys(creds, keys) >+ >+ return creds >+ >+ c = self._get_krb5_creds(prefix='SERVICE', >+ allow_missing_password=allow_missing_password, >+ allow_missing_keys=allow_missing_keys, >+ fallback_creds_fn=create_service_account) >+ return c >+ > def get_krbtgt_creds(self, > require_keys=True, > require_strongest_key=False): >-- >2.25.1 > > >From 836a66fe2f136dabea9e04072b8813e0ef81267c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 22 Jul 2021 16:22:09 +1200 >Subject: [PATCH 152/686] tests/krb5: Add method to calculate account salt > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit f5689bb8fab82d5fcbdbd3c63b86e7618834aac5) >--- > python/samba/tests/krb5/kdc_base_test.py | 2 ++ > python/samba/tests/krb5/raw_testcase.py | 19 +++++++++++++++---- > 2 files changed, 17 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 21e2c04cea1..0dbaeab4a0e 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -192,6 +192,8 @@ class KDCBaseTest(RawKerberosTest): > creds.set_username(account_name) > if machine_account: > creds.set_workstation(name) >+ else: >+ creds.set_workstation('') > # > # Save the account name so it can be deleted in tearDownClass > self.accounts.add(dn) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e48d501ad19..2dbcc39114a 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -295,6 +295,20 @@ class KerberosCredentials(Credentials): > def get_forced_salt(self): > return self.forced_salt > >+ def get_salt(self): >+ if self.forced_salt is not None: >+ return self.forced_salt >+ >+ if self.get_workstation(): >+ salt_string = '%shost%s.%s' % ( >+ self.get_realm().upper(), >+ self.get_username().lower().rsplit('$', 1)[0], >+ self.get_realm().lower()) >+ else: >+ salt_string = self.get_realm().upper() + self.get_username() >+ >+ return salt_string.encode('utf-8') >+ > > class KerberosTicketCreds: > def __init__(self, ticket, session_key, >@@ -940,10 +954,7 @@ class RawKerberosTest(TestCaseInTempDir): > > password = creds.get_password() > self.assertIsNotNone(password, msg=fail_msg) >- salt = creds.get_forced_salt() >- if salt is None: >- salt = bytes("%s%s" % (creds.get_realm(), creds.get_username()), >- encoding='utf-8') >+ salt = creds.get_salt() > return self.PasswordKey_create(etype=etype, > pwd=password, > salt=salt, >-- >2.25.1 > > >From 7544f87c494be36115c6e23068125c417eeec55f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 26 Jul 2021 17:19:04 +1200 >Subject: [PATCH 153/686] tests/krb5: Add check_reply() method to check for AS > or TGS reply > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 28fb50f511f3f693709aa9b41c001d6a5f9c3329) >--- > python/samba/tests/krb5/kdc_base_test.py | 26 +++++------------------- > 1 file changed, 5 insertions(+), 21 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 0dbaeab4a0e..1b550179e0e 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -540,26 +540,7 @@ class KDCBaseTest(RawKerberosTest): > kvno > match the expected values > """ >- >- # Should have a reply, and it should an AS-REP message. >- self.assertIsNotNone(rep) >- self.assertEqual(rep['msg-type'], KRB_AS_REP, "rep = {%s}" % rep) >- >- # Protocol version number should be 5 >- pvno = int(rep['pvno']) >- self.assertEqual(5, pvno, "rep = {%s}" % rep) >- >- # The ticket version number should be 5 >- tkt_vno = int(rep['ticket']['tkt-vno']) >- self.assertEqual(5, tkt_vno, "rep = {%s}" % rep) >- >- # Check that the kvno is not an RODC kvno >- # MIT kerberos does not provide the kvno, so we treat it as optional. >- # This is tested in compatability_test.py >- if 'kvno' in rep['enc-part']: >- kvno = int(rep['enc-part']['kvno']) >- # If the high order bits are set this is an RODC kvno. >- self.assertEqual(0, kvno & 0xFFFF0000, "rep = {%s}" % rep) >+ self.check_reply(rep, msg_type=KRB_AS_REP) > > def check_tgs_reply(self, rep): > """ Check that the kdc response is an TGS-REP and that the >@@ -570,10 +551,13 @@ class KDCBaseTest(RawKerberosTest): > kvno > match the expected values > """ >+ self.check_reply(rep, msg_type=KRB_TGS_REP) >+ >+ def check_reply(self, rep, msg_type): > > # Should have a reply, and it should an TGS-REP message. > self.assertIsNotNone(rep) >- self.assertEqual(rep['msg-type'], KRB_TGS_REP, "rep = {%s}" % rep) >+ self.assertEqual(rep['msg-type'], msg_type, "rep = {%s}" % rep) > > # Protocol version number should be 5 > pvno = int(rep['pvno']) >-- >2.25.1 > > >From df1c573ee388216de0a9f7baee5daccc2732192f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 10:32:52 +1200 >Subject: [PATCH 154/686] tests/krb5: Always specify expected error code > >Now the expected error code is always determined by the test code itself >rather than by generic_check_as_error(). > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 21c64fda8f98d451e028ea483dbe351b1280390c) >--- > python/samba/tests/krb5/as_req_tests.py | 11 ++++++++++- > python/samba/tests/krb5/raw_testcase.py | 13 ++++++------- > 2 files changed, 16 insertions(+), 8 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 3b7841243c5..861d2371b75 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -24,8 +24,10 @@ os.environ["PYTHONUNBUFFERED"] = "1" > > from samba.tests import DynamicTestCase > from samba.tests.krb5.kdc_base_test import KDCBaseTest >+import samba.tests.krb5.kcrypto as kcrypto > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( >+ KDC_ERR_ETYPE_NOSUPP, > KDC_ERR_PREAUTH_REQUIRED, > KU_PA_ENC_TIMESTAMP, > NT_PRINCIPAL, >@@ -68,13 +70,20 @@ class AsReqKerberosTests(KDCBaseTest): > sname = self.PrincipalName_create(name_type=NT_SRV_INST, > names=[krbtgt_account, realm]) > >- expected_error_mode = KDC_ERR_PREAUTH_REQUIRED > expected_crealm = realm > expected_cname = cname > expected_srealm = realm > expected_sname = sname > expected_salt = client_creds.get_forced_salt() > >+ if any(etype in client_as_etypes and etype in initial_etypes >+ for etype in (kcrypto.Enctype.AES256, >+ kcrypto.Enctype.AES128, >+ kcrypto.Enctype.RC4)): >+ expected_error_mode = KDC_ERR_PREAUTH_REQUIRED >+ else: >+ expected_error_mode = KDC_ERR_ETYPE_NOSUPP >+ > def _generate_padata_copy(_kdc_exchange_dict, > _callback_dict, > req_body): >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 2dbcc39114a..5579e989d1c 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -40,9 +40,7 @@ from samba.tests import TestCaseInTempDir > > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( >- KDC_ERR_ETYPE_NOSUPP, > KDC_ERR_GENERIC, >- KDC_ERR_PREAUTH_REQUIRED, > KRB_AP_REQ, > KRB_AS_REP, > KRB_AS_REQ, >@@ -1524,7 +1522,7 @@ class RawKerberosTest(TestCaseInTempDir): > check_padata_fn=None, > check_kdc_private_fn=None, > callback_dict=None, >- expected_error_mode=None, >+ expected_error_mode=0, > client_as_etypes=None, > expected_salt=None): > kdc_exchange_dict = { >@@ -1809,13 +1807,11 @@ class RawKerberosTest(TestCaseInTempDir): > if expected_rc4_type != 0: > expect_etype_info2 += (expected_rc4_type,) > >- expected_error = KDC_ERR_ETYPE_NOSUPP > expected_patypes = () > if expect_etype_info: > self.assertGreater(len(expect_etype_info2), 0) > expected_patypes += (PADATA_ETYPE_INFO,) > if len(expect_etype_info2) != 0: >- expected_error = KDC_ERR_PREAUTH_REQUIRED > expected_patypes += (PADATA_ETYPE_INFO2,) > > expected_patypes += (PADATA_ENC_TIMESTAMP,) >@@ -1824,7 +1820,7 @@ class RawKerberosTest(TestCaseInTempDir): > > self.assertElementEqual(rep, 'pvno', 5) > self.assertElementEqual(rep, 'msg-type', KRB_ERROR) >- self.assertElementEqual(rep, 'error-code', expected_error) >+ self.assertElementEqual(rep, 'error-code', expected_error_mode) > self.assertElementMissing(rep, 'ctime') > self.assertElementMissing(rep, 'cusec') > self.assertElementPresent(rep, 'stime') >@@ -1889,7 +1885,10 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertEqual(len(pk_as_rep19), 0) > continue > >- if expected_error == KDC_ERR_ETYPE_NOSUPP: >+ if all(etype not in client_as_etypes or etype not in proposed_etypes >+ for etype in (kcrypto.Enctype.AES256, >+ kcrypto.Enctype.AES128, >+ kcrypto.Enctype.RC4)): > self.assertIsNone(etype_info2) > self.assertIsNone(etype_info) > if self.strict_checking: >-- >2.25.1 > > >From 95ca362dd5ad6350200aa3e34b418fdd3f11f75f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 10:35:40 +1200 >Subject: [PATCH 155/686] tests/krb5: Include kdc_options in kdc_exchange_dict > >Make kdc_options an element of kdc_exchange_dict instead of a parameter >to _generic_kdc_exchange(). This allows testing code to adjust the reply >checking based on the options that were specified in the request. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 8fe9589da2d8fe6f5c47770c618ebabe028f6a95) >--- > python/samba/tests/krb5/as_req_tests.py | 4 ++-- > python/samba/tests/krb5/raw_testcase.py | 15 ++++++++++----- > 2 files changed, 12 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 861d2371b75..ed97a10b616 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -99,10 +99,10 @@ class AsReqKerberosTests(KDCBaseTest): > check_rep_fn=self.generic_check_kdc_rep, > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, >- expected_salt=expected_salt) >+ expected_salt=expected_salt, >+ kdc_options=str(initial_kdc_options)) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >- kdc_options=str(initial_kdc_options), > cname=cname, > realm=realm, > sname=sname, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 5579e989d1c..00f90c5dea9 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1431,7 +1431,6 @@ class RawKerberosTest(TestCaseInTempDir): > > def _generic_kdc_exchange(self, > kdc_exchange_dict, # required >- kdc_options=None, # required > cname=None, # optional > realm=None, # required > sname=None, # optional >@@ -1454,6 +1453,8 @@ class RawKerberosTest(TestCaseInTempDir): > req_asn1Spec = kdc_exchange_dict['req_asn1Spec'] > rep_msg_type = kdc_exchange_dict['rep_msg_type'] > >+ kdc_options = kdc_exchange_dict['kdc_options'] >+ > if till_time is None: > till_time = self.get_KerberosTime(offset=36000) > if nonce is None: >@@ -1524,7 +1525,8 @@ class RawKerberosTest(TestCaseInTempDir): > callback_dict=None, > expected_error_mode=0, > client_as_etypes=None, >- expected_salt=None): >+ expected_salt=None, >+ kdc_options=''): > kdc_exchange_dict = { > 'req_msg_type': KRB_AS_REQ, > 'req_asn1Spec': krb5_asn1.AS_REQ, >@@ -1545,6 +1547,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_error_mode': expected_error_mode, > 'client_as_etypes': client_as_etypes, > 'expected_salt': expected_salt, >+ 'kdc_options': kdc_options, > } > if callback_dict is None: > callback_dict = {} >@@ -1565,7 +1568,8 @@ class RawKerberosTest(TestCaseInTempDir): > callback_dict=None, > tgt=None, > authenticator_subkey=None, >- body_checksum_type=None): >+ body_checksum_type=None, >+ kdc_options=''): > kdc_exchange_dict = { > 'req_msg_type': KRB_TGS_REQ, > 'req_asn1Spec': krb5_asn1.TGS_REQ, >@@ -1586,6 +1590,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'tgt': tgt, > 'body_checksum_type': body_checksum_type, > 'authenticator_subkey': authenticator_subkey, >+ 'kdc_options': kdc_options > } > if callback_dict is None: > callback_dict = {} >@@ -2047,10 +2052,10 @@ class RawKerberosTest(TestCaseInTempDir): > check_kdc_private_fn=self.generic_check_kdc_private, > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, >- expected_salt=expected_salt) >+ expected_salt=expected_salt, >+ kdc_options=str(kdc_options)) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >- kdc_options=str(kdc_options), > cname=cname, > realm=realm, > sname=sname, >-- >2.25.1 > > >From f45a10415600476a94f6c4a0bd53d4f9a94ab6b8 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 11:06:15 +1200 >Subject: [PATCH 156/686] tests/krb5: Only allow specifying one of check_rep_fn > and check_error_fn > >This means that there can no longer be surprises where a test receives a >reply when it was expecting an error, or vice versa. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 78818655505b3183251940e86270cd40bae73206) >--- > python/samba/tests/krb5/as_req_tests.py | 2 +- > python/samba/tests/krb5/raw_testcase.py | 25 +++++++++++++++++++------ > 2 files changed, 20 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index ed97a10b616..d9a66f99ecf 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -96,7 +96,7 @@ class AsReqKerberosTests(KDCBaseTest): > expected_sname=expected_sname, > generate_padata_fn=_generate_padata_copy, > check_error_fn=self.generic_check_as_error, >- check_rep_fn=self.generic_check_kdc_rep, >+ check_rep_fn=None, > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, > expected_salt=expected_salt, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 00f90c5dea9..d7813387941 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1453,6 +1453,7 @@ class RawKerberosTest(TestCaseInTempDir): > req_asn1Spec = kdc_exchange_dict['req_asn1Spec'] > rep_msg_type = kdc_exchange_dict['rep_msg_type'] > >+ expected_error_mode = kdc_exchange_dict['expected_error_mode'] > kdc_options = kdc_exchange_dict['kdc_options'] > > if till_time is None: >@@ -1497,12 +1498,17 @@ class RawKerberosTest(TestCaseInTempDir): > msg_type = self.getElementValue(rep, 'msg-type') > self.assertIsNotNone(msg_type) > >- allowed_msg_types = () >+ expected_msg_type = None > if check_error_fn is not None: >- allowed_msg_types = (KRB_ERROR,) >+ expected_msg_type = KRB_ERROR >+ self.assertIsNone(check_rep_fn) >+ self.assertNotEqual(0, expected_error_mode) > if check_rep_fn is not None: >- allowed_msg_types += (rep_msg_type,) >- self.assertIn(msg_type, allowed_msg_types) >+ expected_msg_type = rep_msg_type >+ self.assertIsNone(check_error_fn) >+ self.assertEqual(0, expected_error_mode) >+ self.assertIsNotNone(expected_msg_type) >+ self.assertEqual(msg_type, expected_msg_type) > > if msg_type == KRB_ERROR: > return check_error_fn(kdc_exchange_dict, >@@ -2039,6 +2045,13 @@ class RawKerberosTest(TestCaseInTempDir): > as_rep_usage = KU_AS_REP_ENC_PART > return preauth_key, as_rep_usage > >+ if expected_error_mode == 0: >+ check_error_fn = None >+ check_rep_fn = self.generic_check_kdc_rep >+ else: >+ check_error_fn = self.generic_check_as_error >+ check_rep_fn = None >+ > kdc_exchange_dict = self.as_exchange_dict( > expected_crealm=expected_crealm, > expected_cname=expected_cname, >@@ -2046,8 +2059,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_sname=expected_sname, > ticket_decryption_key=ticket_decryption_key, > generate_padata_fn=_generate_padata_copy, >- check_error_fn=self.generic_check_as_error, >- check_rep_fn=self.generic_check_kdc_rep, >+ check_error_fn=check_error_fn, >+ check_rep_fn=check_rep_fn, > check_padata_fn=_check_padata_preauth_key, > check_kdc_private_fn=self.generic_check_kdc_private, > expected_error_mode=expected_error_mode, >-- >2.25.1 > > >From 3acb09ed9ae9121f0c314ca49775db5d99e23a7d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 10:37:48 +1200 >Subject: [PATCH 157/686] tests/krb5: Ensure in assertElementPresent() that > container elements are not empty > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit ba3c92f77b20e1e0d298cd92399dc69535739c27) >--- > python/samba/tests/krb5/raw_testcase.py | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index d7813387941..e1baf0ce943 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -24,6 +24,8 @@ import datetime > import random > import binascii > import itertools >+import collections >+ > from pyasn1.codec.der.decoder import decode as pyasn1_der_decode > from pyasn1.codec.der.encoder import encode as pyasn1_der_encode > from pyasn1.codec.native.decoder import decode as pyasn1_native_decode >@@ -817,6 +819,9 @@ class RawKerberosTest(TestCaseInTempDir): > def assertElementPresent(self, obj, elem): > v = self.getElementValue(obj, elem) > self.assertIsNotNone(v) >+ if self.strict_checking: >+ if isinstance(v, collections.abc.Container): >+ self.assertNotEqual(0, len(v)) > > def assertElementEqual(self, obj, elem, value): > v = self.getElementValue(obj, elem) >-- >2.25.1 > > >From 36d33c305bf65c496c95fbf48ba0d19c53939638 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:39:42 +1200 >Subject: [PATCH 158/686] tests/krb5: Assert that more variables are not None > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 3d1066e923815782036bd11524fda110a2528951) >--- > python/samba/tests/krb5/raw_testcase.py | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e1baf0ce943..3a178f4bce3 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1631,12 +1631,14 @@ class RawKerberosTest(TestCaseInTempDir): > ticket = self.getElementValue(rep, 'ticket') > ticket_encpart = None > ticket_cipher = None >+ self.assertIsNotNone(ticket) > if ticket is not None: # Never None, but gives indentation > self.assertElementPresent(ticket, 'tkt-vno') > self.assertElementEqualUTF8(ticket, 'realm', expected_srealm) > self.assertElementEqualPrincipal(ticket, 'sname', expected_sname) > self.assertElementPresent(ticket, 'enc-part') > ticket_encpart = self.getElementValue(ticket, 'enc-part') >+ self.assertIsNotNone(ticket_encpart) > if ticket_encpart is not None: # Never None, but gives indentation > self.assertElementPresent(ticket_encpart, 'etype') > # 'unspecified' means present, with any value != 0 >@@ -1647,6 +1649,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(rep, 'enc-part') > encpart = self.getElementValue(rep, 'enc-part') > encpart_cipher = None >+ self.assertIsNotNone(encpart) > if encpart is not None: # Never None, but gives indentation > self.assertElementPresent(encpart, 'etype') > self.assertElementKVNO(ticket_encpart, 'kvno', 'autodetect') >@@ -1654,6 +1657,7 @@ class RawKerberosTest(TestCaseInTempDir): > encpart_cipher = self.getElementValue(encpart, 'cipher') > > encpart_decryption_key = None >+ self.assertIsNotNone(check_padata_fn) > if check_padata_fn is not None: > # See if we can get the decryption key from the preauth phase > encpart_decryption_key, encpart_decryption_usage = ( >@@ -1661,6 +1665,7 @@ class RawKerberosTest(TestCaseInTempDir): > rep, padata)) > > ticket_private = None >+ self.assertIsNotNone(ticket_decryption_key) > if ticket_decryption_key is not None: > self.assertElementEqual(ticket_encpart, 'etype', > ticket_decryption_key.etype) >@@ -1673,6 +1678,7 @@ class RawKerberosTest(TestCaseInTempDir): > asn1Spec=krb5_asn1.EncTicketPart()) > > encpart_private = None >+ self.assertIsNotNone(encpart_decryption_key) > if encpart_decryption_key is not None: > self.assertElementEqual(encpart, 'etype', > encpart_decryption_key.etype) >@@ -1692,6 +1698,7 @@ class RawKerberosTest(TestCaseInTempDir): > rep_decpart, > asn1Spec=krb5_asn1.EncTGSRepPart()) > >+ self.assertIsNotNone(check_kdc_private_fn) > if check_kdc_private_fn is not None: > check_kdc_private_fn(kdc_exchange_dict, callback_dict, > rep, ticket_private, encpart_private) >@@ -1718,6 +1725,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(ticket_private, 'flags') > self.assertElementPresent(ticket_private, 'key') > ticket_key = self.getElementValue(ticket_private, 'key') >+ self.assertIsNotNone(ticket_key) > if ticket_key is not None: # Never None, but gives indentation > self.assertElementPresent(ticket_key, 'keytype') > self.assertElementPresent(ticket_key, 'keyvalue') >@@ -1739,6 +1747,7 @@ class RawKerberosTest(TestCaseInTempDir): > if encpart_private is not None: > self.assertElementPresent(encpart_private, 'key') > encpart_key = self.getElementValue(encpart_private, 'key') >+ self.assertIsNotNone(encpart_key) > if encpart_key is not None: # Never None, but gives indentation > self.assertElementPresent(encpart_key, 'keytype') > self.assertElementPresent(encpart_key, 'keyvalue') >-- >2.25.1 > > >From 9028abcdaf6c6b4119ebc4461a9aa4a0f4de41d3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 11:34:19 +1200 >Subject: [PATCH 159/686] tests/krb5: Check version number of obtained ticket > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 98dc19e8c817fc66e253e544874a45b17b8bfa7b) >--- > python/samba/tests/krb5/raw_testcase.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 3a178f4bce3..70062ca338a 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1633,7 +1633,7 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_cipher = None > self.assertIsNotNone(ticket) > if ticket is not None: # Never None, but gives indentation >- self.assertElementPresent(ticket, 'tkt-vno') >+ self.assertElementEqual(ticket, 'tkt-vno', 5) > self.assertElementEqualUTF8(ticket, 'realm', expected_srealm) > self.assertElementEqualPrincipal(ticket, 'sname', expected_sname) > self.assertElementPresent(ticket, 'enc-part') >-- >2.25.1 > > >From b3387f5be17143f2842618b3ef797c98863ffc22 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 11:39:37 +1200 >Subject: [PATCH 160/686] tests/krb5: Make checking less strict > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 6df0e406f1f823bf4d65cd478eb6f2424b69adcc) > >[abartlet@samba.org Adapted to add knownfail because in this >Samba 4.14 backport we do not include >b3ee034b4d457607ef25a5b01da64e1eaf5906dd >(s4:kdc: prefer newer enctypes for preauth responses)] >--- > python/samba/tests/krb5/raw_testcase.py | 52 ++++++++++--------- > .../knownfail.d/samba.tests.krb5.as_req_tests | 42 --------------- > 2 files changed, 27 insertions(+), 67 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 70062ca338a..69b7c7adc9b 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1625,8 +1625,9 @@ class RawKerberosTest(TestCaseInTempDir): > > self.assertElementEqual(rep, 'msg-type', msg_type) # AS-REP | TGS-REP > padata = self.getElementValue(rep, 'padata') >- self.assertElementEqualUTF8(rep, 'crealm', expected_crealm) >- self.assertElementEqualPrincipal(rep, 'cname', expected_cname) >+ if self.strict_checking: >+ self.assertElementEqualUTF8(rep, 'crealm', expected_crealm) >+ self.assertElementEqualPrincipal(rep, 'cname', expected_cname) > self.assertElementPresent(rep, 'ticket') > ticket = self.getElementValue(rep, 'ticket') > ticket_encpart = None >@@ -1682,8 +1683,9 @@ class RawKerberosTest(TestCaseInTempDir): > if encpart_decryption_key is not None: > self.assertElementEqual(encpart, 'etype', > encpart_decryption_key.etype) >- self.assertElementKVNO(encpart, 'kvno', >- encpart_decryption_key.kvno) >+ if self.strict_checking: >+ self.assertElementKVNO(encpart, 'kvno', >+ encpart_decryption_key.kvno) > rep_decpart = encpart_decryption_key.decrypt( > encpart_decryption_usage, > encpart_cipher) >@@ -1846,17 +1848,17 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementEqual(rep, 'pvno', 5) > self.assertElementEqual(rep, 'msg-type', KRB_ERROR) > self.assertElementEqual(rep, 'error-code', expected_error_mode) >- self.assertElementMissing(rep, 'ctime') >- self.assertElementMissing(rep, 'cusec') >+ if self.strict_checking: >+ self.assertElementMissing(rep, 'ctime') >+ self.assertElementMissing(rep, 'cusec') > self.assertElementPresent(rep, 'stime') > self.assertElementPresent(rep, 'susec') > # error-code checked above > if self.strict_checking: > self.assertElementMissing(rep, 'crealm') > self.assertElementMissing(rep, 'cname') >- self.assertElementEqualUTF8(rep, 'realm', expected_srealm) >- self.assertElementEqualPrincipal(rep, 'sname', expected_sname) >- if self.strict_checking: >+ self.assertElementEqualUTF8(rep, 'realm', expected_srealm) >+ self.assertElementEqualPrincipal(rep, 'sname', expected_sname) > self.assertElementMissing(rep, 'e-text') > if expected_error_mode == KDC_ERR_GENERIC: > self.assertElementMissing(rep, 'e-data') >@@ -1922,7 +1924,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(pk_as_rep19) > return > >- self.assertIsNotNone(etype_info2) >+ if self.strict_checking: >+ self.assertIsNotNone(etype_info2) > if expect_etype_info: > self.assertIsNotNone(etype_info) > else: >@@ -1931,23 +1934,22 @@ class RawKerberosTest(TestCaseInTempDir): > if unexpect_etype_info: > self.assertIsNone(etype_info) > >- self.assertGreaterEqual(len(etype_info2), 1) >- self.assertLessEqual(len(etype_info2), len(expect_etype_info2)) > if self.strict_checking: >+ self.assertGreaterEqual(len(etype_info2), 1) > self.assertEqual(len(etype_info2), len(expect_etype_info2)) >- for i in range(0, len(etype_info2)): >- e = self.getElementValue(etype_info2[i], 'etype') >- self.assertEqual(e, expect_etype_info2[i]) >- salt = self.getElementValue(etype_info2[i], 'salt') >- if e == kcrypto.Enctype.RC4: >- self.assertIsNone(salt) >- else: >- self.assertIsNotNone(salt) >- if expected_salt is not None: >- self.assertEqual(salt, expected_salt) >- s2kparams = self.getElementValue(etype_info2[i], 's2kparams') >- if self.strict_checking: >- self.assertIsNone(s2kparams) >+ for i in range(0, len(etype_info2)): >+ e = self.getElementValue(etype_info2[i], 'etype') >+ self.assertEqual(e, expect_etype_info2[i]) >+ salt = self.getElementValue(etype_info2[i], 'salt') >+ if e == kcrypto.Enctype.RC4: >+ self.assertIsNone(salt) >+ else: >+ self.assertIsNotNone(salt) >+ if expected_salt is not None: >+ self.assertEqual(salt, expected_salt) >+ s2kparams = self.getElementValue(etype_info2[i], 's2kparams') >+ if self.strict_checking: >+ self.assertIsNone(s2kparams) > if etype_info is not None: > self.assertEqual(len(etype_info), 1) > e = self.getElementValue(etype_info[0], 'etype') >diff --git a/selftest/knownfail.d/samba.tests.krb5.as_req_tests b/selftest/knownfail.d/samba.tests.krb5.as_req_tests >index f395bdc553b..35375dfcc8e 100644 >--- a/selftest/knownfail.d/samba.tests.krb5.as_req_tests >+++ b/selftest/knownfail.d/samba.tests.krb5.as_req_tests >@@ -1,45 +1,3 @@ >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2008r2dc >-- >2.25.1 > > >From fa97e69405c751bf16f7f20649c27aac96174084 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 12:52:42 +1200 >Subject: [PATCH 161/686] tests/krb5: Check nonce in EncKDCRepPart > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 4951a105b0448854115a7ecc3d867be6f34b0dcf) >--- > python/samba/tests/krb5/raw_testcase.py | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 69b7c7adc9b..60e589464f3 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1442,7 +1442,6 @@ class RawKerberosTest(TestCaseInTempDir): > from_time=None, # optional > till_time=None, # required > renew_time=None, # optional >- nonce=None, # required > etypes=None, # required > addresses=None, # optional > additional_tickets=None, # optional >@@ -1463,8 +1462,12 @@ class RawKerberosTest(TestCaseInTempDir): > > if till_time is None: > till_time = self.get_KerberosTime(offset=36000) >- if nonce is None: >+ >+ if 'nonce' in kdc_exchange_dict: >+ nonce = kdc_exchange_dict['nonce'] >+ else: > nonce = self.get_Nonce() >+ kdc_exchange_dict['nonce'] = nonce > > req_body = self.KDC_REQ_BODY_create( > kdc_options=kdc_options, >@@ -1755,7 +1758,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(encpart_key, 'keyvalue') > encpart_session_key = self.EncryptionKey_import(encpart_key) > self.assertElementPresent(encpart_private, 'last-req') >- self.assertElementPresent(encpart_private, 'nonce') >+ self.assertElementEqual(encpart_private, 'nonce', >+ kdc_exchange_dict['nonce']) > # TODO self.assertElementPresent(encpart_private, > # 'key-expiration') > self.assertElementPresent(encpart_private, 'flags') >-- >2.25.1 > > >From a459790accebabcb22ba97ffcf53dde8ae972217 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Jul 2021 19:27:02 +1200 >Subject: [PATCH 162/686] tests/krb5: Add generate_ap_req() method > >This method will be useful to generate an AP-REQ for use as FAST armor. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 4824dd4e9f40abcbd4134b79e2b2b8fb960f47e7) >--- > python/samba/tests/krb5/raw_testcase.py | 18 ++++++++++++++---- > 1 file changed, 14 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 60e589464f3..67b359f07d8 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1971,10 +1971,10 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_exchange_dict['preauth_etype_info2'] = etype_info2 > return > >- def generate_simple_tgs_padata(self, >- kdc_exchange_dict, >- callback_dict, >- req_body): >+ def generate_ap_req(self, >+ kdc_exchange_dict, >+ _callback_dict, >+ req_body): > tgt = kdc_exchange_dict['tgt'] > authenticator_subkey = kdc_exchange_dict['authenticator_subkey'] > body_checksum_type = kdc_exchange_dict['body_checksum_type'] >@@ -2014,6 +2014,16 @@ class RawKerberosTest(TestCaseInTempDir): > ticket=tgt.ticket, > authenticator=authenticator) > ap_req = self.der_encode(ap_req_obj, asn1Spec=krb5_asn1.AP_REQ()) >+ >+ return ap_req >+ >+ def generate_simple_tgs_padata(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body): >+ ap_req = self.generate_ap_req(kdc_exchange_dict, >+ callback_dict, >+ req_body) > pa_tgs_req = self.PA_DATA_create(PADATA_KDC_REQ, ap_req) > padata = [pa_tgs_req] > >-- >2.25.1 > > >From c8636441a623f728f61405663a9981fa8e61650e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 11:06:35 +1200 >Subject: [PATCH 163/686] tests/krb5: Ensure generated padata is not None > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit b6f96dd6395a30e15fa906959cbe665757aaba8d) >--- > python/samba/tests/krb5/as_req_tests.py | 6 +++++- > python/samba/tests/krb5/raw_testcase.py | 8 +++++++- > 2 files changed, 12 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index d9a66f99ecf..b5a6cfd31c7 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -89,12 +89,16 @@ class AsReqKerberosTests(KDCBaseTest): > req_body): > return initial_padata, req_body > >+ generate_padata_fn = (_generate_padata_copy >+ if initial_padata is not None >+ else None) >+ > kdc_exchange_dict = self.as_exchange_dict( > expected_crealm=expected_crealm, > expected_cname=expected_cname, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >- generate_padata_fn=_generate_padata_copy, >+ generate_padata_fn=generate_padata_fn, > check_error_fn=self.generic_check_as_error, > check_rep_fn=None, > expected_error_mode=expected_error_mode, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 67b359f07d8..e15fc44a962 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1489,6 +1489,7 @@ class RawKerberosTest(TestCaseInTempDir): > padata, req_body = generate_padata_fn(kdc_exchange_dict, > callback_dict, > req_body) >+ self.assertIsNotNone(padata) > else: > padata = None > >@@ -2082,13 +2083,18 @@ class RawKerberosTest(TestCaseInTempDir): > check_error_fn = self.generic_check_as_error > check_rep_fn = None > >+ if padata is not None: >+ generate_padata_fn = _generate_padata_copy >+ else: >+ generate_padata_fn = None >+ > kdc_exchange_dict = self.as_exchange_dict( > expected_crealm=expected_crealm, > expected_cname=expected_cname, > expected_srealm=expected_srealm, > expected_sname=expected_sname, > ticket_decryption_key=ticket_decryption_key, >- generate_padata_fn=_generate_padata_copy, >+ generate_padata_fn=generate_padata_fn, > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, > check_padata_fn=_check_padata_preauth_key, >-- >2.25.1 > > >From 6a1bfd736e88dd723641442ad58a3e26c7ad1c63 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 13:59:36 +1200 >Subject: [PATCH 164/686] tests/krb5: Generate AP-REQ for TGS request in > _generic_kdc_exchange() > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 025737deb5325d25b2ae4c57583c24ae1d0eca33) >--- > python/samba/tests/krb5/raw_testcase.py | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e15fc44a962..4f399467cfe 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1484,13 +1484,34 @@ class RawKerberosTest(TestCaseInTempDir): > EncAuthorizationData=EncAuthorizationData, > EncAuthorizationData_key=EncAuthorizationData_key, > EncAuthorizationData_usage=EncAuthorizationData_usage) >+ >+ if req_msg_type == KRB_AS_REQ: >+ tgs_req = None >+ tgs_req_padata = None >+ else: >+ self.assertEqual(KRB_TGS_REQ, req_msg_type) >+ >+ tgs_req = self.generate_ap_req(kdc_exchange_dict, >+ callback_dict, >+ req_body) >+ tgs_req_padata = self.PA_DATA_create(PADATA_KDC_REQ, tgs_req) >+ > if generate_padata_fn is not None: > # This can alter req_body... > padata, req_body = generate_padata_fn(kdc_exchange_dict, > callback_dict, > req_body) > self.assertIsNotNone(padata) >+ self.assertNotIn(PADATA_KDC_REQ, >+ [pa['padata-type'] for pa in padata], >+ 'Don\'t create TGS-REQ manually') > else: >+ padata = [] >+ >+ if tgs_req_padata is not None: >+ padata.insert(0, tgs_req_padata) >+ >+ if not padata: > padata = None > > kdc_exchange_dict['req_padata'] = padata >-- >2.25.1 > > >From 486e815d60c7b31325cbeebabf9f92a592ed0e68 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 6 Jul 2021 10:21:07 +1200 >Subject: [PATCH 165/686] tests/krb5: Add more ASN1 definitions for FAST > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit ec702900295100ae4e48ba57242eee6670bf30d6) >--- > python/samba/tests/krb5/rfc4120.asn1 | 106 ++++++++++++++++++- > python/samba/tests/krb5/rfc4120_constants.py | 33 ++++++ > python/samba/tests/krb5/rfc4120_pyasn1.py | 100 ++++++++++++++++- > 3 files changed, 236 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 >index d81d06ad6f7..f47c1d00202 100644 >--- a/python/samba/tests/krb5/rfc4120.asn1 >+++ b/python/samba/tests/krb5/rfc4120.asn1 >@@ -1,3 +1,43 @@ >+-- Portions of these ASN.1 modules are structures are from RFC6113 >+-- authored by S. Hartman (Painless Security) and L. Zhu (Microsoft) >+-- >+-- Copyright (c) 2011 IETF Trust and the persons identified as authors of the >+-- code. All rights reserved. >+-- >+-- Redistribution and use in source and binary forms, with or without >+-- modification, is permitted pursuant to, and subject to the license terms >+-- contained in, the Simplified BSD License set forth in Section 4.c of the IETF >+-- Trustâs Legal Provisions Relating to IETF Documents >+-- (http://trustee.ietf.org/license-info). >+-- >+-- BSD License: >+-- >+-- Copyright (c) 2011 IETF Trust and the persons identified as authors of the code. All rights reserved. >+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided >+-- that the following conditions are met: >+-- ⢠Redistributions of source code must retain the above copyright notice, this list of conditions and >+-- the following disclaimer. >+-- >+-- ⢠Redistributions in binary form must reproduce the above copyright notice, this list of conditions >+-- and the following disclaimer in the documentation and/or other materials provided with the >+-- distribution. >+-- >+-- ⢠Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, >+-- may be used to endorse or promote products derived from this software without specific prior written >+-- permission. >+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS âAS ISâ >+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >+-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE >+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE >+-- POSSIBILITY OF SUCH DAMAGE. >+-- >+ > KerberosV5Spec2 { > iso(1) identified-organization(3) dod(6) internet(1) > security(5) kerberosV5(2) modules(4) krb5spec2(2) >@@ -464,6 +504,69 @@ PA-PAC-OPTIONS ::= SEQUENCE { > KERB-KEY-LIST-REQ ::= SEQUENCE OF EncryptionType -- Int32 encryption type -- > KERB-KEY-LIST-REP ::= SEQUENCE OF EncryptionKey > >+FastOptions ::= BIT STRING { >+ reserved(0), >+ hide-client-names(1), >+ kdc-follow-referrals(16) >+} >+ >+KrbFastReq ::= SEQUENCE { >+ fast-options [0] FastOptions, >+ padata [1] SEQUENCE OF PA-DATA, >+ req-body [2] KDC-REQ-BODY, >+ ... >+} >+ >+KrbFastArmor ::= SEQUENCE { >+ armor-type [0] Int32, >+ armor-value [1] OCTET STRING, >+ ... >+} >+ >+KrbFastArmoredReq ::= SEQUENCE { >+ armor [0] KrbFastArmor OPTIONAL, >+ req-checksum [1] Checksum, >+ enc-fast-req [2] EncryptedData -- KrbFastReq -- >+} >+ >+PA-FX-FAST-REQUEST ::= CHOICE { >+ armored-data [0] KrbFastArmoredReq, >+ ... >+} >+ >+KrbFastFinished ::= SEQUENCE { >+ timestamp [0] KerberosTime, >+ usec [1] Int32, >+ crealm [2] Realm, >+ cname [3] PrincipalName, >+ ticket-checksum [4] Checksum, >+ ... >+} >+ >+KrbFastResponse ::= SEQUENCE { >+ padata [0] SEQUENCE OF PA-DATA, >+ -- padata typed holes. >+ strengthen-key [1] EncryptionKey OPTIONAL, >+ -- This, if present, strengthens the reply key for AS and >+ -- TGS. MUST be present for TGS. >+ -- MUST be absent in KRB-ERROR. >+ finished [2] KrbFastFinished OPTIONAL, >+ -- Present in AS or TGS reply; absent otherwise. >+ nonce [3] UInt32, >+ -- Nonce from the client request. >+ ... >+} >+ >+KrbFastArmoredRep ::= SEQUENCE { >+ enc-fast-rep [0] EncryptedData, -- KrbFastResponse -- >+ ... >+} >+ >+PA-FX-FAST-REPLY ::= CHOICE { >+ armored-data [0] KrbFastArmoredRep, >+ ... >+} >+ > -- MS-KILE End > -- > -- >@@ -631,7 +734,8 @@ PADataTypeValues ::= INTEGER { > kRB5-PADATA-PKINIT-KX(147), -- krb-wg-anon > kRB5-PADATA-PKU2U-NAME(148), -- zhu-pku2u > kRB5-PADATA-REQ-ENC-PA-REP(149), -- >- kRB5-PADATA-SUPPORTED-ETYPES(165) -- MS-KILE >+ kRB5-PADATA-SUPPORTED-ETYPES(165), -- MS-KILE >+ kRB5-PADATA-PAC-OPTIONS(167) -- MS-KILE > } > PADataTypeSequence ::= SEQUENCE { > dummy [0] PADataTypeValues >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index b00b8b48ae5..e1a688991a7 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -36,29 +36,44 @@ KRB_TGS_REQ = int(krb5_asn1.MessageTypeValues('krb-tgs-req')) > # PAData types > PADATA_ENC_TIMESTAMP = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-ENC-TIMESTAMP')) >+PADATA_ENCRYPTED_CHALLENGE = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-ENCRYPTED-CHALLENGE')) > PADATA_ETYPE_INFO = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-ETYPE-INFO')) > PADATA_ETYPE_INFO2 = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-ETYPE-INFO2')) > PADATA_FOR_USER = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-FOR-USER')) >+PADATA_FX_COOKIE = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-FX-COOKIE')) >+PADATA_FX_ERROR = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-FX-ERROR')) >+PADATA_FX_FAST = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-FX-FAST')) > PADATA_KDC_REQ = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-KDC-REQ')) >+PADATA_PAC_OPTIONS = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-PAC-OPTIONS')) > PADATA_PAC_REQUEST = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-PA-PAC-REQUEST')) > PADATA_PK_AS_REQ = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-PK-AS-REQ')) > PADATA_PK_AS_REP_19 = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-PK-AS-REP-19')) >+PADATA_SUPPORTED_ETYPES = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-SUPPORTED-ETYPES')) > > # Error codes > KDC_ERR_C_PRINCIPAL_UNKNOWN = 6 >+KDC_ERR_POLICY = 12 > KDC_ERR_ETYPE_NOSUPP = 14 > KDC_ERR_PREAUTH_FAILED = 24 > KDC_ERR_PREAUTH_REQUIRED = 25 >+KDC_ERR_NOT_US = 35 > KDC_ERR_BADMATCH = 36 > KDC_ERR_SKEW = 37 > KDC_ERR_GENERIC = 60 >+KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS = 93 > > # Name types > NT_UNKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-UNKNOWN')) >@@ -67,6 +82,7 @@ NT_SRV_HST = int(krb5_asn1.NameTypeValues('kRB5-NT-SRV-HST')) > NT_SRV_INST = int(krb5_asn1.NameTypeValues('kRB5-NT-SRV-INST')) > NT_ENTERPRISE_PRINCIPAL = int(krb5_asn1.NameTypeValues( > 'kRB5-NT-ENTERPRISE-PRINCIPAL')) >+NT_WELLKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-WELLKNOWN')) > > # Authorization data ad-type values > >@@ -79,6 +95,8 @@ AD_MANDATORY_TICKET_EXTENSIONS = 6 > AD_IN_TICKET_EXTENSIONS = 7 > AD_MANDATORY_FOR_KDC = 8 > AD_INITIAL_VERIFIED_CAS = 9 >+AD_FX_FAST_ARMOR = 71 >+AD_FX_FAST_USED = 72 > AD_WIN2K_PAC = 128 > AD_SIGNTICKET = 512 > >@@ -133,3 +151,18 @@ KU_KRB_SAFE_CKSUM = 15 > (section 5.6.1) ''' > KU_NON_KERB_SALT = 16 > KU_NON_KERB_CKSUM_SALT = 17 >+ >+KU_ACCEPTOR_SEAL = 22 >+KU_ACCEPTOR_SIGN = 23 >+KU_INITIATOR_SEAL = 24 >+KU_INITIATOR_SIGN = 25 >+ >+KU_FAST_REQ_CHKSUM = 50 >+KU_FAST_ENC = 51 >+KU_FAST_REP = 52 >+KU_FAST_FINISHED = 53 >+KU_ENC_CHALLENGE_CLIENT = 54 >+KU_ENC_CHALLENGE_KDC = 55 >+ >+# Armor types >+FX_FAST_ARMOR_AP_REQUEST = 1 >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1.py b/python/samba/tests/krb5/rfc4120_pyasn1.py >index 56fe02a68f0..39ec8ed7982 100644 >--- a/python/samba/tests/krb5/rfc4120_pyasn1.py >+++ b/python/samba/tests/krb5/rfc4120_pyasn1.py >@@ -1,5 +1,5 @@ > # Auto-generated by asn1ate v.0.6.1.dev0 from rfc4120.asn1 >-# (last modified on 2021-06-16 08:54:13.969508) >+# (last modified on 2021-06-25 12:10:34.484667) > > # KerberosV5Spec2 > from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful >@@ -619,6 +619,17 @@ EncryptionTypeSequence.componentType = namedtype.NamedTypes( > ) > > >+class FastOptions(univ.BitString): >+ pass >+ >+ >+FastOptions.namedValues = namedval.NamedValues( >+ ('reserved', 0), >+ ('hide-client-names', 1), >+ ('kdc-follow-referrals', 16) >+) >+ >+ > class KDCOptionsValues(univ.BitString): > pass > >@@ -800,6 +811,72 @@ KerbErrorDataTypeSequence.componentType = namedtype.NamedTypes( > ) > > >+class KrbFastArmor(univ.Sequence): >+ pass >+ >+ >+KrbFastArmor.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('armor-type', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('armor-value', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) >+) >+ >+ >+class KrbFastArmoredRep(univ.Sequence): >+ pass >+ >+ >+KrbFastArmoredRep.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('enc-fast-rep', EncryptedData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) >+) >+ >+ >+class KrbFastArmoredReq(univ.Sequence): >+ pass >+ >+ >+KrbFastArmoredReq.componentType = namedtype.NamedTypes( >+ namedtype.OptionalNamedType('armor', KrbFastArmor().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), >+ namedtype.NamedType('req-checksum', Checksum().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), >+ namedtype.NamedType('enc-fast-req', EncryptedData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))) >+) >+ >+ >+class KrbFastFinished(univ.Sequence): >+ pass >+ >+ >+KrbFastFinished.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('timestamp', KerberosTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('usec', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('crealm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), >+ namedtype.NamedType('cname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))), >+ namedtype.NamedType('ticket-checksum', Checksum().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))) >+) >+ >+ >+class KrbFastReq(univ.Sequence): >+ pass >+ >+ >+KrbFastReq.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('fast-options', FastOptions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.NamedType('padata', univ.SequenceOf(componentType=PA_DATA()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.NamedType('req-body', KDC_REQ_BODY().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))) >+) >+ >+ >+class KrbFastResponse(univ.Sequence): >+ pass >+ >+ >+KrbFastResponse.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('padata', univ.SequenceOf(componentType=PA_DATA()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >+ namedtype.OptionalNamedType('strengthen-key', EncryptionKey().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), >+ namedtype.OptionalNamedType('finished', KrbFastFinished().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), >+ namedtype.NamedType('nonce', UInt32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) >+) >+ >+ > class MessageTypeValues(univ.Integer): > pass > >@@ -871,6 +948,24 @@ PA_ENC_TS_ENC.componentType = namedtype.NamedTypes( > ) > > >+class PA_FX_FAST_REPLY(univ.Choice): >+ pass >+ >+ >+PA_FX_FAST_REPLY.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('armored-data', KrbFastArmoredRep().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) >+) >+ >+ >+class PA_FX_FAST_REQUEST(univ.Choice): >+ pass >+ >+ >+PA_FX_FAST_REQUEST.componentType = namedtype.NamedTypes( >+ namedtype.NamedType('armored-data', KrbFastArmoredReq().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) >+) >+ >+ > class PACOptionFlags(KerberosFlags): > pass > >@@ -980,7 +1075,8 @@ PADataTypeValues.namedValues = namedval.NamedValues( > ('kRB5-PADATA-PKINIT-KX', 147), > ('kRB5-PADATA-PKU2U-NAME', 148), > ('kRB5-PADATA-REQ-ENC-PA-REP', 149), >- ('kRB5-PADATA-SUPPORTED-ETYPES', 165) >+ ('kRB5-PADATA-SUPPORTED-ETYPES', 165), >+ ('kRB5-PADATA-PAC-OPTIONS', 167) > ) > > >-- >2.25.1 > > >From ecbecbc5fdd1ed44c858b4996cb456c8d2dcbcee Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 6 Jul 2021 10:23:26 +1200 >Subject: [PATCH 166/686] tests/krb5: Add more methods to create ASN1 objects > for FAST > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 69a66c0d2a7ed415c8d8acdb8da0f2f3d1abf60d) >--- > python/samba/tests/krb5/raw_testcase.py | 70 +++++++++++++++++++++++++ > 1 file changed, 70 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 4f399467cfe..46ce7605edf 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1013,6 +1013,17 @@ class RawKerberosTest(TestCaseInTempDir): > } > return PrincipalName_obj > >+ def AuthorizationData_create(self, ad_type, ad_data): >+ # AuthorizationData ::= SEQUENCE { >+ # ad-type [0] Int32, >+ # ad-data [1] OCTET STRING >+ # } >+ AUTH_DATA_obj = { >+ 'ad-type': ad_type, >+ 'ad-data': ad_data >+ } >+ return AUTH_DATA_obj >+ > def PA_DATA_create(self, padata_type, padata_value): > # PA-DATA ::= SEQUENCE { > # -- NOTE: first tag is [1], not [0] >@@ -1036,6 +1047,65 @@ class RawKerberosTest(TestCaseInTempDir): > } > return PA_ENC_TS_ENC_obj > >+ def PA_PAC_OPTIONS_create(self, options): >+ # PA-PAC-OPTIONS ::= SEQUENCE { >+ # options [0] PACOptionFlags >+ # } >+ PA_PAC_OPTIONS_obj = { >+ 'options': options >+ } >+ return PA_PAC_OPTIONS_obj >+ >+ def KRB_FAST_ARMOR_create(self, armor_type, armor_value): >+ # KrbFastArmor ::= SEQUENCE { >+ # armor-type [0] Int32, >+ # armor-value [1] OCTET STRING, >+ # ... >+ # } >+ KRB_FAST_ARMOR_obj = { >+ 'armor-type': armor_type, >+ 'armor-value': armor_value >+ } >+ return KRB_FAST_ARMOR_obj >+ >+ def KRB_FAST_REQ_create(self, fast_options, padata, req_body): >+ # KrbFastReq ::= SEQUENCE { >+ # fast-options [0] FastOptions, >+ # padata [1] SEQUENCE OF PA-DATA, >+ # req-body [2] KDC-REQ-BODY, >+ # ... >+ # } >+ KRB_FAST_REQ_obj = { >+ 'fast-options': fast_options, >+ 'padata': padata, >+ 'req-body': req_body >+ } >+ return KRB_FAST_REQ_obj >+ >+ def KRB_FAST_ARMORED_REQ_create(self, armor, req_checksum, enc_fast_req): >+ # KrbFastArmoredReq ::= SEQUENCE { >+ # armor [0] KrbFastArmor OPTIONAL, >+ # req-checksum [1] Checksum, >+ # enc-fast-req [2] EncryptedData -- KrbFastReq -- >+ # } >+ KRB_FAST_ARMORED_REQ_obj = { >+ 'req-checksum': req_checksum, >+ 'enc-fast-req': enc_fast_req >+ } >+ if armor is not None: >+ KRB_FAST_ARMORED_REQ_obj['armor'] = armor >+ return KRB_FAST_ARMORED_REQ_obj >+ >+ def PA_FX_FAST_REQUEST_create(self, armored_data): >+ # PA-FX-FAST-REQUEST ::= CHOICE { >+ # armored-data [0] KrbFastArmoredReq, >+ # ... >+ # } >+ PA_FX_FAST_REQUEST_obj = { >+ 'armored-data': armored_data >+ } >+ return PA_FX_FAST_REQUEST_obj >+ > def KERB_PA_PAC_REQUEST_create(self, include_pac, pa_data_create=True): > # KERB-PA-PAC-REQUEST ::= SEQUENCE { > # include-pac[0] BOOLEAN --If TRUE, and no pac present, >-- >2.25.1 > > >From 25a556390dd2deb2f9b9cebb4fe6e58bdbd92d6b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 6 Jul 2021 12:47:18 +1200 >Subject: [PATCH 167/686] tests/krb5: Add method to generate FAST encrypted > challenge padata > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit aafc86896969d02ff1daecdf2668bfa642860082) >--- > python/samba/tests/krb5/kdc_base_test.py | 19 +++++++++++++++++++ > 1 file changed, 19 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 1b550179e0e..24a1e7cfbc8 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -54,11 +54,13 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_TGS_REP, > KRB_ERROR, > KU_AS_REP_ENC_PART, >+ KU_ENC_CHALLENGE_CLIENT, > KU_PA_ENC_TIMESTAMP, > KU_TGS_REP_ENC_PART_SUB_KEY, > KU_TICKET, > NT_PRINCIPAL, > NT_SRV_HST, >+ PADATA_ENCRYPTED_CHALLENGE, > PADATA_ENC_TIMESTAMP, > PADATA_ETYPE_INFO2, > ) >@@ -511,6 +513,23 @@ class KDCBaseTest(RawKerberosTest): > > return padata > >+ def get_challenge_pa_data(self, client_challenge_key, skew=0): >+ patime, pausec = self.get_KerberosTimeWithUsec(offset=skew) >+ padata = self.PA_ENC_TS_ENC_create(patime, pausec) >+ padata = self.der_encode(padata, >+ asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) >+ >+ padata = self.EncryptedData_create(client_challenge_key, >+ KU_ENC_CHALLENGE_CLIENT, >+ padata) >+ padata = self.der_encode(padata, >+ asn1Spec=krb5_asn1.EncryptedData()) >+ >+ padata = self.PA_DATA_create(PADATA_ENCRYPTED_CHALLENGE, >+ padata) >+ >+ return padata >+ > def get_as_rep_enc_data(self, key, rep): > ''' Decrypt and Decode the encrypted data in an AS-REP > ''' >-- >2.25.1 > > >From 63e5e3396c0a1d89f1bcc450af5e54b2660e3252 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 6 Jul 2021 12:49:05 +1200 >Subject: [PATCH 168/686] tests/krb5: Add methods to calculate keys for FAST > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 080894067469d60e2c71961c2d1c1990ba15b917) >--- > python/samba/tests/krb5/raw_testcase.py | 37 +++++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 46ce7605edf..113f08628b6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2137,6 +2137,43 @@ class RawKerberosTest(TestCaseInTempDir): > > return subkey, subkey_usage > >+ def generate_armor_key(self, subkey, session_key): >+ armor_key = kcrypto.cf2(subkey.key, >+ session_key.key, >+ b'subkeyarmor', >+ b'ticketarmor') >+ armor_key = Krb5EncryptionKey(armor_key, None) >+ >+ return armor_key >+ >+ def generate_strengthen_reply_key(self, strengthen_key, reply_key): >+ strengthen_reply_key = kcrypto.cf2(strengthen_key.key, >+ reply_key.key, >+ b'strengthenkey', >+ b'replykey') >+ strengthen_reply_key = Krb5EncryptionKey(strengthen_reply_key, >+ reply_key.kvno) >+ >+ return strengthen_reply_key >+ >+ def generate_client_challenge_key(self, armor_key, longterm_key): >+ client_challenge_key = kcrypto.cf2(armor_key.key, >+ longterm_key.key, >+ b'clientchallengearmor', >+ b'challengelongterm') >+ client_challenge_key = Krb5EncryptionKey(client_challenge_key, None) >+ >+ return client_challenge_key >+ >+ def generate_kdc_challenge_key(self, armor_key, longterm_key): >+ kdc_challenge_key = kcrypto.cf2(armor_key.key, >+ longterm_key.key, >+ b'kdcchallengearmor', >+ b'challengelongterm') >+ kdc_challenge_key = Krb5EncryptionKey(kdc_challenge_key, None) >+ >+ return kdc_challenge_key >+ > def _test_as_exchange(self, > cname, > realm, >-- >2.25.1 > > >From a7058f47bdde00fe0a1312e0f3e8d796b8763a15 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Jul 2021 20:49:12 +1200 >Subject: [PATCH 169/686] tests/krb5: Rename generic_check_as_error() to > generic_check_kdc_error() > >This method will also be useful in checking TGS-REP error replies. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 74f332c6f9e31b933837cefee69b219054970713) >--- > python/samba/tests/krb5/as_req_tests.py | 2 +- > python/samba/tests/krb5/raw_testcase.py | 10 +++++----- > 2 files changed, 6 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index b5a6cfd31c7..fd258e8164a 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -99,7 +99,7 @@ class AsReqKerberosTests(KDCBaseTest): > expected_srealm=expected_srealm, > expected_sname=expected_sname, > generate_padata_fn=generate_padata_fn, >- check_error_fn=self.generic_check_as_error, >+ check_error_fn=self.generic_check_kdc_error, > check_rep_fn=None, > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 113f08628b6..047bf413b34 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1888,10 +1888,10 @@ class RawKerberosTest(TestCaseInTempDir): > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > >- def generic_check_as_error(self, >- kdc_exchange_dict, >- callback_dict, >- rep): >+ def generic_check_kdc_error(self, >+ kdc_exchange_dict, >+ callback_dict, >+ rep): > > expected_crealm = kdc_exchange_dict['expected_crealm'] > expected_cname = kdc_exchange_dict['expected_cname'] >@@ -2208,7 +2208,7 @@ class RawKerberosTest(TestCaseInTempDir): > check_error_fn = None > check_rep_fn = self.generic_check_kdc_rep > else: >- check_error_fn = self.generic_check_as_error >+ check_error_fn = self.generic_check_kdc_error > check_rep_fn = None > > if padata is not None: >-- >2.25.1 > > >From 6def67e4318a72a101e81673c53ae4b38a4917ae Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 29 Jul 2021 10:19:46 +1200 >Subject: [PATCH 170/686] tests/krb5: Include authenticator_subkey in AS-REQ > exchange dict > >This is needed for FAST. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d554b6dc0f4e14d154e487dc2a842321aa746155) >--- > python/samba/tests/krb5/raw_testcase.py | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 047bf413b34..9375f39937e 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1632,6 +1632,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_error_mode=0, > client_as_etypes=None, > expected_salt=None, >+ authenticator_subkey=None, > kdc_options=''): > kdc_exchange_dict = { > 'req_msg_type': KRB_AS_REQ, >@@ -1653,6 +1654,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_error_mode': expected_error_mode, > 'client_as_etypes': client_as_etypes, > 'expected_salt': expected_salt, >+ 'authenticator_subkey': authenticator_subkey, > 'kdc_options': kdc_options, > } > if callback_dict is None: >-- >2.25.1 > > >From 705b5021b3c9f31da3dd2ffc825f8aacdddffceb Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 29 Jul 2021 10:33:10 +1200 >Subject: [PATCH 171/686] tests/krb5: Modify generate_ap_req() to also generate > FAST armor AP-REQ > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 5c2cd71ae704b853a886c8af5e3cf50b53af7f9e) >--- > python/samba/tests/krb5/raw_testcase.py | 45 ++++++++++++++++++------- > 1 file changed, 32 insertions(+), 13 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 9375f39937e..29ea41ec92b 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -49,6 +49,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_ERROR, > KRB_TGS_REP, > KRB_TGS_REQ, >+ KU_AP_REQ_AUTH, > KU_AS_REP_ENC_PART, > KU_NON_KERB_CKSUM_SALT, > KU_TGS_REP_ENC_PART_SESSION, >@@ -1563,7 +1564,8 @@ class RawKerberosTest(TestCaseInTempDir): > > tgs_req = self.generate_ap_req(kdc_exchange_dict, > callback_dict, >- req_body) >+ req_body, >+ armor=False) > tgs_req_padata = self.PA_DATA_create(PADATA_KDC_REQ, tgs_req) > > if generate_padata_fn is not None: >@@ -1633,6 +1635,8 @@ class RawKerberosTest(TestCaseInTempDir): > client_as_etypes=None, > expected_salt=None, > authenticator_subkey=None, >+ armor_tgt=None, >+ armor_subkey=None, > kdc_options=''): > kdc_exchange_dict = { > 'req_msg_type': KRB_AS_REQ, >@@ -1655,6 +1659,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'client_as_etypes': client_as_etypes, > 'expected_salt': expected_salt, > 'authenticator_subkey': authenticator_subkey, >+ 'armor_tgt': armor_tgt, >+ 'armor_subkey': armor_subkey, > 'kdc_options': kdc_options, > } > if callback_dict is None: >@@ -1675,6 +1681,8 @@ class RawKerberosTest(TestCaseInTempDir): > check_kdc_private_fn=None, > callback_dict=None, > tgt=None, >+ armor_tgt=None, >+ armor_subkey=None, > authenticator_subkey=None, > body_checksum_type=None, > kdc_options=''): >@@ -1697,6 +1705,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'callback_dict': callback_dict, > 'tgt': tgt, > 'body_checksum_type': body_checksum_type, >+ 'armor_tgt': armor_tgt, >+ 'armor_subkey': armor_subkey, > 'authenticator_subkey': authenticator_subkey, > 'kdc_options': kdc_options > } >@@ -2068,18 +2078,25 @@ class RawKerberosTest(TestCaseInTempDir): > def generate_ap_req(self, > kdc_exchange_dict, > _callback_dict, >- req_body): >- tgt = kdc_exchange_dict['tgt'] >- authenticator_subkey = kdc_exchange_dict['authenticator_subkey'] >- body_checksum_type = kdc_exchange_dict['body_checksum_type'] >+ req_body, >+ armor): >+ if armor: >+ tgt = kdc_exchange_dict['armor_tgt'] >+ authenticator_subkey = kdc_exchange_dict['armor_subkey'] > >- req_body_blob = self.der_encode(req_body, >- asn1Spec=krb5_asn1.KDC_REQ_BODY()) >+ req_body_checksum = None >+ else: >+ tgt = kdc_exchange_dict['tgt'] >+ authenticator_subkey = kdc_exchange_dict['authenticator_subkey'] >+ body_checksum_type = kdc_exchange_dict['body_checksum_type'] > >- req_body_checksum = self.Checksum_create(tgt.session_key, >- KU_TGS_REQ_AUTH_CKSUM, >- req_body_blob, >- ctype=body_checksum_type) >+ req_body_blob = self.der_encode(req_body, >+ asn1Spec=krb5_asn1.KDC_REQ_BODY()) >+ >+ req_body_checksum = self.Checksum_create(tgt.session_key, >+ KU_TGS_REQ_AUTH_CKSUM, >+ req_body_blob, >+ ctype=body_checksum_type) > > subkey_obj = None > if authenticator_subkey is not None: >@@ -2099,8 +2116,9 @@ class RawKerberosTest(TestCaseInTempDir): > authenticator_obj, > asn1Spec=krb5_asn1.Authenticator()) > >+ usage = KU_AP_REQ_AUTH if armor else KU_TGS_REQ_AUTH > authenticator = self.EncryptedData_create(tgt.session_key, >- KU_TGS_REQ_AUTH, >+ usage, > authenticator_blob) > > ap_options = krb5_asn1.APOptions('0') >@@ -2117,7 +2135,8 @@ class RawKerberosTest(TestCaseInTempDir): > req_body): > ap_req = self.generate_ap_req(kdc_exchange_dict, > callback_dict, >- req_body) >+ req_body, >+ armor=False) > pa_tgs_req = self.PA_DATA_create(PADATA_KDC_REQ, ap_req) > padata = [pa_tgs_req] > >-- >2.25.1 > > >From 19f9dbfb61a63c5195b43da5313b89f2c4e8a25a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 29 Jul 2021 10:33:24 +1200 >Subject: [PATCH 172/686] tests/krb5: Add FAST armor generation to > _generic_kdc_exchange() > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 0df385fc49cc2693c195209936a29e31216df16d) >--- > python/samba/tests/krb5/raw_testcase.py | 95 +++++++++++++++++++++++-- > 1 file changed, 88 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 29ea41ec92b..151dc0355a3 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -42,6 +42,7 @@ from samba.tests import TestCaseInTempDir > > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( >+ FX_FAST_ARMOR_AP_REQUEST, > KDC_ERR_GENERIC, > KRB_AP_REQ, > KRB_AS_REP, >@@ -51,6 +52,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_TGS_REQ, > KU_AP_REQ_AUTH, > KU_AS_REP_ENC_PART, >+ KU_FAST_REQ_CHKSUM, > KU_NON_KERB_CKSUM_SALT, > KU_TGS_REP_ENC_PART_SESSION, > KU_TGS_REP_ENC_PART_SUB_KEY, >@@ -1522,6 +1524,9 @@ class RawKerberosTest(TestCaseInTempDir): > > check_error_fn = kdc_exchange_dict['check_error_fn'] > check_rep_fn = kdc_exchange_dict['check_rep_fn'] >+ generate_fast_fn = kdc_exchange_dict['generate_fast_fn'] >+ generate_fast_armor_fn = kdc_exchange_dict['generate_fast_armor_fn'] >+ generate_fast_padata_fn = kdc_exchange_dict['generate_fast_padata_fn'] > generate_padata_fn = kdc_exchange_dict['generate_padata_fn'] > callback_dict = kdc_exchange_dict['callback_dict'] > req_msg_type = kdc_exchange_dict['req_msg_type'] >@@ -1568,25 +1573,81 @@ class RawKerberosTest(TestCaseInTempDir): > armor=False) > tgs_req_padata = self.PA_DATA_create(PADATA_KDC_REQ, tgs_req) > >+ if generate_fast_padata_fn is not None: >+ self.assertIsNotNone(generate_fast_fn) >+ # This can alter req_body... >+ fast_padata, req_body = generate_fast_padata_fn(kdc_exchange_dict, >+ callback_dict, >+ req_body) >+ else: >+ fast_padata = [] >+ >+ if generate_fast_armor_fn is not None: >+ self.assertIsNotNone(generate_fast_fn) >+ fast_ap_req = generate_fast_armor_fn(kdc_exchange_dict, >+ callback_dict, >+ req_body, >+ armor=True) >+ >+ fast_armor_type = kdc_exchange_dict['fast_armor_type'] >+ fast_armor = self.KRB_FAST_ARMOR_create(fast_armor_type, >+ fast_ap_req) >+ else: >+ fast_armor = None >+ > if generate_padata_fn is not None: > # This can alter req_body... >- padata, req_body = generate_padata_fn(kdc_exchange_dict, >- callback_dict, >- req_body) >- self.assertIsNotNone(padata) >+ outer_padata, req_body = generate_padata_fn(kdc_exchange_dict, >+ callback_dict, >+ req_body) >+ self.assertIsNotNone(outer_padata) > self.assertNotIn(PADATA_KDC_REQ, >- [pa['padata-type'] for pa in padata], >+ [pa['padata-type'] for pa in outer_padata], > 'Don\'t create TGS-REQ manually') > else: >- padata = [] >+ outer_padata = None >+ >+ if generate_fast_fn is not None: >+ armor_key = kdc_exchange_dict['armor_key'] >+ self.assertIsNotNone(armor_key) >+ >+ if req_msg_type == KRB_AS_REQ: >+ checksum_blob = self.der_encode( >+ req_body, >+ asn1Spec=krb5_asn1.KDC_REQ_BODY()) >+ else: >+ self.assertEqual(KRB_TGS_REQ, req_msg_type) >+ checksum_blob = tgs_req >+ >+ checksum = self.Checksum_create(armor_key, >+ KU_FAST_REQ_CHKSUM, >+ checksum_blob) >+ >+ fast = generate_fast_fn(kdc_exchange_dict, >+ callback_dict, >+ req_body, >+ fast_padata, >+ fast_armor, >+ checksum) >+ else: >+ fast = None >+ >+ padata = [] > > if tgs_req_padata is not None: >- padata.insert(0, tgs_req_padata) >+ padata.append(tgs_req_padata) >+ >+ if fast is not None: >+ padata.append(fast) >+ >+ if outer_padata is not None: >+ padata += outer_padata > > if not padata: > padata = None > > kdc_exchange_dict['req_padata'] = padata >+ kdc_exchange_dict['fast_padata'] = fast_padata > kdc_exchange_dict['req_body'] = req_body > > req_obj, req_decoded = self.KDC_REQ_create(msg_type=req_msg_type, >@@ -1625,6 +1686,10 @@ class RawKerberosTest(TestCaseInTempDir): > expected_srealm=None, > expected_sname=None, > ticket_decryption_key=None, >+ generate_fast_fn=None, >+ generate_fast_armor_fn=None, >+ generate_fast_padata_fn=None, >+ fast_armor_type=FX_FAST_ARMOR_AP_REQUEST, > generate_padata_fn=None, > check_error_fn=None, > check_rep_fn=None, >@@ -1635,6 +1700,7 @@ class RawKerberosTest(TestCaseInTempDir): > client_as_etypes=None, > expected_salt=None, > authenticator_subkey=None, >+ armor_key=None, > armor_tgt=None, > armor_subkey=None, > kdc_options=''): >@@ -1649,6 +1715,10 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, > 'ticket_decryption_key': ticket_decryption_key, >+ 'generate_fast_fn': generate_fast_fn, >+ 'generate_fast_armor_fn': generate_fast_armor_fn, >+ 'generate_fast_padata_fn': generate_fast_padata_fn, >+ 'fast_armor_type': fast_armor_type, > 'generate_padata_fn': generate_padata_fn, > 'check_error_fn': check_error_fn, > 'check_rep_fn': check_rep_fn, >@@ -1659,6 +1729,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'client_as_etypes': client_as_etypes, > 'expected_salt': expected_salt, > 'authenticator_subkey': authenticator_subkey, >+ 'armor_key': armor_key, > 'armor_tgt': armor_tgt, > 'armor_subkey': armor_subkey, > 'kdc_options': kdc_options, >@@ -1674,6 +1745,10 @@ class RawKerberosTest(TestCaseInTempDir): > expected_srealm=None, > expected_sname=None, > ticket_decryption_key=None, >+ generate_fast_fn=None, >+ generate_fast_armor_fn=None, >+ generate_fast_padata_fn=None, >+ fast_armor_type=FX_FAST_ARMOR_AP_REQUEST, > generate_padata_fn=None, > check_error_fn=None, > check_rep_fn=None, >@@ -1681,6 +1756,7 @@ class RawKerberosTest(TestCaseInTempDir): > check_kdc_private_fn=None, > callback_dict=None, > tgt=None, >+ armor_key=None, > armor_tgt=None, > armor_subkey=None, > authenticator_subkey=None, >@@ -1697,6 +1773,10 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, > 'ticket_decryption_key': ticket_decryption_key, >+ 'generate_fast_fn': generate_fast_fn, >+ 'generate_fast_armor_fn': generate_fast_armor_fn, >+ 'generate_fast_padata_fn': generate_fast_padata_fn, >+ 'fast_armor_type': fast_armor_type, > 'generate_padata_fn': generate_padata_fn, > 'check_error_fn': check_error_fn, > 'check_rep_fn': check_rep_fn, >@@ -1705,6 +1785,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'callback_dict': callback_dict, > 'tgt': tgt, > 'body_checksum_type': body_checksum_type, >+ 'armor_key': armor_key, > 'armor_tgt': armor_tgt, > 'armor_subkey': armor_subkey, > 'authenticator_subkey': authenticator_subkey, >-- >2.25.1 > > >From 1b475e1fafb052c39d7eb9731adda149e695bbe2 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:01:36 +1200 >Subject: [PATCH 173/686] tests/krb5: Allow specifying parameters specific to > the outer request body > >This is useful for testing FAST. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 16ce1a1d304b87ed5b390fb87a4542c7c9a484fb) >--- > python/samba/tests/krb5/raw_testcase.py | 25 ++++++++++++++++++++----- > 1 file changed, 20 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 151dc0355a3..a173caf98d1 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1536,6 +1536,9 @@ class RawKerberosTest(TestCaseInTempDir): > expected_error_mode = kdc_exchange_dict['expected_error_mode'] > kdc_options = kdc_exchange_dict['kdc_options'] > >+ # Parameters specific to the outer request body >+ outer_req = kdc_exchange_dict['outer_req'] >+ > if till_time is None: > till_time = self.get_KerberosTime(offset=36000) > >@@ -1561,6 +1564,14 @@ class RawKerberosTest(TestCaseInTempDir): > EncAuthorizationData_key=EncAuthorizationData_key, > EncAuthorizationData_usage=EncAuthorizationData_usage) > >+ inner_req_body = dict(req_body) >+ if outer_req is not None: >+ for key, value in outer_req.items(): >+ if value is not None: >+ req_body[key] = value >+ else: >+ del req_body[key] >+ > if req_msg_type == KRB_AS_REQ: > tgs_req = None > tgs_req_padata = None >@@ -1625,7 +1636,7 @@ class RawKerberosTest(TestCaseInTempDir): > > fast = generate_fast_fn(kdc_exchange_dict, > callback_dict, >- req_body, >+ inner_req_body, > fast_padata, > fast_armor, > checksum) >@@ -1648,7 +1659,7 @@ class RawKerberosTest(TestCaseInTempDir): > > kdc_exchange_dict['req_padata'] = padata > kdc_exchange_dict['fast_padata'] = fast_padata >- kdc_exchange_dict['req_body'] = req_body >+ kdc_exchange_dict['req_body'] = inner_req_body > > req_obj, req_decoded = self.KDC_REQ_create(msg_type=req_msg_type, > padata=padata, >@@ -1703,7 +1714,8 @@ class RawKerberosTest(TestCaseInTempDir): > armor_key=None, > armor_tgt=None, > armor_subkey=None, >- kdc_options=''): >+ kdc_options='', >+ outer_req=None): > kdc_exchange_dict = { > 'req_msg_type': KRB_AS_REQ, > 'req_asn1Spec': krb5_asn1.AS_REQ, >@@ -1733,6 +1745,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'armor_tgt': armor_tgt, > 'armor_subkey': armor_subkey, > 'kdc_options': kdc_options, >+ 'outer_req': outer_req > } > if callback_dict is None: > callback_dict = {} >@@ -1761,7 +1774,8 @@ class RawKerberosTest(TestCaseInTempDir): > armor_subkey=None, > authenticator_subkey=None, > body_checksum_type=None, >- kdc_options=''): >+ kdc_options='', >+ outer_req=None): > kdc_exchange_dict = { > 'req_msg_type': KRB_TGS_REQ, > 'req_asn1Spec': krb5_asn1.TGS_REQ, >@@ -1789,7 +1803,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'armor_tgt': armor_tgt, > 'armor_subkey': armor_subkey, > 'authenticator_subkey': authenticator_subkey, >- 'kdc_options': kdc_options >+ 'kdc_options': kdc_options, >+ 'outer_req': outer_req > } > if callback_dict is None: > callback_dict = {} >-- >2.25.1 > > >From ef8365f4aca81feb682c5dc73d306d07d352af10 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:04:37 +1200 >Subject: [PATCH 174/686] tests/krb5: Add method to check PA-FX-FAST-REPLY > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit b62488113f6053755f9be9faa9b757e7193074fa) >--- > python/samba/tests/krb5/raw_testcase.py | 31 +++++++++++++++++++++++++ > 1 file changed, 31 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index a173caf98d1..dd733aea09b 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -52,6 +52,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_TGS_REQ, > KU_AP_REQ_AUTH, > KU_AS_REP_ENC_PART, >+ KU_FAST_REP, > KU_FAST_REQ_CHKSUM, > KU_NON_KERB_CKSUM_SALT, > KU_TGS_REP_ENC_PART_SESSION, >@@ -1910,6 +1911,36 @@ class RawKerberosTest(TestCaseInTempDir): > > return rep > >+ def check_fx_fast_data(self, >+ kdc_exchange_dict, >+ fx_fast_data, >+ armor_key, >+ finished=False, >+ expect_strengthen_key=True): >+ fx_fast_data = self.der_decode(fx_fast_data, >+ asn1Spec=krb5_asn1.PA_FX_FAST_REPLY()) >+ >+ enc_fast_rep = fx_fast_data['armored-data']['enc-fast-rep'] >+ self.assertEqual(enc_fast_rep['etype'], armor_key.etype) >+ >+ fast_rep = armor_key.decrypt(KU_FAST_REP, enc_fast_rep['cipher']) >+ >+ fast_response = self.der_decode(fast_rep, >+ asn1Spec=krb5_asn1.KrbFastResponse()) >+ >+ if expect_strengthen_key and self.strict_checking: >+ self.assertIn('strengthen-key', fast_response) >+ >+ if finished: >+ self.assertIn('finished', fast_response) >+ >+ # Ensure that the nonce matches the nonce in the body of the request >+ # (RFC6113 5.4.3). >+ nonce = kdc_exchange_dict['nonce'] >+ self.assertEqual(nonce, fast_response['nonce']) >+ >+ return fast_response >+ > def generic_check_kdc_private(self, > kdc_exchange_dict, > callback_dict, >-- >2.25.1 > > >From 6b90098e85ae746c7622321896b4d53bfc027fe9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:10:13 +1200 >Subject: [PATCH 175/686] tests/krb5: Add method to verify ticket checksum for > FAST > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 4ca05402b36ba13a987b07b2402906764d3cd49b) >--- > python/samba/tests/krb5/raw_testcase.py | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index dd733aea09b..da38a9dfa62 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -52,6 +52,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_TGS_REQ, > KU_AP_REQ_AUTH, > KU_AS_REP_ENC_PART, >+ KU_FAST_FINISHED, > KU_FAST_REP, > KU_FAST_REQ_CHKSUM, > KU_NON_KERB_CKSUM_SALT, >@@ -2322,6 +2323,17 @@ class RawKerberosTest(TestCaseInTempDir): > > return kdc_challenge_key > >+ def verify_ticket_checksum(self, ticket, expected_checksum, armor_key): >+ expected_type = expected_checksum['cksumtype'] >+ self.assertEqual(armor_key.ctype, expected_type) >+ >+ ticket_blob = self.der_encode(ticket, >+ asn1Spec=krb5_asn1.Ticket()) >+ checksum = self.Checksum_create(armor_key, >+ KU_FAST_FINISHED, >+ ticket_blob) >+ self.assertEqual(expected_checksum, checksum) >+ > def _test_as_exchange(self, > cname, > realm, >-- >2.25.1 > > >From 20b724ca253aa9cd424c617068423885277a1a1e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:42:57 +1200 >Subject: [PATCH 176/686] tests/krb5: Check FAST response > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit d878bd6404d26c8be45bb2016ec206ed79d4ef6e) >--- > python/samba/tests/krb5/raw_testcase.py | 41 +++++++++++++++++++++++-- > 1 file changed, 39 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index da38a9dfa62..ab1f711cde1 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -67,6 +67,7 @@ from samba.tests.krb5.rfc4120_constants import ( > PADATA_ETYPE_INFO, > PADATA_ETYPE_INFO2, > PADATA_FOR_USER, >+ PADATA_FX_FAST, > PADATA_KDC_REQ, > PADATA_PAC_REQUEST, > PADATA_PK_AS_REQ, >@@ -1827,6 +1828,7 @@ class RawKerberosTest(TestCaseInTempDir): > check_kdc_private_fn = kdc_exchange_dict['check_kdc_private_fn'] > rep_encpart_asn1Spec = kdc_exchange_dict['rep_encpart_asn1Spec'] > msg_type = kdc_exchange_dict['rep_msg_type'] >+ armor_key = kdc_exchange_dict['armor_key'] > > self.assertElementEqual(rep, 'msg-type', msg_type) # AS-REP | TGS-REP > padata = self.getElementValue(rep, 'padata') >@@ -1862,6 +1864,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(encpart, 'cipher') > encpart_cipher = self.getElementValue(encpart, 'cipher') > >+ ticket_checksum = None >+ > encpart_decryption_key = None > self.assertIsNotNone(check_padata_fn) > if check_padata_fn is not None: >@@ -1870,6 +1874,33 @@ class RawKerberosTest(TestCaseInTempDir): > check_padata_fn(kdc_exchange_dict, callback_dict, > rep, padata)) > >+ if armor_key is not None: >+ pa_dict = self.get_pa_dict(padata) >+ >+ if PADATA_FX_FAST in pa_dict: >+ fx_fast_data = pa_dict[PADATA_FX_FAST] >+ fast_response = self.check_fx_fast_data(kdc_exchange_dict, >+ fx_fast_data, >+ armor_key, >+ finished=True) >+ >+ if 'strengthen-key' in fast_response: >+ strengthen_key = self.EncryptionKey_import( >+ fast_response['strengthen-key']) >+ encpart_decryption_key = ( >+ self.generate_strengthen_reply_key( >+ strengthen_key, >+ encpart_decryption_key)) >+ >+ fast_finished = fast_response.get('finished', None) >+ if fast_finished is not None: >+ ticket_checksum = fast_finished['ticket-checksum'] >+ >+ self.check_rep_padata(kdc_exchange_dict, >+ callback_dict, >+ rep, >+ fast_response['padata']) >+ > ticket_private = None > self.assertIsNotNone(ticket_decryption_key) > if ticket_decryption_key is not None: >@@ -1908,7 +1939,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(check_kdc_private_fn) > if check_kdc_private_fn is not None: > check_kdc_private_fn(kdc_exchange_dict, callback_dict, >- rep, ticket_private, encpart_private) >+ rep, ticket_private, encpart_private, >+ ticket_checksum) > > return rep > >@@ -1947,7 +1979,8 @@ class RawKerberosTest(TestCaseInTempDir): > callback_dict, > rep, > ticket_private, >- encpart_private): >+ encpart_private, >+ ticket_checksum): > > expected_crealm = kdc_exchange_dict['expected_crealm'] > expected_cname = kdc_exchange_dict['expected_cname'] >@@ -1957,6 +1990,10 @@ class RawKerberosTest(TestCaseInTempDir): > > ticket = self.getElementValue(rep, 'ticket') > >+ if ticket_checksum is not None: >+ armor_key = kdc_exchange_dict['armor_key'] >+ self.verify_ticket_checksum(ticket, ticket_checksum, armor_key) >+ > ticket_session_key = None > if ticket_private is not None: > self.assertElementPresent(ticket_private, 'flags') >-- >2.25.1 > > >From 821a9fc062b4e6cdf7d47bab5ce4b072345032ce Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 15:20:44 +1200 >Subject: [PATCH 177/686] tests/krb5: Add functions to get dicts of request > padata > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit dc7dac95ec509d90d8372005cd7b13fabd8e64c6) >--- > python/samba/tests/krb5/raw_testcase.py | 11 +++++++++++ > 1 file changed, 11 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index ab1f711cde1..2963df70003 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2371,6 +2371,17 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_blob) > self.assertEqual(expected_checksum, checksum) > >+ def get_outer_pa_dict(self, kdc_exchange_dict): >+ return self.get_pa_dict(kdc_exchange_dict['req_padata']) >+ >+ def get_fast_pa_dict(self, kdc_exchange_dict): >+ req_pa_dict = self.get_pa_dict(kdc_exchange_dict['fast_padata']) >+ >+ if req_pa_dict: >+ return req_pa_dict >+ >+ return self.get_outer_pa_dict(kdc_exchange_dict) >+ > def _test_as_exchange(self, > cname, > realm, >-- >2.25.1 > > >From 9ba8e6b1490b42699ad193154d6e4d7624c2cdab Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 15:21:01 +1200 >Subject: [PATCH 178/686] tests/krb5: Add methods to determine whether elements > were included in the request > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 99e3b909edf27c751b959a3d0b672ddd2b7140e2) >--- > python/samba/tests/krb5/raw_testcase.py | 25 +++++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 2963df70003..d96cd1cfc15 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -69,6 +69,7 @@ from samba.tests.krb5.rfc4120_constants import ( > PADATA_FOR_USER, > PADATA_FX_FAST, > PADATA_KDC_REQ, >+ PADATA_PAC_OPTIONS, > PADATA_PAC_REQUEST, > PADATA_PK_AS_REQ, > PADATA_PK_AS_REP_19 >@@ -2382,6 +2383,30 @@ class RawKerberosTest(TestCaseInTempDir): > > return self.get_outer_pa_dict(kdc_exchange_dict) > >+ def sent_fast(self, kdc_exchange_dict): >+ outer_pa_dict = self.get_outer_pa_dict(kdc_exchange_dict) >+ >+ return PADATA_FX_FAST in outer_pa_dict >+ >+ def sent_enc_challenge(self, kdc_exchange_dict): >+ fast_pa_dict = self.get_fast_pa_dict(kdc_exchange_dict) >+ >+ return PADATA_ENCRYPTED_CHALLENGE in fast_pa_dict >+ >+ def sent_claims(self, kdc_exchange_dict): >+ fast_pa_dict = self.get_fast_pa_dict(kdc_exchange_dict) >+ >+ if PADATA_PAC_OPTIONS not in fast_pa_dict: >+ return False >+ >+ pac_options = self.der_decode(fast_pa_dict[PADATA_PAC_OPTIONS], >+ asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >+ pac_options = pac_options['options'] >+ claims_pos = len(tuple(krb5_asn1.PACOptionFlags('claims'))) - 1 >+ >+ return (claims_pos < len(pac_options) >+ and pac_options[claims_pos] == '1') >+ > def _test_as_exchange(self, > cname, > realm, >-- >2.25.1 > > >From d9fb5223432fb70da7ea79a95a905f097515c646 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:34:49 +1200 >Subject: [PATCH 179/686] tests/krb5: Check encrypted-pa-data > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 0c029e780cf16a49c674593e8329eaf3b87aec69) >--- > python/samba/tests/krb5/raw_testcase.py | 52 ++++++++++++++++++++++++- > 1 file changed, 51 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index d96cd1cfc15..2512ee1b99f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -72,7 +72,8 @@ from samba.tests.krb5.rfc4120_constants import ( > PADATA_PAC_OPTIONS, > PADATA_PAC_REQUEST, > PADATA_PK_AS_REQ, >- PADATA_PK_AS_REP_19 >+ PADATA_PK_AS_REP_19, >+ PADATA_SUPPORTED_ETYPES > ) > import samba.tests.krb5.kcrypto as kcrypto > >@@ -1982,6 +1983,10 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_private, > encpart_private, > ticket_checksum): >+ kdc_options = kdc_exchange_dict['kdc_options'] >+ canon_pos = len(tuple(krb5_asn1.KDCOptions('canonicalize'))) - 1 >+ canonicalize = (canon_pos < len(kdc_options) >+ and kdc_options[canon_pos] == '1') > > expected_crealm = kdc_exchange_dict['expected_crealm'] > expected_cname = kdc_exchange_dict['expected_cname'] >@@ -2044,6 +2049,46 @@ class RawKerberosTest(TestCaseInTempDir): > expected_sname) > # TODO self.assertElementMissing(encpart_private, 'caddr') > >+ sent_claims = self.sent_claims(kdc_exchange_dict) >+ >+ if self.strict_checking: >+ if sent_claims or canonicalize: >+ self.assertElementPresent(encpart_private, >+ 'encrypted-pa-data') >+ enc_pa_dict = self.get_pa_dict( >+ encpart_private['encrypted-pa-data']) >+ if canonicalize: >+ self.assertIn(PADATA_SUPPORTED_ETYPES, enc_pa_dict) >+ >+ (supported_etypes,) = struct.unpack( >+ '<L', >+ enc_pa_dict[PADATA_SUPPORTED_ETYPES]) >+ >+ self.assertTrue( >+ security.KERB_ENCTYPE_FAST_SUPPORTED >+ & supported_etypes) >+ self.assertTrue( >+ security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED >+ & supported_etypes) >+ self.assertTrue( >+ security.KERB_ENCTYPE_CLAIMS_SUPPORTED >+ & supported_etypes) >+ else: >+ self.assertNotIn(PADATA_SUPPORTED_ETYPES, enc_pa_dict) >+ >+ # ClaimsCompIdFASTSupported registry key >+ if sent_claims: >+ self.assertIn(PADATA_PAC_OPTIONS, enc_pa_dict) >+ >+ self.check_pac_options_claims_support( >+ enc_pa_dict[PADATA_PAC_OPTIONS]) >+ else: >+ self.assertNotIn(PADATA_PAC_OPTIONS, enc_pa_dict) >+ else: >+ self.assertElementEqual(encpart_private, >+ 'encrypted-pa-data', >+ []) >+ > if ticket_session_key is not None and encpart_session_key is not None: > self.assertEqual(ticket_session_key.etype, > encpart_session_key.etype) >@@ -2066,6 +2111,11 @@ class RawKerberosTest(TestCaseInTempDir): > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > >+ def check_pac_options_claims_support(self, pac_options): >+ pac_options = self.der_decode(pac_options, >+ asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >+ self.assertEqual('1', pac_options['options'][0]) # claims bit >+ > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >-- >2.25.1 > > >From aa590b0546fde0a0545a039a96826127f0c5b842 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:05:59 +1200 >Subject: [PATCH 180/686] tests/krb5: Add expected_cname_private parameter to > kdc_exchange_dict > >This is useful for testing the 'hide client names' FAST option. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 2ee87dbf08e66e1dc812430026bfe214f9f5503d) >--- > python/samba/tests/krb5/raw_testcase.py | 16 +++++++++++++++- > 1 file changed, 15 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 2512ee1b99f..b79b84686a6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1699,6 +1699,7 @@ class RawKerberosTest(TestCaseInTempDir): > def as_exchange_dict(self, > expected_crealm=None, > expected_cname=None, >+ expected_cname_private=None, > expected_srealm=None, > expected_sname=None, > ticket_decryption_key=None, >@@ -1752,6 +1753,10 @@ class RawKerberosTest(TestCaseInTempDir): > 'kdc_options': kdc_options, > 'outer_req': outer_req > } >+ if expected_cname_private is not None: >+ kdc_exchange_dict['expected_cname_private'] = ( >+ expected_cname_private) >+ > if callback_dict is None: > callback_dict = {} > >@@ -1760,6 +1765,7 @@ class RawKerberosTest(TestCaseInTempDir): > def tgs_exchange_dict(self, > expected_crealm=None, > expected_cname=None, >+ expected_cname_private=None, > expected_srealm=None, > expected_sname=None, > ticket_decryption_key=None, >@@ -1811,6 +1817,10 @@ class RawKerberosTest(TestCaseInTempDir): > 'kdc_options': kdc_options, > 'outer_req': outer_req > } >+ if expected_cname_private is not None: >+ kdc_exchange_dict['expected_cname_private'] = ( >+ expected_cname_private) >+ > if callback_dict is None: > callback_dict = {} > >@@ -1989,11 +1999,15 @@ class RawKerberosTest(TestCaseInTempDir): > and kdc_options[canon_pos] == '1') > > expected_crealm = kdc_exchange_dict['expected_crealm'] >- expected_cname = kdc_exchange_dict['expected_cname'] > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] > ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] > >+ try: >+ expected_cname = kdc_exchange_dict['expected_cname_private'] >+ except KeyError: >+ expected_cname = kdc_exchange_dict['expected_cname'] >+ > ticket = self.getElementValue(rep, 'ticket') > > if ticket_checksum is not None: >-- >2.25.1 > > >From 8e397a93e97d47b93c5008b38b7329d48d4e50b6 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:18:29 +1200 >Subject: [PATCH 181/686] tests/krb5: Include authdata in kdc_exchange_dict > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit ea1ed63e8819926db1cf15974009601c7d37e944) >--- > python/samba/tests/krb5/raw_testcase.py | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b79b84686a6..c1dfe44dfd1 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1720,6 +1720,7 @@ class RawKerberosTest(TestCaseInTempDir): > armor_key=None, > armor_tgt=None, > armor_subkey=None, >+ auth_data=None, > kdc_options='', > outer_req=None): > kdc_exchange_dict = { >@@ -1750,6 +1751,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'armor_key': armor_key, > 'armor_tgt': armor_tgt, > 'armor_subkey': armor_subkey, >+ 'auth_data': auth_data, > 'kdc_options': kdc_options, > 'outer_req': outer_req > } >@@ -1784,6 +1786,7 @@ class RawKerberosTest(TestCaseInTempDir): > armor_tgt=None, > armor_subkey=None, > authenticator_subkey=None, >+ auth_data=None, > body_checksum_type=None, > kdc_options='', > outer_req=None): >@@ -1813,6 +1816,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'armor_key': armor_key, > 'armor_tgt': armor_tgt, > 'armor_subkey': armor_subkey, >+ 'auth_data': auth_data, > 'authenticator_subkey': authenticator_subkey, > 'kdc_options': kdc_options, > 'outer_req': outer_req >@@ -2328,6 +2332,8 @@ class RawKerberosTest(TestCaseInTempDir): > req_body_blob, > ctype=body_checksum_type) > >+ auth_data = kdc_exchange_dict['auth_data'] >+ > subkey_obj = None > if authenticator_subkey is not None: > subkey_obj = authenticator_subkey.export_obj() >@@ -2341,7 +2347,7 @@ class RawKerberosTest(TestCaseInTempDir): > ctime=ctime, > subkey=subkey_obj, > seq_number=seq_number, >- authorization_data=None) >+ authorization_data=auth_data) > authenticator_blob = self.der_encode( > authenticator_obj, > asn1Spec=krb5_asn1.Authenticator()) >-- >2.25.1 > > >From c78960de91fdedbdd07520ca3486e2d93782e294 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 15:20:09 +1200 >Subject: [PATCH 182/686] tests/krb5: Add generate_simple_fast() method to > generate FX-FAST padata > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 1389ba346df81c9ea1e1143c4e819212939f6aeb) >--- > python/samba/tests/krb5/raw_testcase.py | 34 +++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index c1dfe44dfd1..a557c424527 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -52,6 +52,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_TGS_REQ, > KU_AP_REQ_AUTH, > KU_AS_REP_ENC_PART, >+ KU_FAST_ENC, > KU_FAST_FINISHED, > KU_FAST_REP, > KU_FAST_REQ_CHKSUM, >@@ -2309,6 +2310,39 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_exchange_dict['preauth_etype_info2'] = etype_info2 > return > >+ def generate_simple_fast(self, >+ kdc_exchange_dict, >+ _callback_dict, >+ req_body, >+ fast_padata, >+ fast_armor, >+ checksum, >+ fast_options=''): >+ armor_key = kdc_exchange_dict['armor_key'] >+ >+ fast_req = self.KRB_FAST_REQ_create(fast_options, >+ fast_padata, >+ req_body) >+ fast_req = self.der_encode(fast_req, >+ asn1Spec=krb5_asn1.KrbFastReq()) >+ fast_req = self.EncryptedData_create(armor_key, >+ KU_FAST_ENC, >+ fast_req) >+ >+ fast_armored_req = self.KRB_FAST_ARMORED_REQ_create(fast_armor, >+ checksum, >+ fast_req) >+ >+ fx_fast_request = self.PA_FX_FAST_REQUEST_create(fast_armored_req) >+ fx_fast_request = self.der_encode( >+ fx_fast_request, >+ asn1Spec=krb5_asn1.PA_FX_FAST_REQUEST()) >+ >+ fast_padata = self.PA_DATA_create(PADATA_FX_FAST, >+ fx_fast_request) >+ >+ return fast_padata >+ > def generate_ap_req(self, > kdc_exchange_dict, > _callback_dict, >-- >2.25.1 > > >From 636f9bdd19edd95229bc830221b81c1cf4942719 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 16:21:14 +1200 >Subject: [PATCH 183/686] tests/krb5: Add check_rep_padata() method to check > padata in reply > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 79b9aac65b7dbdc58275368eae9feb7d87bf6dab) >--- > python/samba/tests/krb5/raw_testcase.py | 83 ++++++++++++++----------- > 1 file changed, 48 insertions(+), 35 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index a557c424527..80c60682bd1 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2144,13 +2144,54 @@ class RawKerberosTest(TestCaseInTempDir): > expected_cname = kdc_exchange_dict['expected_cname'] > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] >- expected_salt = kdc_exchange_dict['expected_salt'] >- client_as_etypes = kdc_exchange_dict['client_as_etypes'] >+ expected_error_mode = kdc_exchange_dict['expected_error_mode'] >+ >+ self.assertElementEqual(rep, 'pvno', 5) >+ self.assertElementEqual(rep, 'msg-type', KRB_ERROR) >+ self.assertElementEqual(rep, 'error-code', expected_error_mode) >+ if self.strict_checking: >+ self.assertElementMissing(rep, 'ctime') >+ self.assertElementMissing(rep, 'cusec') >+ self.assertElementPresent(rep, 'stime') >+ self.assertElementPresent(rep, 'susec') >+ # error-code checked above >+ if self.strict_checking: >+ self.assertElementMissing(rep, 'crealm') >+ self.assertElementMissing(rep, 'cname') >+ self.assertElementEqualUTF8(rep, 'realm', expected_srealm) >+ self.assertElementEqualPrincipal(rep, 'sname', expected_sname) >+ self.assertElementMissing(rep, 'e-text') >+ if expected_error_mode == KDC_ERR_GENERIC: >+ self.assertElementMissing(rep, 'e-data') >+ return rep >+ edata = self.getElementValue(rep, 'e-data') >+ if self.strict_checking: >+ self.assertIsNotNone(edata) >+ if edata is not None: >+ rep_padata = self.der_decode(edata, >+ asn1Spec=krb5_asn1.METHOD_DATA()) >+ self.assertGreater(len(rep_padata), 0) >+ else: >+ rep_padata = [] >+ >+ etype_info2 = self.check_rep_padata(kdc_exchange_dict, >+ callback_dict, >+ rep, >+ rep_padata) >+ >+ kdc_exchange_dict['preauth_etype_info2'] = etype_info2 >+ >+ return rep >+ >+ def check_rep_padata(self, >+ kdc_exchange_dict, >+ callback_dict, >+ rep, >+ rep_padata): > expected_error_mode = kdc_exchange_dict['expected_error_mode'] > req_body = kdc_exchange_dict['req_body'] > proposed_etypes = req_body['etype'] >- >- kdc_exchange_dict['preauth_etype_info2'] = None >+ client_as_etypes = kdc_exchange_dict.get('client_as_etypes', []) > > expect_etype_info2 = () > expect_etype_info = False >@@ -2188,34 +2229,6 @@ class RawKerberosTest(TestCaseInTempDir): > expected_patypes += (PADATA_PK_AS_REQ,) > expected_patypes += (PADATA_PK_AS_REP_19,) > >- self.assertElementEqual(rep, 'pvno', 5) >- self.assertElementEqual(rep, 'msg-type', KRB_ERROR) >- self.assertElementEqual(rep, 'error-code', expected_error_mode) >- if self.strict_checking: >- self.assertElementMissing(rep, 'ctime') >- self.assertElementMissing(rep, 'cusec') >- self.assertElementPresent(rep, 'stime') >- self.assertElementPresent(rep, 'susec') >- # error-code checked above >- if self.strict_checking: >- self.assertElementMissing(rep, 'crealm') >- self.assertElementMissing(rep, 'cname') >- self.assertElementEqualUTF8(rep, 'realm', expected_srealm) >- self.assertElementEqualPrincipal(rep, 'sname', expected_sname) >- self.assertElementMissing(rep, 'e-text') >- if expected_error_mode == KDC_ERR_GENERIC: >- self.assertElementMissing(rep, 'e-data') >- return >- edata = self.getElementValue(rep, 'e-data') >- if self.strict_checking: >- self.assertIsNotNone(edata) >- if edata is not None: >- rep_padata = self.der_decode(edata, >- asn1Spec=krb5_asn1.METHOD_DATA()) >- self.assertGreater(len(rep_padata), 0) >- else: >- rep_padata = [] >- > if self.strict_checking: > for i, patype in enumerate(expected_patypes): > self.assertElementEqual(rep_padata[i], 'padata-type', patype) >@@ -2265,7 +2278,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(enc_timestamp) > self.assertIsNotNone(pk_as_req) > self.assertIsNotNone(pk_as_rep19) >- return >+ return None > > if self.strict_checking: > self.assertIsNotNone(etype_info2) >@@ -2288,6 +2301,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNone(salt) > else: > self.assertIsNotNone(salt) >+ expected_salt = kdc_exchange_dict['expected_salt'] > if expected_salt is not None: > self.assertEqual(salt, expected_salt) > s2kparams = self.getElementValue(etype_info2[i], 's2kparams') >@@ -2307,8 +2321,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(pk_as_req) > self.assertIsNotNone(pk_as_rep19) > >- kdc_exchange_dict['preauth_etype_info2'] = etype_info2 >- return >+ return etype_info2 > > def generate_simple_fast(self, > kdc_exchange_dict, >-- >2.25.1 > > >From 66ca1a58c1840e11d4584184cdbdcebe38cd0b77 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 16:35:32 +1200 >Subject: [PATCH 184/686] tests/krb5: Don't expect RC4 in ETYPE-INFO2 for a > non-error reply > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 705e45e37f4752e283a80626be10c38b29232359) >--- > python/samba/tests/krb5/raw_testcase.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 80c60682bd1..7a66b74adfe 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2208,7 +2208,7 @@ class RawKerberosTest(TestCaseInTempDir): > if etype in (kcrypto.Enctype.AES256, kcrypto.Enctype.AES128): > if etype > expected_aes_type: > expected_aes_type = etype >- if etype in (kcrypto.Enctype.RC4,): >+ if etype in (kcrypto.Enctype.RC4,) and expected_error_mode != 0: > unexpect_etype_info = False > if etype > expected_rc4_type: > expected_rc4_type = etype >-- >2.25.1 > > >From d67e683afbf6180c86aeede5c69ebd7f40d3d4b0 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 16:26:06 +1200 >Subject: [PATCH 185/686] tests/krb5: Remove unused variables > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 5edbabeb26e110648d4588c90843e4715ec1ac5c) >--- > python/samba/tests/krb5/kdc_base_test.py | 2 -- > python/samba/tests/krb5/raw_testcase.py | 1 - > 2 files changed, 3 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 24a1e7cfbc8..b148fa01f65 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -256,8 +256,6 @@ class KDCBaseTest(RawKerberosTest): > > rid = identifier.sid.split()[1] > >- forced_keys = dict() >- > net_ctx = net.Net(admin_creds) > > keys = {} >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 7a66b74adfe..60d35923b35 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2140,7 +2140,6 @@ class RawKerberosTest(TestCaseInTempDir): > callback_dict, > rep): > >- expected_crealm = kdc_exchange_dict['expected_crealm'] > expected_cname = kdc_exchange_dict['expected_cname'] > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] >-- >2.25.1 > > >From 1a45d40e84aa09c4fe09128c296641cb59692b9c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 11:15:00 +1200 >Subject: [PATCH 186/686] tests/krb5: Add get_krbtgt_sname() method > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit dbe98005d5873440063b91e56679937149535be7) >--- > python/samba/tests/krb5/raw_testcase.py | 10 ++++++++++ > 1 file changed, 10 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 60d35923b35..8351de1e6e3 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -64,6 +64,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KU_TGS_REQ_AUTH_DAT_SESSION, > KU_TGS_REQ_AUTH_DAT_SUBKEY, > KU_TICKET, >+ NT_SRV_INST, > PADATA_ENC_TIMESTAMP, > PADATA_ETYPE_INFO, > PADATA_ETYPE_INFO2, >@@ -2523,6 +2524,15 @@ class RawKerberosTest(TestCaseInTempDir): > return (claims_pos < len(pac_options) > and pac_options[claims_pos] == '1') > >+ def get_krbtgt_sname(self): >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_username = krbtgt_creds.get_username() >+ krbtgt_realm = krbtgt_creds.get_realm() >+ krbtgt_sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ >+ return krbtgt_sname >+ > def _test_as_exchange(self, > cname, > realm, >-- >2.25.1 > > >From d6994f2deb88854fc0db919d051698e8c4e8f03a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 16:25:39 +1200 >Subject: [PATCH 187/686] tests/krb5: Check sname is krbtgt for FAST generic > error > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 7a27b75621908a4a6449efaecb54eb20fa45aca0) >--- > python/samba/tests/krb5/raw_testcase.py | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 8351de1e6e3..77b682e57ea 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2146,6 +2146,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_sname = kdc_exchange_dict['expected_sname'] > expected_error_mode = kdc_exchange_dict['expected_error_mode'] > >+ sent_fast = self.sent_fast(kdc_exchange_dict) >+ > self.assertElementEqual(rep, 'pvno', 5) > self.assertElementEqual(rep, 'msg-type', KRB_ERROR) > self.assertElementEqual(rep, 'error-code', expected_error_mode) >@@ -2159,7 +2161,11 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementMissing(rep, 'crealm') > self.assertElementMissing(rep, 'cname') > self.assertElementEqualUTF8(rep, 'realm', expected_srealm) >- self.assertElementEqualPrincipal(rep, 'sname', expected_sname) >+ if sent_fast and expected_error_mode == KDC_ERR_GENERIC: >+ self.assertElementEqualPrincipal(rep, 'sname', >+ self.get_krbtgt_sname()) >+ else: >+ self.assertElementEqualPrincipal(rep, 'sname', expected_sname) > self.assertElementMissing(rep, 'e-text') > if expected_error_mode == KDC_ERR_GENERIC: > self.assertElementMissing(rep, 'e-data') >-- >2.25.1 > > >From a60bf64172d23e6b97db8d27c7ee81deb2a8bbf5 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 16:31:39 +1200 >Subject: [PATCH 188/686] tests/krb5: Check reply FAST padata if request > included FAST > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 056fb71832e7aa16132c58ff393ab8b752ef6a93) >--- > python/samba/tests/krb5/raw_testcase.py | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 77b682e57ea..965a8f9fb00 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2177,6 +2177,21 @@ class RawKerberosTest(TestCaseInTempDir): > rep_padata = self.der_decode(edata, > asn1Spec=krb5_asn1.METHOD_DATA()) > self.assertGreater(len(rep_padata), 0) >+ >+ if sent_fast: >+ self.assertEqual(1, len(rep_padata)) >+ rep_pa_dict = self.get_pa_dict(rep_padata) >+ self.assertIn(PADATA_FX_FAST, rep_pa_dict) >+ >+ armor_key = kdc_exchange_dict['armor_key'] >+ self.assertIsNotNone(armor_key) >+ fast_response = self.check_fx_fast_data( >+ kdc_exchange_dict, >+ rep_pa_dict[PADATA_FX_FAST], >+ armor_key, >+ expect_strengthen_key=False) >+ >+ rep_padata = fast_response['padata'] > else: > rep_padata = [] > >-- >2.25.1 > > >From f3712a5bdb8453f47c0307baf7f0187427c049c2 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 16:42:26 +1200 >Subject: [PATCH 189/686] tests/krb5: Adjust reply padata checking depending on > whether FAST was sent > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 44a44109db96eab08a3da3683c34446bc13b295b) >--- > python/samba/tests/krb5/raw_testcase.py | 62 ++++++++++++++++++++++--- > 1 file changed, 55 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 965a8f9fb00..529d4d925e6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -44,6 +44,7 @@ import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > FX_FAST_ARMOR_AP_REQUEST, > KDC_ERR_GENERIC, >+ KDC_ERR_PREAUTH_FAILED, > KRB_AP_REQ, > KRB_AS_REP, > KRB_AS_REQ, >@@ -65,10 +66,13 @@ from samba.tests.krb5.rfc4120_constants import ( > KU_TGS_REQ_AUTH_DAT_SUBKEY, > KU_TICKET, > NT_SRV_INST, >+ PADATA_ENCRYPTED_CHALLENGE, > PADATA_ENC_TIMESTAMP, > PADATA_ETYPE_INFO, > PADATA_ETYPE_INFO2, > PADATA_FOR_USER, >+ PADATA_FX_COOKIE, >+ PADATA_FX_ERROR, > PADATA_FX_FAST, > PADATA_KDC_REQ, > PADATA_PAC_OPTIONS, >@@ -407,6 +411,8 @@ class RawKerberosTest(TestCaseInTempDir): > # obtained. > cls.creds_dict = {} > >+ cls.kdc_fast_support = False >+ > def setUp(self): > super().setUp() > self.do_asn1_print = False >@@ -2214,6 +2220,9 @@ class RawKerberosTest(TestCaseInTempDir): > proposed_etypes = req_body['etype'] > client_as_etypes = kdc_exchange_dict.get('client_as_etypes', []) > >+ sent_fast = self.sent_fast(kdc_exchange_dict) >+ sent_enc_challenge = self.sent_enc_challenge(kdc_exchange_dict) >+ > expect_etype_info2 = () > expect_etype_info = False > unexpect_etype_info = True >@@ -2240,15 +2249,31 @@ class RawKerberosTest(TestCaseInTempDir): > expect_etype_info2 += (expected_rc4_type,) > > expected_patypes = () >+ if sent_fast and expected_error_mode != 0: >+ expected_patypes += (PADATA_FX_ERROR,) >+ expected_patypes += (PADATA_FX_COOKIE,) >+ > if expect_etype_info: > self.assertGreater(len(expect_etype_info2), 0) > expected_patypes += (PADATA_ETYPE_INFO,) > if len(expect_etype_info2) != 0: > expected_patypes += (PADATA_ETYPE_INFO2,) > >- expected_patypes += (PADATA_ENC_TIMESTAMP,) >- expected_patypes += (PADATA_PK_AS_REQ,) >- expected_patypes += (PADATA_PK_AS_REP_19,) >+ if expected_error_mode != KDC_ERR_PREAUTH_FAILED: >+ if sent_fast: >+ expected_patypes += (PADATA_ENCRYPTED_CHALLENGE,) >+ else: >+ expected_patypes += (PADATA_ENC_TIMESTAMP,) >+ >+ if not sent_enc_challenge: >+ expected_patypes += (PADATA_PK_AS_REQ,) >+ expected_patypes += (PADATA_PK_AS_REP_19,) >+ >+ if (self.kdc_fast_support >+ and not sent_fast >+ and not sent_enc_challenge): >+ expected_patypes += (PADATA_FX_FAST,) >+ expected_patypes += (PADATA_FX_COOKIE,) > > if self.strict_checking: > for i, patype in enumerate(expected_patypes): >@@ -2296,7 +2321,12 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNone(etype_info2) > self.assertIsNone(etype_info) > if self.strict_checking: >- self.assertIsNotNone(enc_timestamp) >+ if sent_fast: >+ self.assertIsNotNone(enc_challenge) >+ self.assertIsNone(enc_timestamp) >+ else: >+ self.assertIsNotNone(enc_timestamp) >+ self.assertIsNone(enc_challenge) > self.assertIsNotNone(pk_as_req) > self.assertIsNotNone(pk_as_rep19) > return None >@@ -2338,9 +2368,27 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(salt) > self.assertEqual(len(salt), 0) > >- self.assertIsNotNone(enc_timestamp) >- self.assertIsNotNone(pk_as_req) >- self.assertIsNotNone(pk_as_rep19) >+ if expected_error_mode != KDC_ERR_PREAUTH_FAILED: >+ if sent_fast: >+ self.assertIsNotNone(enc_challenge) >+ if self.strict_checking: >+ self.assertIsNone(enc_timestamp) >+ else: >+ self.assertIsNotNone(enc_timestamp) >+ if self.strict_checking: >+ self.assertIsNone(enc_challenge) >+ if not sent_enc_challenge: >+ self.assertIsNotNone(pk_as_req) >+ self.assertIsNotNone(pk_as_rep19) >+ else: >+ self.assertIsNone(pk_as_req) >+ self.assertIsNone(pk_as_rep19) >+ else: >+ if self.strict_checking: >+ self.assertIsNone(enc_timestamp) >+ self.assertIsNone(enc_challenge) >+ self.assertIsNone(pk_as_req) >+ self.assertIsNone(pk_as_rep19) > > return etype_info2 > >-- >2.25.1 > > >From 12c6f0cf854998c3d1133b8616cda115b3fe42cd Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:36:56 +1200 >Subject: [PATCH 190/686] tests/krb5: Check PADATA-ENCRYPTED-CHALLENGE in reply > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 2f7919db395c24f6890ffe4ee46a5e34df95fccd) >--- > python/samba/tests/krb5/raw_testcase.py | 54 +++++++++++++++++++++++++ > 1 file changed, 54 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 529d4d925e6..ca967c1ac13 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -53,6 +53,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_TGS_REQ, > KU_AP_REQ_AUTH, > KU_AS_REP_ENC_PART, >+ KU_ENC_CHALLENGE_KDC, > KU_FAST_ENC, > KU_FAST_FINISHED, > KU_FAST_REP, >@@ -2283,6 +2284,7 @@ class RawKerberosTest(TestCaseInTempDir): > etype_info2 = None > etype_info = None > enc_timestamp = None >+ enc_challenge = None > pk_as_req = None > pk_as_rep19 = None > for pa in rep_padata: >@@ -2303,6 +2305,10 @@ class RawKerberosTest(TestCaseInTempDir): > enc_timestamp = pavalue > self.assertEqual(len(enc_timestamp), 0) > continue >+ if patype == PADATA_ENCRYPTED_CHALLENGE: >+ self.assertIsNone(enc_challenge) >+ enc_challenge = pavalue >+ continue > if patype == PADATA_PK_AS_REQ: > self.assertIsNone(pk_as_req) > pk_as_req = pavalue >@@ -2314,6 +2320,54 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertEqual(len(pk_as_rep19), 0) > continue > >+ if enc_challenge is not None: >+ if not sent_enc_challenge: >+ self.assertEqual(len(enc_challenge), 0) >+ else: >+ armor_key = kdc_exchange_dict['armor_key'] >+ self.assertIsNotNone(armor_key) >+ >+ check_padata_fn = kdc_exchange_dict['check_padata_fn'] >+ padata = self.getElementValue(rep, 'padata') >+ self.assertIsNotNone(check_padata_fn) >+ preauth_key, _ = check_padata_fn(kdc_exchange_dict, >+ callback_dict, >+ rep, >+ padata) >+ >+ kdc_challenge_key = self.generate_kdc_challenge_key( >+ armor_key, preauth_key) >+ >+ # Ensure that the encrypted challenge FAST factor is supported >+ # (RFC6113 5.4.6). >+ if self.strict_checking: >+ self.assertNotEqual(len(enc_challenge), 0) >+ if len(enc_challenge) != 0: >+ encrypted_challenge = self.der_decode( >+ enc_challenge, >+ asn1Spec=krb5_asn1.EncryptedData()) >+ self.assertEqual(encrypted_challenge['etype'], >+ kdc_challenge_key.etype) >+ >+ challenge = kdc_challenge_key.decrypt( >+ KU_ENC_CHALLENGE_KDC, >+ encrypted_challenge['cipher']) >+ challenge = self.der_decode( >+ challenge, >+ asn1Spec=krb5_asn1.PA_ENC_TS_ENC()) >+ >+ # Retrieve the returned timestamp. >+ rep_patime = challenge['patimestamp'] >+ self.assertIn('pausec', challenge) >+ >+ # Ensure the returned time is within five minutes of the >+ # current time. >+ rep_time = self.get_EpochFromKerberosTime(rep_patime) >+ current_time = time.time() >+ >+ self.assertLess(current_time - 300, rep_time) >+ self.assertLess(rep_time, current_time) >+ > if all(etype not in client_as_etypes or etype not in proposed_etypes > for etype in (kcrypto.Enctype.AES256, > kcrypto.Enctype.AES128, >-- >2.25.1 > > >From c96651f189b9176b8564667f0a4dcf64dc2f5aa3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:49:12 +1200 >Subject: [PATCH 191/686] tests/krb5: Check PADATA-FX-COOKIE in reply > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 95b54078c2f82179283dfc397c4ec1f36d5edfe7) >--- > python/samba/tests/krb5/raw_testcase.py | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index ca967c1ac13..23a4e70c22f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2287,6 +2287,8 @@ class RawKerberosTest(TestCaseInTempDir): > enc_challenge = None > pk_as_req = None > pk_as_rep19 = None >+ fast_cookie = None >+ fx_fast = None > for pa in rep_padata: > patype = self.getElementValue(pa, 'padata-type') > pavalue = self.getElementValue(pa, 'padata-value') >@@ -2319,6 +2321,19 @@ class RawKerberosTest(TestCaseInTempDir): > pk_as_rep19 = pavalue > self.assertEqual(len(pk_as_rep19), 0) > continue >+ if patype == PADATA_FX_COOKIE: >+ self.assertIsNone(fast_cookie) >+ fast_cookie = pavalue >+ self.assertIsNotNone(fast_cookie) >+ continue >+ if patype == PADATA_FX_FAST: >+ self.assertIsNone(fx_fast) >+ fx_fast = pavalue >+ self.assertEqual(len(fx_fast), 0) >+ continue >+ >+ if fast_cookie is not None: >+ kdc_exchange_dict['fast_cookie'] = fast_cookie > > if enc_challenge is not None: > if not sent_enc_challenge: >-- >2.25.1 > > >From ecff0dcd9d6661ab4fb326648265cc8429ab2dbf Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Jul 2021 20:49:25 +1200 >Subject: [PATCH 192/686] tests/krb5: Make check_rep_padata() also work for > checking TGS replies > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit ab4e7028a6ac01eab9531c8a26507a912df54278) >--- > python/samba/tests/krb5/raw_testcase.py | 72 +++++++++++++++---------- > 1 file changed, 45 insertions(+), 27 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 23a4e70c22f..14f86fb87a8 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1789,6 +1789,7 @@ class RawKerberosTest(TestCaseInTempDir): > check_rep_fn=None, > check_padata_fn=None, > check_kdc_private_fn=None, >+ expected_error_mode=0, > callback_dict=None, > tgt=None, > armor_key=None, >@@ -1820,6 +1821,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'check_padata_fn': check_padata_fn, > 'check_kdc_private_fn': check_kdc_private_fn, > 'callback_dict': callback_dict, >+ 'expected_error_mode': expected_error_mode, > 'tgt': tgt, > 'body_checksum_type': body_checksum_type, > 'armor_key': armor_key, >@@ -2216,6 +2218,8 @@ class RawKerberosTest(TestCaseInTempDir): > callback_dict, > rep, > rep_padata): >+ rep_msg_type = kdc_exchange_dict['rep_msg_type'] >+ > expected_error_mode = kdc_exchange_dict['expected_error_mode'] > req_body = kdc_exchange_dict['req_body'] > proposed_etypes = req_body['etype'] >@@ -2224,6 +2228,9 @@ class RawKerberosTest(TestCaseInTempDir): > sent_fast = self.sent_fast(kdc_exchange_dict) > sent_enc_challenge = self.sent_enc_challenge(kdc_exchange_dict) > >+ if rep_msg_type == KRB_TGS_REP: >+ self.assertTrue(sent_fast) >+ > expect_etype_info2 = () > expect_etype_info = False > unexpect_etype_info = True >@@ -2254,27 +2261,32 @@ class RawKerberosTest(TestCaseInTempDir): > expected_patypes += (PADATA_FX_ERROR,) > expected_patypes += (PADATA_FX_COOKIE,) > >- if expect_etype_info: >- self.assertGreater(len(expect_etype_info2), 0) >- expected_patypes += (PADATA_ETYPE_INFO,) >- if len(expect_etype_info2) != 0: >- expected_patypes += (PADATA_ETYPE_INFO2,) >+ if rep_msg_type == KRB_TGS_REP: >+ sent_claims = self.sent_claims(kdc_exchange_dict) >+ if sent_claims and expected_error_mode != 0: >+ expected_patypes += (PADATA_PAC_OPTIONS,) >+ else: >+ if expect_etype_info: >+ self.assertGreater(len(expect_etype_info2), 0) >+ expected_patypes += (PADATA_ETYPE_INFO,) >+ if len(expect_etype_info2) != 0: >+ expected_patypes += (PADATA_ETYPE_INFO2,) > >- if expected_error_mode != KDC_ERR_PREAUTH_FAILED: >- if sent_fast: >- expected_patypes += (PADATA_ENCRYPTED_CHALLENGE,) >- else: >- expected_patypes += (PADATA_ENC_TIMESTAMP,) >+ if expected_error_mode != KDC_ERR_PREAUTH_FAILED: >+ if sent_fast: >+ expected_patypes += (PADATA_ENCRYPTED_CHALLENGE,) >+ else: >+ expected_patypes += (PADATA_ENC_TIMESTAMP,) > >- if not sent_enc_challenge: >- expected_patypes += (PADATA_PK_AS_REQ,) >- expected_patypes += (PADATA_PK_AS_REP_19,) >+ if not sent_enc_challenge: >+ expected_patypes += (PADATA_PK_AS_REQ,) >+ expected_patypes += (PADATA_PK_AS_REP_19,) > >- if (self.kdc_fast_support >- and not sent_fast >- and not sent_enc_challenge): >- expected_patypes += (PADATA_FX_FAST,) >- expected_patypes += (PADATA_FX_COOKIE,) >+ if (self.kdc_fast_support >+ and not sent_fast >+ and not sent_enc_challenge): >+ expected_patypes += (PADATA_FX_FAST,) >+ expected_patypes += (PADATA_FX_COOKIE,) > > if self.strict_checking: > for i, patype in enumerate(expected_patypes): >@@ -2389,15 +2401,21 @@ class RawKerberosTest(TestCaseInTempDir): > kcrypto.Enctype.RC4)): > self.assertIsNone(etype_info2) > self.assertIsNone(etype_info) >- if self.strict_checking: >- if sent_fast: >- self.assertIsNotNone(enc_challenge) >- self.assertIsNone(enc_timestamp) >- else: >- self.assertIsNotNone(enc_timestamp) >- self.assertIsNone(enc_challenge) >- self.assertIsNotNone(pk_as_req) >- self.assertIsNotNone(pk_as_rep19) >+ if rep_msg_type == KRB_AS_REP: >+ if self.strict_checking: >+ if sent_fast: >+ self.assertIsNotNone(enc_challenge) >+ self.assertIsNone(enc_timestamp) >+ else: >+ self.assertIsNotNone(enc_timestamp) >+ self.assertIsNone(enc_challenge) >+ self.assertIsNotNone(pk_as_req) >+ self.assertIsNotNone(pk_as_rep19) >+ else: >+ self.assertIsNone(enc_timestamp) >+ self.assertIsNone(enc_challenge) >+ self.assertIsNone(pk_as_req) >+ self.assertIsNone(pk_as_rep19) > return None > > if self.strict_checking: >-- >2.25.1 > > >From 107b772f25f215bb8caacb120ef3060401fce52d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 16:29:39 +1200 >Subject: [PATCH 193/686] tests/krb5: Make generic_check_kdc_error() also work > for checking TGS replies > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 29070e74baa18d94642efcd36930b9bab216e10c) >--- > python/samba/tests/krb5/raw_testcase.py | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 14f86fb87a8..8cbf3edbbab 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -45,6 +45,7 @@ from samba.tests.krb5.rfc4120_constants import ( > FX_FAST_ARMOR_AP_REQUEST, > KDC_ERR_GENERIC, > KDC_ERR_PREAUTH_FAILED, >+ KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, > KRB_AP_REQ, > KRB_AS_REP, > KRB_AS_REQ, >@@ -2150,6 +2151,8 @@ class RawKerberosTest(TestCaseInTempDir): > callback_dict, > rep): > >+ rep_msg_type = kdc_exchange_dict['rep_msg_type'] >+ > expected_cname = kdc_exchange_dict['expected_cname'] > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] >@@ -2157,6 +2160,8 @@ class RawKerberosTest(TestCaseInTempDir): > > sent_fast = self.sent_fast(kdc_exchange_dict) > >+ fast_armor_type = kdc_exchange_dict['fast_armor_type'] >+ > self.assertElementEqual(rep, 'pvno', 5) > self.assertElementEqual(rep, 'msg-type', KRB_ERROR) > self.assertElementEqual(rep, 'error-code', expected_error_mode) >@@ -2176,7 +2181,12 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertElementEqualPrincipal(rep, 'sname', expected_sname) > self.assertElementMissing(rep, 'e-text') >- if expected_error_mode == KDC_ERR_GENERIC: >+ if (expected_error_mode in (KDC_ERR_GENERIC, >+ KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS) >+ or (rep_msg_type == KRB_TGS_REP >+ and not sent_fast) >+ or (sent_fast and fast_armor_type is not None >+ and fast_armor_type != FX_FAST_ARMOR_AP_REQUEST)): > self.assertElementMissing(rep, 'e-data') > return rep > edata = self.getElementValue(rep, 'e-data') >-- >2.25.1 > > >From e78438df508a1df7238303f88cfb8078b9ddff8b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:50:20 +1200 >Subject: [PATCH 194/686] tests/krb5: Check PADATA-PAC-OPTIONS in reply > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 0c857f67a3a4a27aa4b799c9a61a1a1b59932c07) >--- > python/samba/tests/krb5/raw_testcase.py | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 8cbf3edbbab..5016e14783c 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2311,6 +2311,7 @@ class RawKerberosTest(TestCaseInTempDir): > pk_as_rep19 = None > fast_cookie = None > fx_fast = None >+ pac_options = None > for pa in rep_padata: > patype = self.getElementValue(pa, 'padata-type') > pavalue = self.getElementValue(pa, 'padata-value') >@@ -2353,10 +2354,18 @@ class RawKerberosTest(TestCaseInTempDir): > fx_fast = pavalue > self.assertEqual(len(fx_fast), 0) > continue >+ if patype == PADATA_PAC_OPTIONS: >+ self.assertIsNone(pac_options) >+ pac_options = pavalue >+ self.assertIsNotNone(pac_options) >+ continue > > if fast_cookie is not None: > kdc_exchange_dict['fast_cookie'] = fast_cookie > >+ if pac_options is not None: >+ self.check_pac_options_claims_support(pac_options) >+ > if enc_challenge is not None: > if not sent_enc_challenge: > self.assertEqual(len(enc_challenge), 0) >-- >2.25.1 > > >From 8dfa50c02eb3b2da6cd1b47cc8720a549274172f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 29 Jul 2021 11:50:16 +1200 >Subject: [PATCH 195/686] tests/krb5: Allow generic_check_kdc_error() to check > inner FAST errors > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit 66e1eb58bedf036ad25a868993d44480c4e0e055) >--- > python/samba/tests/krb5/raw_testcase.py | 12 +++++++++--- > 1 file changed, 9 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 5016e14783c..4ebab367141 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -68,6 +68,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KU_TGS_REQ_AUTH_DAT_SUBKEY, > KU_TICKET, > NT_SRV_INST, >+ NT_WELLKNOWN, > PADATA_ENCRYPTED_CHALLENGE, > PADATA_ENC_TIMESTAMP, > PADATA_ETYPE_INFO, >@@ -2149,7 +2150,8 @@ class RawKerberosTest(TestCaseInTempDir): > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >- rep): >+ rep, >+ inner=False): > > rep_msg_type = kdc_exchange_dict['rep_msg_type'] > >@@ -2173,7 +2175,10 @@ class RawKerberosTest(TestCaseInTempDir): > # error-code checked above > if self.strict_checking: > self.assertElementMissing(rep, 'crealm') >- self.assertElementMissing(rep, 'cname') >+ if expected_cname['name-type'] == NT_WELLKNOWN and not inner: >+ self.assertElementEqualPrincipal(rep, 'cname', expected_cname) >+ else: >+ self.assertElementMissing(rep, 'cname') > self.assertElementEqualUTF8(rep, 'realm', expected_srealm) > if sent_fast and expected_error_mode == KDC_ERR_GENERIC: > self.assertElementEqualPrincipal(rep, 'sname', >@@ -2186,7 +2191,8 @@ class RawKerberosTest(TestCaseInTempDir): > or (rep_msg_type == KRB_TGS_REP > and not sent_fast) > or (sent_fast and fast_armor_type is not None >- and fast_armor_type != FX_FAST_ARMOR_AP_REQUEST)): >+ and fast_armor_type != FX_FAST_ARMOR_AP_REQUEST) >+ or inner): > self.assertElementMissing(rep, 'e-data') > return rep > edata = self.getElementValue(rep, 'e-data') >-- >2.25.1 > > >From dfc8592945996362be9c9a79ba163cb2f8c4380b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 27 Jul 2021 14:49:58 +1200 >Subject: [PATCH 196/686] tests/krb5: Check PADATA-FX-ERROR in reply > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit aa2c221f4e1bfc3403de857e62eaeaee1577560c) >--- > python/samba/tests/krb5/raw_testcase.py | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 4ebab367141..17ef8df5daa 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2316,6 +2316,7 @@ class RawKerberosTest(TestCaseInTempDir): > pk_as_req = None > pk_as_rep19 = None > fast_cookie = None >+ fast_error = None > fx_fast = None > pac_options = None > for pa in rep_padata: >@@ -2355,6 +2356,11 @@ class RawKerberosTest(TestCaseInTempDir): > fast_cookie = pavalue > self.assertIsNotNone(fast_cookie) > continue >+ if patype == PADATA_FX_ERROR: >+ self.assertIsNone(fast_error) >+ fast_error = pavalue >+ self.assertIsNotNone(fast_error) >+ continue > if patype == PADATA_FX_FAST: > self.assertIsNone(fx_fast) > fx_fast = pavalue >@@ -2369,6 +2375,14 @@ class RawKerberosTest(TestCaseInTempDir): > if fast_cookie is not None: > kdc_exchange_dict['fast_cookie'] = fast_cookie > >+ if fast_error is not None: >+ fast_error = self.der_decode(fast_error, >+ asn1Spec=krb5_asn1.KRB_ERROR()) >+ self.generic_check_kdc_error(kdc_exchange_dict, >+ callback_dict, >+ fast_error, >+ inner=True) >+ > if pac_options is not None: > self.check_pac_options_claims_support(pac_options) > >-- >2.25.1 > > >From 4674d7c76652140791889a0bb564edf77ed8308e Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Thu, 10 Jun 2021 09:56:58 +1200 >Subject: [PATCH 197/686] initial FAST tests > >Currently incomplete, and tested only against MIT Kerberos. > >[abartlet@samba.org > Originally "WIP inital FAST tests" > > Samba's general policy that we don't push WIP patches, we polish > into a 'perfect' patch stream. > > However, I think there are good reasons to keep this patch distinct > in this particular case. > > Gary is being modest in titling this WIP (now removed from the title > to avoid confusion). They are not WIP in the normal sense of > partially or untested code or random unfinished thoughts. The primary > issue is that at that point where Gary had to finish up he had > trouble getting FAST support enabled on Windows, so couldn't test > against our standard reference. They are instead good, working > initial tests written against the RFC and tested against Samba's AD DC > in the mode backed by MIT Kerberos. > > This preserves clear authorship for the two distinct bodies of work, > as in the next patch Joseph was able to extend and improve the tests > significantly. ] > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >(cherry picked from commit b7b62957bdce9929fabd3812b9378bdbd6c12966) >--- > python/samba/tests/krb5/fast_tests.py | 245 ++++++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > selftest/knownfail_heimdal_kdc | 8 + > source4/selftest/tests.py | 8 + > 4 files changed, 262 insertions(+) > create mode 100755 python/samba/tests/krb5/fast_tests.py > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >new file mode 100755 >index 00000000000..c4d1c2c5d82 >--- /dev/null >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -0,0 +1,245 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) 2020 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+from samba.tests.krb5.rfc4120_constants import ( >+ AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5, >+ NT_PRINCIPAL, >+ NT_SRV_INST, >+ PADATA_FX_COOKIE, >+ PADATA_FX_FAST, >+) >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class FAST_Tests(KDCBaseTest): >+ ''' >+ ''' >+ >+ def setUp(self): >+ super().setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def get_padata_element(self, rep, padata_type): >+ rep_padata = self.der_decode( >+ rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) >+ for pa in rep_padata: >+ if pa['padata-type'] == padata_type: >+ return pa['padata-value'] >+ return None >+ >+ def test_fast_supported(self): >+ '''Confirm that the kdc supports FAST >+ The KDC SHOULD return an empty PA-FX-FAST in a >+ PREAUTH_REQUIRED error if FAST is supported >+ >+ >+ ''' >+ >+ # Create a user account for the test. >+ # >+ samdb = self.get_samdb() >+ user_name = "krb5fastusr" >+ (uc, dn) = self.create_account(samdb, user_name) >+ realm = uc.get_realm().lower() >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.assertIsNotNone(rep) >+ self.assertEqual(rep['msg-type'], 30) >+ self.assertEqual(rep['error-code'], 25) >+ >+ fx_fast = self.get_padata_element(rep, PADATA_FX_FAST) >+ self.assertIsNotNone(fx_fast, "No PADATA_FX_FAST element") >+ >+ def test_explicit_PA_FX_FAST_in_as_req(self): >+ ''' >+ Add an empty PA-FX-FAST in the initial AS-REQ >+ This should get rejected with a Generic error. >+ >+ ''' >+ >+ # Create a user account for the test. >+ # >+ samdb = self.get_samdb() >+ user_name = "krb5fastusr" >+ (uc, dn) = self.create_account(samdb, user_name) >+ realm = uc.get_realm().lower() >+ >+ # Do the initial AS-REQ, should get a generic error response >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ x = self.PA_DATA_create(PADATA_FX_FAST, b'') >+ padata = [x] >+ rep = self.as_req(cname, sname, realm, etype, padata) >+ >+ self.assertIsNotNone(rep) >+ self.assertEqual(rep['msg-type'], 30) >+ self.assertEqual(rep['error-code'], 60) >+ >+ def test_fast_cookie_retured_in_pre_auth(self): >+ '''Confirm that the kdc returns PA-FX-COOKIE >+ ''' >+ >+ # Create a user account for the test. >+ # >+ samdb = self.get_samdb() >+ user_name = "krb5fastusr" >+ (uc, dn) = self.create_account(samdb, user_name) >+ realm = uc.get_realm().lower() >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.assertIsNotNone(rep) >+ self.assertEqual(rep['msg-type'], 30) >+ self.assertEqual(rep['error-code'], 25) >+ >+ fx_fast = self.get_padata_element(rep, PADATA_FX_FAST) >+ self.assertIsNotNone(fx_fast, "No PADATA_FX_FAST element") >+ >+ fx_cookie = self.get_padata_element(rep, PADATA_FX_COOKIE) >+ self.assertIsNotNone(fx_cookie, "No PADATA_FX_COOKIE element") >+ >+ def test_ignore_fast(self): >+ ''' >+ TODO reword this >+ Attempt to authenticate with out FAST, i.e. ignoring the >+ FAST advertised in the pre-auth >+ ''' >+ >+ # Create a user account for the test. >+ # >+ samdb = self.get_samdb() >+ user_name = "krb5fastusr" >+ (uc, dn) = self.create_account(samdb, user_name) >+ realm = uc.get_realm().lower() >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.assertIsNotNone(rep) >+ self.assertEqual(rep['msg-type'], 30) >+ self.assertEqual(rep['error-code'], 25) >+ >+ fx_fast = self.get_padata_element(rep, PADATA_FX_FAST) >+ self.assertIsNotNone(fx_fast, "No PADATA_FX_FAST element") >+ >+ fx_cookie = self.get_padata_element(rep, PADATA_FX_COOKIE) >+ self.assertIsNotNone(fx_cookie, "No PADATA_FX_COOKIE element") >+ >+ # Do the next AS-REQ >+ padata = [self.get_enc_timestamp_pa_data(uc, rep)] >+ rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ self.check_as_reply(rep) >+ >+ def test_fast(self): >+ ''' >+ Attempt to authenticate with >+ ''' >+ >+ # Create a user account for the test. >+ # >+ samdb = self.get_samdb() >+ user_name = "krb5fastusr" >+ (uc, dn) = self.create_account(samdb, user_name) >+ realm = uc.get_realm().lower() >+ >+ # Do the initial AS-REQ, should get a pre-authentication required >+ # response >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[user_name]) >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ >+ rep = self.as_req(cname, sname, realm, etype) >+ self.assertIsNotNone(rep) >+ self.assertEqual(rep['msg-type'], 30) >+ self.assertEqual(rep['error-code'], 25) >+ >+ fx_fast = self.get_padata_element(rep, PADATA_FX_FAST) >+ self.assertIsNotNone(fx_fast, "No PADATA_FX_FAST element") >+ >+ fx_cookie = self.get_padata_element(rep, PADATA_FX_COOKIE) >+ self.assertIsNotNone(fx_cookie, "No PADATA_FX_COOKIE element") >+ >+ cookie = self.PA_DATA_create(PADATA_FX_COOKIE, fx_cookie) >+ >+ # Do the next AS-REQ >+ padata = [self.get_enc_timestamp_pa_data(uc, rep)] >+ padata.append(cookie) >+ # req = self.AS_REQ_create(padata=padata, >+ # kdc_options=str(kdc_options), >+ # cname=cname, >+ # realm=realm, >+ # sname=sname, >+ # from_time=None, >+ # till_time=till, >+ # renew_time=None, >+ # nonce=0x7fffffff, >+ # etypes=etypes, >+ # addresses=None, >+ # EncAuthorizationData=None, >+ # EncAuthorizationData_key=None, >+ # additional_tickets=None) >+ # rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ # self.check_as_reply(rep) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = False >+ global_hexdump = False >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index db46705cdb4..1795846d7bc 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -99,6 +99,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/test_smb.py', > 'python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py', > 'python/samba/tests/krb5/as_req_tests.py', >+ 'python/samba/tests/krb5/fast_tests.py', > } > > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 4e6ee93ce96..66f07cebc14 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -14,3 +14,11 @@ > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_b > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c >+# >+# MIT specific FAST tests, >+# >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_explicit_PA_FX_FAST_in_as_req\(ad_dc\) >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast\(ad_dc\) >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_cookie_retured_in_pre_auth\(ad_dc\) >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_supported\(ad_dc\) >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_ignore_fast\(ad_dc\) >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 62e2bc33754..3866b1791d0 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1270,6 +1270,14 @@ planpythontestsuite( > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD' > }) >+planpythontestsuite( >+ "ad_dc", >+ "samba.tests.krb5.fast_tests", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'SERVICE_USERNAME': '$SERVER' >+ }) > planpythontestsuite( > "ad_dc", > "samba.tests.krb5.ms_kile_client_principal_lookup_tests", >-- >2.25.1 > > >From afd7c9232ac270c279ae39dec793ccf02b8de9b8 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 29 Jul 2021 10:58:44 +1200 >Subject: [PATCH 198/686] tests/krb5: Add FAST tests > >Example command: > >SERVER=addc STRICT_CHECKING=0 SMB_CONF_PATH=/dev/null \ >KRB5_CONFIG=krb5.conf DOMAIN=ADDOMAIN REALM=ADDOM.SAMBA.EXAMPLE.COM \ >ADMIN_USERNAME=Administrator ADMIN_PASSWORD=locDCpass1 \ >PYTHONPATH=bin/python python/samba/tests/krb5/fast_tests.py > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Wed Aug 18 23:20:14 UTC 2021 on sn-devel-184 > >(cherry picked from commit 984a0db00c3f2e38b568a75eb1944f4d7bb7f854) >--- > python/samba/tests/krb5/fast_tests.py | 1649 ++++++++++++++++++++++--- > selftest/knownfail_heimdal_kdc | 54 +- > selftest/knownfail_mit_kdc | 53 + > source4/selftest/tests.py | 2 +- > 4 files changed, 1585 insertions(+), 173 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index c4d1c2c5d82..e38b2e0a6e1 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -17,225 +17,1542 @@ > # along with this program. If not, see <http://www.gnu.org/licenses/>. > # > >-import sys >+import functools > import os >+import sys > >-sys.path.insert(0, "bin/python") >-os.environ["PYTHONUNBUFFERED"] = "1" >+import ldb > >+from samba.dcerpc import security >+from samba.tests.krb5.raw_testcase import ( >+ KerberosTicketCreds, >+ Krb5EncryptionKey >+) > from samba.tests.krb5.kdc_base_test import KDCBaseTest > from samba.tests.krb5.rfc4120_constants import ( >+ AD_FX_FAST_ARMOR, >+ AD_FX_FAST_USED, > AES256_CTS_HMAC_SHA1_96, > ARCFOUR_HMAC_MD5, >+ FX_FAST_ARMOR_AP_REQUEST, >+ KDC_ERR_ETYPE_NOSUPP, >+ KDC_ERR_GENERIC, >+ KDC_ERR_NOT_US, >+ KDC_ERR_PREAUTH_FAILED, >+ KDC_ERR_PREAUTH_REQUIRED, >+ KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, >+ KRB_AS_REP, >+ KRB_TGS_REP, >+ KU_AS_REP_ENC_PART, >+ KU_TICKET, > NT_PRINCIPAL, > NT_SRV_INST, >+ NT_WELLKNOWN, > PADATA_FX_COOKIE, > PADATA_FX_FAST, >+ PADATA_PAC_OPTIONS > ) > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 >+import samba.tests.krb5.kcrypto as kcrypto >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" > > global_asn1_print = False > global_hexdump = False > > > class FAST_Tests(KDCBaseTest): >- ''' >- ''' >+ @classmethod >+ def setUpClass(cls): >+ super().setUpClass() >+ >+ cls.user_tgt = None >+ cls.user_enc_part = None >+ cls.user_service_ticket = None >+ >+ cls.mach_tgt = None >+ cls.mach_enc_part = None >+ cls.mach_service_ticket = None > > def setUp(self): > super().setUp() > self.do_asn1_print = global_asn1_print > self.do_hexdump = global_hexdump > >- def get_padata_element(self, rep, padata_type): >- rep_padata = self.der_decode( >- rep['e-data'], asn1Spec=krb5_asn1.METHOD_DATA()) >- for pa in rep_padata: >- if pa['padata-type'] == padata_type: >- return pa['padata-value'] >- return None >+ def test_simple(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': False >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': False, >+ 'gen_padata_fn': self.generate_enc_timestamp_padata >+ } >+ ]) > >- def test_fast_supported(self): >- '''Confirm that the kdc supports FAST >- The KDC SHOULD return an empty PA-FX-FAST in a >- PREAUTH_REQUIRED error if FAST is supported >+ def test_simple_tgs(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': False, >+ 'gen_tgt_fn': self.get_user_tgt >+ } >+ ]) > >+ def test_simple_tgs_wrong_principal(self): >+ mach_creds = self.get_mach_creds() >+ mach_name = mach_creds.get_username() >+ expected_cname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[mach_name]) > >- ''' >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': False, >+ 'gen_tgt_fn': self.get_mach_tgt, >+ 'expected_cname': expected_cname >+ } >+ ]) > >- # Create a user account for the test. >- # >- samdb = self.get_samdb() >- user_name = "krb5fastusr" >- (uc, dn) = self.create_account(samdb, user_name) >- realm = uc.get_realm().lower() >+ def test_simple_tgs_service_ticket(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_NOT_US, >+ 'use_fast': False, >+ 'gen_tgt_fn': self.get_user_service_ticket, >+ } >+ ]) > >- # Do the initial AS-REQ, should get a pre-authentication required >- # response >- etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >- cname = self.PrincipalName_create( >- name_type=NT_PRINCIPAL, names=[user_name]) >- sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ def test_simple_tgs_service_ticket_mach(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_NOT_US, >+ 'use_fast': False, >+ 'gen_tgt_fn': self.get_mach_service_ticket, >+ } >+ ]) > >- rep = self.as_req(cname, sname, realm, etype) >- self.assertIsNotNone(rep) >- self.assertEqual(rep['msg-type'], 30) >- self.assertEqual(rep['error-code'], 25) >+ def test_fast_no_claims(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'pac_options': '0' >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'pac_options': '0' >+ } >+ ]) > >- fx_fast = self.get_padata_element(rep, PADATA_FX_FAST) >- self.assertIsNotNone(fx_fast, "No PADATA_FX_FAST element") >+ def test_fast_tgs_no_claims(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None, >+ 'pac_options': '0' >+ } >+ ]) > >- def test_explicit_PA_FX_FAST_in_as_req(self): >- ''' >- Add an empty PA-FX-FAST in the initial AS-REQ >- This should get rejected with a Generic error. >+ def test_fast_no_claims_or_canon(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'pac_options': '0', >+ 'kdc_options': '0' >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'pac_options': '0', >+ 'kdc_options': '0' >+ } >+ ]) > >- ''' >+ def test_fast_tgs_no_claims_or_canon(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None, >+ 'pac_options': '0', >+ 'kdc_options': '0' >+ } >+ ]) > >- # Create a user account for the test. >- # >- samdb = self.get_samdb() >- user_name = "krb5fastusr" >- (uc, dn) = self.create_account(samdb, user_name) >- realm = uc.get_realm().lower() >+ def test_fast_no_canon(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'kdc_options': '0' >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'kdc_options': '0' >+ } >+ ]) > >- # Do the initial AS-REQ, should get a generic error response >- # response >- etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >- cname = self.PrincipalName_create( >- name_type=NT_PRINCIPAL, names=[user_name]) >- sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ def test_fast_tgs_no_canon(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None, >+ 'kdc_options': '0' >+ } >+ ]) >+ >+ def test_simple_tgs_no_etypes(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_ETYPE_NOSUPP, >+ 'use_fast': False, >+ 'gen_tgt_fn': self.get_mach_tgt, >+ 'etypes': () >+ } >+ ]) >+ >+ def test_fast_tgs_no_etypes(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_ETYPE_NOSUPP, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_mach_tgt, >+ 'fast_armor': None, >+ 'etypes': () >+ } >+ ]) >+ >+ def test_simple_no_etypes(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_ETYPE_NOSUPP, >+ 'use_fast': False, >+ 'etypes': () >+ } >+ ]) >+ >+ def test_simple_fast_no_etypes(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_ETYPE_NOSUPP, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'etypes': () >+ } >+ ]) >+ >+ def test_empty_fast(self): >+ # Add an empty PA-FX-FAST in the initial AS-REQ. This should get >+ # rejected with a Generic error. >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'use_fast': True, >+ 'gen_fast_fn': self.generate_empty_fast, >+ 'fast_armor': None, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_fast_unknown_critical_option(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, >+ 'use_fast': True, >+ 'fast_options': '001', # unsupported critical option >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_unarmored_as_req(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'use_fast': True, >+ 'fast_armor': None, # no armor, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_fast_invalid_armor_type(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_FAILED, >+ 'use_fast': True, >+ 'fast_armor': 0, # invalid armor type >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_fast_invalid_armor_type2(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_FAILED, >+ 'use_fast': True, >+ 'fast_armor': 2, # invalid armor type >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_fast_encrypted_challenge(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_fast_encrypted_challenge_wrong_key(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_FAILED, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata_wrong_key, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_fast_encrypted_challenge_wrong_key_kdc(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_FAILED, >+ 'use_fast': True, >+ 'gen_padata_fn': >+ self.generate_enc_challenge_padata_wrong_key_kdc, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_fast_encrypted_challenge_clock_skew(self): >+ # The KDC is supposed to confirm that the timestamp is within its >+ # current clock skew, and return KRB_APP_ERR_SKEW if it is not (RFC6113 >+ # 5.4.6). However, Windows accepts a skewed timestamp in the encrypted >+ # challenge. >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': functools.partial( >+ self.generate_enc_challenge_padata, >+ skew=10000), >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_fast_invalid_tgt(self): >+ # The armor ticket 'sname' field is required to identify the target >+ # realm TGS (RFC6113 5.4.1.1). However, Windows will still accept a >+ # service ticket identifying a different server principal. >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_user_service_ticket >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_user_service_ticket >+ # ticket not identifying TGS of current >+ # realm >+ } >+ ]) >+ >+ def test_fast_invalid_tgt_mach(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_service_ticket >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_service_ticket >+ # ticket not identifying TGS of current >+ # realm >+ } >+ ]) >+ >+ def test_fast_enc_timestamp(self): >+ # Provide ENC-TIMESTAMP as FAST padata when we should be providing >+ # ENCRYPTED-CHALLENGE - ensure that we get PREAUTH_REQUIRED. >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_timestamp_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_fast(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_fast_tgs(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None >+ } >+ ]) >+ >+ def test_fast_tgs_armor(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST >+ } >+ ]) >+ >+ def test_fast_outer_wrong_realm(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'outer_req': { >+ 'realm': 'TEST' # should be ignored >+ } >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'outer_req': { >+ 'realm': 'TEST' # should be ignored >+ } >+ } >+ ]) >+ >+ def test_fast_tgs_outer_wrong_realm(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None, >+ 'outer_req': { >+ 'realm': 'TEST' # should be ignored >+ } >+ } >+ ]) >+ >+ def test_fast_outer_wrong_nonce(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'outer_req': { >+ 'nonce': '123' # should be ignored >+ } >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'outer_req': { >+ 'nonce': '123' # should be ignored >+ } >+ } >+ ]) >+ >+ def test_fast_tgs_outer_wrong_nonce(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None, >+ 'outer_req': { >+ 'nonce': '123' # should be ignored >+ } >+ } >+ ]) >+ >+ def test_fast_outer_wrong_flags(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'outer_req': { >+ 'kdc-options': '11111111111111111' # should be ignored >+ } >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'outer_req': { >+ 'kdc-options': '11111111111111111' # should be ignored >+ } >+ } >+ ]) >+ >+ def test_fast_tgs_outer_wrong_flags(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None, >+ 'outer_req': { >+ 'kdc-options': '11111111111111111' # should be ignored >+ } >+ } >+ ]) >+ >+ def test_fast_outer_wrong_till(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'outer_req': { >+ 'till': '15000101000000Z' # should be ignored >+ } >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'outer_req': { >+ 'till': '15000101000000Z' # should be ignored >+ } >+ } >+ ]) >+ >+ def test_fast_tgs_outer_wrong_till(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None, >+ 'outer_req': { >+ 'till': '15000101000000Z' # should be ignored >+ } >+ } >+ ]) >+ >+ def test_fast_authdata_fast_used(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_authdata_fn': self.generate_fast_used_auth_data, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None >+ } >+ ]) >+ >+ def test_fast_authdata_fast_not_used(self): >+ # The AD-fx-fast-used authdata type can be included in the >+ # authenticator or the TGT authentication data to indicate that FAST >+ # must be used. The KDC must return KRB_APP_ERR_MODIFIED if it receives >+ # this authdata type in a request not using FAST (RFC6113 5.4.2). >+ self._run_test_sequence([ >+ # This request works without FAST. >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': False, >+ 'gen_tgt_fn': self.get_user_tgt >+ }, >+ # Add the 'FAST used' auth data and it now fails. >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ # should be KRB_APP_ERR_MODIFIED >+ 'use_fast': False, >+ 'gen_authdata_fn': self.generate_fast_used_auth_data, >+ 'gen_tgt_fn': self.get_user_tgt >+ } >+ ]) >+ >+ def test_fast_ad_fx_fast_armor(self): >+ # If the authenticator or TGT authentication data contains the >+ # AD-fx-fast-armor authdata type, the KDC must reject the request >+ # (RFC6113 5.4.1.1). >+ self._run_test_sequence([ >+ # This request works. >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None >+ }, >+ # Add the 'FAST armor' auth data and it now fails. >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'use_fast': True, >+ 'gen_authdata_fn': self.generate_fast_armor_auth_data, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None >+ } >+ ]) >+ >+ def test_fast_ad_fx_fast_armor2(self): >+ # Show that we can still use the AD-fx-fast-armor authorization data in >+ # FAST armor tickets. >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'gen_authdata_fn': self.generate_fast_armor_auth_data, >+ # include the auth data in the FAST armor. >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ } >+ ]) >+ >+ def test_fast_ad_fx_fast_armor_ticket(self): >+ # If the authenticator or TGT authentication data contains the >+ # AD-fx-fast-armor authdata type, the KDC must reject the request >+ # (RFC6113 5.4.2). >+ self._run_test_sequence([ >+ # This request works. >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None >+ }, >+ # Add AD-fx-fast-armor authdata element to user TGT. This request >+ # fails. >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.gen_tgt_fast_armor_auth_data, >+ 'fast_armor': None >+ } >+ ]) >+ >+ def test_fast_ad_fx_fast_armor_ticket2(self): >+ self._run_test_sequence([ >+ # Show that we can still use the modified ticket as armor. >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.gen_tgt_fast_armor_auth_data >+ } >+ ]) >+ >+ def test_fast_tgs_service_ticket(self): >+ # Try to use a non-TGT ticket to establish an armor key, which fails >+ # (RFC6113 5.4.2). >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_NOT_US, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_service_ticket, # fails >+ 'fast_armor': None >+ } >+ ]) >+ >+ def test_fast_tgs_service_ticket_mach(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_NOT_US, # fails >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_mach_service_ticket, >+ 'fast_armor': None >+ } >+ ]) >+ >+ def test_simple_tgs_no_subkey(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': False, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'include_subkey': False >+ } >+ ]) >+ >+ def test_fast_tgs_no_subkey(self): >+ # Show that omitting the subkey in the TGS-REQ authenticator fails >+ # (RFC6113 5.4.2). >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None, >+ 'include_subkey': False >+ } >+ ]) >+ >+ def test_fast_hide_client_names(self): >+ user_creds = self.get_client_creds() >+ user_name = user_creds.get_username() >+ user_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ >+ expected_cname = self.PrincipalName_create( >+ name_type=NT_WELLKNOWN, names=['WELLKNOWN', 'ANONYMOUS']) >+ >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'fast_options': '01', # hide client names >+ 'expected_cname': expected_cname >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'fast_options': '01', # hide client names >+ 'expected_cname': expected_cname, >+ 'expected_cname_private': user_cname >+ } >+ ]) >+ >+ def test_fast_tgs_hide_client_names(self): >+ user_creds = self.get_client_creds() >+ user_name = user_creds.get_username() >+ user_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ >+ expected_cname = self.PrincipalName_create( >+ name_type=NT_WELLKNOWN, names=['WELLKNOWN', 'ANONYMOUS']) >+ >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None, >+ 'fast_options': '01', # hide client names >+ 'expected_cname': expected_cname, >+ 'expected_cname_private': user_cname >+ } >+ ]) >+ >+ def test_fast_encrypted_challenge_replay(self): >+ # The KDC is supposed to check that encrypted challenges are not >+ # replays (RFC6113 5.4.6), but timestamps may be reused; an encrypted >+ # challenge is only considered a replay if the ciphertext is identical >+ # to a previous challenge. Windows does not perform this check. >+ >+ class GenerateEncChallengePadataReplay: >+ def __init__(replay): >+ replay._padata = None >+ >+ def __call__(replay, key, armor_key): >+ if replay._padata is None: >+ client_challenge_key = ( >+ self.generate_client_challenge_key(armor_key, key)) >+ replay._padata = self.get_challenge_pa_data( >+ client_challenge_key) >+ >+ return replay._padata >+ >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': GenerateEncChallengePadataReplay(), >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'repeat': 2 >+ } >+ ]) >+ >+ def generate_enc_timestamp_padata(self, key, _armor_key): >+ return self.get_enc_timestamp_pa_data_from_key(key) >+ >+ def generate_enc_challenge_padata(self, key, armor_key, skew=0): >+ client_challenge_key = ( >+ self.generate_client_challenge_key(armor_key, key)) >+ return self.get_challenge_pa_data(client_challenge_key, skew=skew) >+ >+ def generate_enc_challenge_padata_wrong_key_kdc(self, key, armor_key): >+ kdc_challenge_key = ( >+ self.generate_kdc_challenge_key(armor_key, key)) >+ return self.get_challenge_pa_data(kdc_challenge_key) >+ >+ def generate_enc_challenge_padata_wrong_key(self, key, _armor_key): >+ return self.get_challenge_pa_data(key) >+ >+ def generate_empty_fast(self, >+ _kdc_exchange_dict, >+ _callback_dict, >+ _req_body, >+ _fast_padata, >+ _fast_armor, >+ _checksum, >+ _fast_options=''): >+ fast_padata = self.PA_DATA_create(PADATA_FX_FAST, b'') >+ >+ return fast_padata >+ >+ def _run_test_sequence(self, test_sequence): >+ if self.strict_checking: >+ self.check_kdc_fast_support() >+ >+ kdc_options_default = str(krb5_asn1.KDCOptions('forwardable,' >+ 'renewable,' >+ 'canonicalize,' >+ 'renewable-ok')) >+ >+ pac_request = self.get_pa_pac_request() >+ >+ client_creds = self.get_client_creds() >+ target_creds = self.get_service_creds() >+ krbtgt_creds = self.get_krbtgt_creds() >+ >+ client_username = client_creds.get_username() >+ client_realm = client_creds.get_realm() >+ client_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[client_username]) >+ >+ krbtgt_username = krbtgt_creds.get_username() >+ krbtgt_realm = krbtgt_creds.get_realm() >+ krbtgt_sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ krbtgt_decryption_key = self.TicketDecryptionKey_from_creds( >+ krbtgt_creds) >+ >+ target_username = target_creds.get_username()[:-1] >+ target_realm = target_creds.get_realm() >+ target_service = 'host' >+ target_sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=[target_service, target_username]) >+ target_decryption_key = self.TicketDecryptionKey_from_creds( >+ target_creds, etype=kcrypto.Enctype.RC4) >+ >+ fast_cookie = None >+ preauth_etype_info2 = None >+ >+ preauth_key = None >+ >+ for kdc_dict in test_sequence: >+ rep_type = kdc_dict.pop('rep_type') >+ self.assertIn(rep_type, (KRB_AS_REP, KRB_TGS_REP)) >+ >+ expected_error_mode = kdc_dict.pop('expected_error_mode') >+ self.assertIn(expected_error_mode, range(240)) >+ >+ use_fast = kdc_dict.pop('use_fast') >+ self.assertIs(type(use_fast), bool) >+ >+ if use_fast: >+ self.assertIn('fast_armor', kdc_dict) >+ fast_armor_type = kdc_dict.pop('fast_armor') >+ >+ if fast_armor_type is not None: >+ self.assertIn('gen_armor_tgt_fn', kdc_dict) >+ elif expected_error_mode != KDC_ERR_GENERIC: >+ self.assertNotIn('gen_armor_tgt_fn', kdc_dict) >+ >+ gen_armor_tgt_fn = kdc_dict.pop('gen_armor_tgt_fn', None) >+ if gen_armor_tgt_fn is not None: >+ armor_tgt = gen_armor_tgt_fn() >+ else: >+ armor_tgt = None > >- x = self.PA_DATA_create(PADATA_FX_FAST, b'') >- padata = [x] >- rep = self.as_req(cname, sname, realm, etype, padata) >+ fast_options = kdc_dict.pop('fast_options', '') >+ else: >+ fast_armor_type = None >+ armor_tgt = None > >- self.assertIsNotNone(rep) >- self.assertEqual(rep['msg-type'], 30) >- self.assertEqual(rep['error-code'], 60) >+ self.assertNotIn('fast_options', kdc_dict) >+ fast_options = None > >- def test_fast_cookie_retured_in_pre_auth(self): >- '''Confirm that the kdc returns PA-FX-COOKIE >- ''' >+ if rep_type == KRB_TGS_REP: >+ gen_tgt_fn = kdc_dict.pop('gen_tgt_fn') >+ tgt = gen_tgt_fn() >+ else: >+ self.assertNotIn('gen_tgt_fn', kdc_dict) >+ tgt = None >+ >+ if expected_error_mode != 0: >+ check_error_fn = self.generic_check_kdc_error >+ check_rep_fn = None >+ else: >+ check_error_fn = None >+ check_rep_fn = self.generic_check_kdc_rep >+ >+ etypes = kdc_dict.pop('etypes', (AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5)) >+ >+ cname = client_cname if rep_type == KRB_AS_REP else None >+ crealm = client_realm >+ >+ if rep_type == KRB_AS_REP: >+ sname = krbtgt_sname >+ srealm = krbtgt_realm >+ else: # KRB_TGS_REP >+ sname = target_sname >+ srealm = target_realm >+ >+ expected_cname = kdc_dict.pop('expected_cname', client_cname) >+ expected_cname_private = kdc_dict.pop('expected_cname_private', >+ None) >+ expected_crealm = kdc_dict.pop('expected_crealm', client_realm) >+ expected_sname = kdc_dict.pop('expected_sname', sname) >+ expected_srealm = kdc_dict.pop('expected_srealm', srealm) >+ >+ expected_salt = client_creds.get_salt() >+ >+ authenticator_subkey = self.RandomKey(kcrypto.Enctype.AES256) >+ if rep_type == KRB_AS_REP: >+ if use_fast: >+ armor_key = self.generate_armor_key(authenticator_subkey, >+ armor_tgt.session_key) >+ armor_subkey = authenticator_subkey >+ else: >+ armor_key = None >+ armor_subkey = authenticator_subkey >+ else: # KRB_TGS_REP >+ if fast_armor_type is not None: >+ armor_subkey = self.RandomKey(kcrypto.Enctype.AES256) >+ explicit_armor_key = self.generate_armor_key( >+ armor_subkey, >+ armor_tgt.session_key) >+ armor_key = kcrypto.cf2(explicit_armor_key.key, >+ authenticator_subkey.key, >+ b'explicitarmor', >+ b'tgsarmor') >+ armor_key = Krb5EncryptionKey(armor_key, None) >+ else: >+ armor_key = self.generate_armor_key(authenticator_subkey, >+ tgt.session_key) >+ armor_subkey = authenticator_subkey >+ >+ if not kdc_dict.pop('include_subkey', True): >+ authenticator_subkey = None >+ >+ if use_fast: >+ generate_fast_fn = kdc_dict.pop('gen_fast_fn', None) >+ if generate_fast_fn is None: >+ generate_fast_fn = functools.partial( >+ self.generate_simple_fast, >+ fast_options=fast_options) >+ else: >+ generate_fast_fn = None >+ >+ generate_fast_armor_fn = ( >+ self.generate_ap_req >+ if fast_armor_type is not None >+ else None) >+ >+ def _generate_padata_copy(_kdc_exchange_dict, >+ _callback_dict, >+ req_body, >+ padata): >+ return padata, req_body >+ >+ def _check_padata_preauth_key(_kdc_exchange_dict, >+ _callback_dict, >+ _rep, >+ _padata): >+ as_rep_usage = KU_AS_REP_ENC_PART >+ return preauth_key, as_rep_usage >+ >+ pac_options = kdc_dict.pop('pac_options', '1') # claims support >+ pac_options = self.get_pa_pac_options(pac_options) >+ >+ kdc_options = kdc_dict.pop('kdc_options', kdc_options_default) >+ >+ if rep_type == KRB_AS_REP: >+ padata = [pac_request, pac_options] >+ else: >+ padata = [pac_options] >+ >+ gen_padata_fn = kdc_dict.pop('gen_padata_fn', None) >+ if gen_padata_fn is not None: >+ self.assertEqual(KRB_AS_REP, rep_type) >+ self.assertIsNotNone(preauth_etype_info2) >+ >+ preauth_key = self.PasswordKey_from_etype_info2( >+ client_creds, >+ preauth_etype_info2[0], >+ client_creds.get_kvno()) >+ gen_padata = gen_padata_fn(preauth_key, armor_key) >+ padata.insert(0, gen_padata) >+ else: >+ preauth_key = None >+ >+ if rep_type == KRB_AS_REP: >+ check_padata_fn = _check_padata_preauth_key >+ else: >+ check_padata_fn = self.check_simple_tgs_padata >+ >+ if use_fast: >+ inner_padata = padata >+ outer_padata = [] >+ else: >+ inner_padata = [] >+ outer_padata = padata >+ >+ if use_fast and fast_cookie is not None: >+ outer_padata.append(fast_cookie) >+ >+ generate_fast_padata_fn = (functools.partial(_generate_padata_copy, >+ padata=inner_padata) >+ if inner_padata else None) >+ generate_padata_fn = (functools.partial(_generate_padata_copy, >+ padata=outer_padata) >+ if outer_padata else None) >+ >+ gen_authdata_fn = kdc_dict.pop('gen_authdata_fn', None) >+ if gen_authdata_fn is not None: >+ auth_data = [gen_authdata_fn()] >+ else: >+ auth_data = None >+ >+ if not use_fast: >+ self.assertNotIn('outer_req', kdc_dict) >+ outer_req = kdc_dict.pop('outer_req', None) >+ >+ if rep_type == KRB_AS_REP: >+ kdc_exchange_dict = self.as_exchange_dict( >+ expected_crealm=expected_crealm, >+ expected_cname=expected_cname, >+ expected_cname_private=expected_cname_private, >+ expected_srealm=expected_srealm, >+ expected_sname=expected_sname, >+ ticket_decryption_key=krbtgt_decryption_key, >+ generate_fast_fn=generate_fast_fn, >+ generate_fast_armor_fn=generate_fast_armor_fn, >+ generate_fast_padata_fn=generate_fast_padata_fn, >+ fast_armor_type=fast_armor_type, >+ generate_padata_fn=generate_padata_fn, >+ check_error_fn=check_error_fn, >+ check_rep_fn=check_rep_fn, >+ check_padata_fn=check_padata_fn, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ callback_dict={}, >+ expected_error_mode=expected_error_mode, >+ client_as_etypes=etypes, >+ expected_salt=expected_salt, >+ authenticator_subkey=authenticator_subkey, >+ auth_data=auth_data, >+ armor_key=armor_key, >+ armor_tgt=armor_tgt, >+ armor_subkey=armor_subkey, >+ kdc_options=kdc_options, >+ outer_req=outer_req) >+ else: # KRB_TGS_REP >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=expected_crealm, >+ expected_cname=expected_cname, >+ expected_cname_private=expected_cname_private, >+ expected_srealm=expected_srealm, >+ expected_sname=expected_sname, >+ ticket_decryption_key=target_decryption_key, >+ generate_fast_fn=generate_fast_fn, >+ generate_fast_armor_fn=generate_fast_armor_fn, >+ generate_fast_padata_fn=generate_fast_padata_fn, >+ fast_armor_type=fast_armor_type, >+ generate_padata_fn=generate_padata_fn, >+ check_error_fn=check_error_fn, >+ check_rep_fn=check_rep_fn, >+ check_padata_fn=check_padata_fn, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ expected_error_mode=expected_error_mode, >+ callback_dict={}, >+ tgt=tgt, >+ armor_key=armor_key, >+ armor_tgt=armor_tgt, >+ armor_subkey=armor_subkey, >+ authenticator_subkey=authenticator_subkey, >+ auth_data=auth_data, >+ body_checksum_type=None, >+ kdc_options=kdc_options, >+ outer_req=outer_req) >+ >+ repeat = kdc_dict.pop('repeat', 1) >+ for _ in range(repeat): >+ rep = self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=cname, >+ realm=crealm, >+ sname=sname, >+ etypes=etypes) >+ if expected_error_mode == 0: >+ self.check_reply(rep, rep_type) >+ >+ fast_cookie = None >+ preauth_etype_info2 = None >+ else: >+ self.check_error_rep(rep, expected_error_mode) >+ >+ if 'fast_cookie' in kdc_exchange_dict: >+ fast_cookie = self.create_fast_cookie( >+ kdc_exchange_dict['fast_cookie']) >+ else: >+ fast_cookie = None >+ >+ if expected_error_mode == KDC_ERR_PREAUTH_REQUIRED: >+ preauth_etype_info2 = ( >+ kdc_exchange_dict['preauth_etype_info2']) >+ else: >+ preauth_etype_info2 = None >+ >+ # Ensure we used all the parameters given to us. >+ self.assertEqual({}, kdc_dict) >+ >+ def generate_fast_armor_auth_data(self): >+ auth_data = self.AuthorizationData_create(AD_FX_FAST_ARMOR, b'') >+ >+ return auth_data >+ >+ def generate_fast_used_auth_data(self): >+ auth_data = self.AuthorizationData_create(AD_FX_FAST_USED, b'') >+ >+ return auth_data >+ >+ def gen_tgt_fast_armor_auth_data(self): >+ user_tgt = self.get_user_tgt() >+ >+ ticket_decryption_key = user_tgt.decryption_key >+ >+ tgt_encpart = self.getElementValue(user_tgt.ticket, 'enc-part') >+ self.assertElementEqual(tgt_encpart, 'etype', >+ ticket_decryption_key.etype) >+ self.assertElementKVNO(tgt_encpart, 'kvno', >+ ticket_decryption_key.kvno) >+ tgt_cipher = self.getElementValue(tgt_encpart, 'cipher') >+ tgt_decpart = ticket_decryption_key.decrypt(KU_TICKET, tgt_cipher) >+ tgt_private = self.der_decode(tgt_decpart, >+ asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ auth_data = self.generate_fast_armor_auth_data() >+ tgt_private['authorization-data'].append(auth_data) >+ >+ # Re-encrypt the user TGT. >+ tgt_private_new = self.der_encode( >+ tgt_private, >+ asn1Spec=krb5_asn1.EncTicketPart()) >+ tgt_encpart = self.EncryptedData_create(ticket_decryption_key, >+ KU_TICKET, >+ tgt_private_new) >+ user_ticket = user_tgt.ticket.copy() >+ user_ticket['enc-part'] = tgt_encpart >+ >+ user_tgt = KerberosTicketCreds( >+ user_ticket, >+ session_key=user_tgt.session_key, >+ crealm=user_tgt.crealm, >+ cname=user_tgt.cname, >+ srealm=user_tgt.srealm, >+ sname=user_tgt.sname, >+ decryption_key=user_tgt.decryption_key, >+ ticket_private=tgt_private, >+ encpart_private=user_tgt.encpart_private) >+ >+ # Use our modifed TGT to replace the one in the request. >+ return user_tgt >+ >+ def create_fast_cookie(self, cookie): >+ self.assertIsNotNone(cookie) >+ if self.strict_checking: >+ self.assertNotEqual(0, len(cookie)) >+ >+ return self.PA_DATA_create(PADATA_FX_COOKIE, cookie) >+ >+ def get_pa_pac_request(self, request_pac=True): >+ pac_request = self.KERB_PA_PAC_REQUEST_create(request_pac) >+ >+ return pac_request >+ >+ def get_pa_pac_options(self, options): >+ pac_options = self.PA_PAC_OPTIONS_create(options) >+ pac_options = self.der_encode(pac_options, >+ asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >+ pac_options = self.PA_DATA_create(PADATA_PAC_OPTIONS, pac_options) >+ >+ return pac_options >+ >+ def check_kdc_fast_support(self): >+ # Check that the KDC supports FAST > >- # Create a user account for the test. >- # > samdb = self.get_samdb() >- user_name = "krb5fastusr" >- (uc, dn) = self.create_account(samdb, user_name) >- realm = uc.get_realm().lower() > >- # Do the initial AS-REQ, should get a pre-authentication required >- # response >+ krbtgt_rid = 502 >+ krbtgt_sid = '%s-%d' % (samdb.get_domain_sid(), krbtgt_rid) >+ >+ res = samdb.search(base='<SID=%s>' % krbtgt_sid, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-SupportedEncryptionTypes']) >+ >+ krbtgt_etypes = int(res[0]['msDS-SupportedEncryptionTypes'][0]) >+ >+ self.assertTrue( >+ security.KERB_ENCTYPE_FAST_SUPPORTED & krbtgt_etypes) >+ self.assertTrue( >+ security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED & krbtgt_etypes) >+ self.assertTrue( >+ security.KERB_ENCTYPE_CLAIMS_SUPPORTED & krbtgt_etypes) >+ >+ def get_service_ticket(self, tgt, target_creds, service='host'): > etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >- cname = self.PrincipalName_create( >- name_type=NT_PRINCIPAL, names=[user_name]) >- sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=["krbtgt", realm]) >- >- rep = self.as_req(cname, sname, realm, etype) >- self.assertIsNotNone(rep) >- self.assertEqual(rep['msg-type'], 30) >- self.assertEqual(rep['error-code'], 25) >- >- fx_fast = self.get_padata_element(rep, PADATA_FX_FAST) >- self.assertIsNotNone(fx_fast, "No PADATA_FX_FAST element") >- >- fx_cookie = self.get_padata_element(rep, PADATA_FX_COOKIE) >- self.assertIsNotNone(fx_cookie, "No PADATA_FX_COOKIE element") >- >- def test_ignore_fast(self): >- ''' >- TODO reword this >- Attempt to authenticate with out FAST, i.e. ignoring the >- FAST advertised in the pre-auth >- ''' >- >- # Create a user account for the test. >- # >- samdb = self.get_samdb() >- user_name = "krb5fastusr" >- (uc, dn) = self.create_account(samdb, user_name) >- realm = uc.get_realm().lower() > >- # Do the initial AS-REQ, should get a pre-authentication required >- # response >+ key = tgt.session_key >+ ticket = tgt.ticket >+ >+ cname = tgt.cname >+ realm = tgt.crealm >+ >+ target_name = target_creds.get_username()[:-1] >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[service, target_name]) >+ >+ rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype) >+ >+ service_ticket = rep['ticket'] >+ >+ ticket_etype = service_ticket['enc-part']['etype'] >+ target_key = self.TicketDecryptionKey_from_creds(target_creds, >+ etype=ticket_etype) >+ >+ session_key = self.EncryptionKey_import(enc_part['key']) >+ >+ service_ticket_creds = KerberosTicketCreds(service_ticket, >+ session_key, >+ crealm=realm, >+ cname=cname, >+ srealm=realm, >+ sname=sname, >+ decryption_key=target_key) >+ >+ return service_ticket_creds >+ >+ def get_tgt(self, creds): >+ user_name = creds.get_username() >+ realm = creds.get_realm() >+ >+ salt = creds.get_salt() >+ > etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >- cname = self.PrincipalName_create( >- name_type=NT_PRINCIPAL, names=[user_name]) >- sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=["krbtgt", realm]) >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ sname = self.PrincipalName_create(name_type=NT_SRV_INST, >+ names=['krbtgt', realm]) > >- rep = self.as_req(cname, sname, realm, etype) >- self.assertIsNotNone(rep) >- self.assertEqual(rep['msg-type'], 30) >- self.assertEqual(rep['error-code'], 25) >+ till = self.get_KerberosTime(offset=36000) > >- fx_fast = self.get_padata_element(rep, PADATA_FX_FAST) >- self.assertIsNotNone(fx_fast, "No PADATA_FX_FAST element") >+ krbtgt_creds = self.get_krbtgt_creds() >+ ticket_decryption_key = ( >+ self.TicketDecryptionKey_from_creds(krbtgt_creds)) > >- fx_cookie = self.get_padata_element(rep, PADATA_FX_COOKIE) >- self.assertIsNotNone(fx_cookie, "No PADATA_FX_COOKIE element") >+ kdc_options = str(krb5_asn1.KDCOptions('forwardable,' >+ 'renewable,' >+ 'canonicalize,' >+ 'renewable-ok')) > >- # Do the next AS-REQ >- padata = [self.get_enc_timestamp_pa_data(uc, rep)] >- rep = self.as_req(cname, sname, realm, etype, padata=padata) >+ pac_request = self.get_pa_pac_request() >+ pac_options = self.get_pa_pac_options('1') # supports claims >+ >+ padata = [pac_request, pac_options] >+ >+ rep, kdc_exchange_dict = self._test_as_exchange( >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ till=till, >+ client_as_etypes=etype, >+ expected_error_mode=KDC_ERR_PREAUTH_REQUIRED, >+ expected_crealm=realm, >+ expected_cname=cname, >+ expected_srealm=realm, >+ expected_sname=sname, >+ expected_salt=salt, >+ etypes=etype, >+ padata=padata, >+ kdc_options=kdc_options, >+ preauth_key=None, >+ ticket_decryption_key=ticket_decryption_key) >+ self.check_pre_authentication(rep) >+ >+ etype_info2 = kdc_exchange_dict['preauth_etype_info2'] >+ >+ preauth_key = self.PasswordKey_from_etype_info2(creds, >+ etype_info2[0], >+ creds.get_kvno()) >+ >+ ts_enc_padata = self.get_enc_timestamp_pa_data(creds, rep) >+ >+ padata = [ts_enc_padata, pac_request, pac_options] >+ >+ expected_realm = realm.upper() >+ >+ expected_sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=['krbtgt', realm.upper()]) >+ >+ rep, kdc_exchange_dict = self._test_as_exchange( >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ till=till, >+ client_as_etypes=etype, >+ expected_error_mode=0, >+ expected_crealm=expected_realm, >+ expected_cname=cname, >+ expected_srealm=expected_realm, >+ expected_sname=expected_sname, >+ expected_salt=salt, >+ etypes=etype, >+ padata=padata, >+ kdc_options=kdc_options, >+ preauth_key=preauth_key, >+ ticket_decryption_key=ticket_decryption_key) > self.check_as_reply(rep) > >- def test_fast(self): >- ''' >- Attempt to authenticate with >- ''' >+ tgt = rep['ticket'] > >- # Create a user account for the test. >- # >- samdb = self.get_samdb() >- user_name = "krb5fastusr" >- (uc, dn) = self.create_account(samdb, user_name) >- realm = uc.get_realm().lower() >+ enc_part = self.get_as_rep_enc_data(preauth_key, rep) >+ session_key = self.EncryptionKey_import(enc_part['key']) > >- # Do the initial AS-REQ, should get a pre-authentication required >- # response >- etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >- cname = self.PrincipalName_create( >- name_type=NT_PRINCIPAL, names=[user_name]) >- sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=["krbtgt", realm]) >- >- rep = self.as_req(cname, sname, realm, etype) >- self.assertIsNotNone(rep) >- self.assertEqual(rep['msg-type'], 30) >- self.assertEqual(rep['error-code'], 25) >- >- fx_fast = self.get_padata_element(rep, PADATA_FX_FAST) >- self.assertIsNotNone(fx_fast, "No PADATA_FX_FAST element") >- >- fx_cookie = self.get_padata_element(rep, PADATA_FX_COOKIE) >- self.assertIsNotNone(fx_cookie, "No PADATA_FX_COOKIE element") >- >- cookie = self.PA_DATA_create(PADATA_FX_COOKIE, fx_cookie) >- >- # Do the next AS-REQ >- padata = [self.get_enc_timestamp_pa_data(uc, rep)] >- padata.append(cookie) >- # req = self.AS_REQ_create(padata=padata, >- # kdc_options=str(kdc_options), >- # cname=cname, >- # realm=realm, >- # sname=sname, >- # from_time=None, >- # till_time=till, >- # renew_time=None, >- # nonce=0x7fffffff, >- # etypes=etypes, >- # addresses=None, >- # EncAuthorizationData=None, >- # EncAuthorizationData_key=None, >- # additional_tickets=None) >- # rep = self.as_req(cname, sname, realm, etype, padata=padata) >- # self.check_as_reply(rep) >+ ticket_creds = KerberosTicketCreds( >+ tgt, >+ session_key, >+ crealm=realm, >+ cname=cname, >+ srealm=realm, >+ sname=sname, >+ decryption_key=ticket_decryption_key) >+ >+ return ticket_creds, enc_part >+ >+ def get_mach_tgt(self): >+ if self.mach_tgt is None: >+ mach_creds = self.get_mach_creds() >+ type(self).mach_tgt, type(self).mach_enc_part = ( >+ self.get_tgt(mach_creds)) >+ >+ return self.mach_tgt >+ >+ def get_user_tgt(self): >+ if self.user_tgt is None: >+ user_creds = self.get_client_creds() >+ type(self).user_tgt, type(self).user_enc_part = ( >+ self.get_tgt(user_creds)) >+ >+ return self.user_tgt >+ >+ def get_user_service_ticket(self): >+ if self.user_service_ticket is None: >+ user_tgt = self.get_user_tgt() >+ service_creds = self.get_service_creds() >+ type(self).user_service_ticket = ( >+ self.get_service_ticket(user_tgt, service_creds)) >+ >+ return self.user_service_ticket >+ >+ def get_mach_service_ticket(self): >+ if self.mach_service_ticket is None: >+ mach_tgt = self.get_mach_tgt() >+ service_creds = self.get_service_creds() >+ type(self).mach_service_ticket = ( >+ self.get_service_ticket(mach_tgt, service_creds)) >+ >+ return self.mach_service_ticket > > > if __name__ == "__main__": >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 66f07cebc14..02a3db1a3cd 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -15,10 +15,52 @@ > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c > # >-# MIT specific FAST tests, >+# FAST tests > # >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_explicit_PA_FX_FAST_in_as_req\(ad_dc\) >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast\(ad_dc\) >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_cookie_retured_in_pre_auth\(ad_dc\) >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_supported\(ad_dc\) >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_ignore_fast\(ad_dc\) >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_empty_fast.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor2.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor_ticket.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor_ticket2.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_authdata_fast_not_used.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_authdata_fast_used.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_enc_timestamp.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_clock_skew.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_replay.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_wrong_key.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_wrong_key_kdc.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_hide_client_names.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_armor_type.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_armor_type2.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_tgt.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_tgt_mach.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_canon.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_claims.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_claims_or_canon.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_flags.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_nonce.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_realm.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_till.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_armor.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_hide_client_names.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_claims.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_etypes.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_subkey.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_flags.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_nonce.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_realm.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_till.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_service_ticket.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_service_ticket_mach.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_unknown_critical_option.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_fast_no_etypes.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_etypes.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_subkey.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_service_ticket.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_service_ticket_mach.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_wrong_principal.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_unarmored_as_req.ad_dc >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index fffa5c3cd7e..0e302343111 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -647,3 +647,56 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > # > # fl2000dc doesn't support AES > ^samba4.krb5.kdc.*as-req-aes.*fl2000dc >+# >+# FAST tests >+# >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_empty_fast.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor2.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor_ticket.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor_ticket2.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_authdata_fast_not_used.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_authdata_fast_used.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_enc_timestamp.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_clock_skew.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_replay.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_wrong_key.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_wrong_key_kdc.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_hide_client_names.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_armor_type.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_armor_type2.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_tgt.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_tgt_mach.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_canon.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_claims.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_claims_or_canon.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_flags.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_nonce.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_realm.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_till.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_armor.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_hide_client_names.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_canon.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_claims.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_claims_or_canon.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_etypes.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_subkey.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_flags.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_nonce.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_realm.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_till.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_service_ticket.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_service_ticket_mach.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_unknown_critical_option.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_fast_no_etypes.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_etypes.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_subkey.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_service_ticket.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_service_ticket_mach.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_wrong_principal.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_unarmored_as_req.ad_dc >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 3866b1791d0..0b01639c041 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1276,7 +1276,7 @@ planpythontestsuite( > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'SERVICE_USERNAME': '$SERVER' >+ 'STRICT_CHECKING': '0', > }) > planpythontestsuite( > "ad_dc", >-- >2.25.1 > > >From 4b137f15209a75ae4a896eb1a1b9458c5a3fff5b Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 7 Sep 2021 17:23:32 +1200 >Subject: [PATCH 199/686] selftest: Remove knownfail for no_etypes FAST tests > >These test pass because b3ee034b4d457607ef25a5b01da64e1eaf5906dd >(s4:kdc: prefer newer enctypes for preauth responses) is not included >in the 4.13 backport. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >--- > selftest/knownfail_heimdal_kdc | 3 --- > 1 file changed, 3 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 02a3db1a3cd..9a61f476469 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -47,7 +47,6 @@ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_armor.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_hide_client_names.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_claims.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_etypes.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_subkey.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_flags.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_nonce.ad_dc >@@ -56,9 +55,7 @@ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_service_ticket.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_service_ticket_mach.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_unknown_critical_option.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_fast_no_etypes.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_etypes.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_subkey.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_service_ticket.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_service_ticket_mach.ad_dc >-- >2.25.1 > > >From f6f7d974b18be5b2e228dd88949d1f63390c61d8 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 27 Aug 2021 13:35:59 +1200 >Subject: [PATCH 200/686] tests/krb5: Make e-data checking less strict > >Without this additional 'self.strict_checking' check, the tests in the >following patches do not get far enough to trigger a crash with the MIT >KDC, instead failing when obtaining a TGT for the user or machine. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14770 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> > >[abartlet@samba.org Backported from commit > 79dda329f2a8382f1e46b50f4b9692e78d687826 as knownfail needed splitting > into only failing in the Heimdal case due likely because > b3ee034b4d457607ef25a5b01da64e1eaf5906dd > (s4:kdc: prefer newer enctypes for preauth responses) is not included > in the 4.14 backport. ] >--- > python/samba/tests/krb5/raw_testcase.py | 5 +- > .../knownfail.d/samba.tests.krb5.as_req_tests | 54 --- > selftest/knownfail_heimdal_kdc | 57 +++ > selftest/knownfail_mit_kdc | 341 ------------------ > 4 files changed, 60 insertions(+), 397 deletions(-) > delete mode 100644 selftest/knownfail.d/samba.tests.krb5.as_req_tests > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 17ef8df5daa..22f64f25f14 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2504,8 +2504,9 @@ class RawKerberosTest(TestCaseInTempDir): > if self.strict_checking: > self.assertIsNone(enc_challenge) > if not sent_enc_challenge: >- self.assertIsNotNone(pk_as_req) >- self.assertIsNotNone(pk_as_rep19) >+ if self.strict_checking: >+ self.assertIsNotNone(pk_as_req) >+ self.assertIsNotNone(pk_as_rep19) > else: > self.assertIsNone(pk_as_req) > self.assertIsNone(pk_as_rep19) >diff --git a/selftest/knownfail.d/samba.tests.krb5.as_req_tests b/selftest/knownfail.d/samba.tests.krb5.as_req_tests >deleted file mode 100644 >index 35375dfcc8e..00000000000 >--- a/selftest/knownfail.d/samba.tests.krb5.as_req_tests >+++ /dev/null >@@ -1,54 +0,0 @@ >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 9a61f476469..6a36640233e 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -15,6 +15,63 @@ > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c > # >+# Heimdal (not MIT) still fails these after 'Make e-data checking less strict' >+# >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc >+# > # FAST tests > # > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_empty_fast.ad_dc >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 0e302343111..025504c1268 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -291,356 +291,15 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c > # >-# MIT currently fails the test_as_req_enc_timestamp test. >-# >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_enc_timestamp.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_enc_timestamp.fl2008r2dc >-# > # MIT currently fails some as_req_no_preauth tests. > # > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_False >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_dummy_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_aes256_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_dummy_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_dummy_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_dummy_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_aes256_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_aes128_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_aes256_rc4_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_pac_True.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128.fl2003dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_pac_True.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_False.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_False.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_None.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_None.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_True.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_pac_True.fl2008r2dc > # Differences in our KDC compared to windows > # > ^samba4.krb5.kdc .*.as-req-pac-request # We should reply to a request for a PAC over UDP with KRB5KRB_ERR_RESPONSE_TOO_BIG unconditionally >-- >2.25.1 > > >From c87e98517a24ec6490feff6ee7a906b0ccec9fcf Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 14:43:53 +1200 >Subject: [PATCH 201/686] tests/krb5: Make cname checking less strict > >Without this additional 'self.strict_checking' check, the tests in the >following patches do not get far enough to trigger a crash with the MIT >KDC. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 >[abartlet@samba.org backported from commit > 36798f5b651a02b74b6844c024101f7a026f1f68 as Samba 4.14 is tested > on MIT 1.16 and so the knownfails need to match this version] >--- > python/samba/tests/krb5/raw_testcase.py | 5 ++-- > selftest/knownfail_mit_kdc | 35 ------------------------- > 2 files changed, 3 insertions(+), 37 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 22f64f25f14..32de51c2da4 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2043,8 +2043,9 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_session_key = self.EncryptionKey_import(ticket_key) > self.assertElementEqualUTF8(ticket_private, 'crealm', > expected_crealm) >- self.assertElementEqualPrincipal(ticket_private, 'cname', >- expected_cname) >+ if self.strict_checking: >+ self.assertElementEqualPrincipal(ticket_private, 'cname', >+ expected_cname) > self.assertElementPresent(ticket_private, 'transited') > self.assertElementPresent(ticket_private, 'authtime') > if self.strict_checking: >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 025504c1268..d2114136ddb 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -309,53 +309,18 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > # > # FAST tests > # >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_empty_fast.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor2.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor_ticket.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_ad_fx_fast_armor_ticket2.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_authdata_fast_not_used.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_authdata_fast_used.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_enc_timestamp.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_clock_skew.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_replay.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_wrong_key.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_wrong_key_kdc.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_hide_client_names.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_armor_type.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_armor_type2.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_tgt.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_tgt_mach.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_canon.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_claims.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_claims_or_canon.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_flags.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_nonce.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_realm.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_wrong_till.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_armor.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_hide_client_names.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_canon.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_claims.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_claims_or_canon.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_etypes.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_subkey.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_flags.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_nonce.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_realm.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_wrong_till.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_service_ticket.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_service_ticket_mach.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_unknown_critical_option.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_fast_no_etypes.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_etypes.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_subkey.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_service_ticket.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_service_ticket_mach.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_wrong_principal.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_unarmored_as_req.ad_dc >-- >2.25.1 > > >From da138baf24d985ebe173e5410be314d24fa874b7 Mon Sep 17 00:00:00 2001 >From: Luke Howard <lukeh@padl.com> >Date: Fri, 27 Aug 2021 11:42:48 +1000 >Subject: [PATCH 202/686] CVE-2021-3671 HEIMDAL kdc: validate sname in TGS-REQ > >In tgs_build_reply(), validate the server name in the TGS-REQ is present before >dereferencing. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14770 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >[abartlet@samba.org backported from from Heimdal >commit 04171147948d0a3636bc6374181926f0fb2ec83a via reference >to an earlier patch by Joseph Sutton] > >RN: An unuthenticated user can crash the AD DC KDC by omitting the server name in a TGS-REQ > >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit 0cb4b939f192376bf5e33637863a91a20f74c5a5) >--- > source4/heimdal/kdc/krb5tgs.c | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index efbdd6ed77f..ef337ea4faf 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -1603,6 +1603,10 @@ tgs_build_reply(krb5_context context, > > s = &adtkt.cname; > r = adtkt.crealm; >+ } else if (s == NULL) { >+ ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; >+ krb5_set_error_message(context, ret, "No server in request"); >+ goto out; > } > > _krb5_principalname2krb5_principal(context, &sp, *s, r); >-- >2.25.1 > > >From 77c72fb6cef8579faf316f369127093d581f331f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 29 Jul 2021 12:25:06 +1200 >Subject: [PATCH 203/686] CVE-2021-3671 tests/krb5: Add tests for omitting > sname in outer request > >Note: Without the previous patch, 'test_fast_tgs_outer_no_sname' would >crash the Heimdal KDC. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14770 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit b8e2515552ffa158fab1e86a39004de4cc419da5) >--- > python/samba/tests/krb5/fast_tests.py | 39 +++++++++++++++++++++++++++ > selftest/knownfail_heimdal_kdc | 2 ++ > selftest/knownfail_mit_kdc | 2 ++ > 3 files changed, 43 insertions(+) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index e38b2e0a6e1..5189411e94f 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -655,6 +655,45 @@ class FAST_Tests(KDCBaseTest): > } > ]) > >+ def test_fast_outer_no_sname(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_PREAUTH_REQUIRED, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'outer_req': { >+ 'sname': None # should be ignored >+ } >+ }, >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_padata_fn': self.generate_enc_challenge_padata, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'outer_req': { >+ 'sname': None # should be ignored >+ } >+ } >+ ]) >+ >+ def test_fast_tgs_outer_no_sname(self): >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': 0, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None, >+ 'outer_req': { >+ 'sname': None # should be ignored >+ } >+ } >+ ]) >+ > def test_fast_outer_wrong_till(self): > self._run_test_sequence([ > { >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 6a36640233e..4a4e98f6727 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -118,3 +118,5 @@ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_service_ticket_mach.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_wrong_principal.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_unarmored_as_req.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index d2114136ddb..41142defe6c 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -324,3 +324,5 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_service_ticket.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_service_ticket_mach.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_unarmored_as_req.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc >-- >2.25.1 > > >From fc3e051dad60a9e7b4563669196857a1e688ddf9 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Wed, 1 Sep 2021 10:43:06 +1200 >Subject: [PATCH 204/686] tests/krb5: Remove harmful and a-typical return in > as_req testcase > >A test in a TestCase class should not return a value, the >test is determined by the assertions raised. > >Other changes will shortly cause kdc_exchange_dict[preauth_etype_info2] >to not always be filled, so we need to remove this >rudundent code. > >This also fixes a *lot* of tests against the MIT KDC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14770 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit 3330eaf39c6174f2d90fe4d8e016efb97005d1e5) >--- > python/samba/tests/krb5/as_req_tests.py | 14 ++++++-------- > selftest/knownfail_mit_kdc | 10 ---------- > 2 files changed, 6 insertions(+), 18 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index fd258e8164a..82ff3f4845c 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -106,13 +106,11 @@ class AsReqKerberosTests(KDCBaseTest): > expected_salt=expected_salt, > kdc_options=str(initial_kdc_options)) > >- rep = self._generic_kdc_exchange(kdc_exchange_dict, >- cname=cname, >- realm=realm, >- sname=sname, >- etypes=initial_etypes) >- >- return kdc_exchange_dict['preauth_etype_info2'] >+ self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ etypes=initial_etypes) > > def _test_as_req_no_preauth_with_args(self, etype_idx, pac): > name, etypes = self.etype_test_permutation_by_idx(etype_idx) >@@ -121,7 +119,7 @@ class AsReqKerberosTests(KDCBaseTest): > else: > pa_pac = self.KERB_PA_PAC_REQUEST_create(pac) > padata = [pa_pac] >- return self._test_as_req_nopreauth( >+ self._test_as_req_nopreauth( > initial_padata=padata, > initial_etypes=etypes, > initial_kdc_options=krb5_asn1.KDCOptions('forwardable')) >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 41142defe6c..59db6e80c09 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -290,16 +290,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_b > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c >-# >-# MIT currently fails some as_req_no_preauth tests. >-# >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_aes256.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes128_rc4.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_aes256_aes128_rc4.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4.fl2008r2dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128.fl2003dc >-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128.fl2008r2dc > # Differences in our KDC compared to windows > # > ^samba4.krb5.kdc .*.as-req-pac-request # We should reply to a request for a PAC over UDP with KRB5KRB_ERR_RESPONSE_TOO_BIG unconditionally >-- >2.25.1 > > >From 10b848c514d4eb0176c321aacd03491c5369b514 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 27 Aug 2021 13:00:21 +1200 >Subject: [PATCH 205/686] tests/krb5: Check e-data element for TGS-REP errors > without FAST > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14770 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit e373c6461a88c44303ea8cdbebc2d78dd15dec4a) >--- > python/samba/tests/krb5/raw_testcase.py | 52 ++++++++++++-------- > python/samba/tests/krb5/rfc4120_constants.py | 2 + > 2 files changed, 34 insertions(+), 20 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 32de51c2da4..ba6d07ce465 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -82,6 +82,7 @@ from samba.tests.krb5.rfc4120_constants import ( > PADATA_PAC_REQUEST, > PADATA_PK_AS_REQ, > PADATA_PK_AS_REP_19, >+ PADATA_PW_SALT, > PADATA_SUPPORTED_ETYPES > ) > import samba.tests.krb5.kcrypto as kcrypto >@@ -2187,8 +2188,7 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertElementEqualPrincipal(rep, 'sname', expected_sname) > self.assertElementMissing(rep, 'e-text') >- if (expected_error_mode in (KDC_ERR_GENERIC, >- KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS) >+ if (expected_error_mode == KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS > or (rep_msg_type == KRB_TGS_REP > and not sent_fast) > or (sent_fast and fast_armor_type is not None >@@ -2198,10 +2198,17 @@ class RawKerberosTest(TestCaseInTempDir): > return rep > edata = self.getElementValue(rep, 'e-data') > if self.strict_checking: >- self.assertIsNotNone(edata) >+ if expected_error_mode != KDC_ERR_GENERIC: >+ # Predicting whether an ERR_GENERIC error contains e-data is >+ # more complicated. >+ self.assertIsNotNone(edata) > if edata is not None: >- rep_padata = self.der_decode(edata, >- asn1Spec=krb5_asn1.METHOD_DATA()) >+ if rep_msg_type == KRB_TGS_REP and not sent_fast: >+ rep_padata = [self.der_decode(edata, >+ asn1Spec=krb5_asn1.PA_DATA())] >+ else: >+ rep_padata = self.der_decode(edata, >+ asn1Spec=krb5_asn1.METHOD_DATA()) > self.assertGreater(len(rep_padata), 0) > > if sent_fast: >@@ -2218,15 +2225,13 @@ class RawKerberosTest(TestCaseInTempDir): > expect_strengthen_key=False) > > rep_padata = fast_response['padata'] >- else: >- rep_padata = [] > >- etype_info2 = self.check_rep_padata(kdc_exchange_dict, >- callback_dict, >- rep, >- rep_padata) >+ etype_info2 = self.check_rep_padata(kdc_exchange_dict, >+ callback_dict, >+ rep, >+ rep_padata) > >- kdc_exchange_dict['preauth_etype_info2'] = etype_info2 >+ kdc_exchange_dict['preauth_etype_info2'] = etype_info2 > > return rep > >@@ -2279,10 +2284,13 @@ class RawKerberosTest(TestCaseInTempDir): > expected_patypes += (PADATA_FX_COOKIE,) > > if rep_msg_type == KRB_TGS_REP: >- sent_claims = self.sent_claims(kdc_exchange_dict) >- if sent_claims and expected_error_mode != 0: >- expected_patypes += (PADATA_PAC_OPTIONS,) >- else: >+ if not sent_fast and expected_error_mode != 0: >+ expected_patypes += (PADATA_PW_SALT,) >+ else: >+ sent_claims = self.sent_claims(kdc_exchange_dict) >+ if sent_claims and expected_error_mode not in (0, KDC_ERR_GENERIC): >+ expected_patypes += (PADATA_PAC_OPTIONS,) >+ elif expected_error_mode != KDC_ERR_GENERIC: > if expect_etype_info: > self.assertGreater(len(expect_etype_info2), 0) > expected_patypes += (PADATA_ETYPE_INFO,) >@@ -2458,8 +2466,11 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNone(pk_as_rep19) > return None > >- if self.strict_checking: >- self.assertIsNotNone(etype_info2) >+ if expected_error_mode != KDC_ERR_GENERIC: >+ if self.strict_checking: >+ self.assertIsNotNone(etype_info2) >+ else: >+ self.assertIsNone(etype_info2) > if expect_etype_info: > self.assertIsNotNone(etype_info) > else: >@@ -2468,7 +2479,7 @@ class RawKerberosTest(TestCaseInTempDir): > if unexpect_etype_info: > self.assertIsNone(etype_info) > >- if self.strict_checking: >+ if expected_error_mode != KDC_ERR_GENERIC and self.strict_checking: > self.assertGreaterEqual(len(etype_info2), 1) > self.assertEqual(len(etype_info2), len(expect_etype_info2)) > for i in range(0, len(etype_info2)): >@@ -2495,7 +2506,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(salt) > self.assertEqual(len(salt), 0) > >- if expected_error_mode != KDC_ERR_PREAUTH_FAILED: >+ if expected_error_mode not in (KDC_ERR_PREAUTH_FAILED, >+ KDC_ERR_GENERIC): > if sent_fast: > self.assertIsNotNone(enc_challenge) > if self.strict_checking: >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index e1a688991a7..c70ce309b95 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -60,6 +60,8 @@ PADATA_PK_AS_REQ = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-PK-AS-REQ')) > PADATA_PK_AS_REP_19 = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-PK-AS-REP-19')) >+PADATA_PW_SALT = int( >+ krb5_asn1.PADataTypeValues('kRB5-PADATA-PW-SALT')) > PADATA_SUPPORTED_ETYPES = int( > krb5_asn1.PADataTypeValues('kRB5-PADATA-SUPPORTED-ETYPES')) > >-- >2.25.1 > > >From 4550ae2dacc146c410956ed0b8782dfe9145af82 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 27 Aug 2021 13:00:37 +1200 >Subject: [PATCH 206/686] tests/krb5: Check PADATA-PW-SALT element in e-data > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14770 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit 1e4d757394a0bbda587d5ff91801f88539b712b1) >--- > python/samba/tests/krb5/raw_testcase.py | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index ba6d07ce465..4e7891ae89a 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2328,6 +2328,7 @@ class RawKerberosTest(TestCaseInTempDir): > fast_error = None > fx_fast = None > pac_options = None >+ pw_salt = None > for pa in rep_padata: > patype = self.getElementValue(pa, 'padata-type') > pavalue = self.getElementValue(pa, 'padata-value') >@@ -2380,6 +2381,11 @@ class RawKerberosTest(TestCaseInTempDir): > pac_options = pavalue > self.assertIsNotNone(pac_options) > continue >+ if patype == PADATA_PW_SALT: >+ self.assertIsNone(pw_salt) >+ pw_salt = pavalue >+ self.assertIsNotNone(pw_salt) >+ continue > > if fast_cookie is not None: > kdc_exchange_dict['fast_cookie'] = fast_cookie >@@ -2395,6 +2401,14 @@ class RawKerberosTest(TestCaseInTempDir): > if pac_options is not None: > self.check_pac_options_claims_support(pac_options) > >+ if pw_salt is not None: >+ self.assertEqual(12, len(pw_salt)) >+ >+ status = int.from_bytes(pw_salt[:4], 'little') >+ flags = int.from_bytes(pw_salt[8:], 'little') >+ >+ self.assertEqual(3, flags) >+ > if enc_challenge is not None: > if not sent_enc_challenge: > self.assertEqual(len(enc_challenge), 0) >-- >2.25.1 > > >From b5bcbd1c2f78a68436d805507680392e4b2baa33 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 27 Aug 2021 13:02:04 +1200 >Subject: [PATCH 207/686] tests/krb5: Add tests for omitting sname in request > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14770 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit bbbb13caf7bd2440c80f4f4775725b7863d16a5b) >--- > python/samba/tests/krb5/fast_tests.py | 83 ++++++++++++++++++++++++++- > selftest/knownfail_heimdal_kdc | 3 + > selftest/knownfail_mit_kdc | 4 ++ > 3 files changed, 88 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 5189411e94f..e0fd3cc4d5e 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -105,6 +105,79 @@ class FAST_Tests(KDCBaseTest): > } > ]) > >+ def test_simple_no_sname(self): >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_username = krbtgt_creds.get_username() >+ krbtgt_realm = krbtgt_creds.get_realm() >+ expected_sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'use_fast': False, >+ 'sname': None, >+ 'expected_sname': expected_sname >+ } >+ ]) >+ >+ def test_simple_tgs_no_sname(self): >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_username = krbtgt_creds.get_username() >+ krbtgt_realm = krbtgt_creds.get_realm() >+ expected_sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'use_fast': False, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'sname': None, >+ 'expected_sname': expected_sname >+ } >+ ]) >+ >+ def test_fast_no_sname(self): >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_username = krbtgt_creds.get_username() >+ krbtgt_realm = krbtgt_creds.get_realm() >+ expected_sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_AS_REP, >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'use_fast': True, >+ 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'sname': None, >+ 'expected_sname': expected_sname >+ } >+ ]) >+ >+ def test_fast_tgs_no_sname(self): >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_username = krbtgt_creds.get_username() >+ krbtgt_realm = krbtgt_creds.get_realm() >+ expected_sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ >+ self._run_test_sequence([ >+ { >+ 'rep_type': KRB_TGS_REP, >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'use_fast': True, >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'fast_armor': None, >+ 'sname': None, >+ 'expected_sname': expected_sname >+ } >+ ]) >+ > def test_simple_tgs_wrong_principal(self): > mach_creds = self.get_mach_creds() > mach_name = mach_creds.get_username() >@@ -1122,11 +1195,17 @@ class FAST_Tests(KDCBaseTest): > cname = client_cname if rep_type == KRB_AS_REP else None > crealm = client_realm > >+ if 'sname' in kdc_dict: >+ sname = kdc_dict.pop('sname') >+ else: >+ if rep_type == KRB_AS_REP: >+ sname = krbtgt_sname >+ else: # KRB_TGS_REP >+ sname = target_sname >+ > if rep_type == KRB_AS_REP: >- sname = krbtgt_sname > srealm = krbtgt_realm > else: # KRB_TGS_REP >- sname = target_sname > srealm = target_realm > > expected_cname = kdc_dict.pop('expected_cname', client_cname) >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 4a4e98f6727..b0981a06002 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -120,3 +120,6 @@ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_unarmored_as_req.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_sname.ad_dc >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 59db6e80c09..f167c2bf856 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -316,3 +316,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_unarmored_as_req.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_sname.ad_dc >-- >2.25.1 > > >From e62baf09869eac867b557ecef2d81cb9573f52cc Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 27 Aug 2021 13:26:45 +1200 >Subject: [PATCH 208/686] tests/krb5: Allow specifying parameters specific to > the inner FAST request body > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14770 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit c6d7e19ecfb264c6f79df5a20e830e4ea6fdb340) >--- > python/samba/tests/krb5/fast_tests.py | 4 ++++ > python/samba/tests/krb5/raw_testcase.py | 13 +++++++++++++ > 2 files changed, 17 insertions(+) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index e0fd3cc4d5e..551790a3e42 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1325,7 +1325,9 @@ class FAST_Tests(KDCBaseTest): > auth_data = None > > if not use_fast: >+ self.assertNotIn('inner_req', kdc_dict) > self.assertNotIn('outer_req', kdc_dict) >+ inner_req = kdc_dict.pop('inner_req', None) > outer_req = kdc_dict.pop('outer_req', None) > > if rep_type == KRB_AS_REP: >@@ -1355,6 +1357,7 @@ class FAST_Tests(KDCBaseTest): > armor_tgt=armor_tgt, > armor_subkey=armor_subkey, > kdc_options=kdc_options, >+ inner_req=inner_req, > outer_req=outer_req) > else: # KRB_TGS_REP > kdc_exchange_dict = self.tgs_exchange_dict( >@@ -1383,6 +1386,7 @@ class FAST_Tests(KDCBaseTest): > auth_data=auth_data, > body_checksum_type=None, > kdc_options=kdc_options, >+ inner_req=inner_req, > outer_req=outer_req) > > repeat = kdc_dict.pop('repeat', 1) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 4e7891ae89a..15873d69fa6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1553,6 +1553,9 @@ class RawKerberosTest(TestCaseInTempDir): > expected_error_mode = kdc_exchange_dict['expected_error_mode'] > kdc_options = kdc_exchange_dict['kdc_options'] > >+ # Parameters specific to the inner request body >+ inner_req = kdc_exchange_dict['inner_req'] >+ > # Parameters specific to the outer request body > outer_req = kdc_exchange_dict['outer_req'] > >@@ -1582,6 +1585,12 @@ class RawKerberosTest(TestCaseInTempDir): > EncAuthorizationData_usage=EncAuthorizationData_usage) > > inner_req_body = dict(req_body) >+ if inner_req is not None: >+ for key, value in inner_req.items(): >+ if value is not None: >+ inner_req_body[key] = value >+ else: >+ del inner_req_body[key] > if outer_req is not None: > for key, value in outer_req.items(): > if value is not None: >@@ -1734,6 +1743,7 @@ class RawKerberosTest(TestCaseInTempDir): > armor_subkey=None, > auth_data=None, > kdc_options='', >+ inner_req=None, > outer_req=None): > kdc_exchange_dict = { > 'req_msg_type': KRB_AS_REQ, >@@ -1765,6 +1775,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'armor_subkey': armor_subkey, > 'auth_data': auth_data, > 'kdc_options': kdc_options, >+ 'inner_req': inner_req, > 'outer_req': outer_req > } > if expected_cname_private is not None: >@@ -1802,6 +1813,7 @@ class RawKerberosTest(TestCaseInTempDir): > auth_data=None, > body_checksum_type=None, > kdc_options='', >+ inner_req=None, > outer_req=None): > kdc_exchange_dict = { > 'req_msg_type': KRB_TGS_REQ, >@@ -1833,6 +1845,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'auth_data': auth_data, > 'authenticator_subkey': authenticator_subkey, > 'kdc_options': kdc_options, >+ 'inner_req': inner_req, > 'outer_req': outer_req > } > if expected_cname_private is not None: >-- >2.25.1 > > >From b91242a3acb6a46a9c783b99c51da31a70d5b329 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 31 Aug 2021 19:42:33 +1200 >Subject: [PATCH 209/686] tests/krb5: Allow expected_error_mode to be a > container type > >This allows a range of possible error codes to be checked against, for >cases when the particular error code returned is not so important. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14770 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit ebd673e976aea5dd481a75f180fd526995c4fda0) >--- > python/samba/tests/krb5/raw_testcase.py | 56 +++++++++++++++---------- > 1 file changed, 35 insertions(+), 21 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 15873d69fa6..6db17f2a118 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1702,11 +1702,12 @@ class RawKerberosTest(TestCaseInTempDir): > if check_error_fn is not None: > expected_msg_type = KRB_ERROR > self.assertIsNone(check_rep_fn) >- self.assertNotEqual(0, expected_error_mode) >+ self.assertNotEqual(0, len(expected_error_mode)) >+ self.assertNotIn(0, expected_error_mode) > if check_rep_fn is not None: > expected_msg_type = rep_msg_type > self.assertIsNone(check_error_fn) >- self.assertEqual(0, expected_error_mode) >+ self.assertEqual(0, len(expected_error_mode)) > self.assertIsNotNone(expected_msg_type) > self.assertEqual(msg_type, expected_msg_type) > >@@ -1745,6 +1746,11 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_options='', > inner_req=None, > outer_req=None): >+ if expected_error_mode == 0: >+ expected_error_mode = () >+ elif not isinstance(expected_error_mode, collections.abc.Container): >+ expected_error_mode = (expected_error_mode,) >+ > kdc_exchange_dict = { > 'req_msg_type': KRB_AS_REQ, > 'req_asn1Spec': krb5_asn1.AS_REQ, >@@ -1815,6 +1821,11 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_options='', > inner_req=None, > outer_req=None): >+ if expected_error_mode == 0: >+ expected_error_mode = () >+ elif not isinstance(expected_error_mode, collections.abc.Container): >+ expected_error_mode = (expected_error_mode,) >+ > kdc_exchange_dict = { > 'req_msg_type': KRB_TGS_REQ, > 'req_asn1Spec': krb5_asn1.TGS_REQ, >@@ -1942,7 +1953,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.check_rep_padata(kdc_exchange_dict, > callback_dict, > rep, >- fast_response['padata']) >+ fast_response['padata'], >+ error_code=0) > > ticket_private = None > self.assertIsNotNone(ticket_decryption_key) >@@ -2181,7 +2193,8 @@ class RawKerberosTest(TestCaseInTempDir): > > self.assertElementEqual(rep, 'pvno', 5) > self.assertElementEqual(rep, 'msg-type', KRB_ERROR) >- self.assertElementEqual(rep, 'error-code', expected_error_mode) >+ error_code = self.getElementValue(rep, 'error-code') >+ self.assertIn(error_code, expected_error_mode) > if self.strict_checking: > self.assertElementMissing(rep, 'ctime') > self.assertElementMissing(rep, 'cusec') >@@ -2195,13 +2208,13 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertElementMissing(rep, 'cname') > self.assertElementEqualUTF8(rep, 'realm', expected_srealm) >- if sent_fast and expected_error_mode == KDC_ERR_GENERIC: >+ if sent_fast and error_code == KDC_ERR_GENERIC: > self.assertElementEqualPrincipal(rep, 'sname', > self.get_krbtgt_sname()) > else: > self.assertElementEqualPrincipal(rep, 'sname', expected_sname) > self.assertElementMissing(rep, 'e-text') >- if (expected_error_mode == KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS >+ if (error_code == KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS > or (rep_msg_type == KRB_TGS_REP > and not sent_fast) > or (sent_fast and fast_armor_type is not None >@@ -2211,7 +2224,7 @@ class RawKerberosTest(TestCaseInTempDir): > return rep > edata = self.getElementValue(rep, 'e-data') > if self.strict_checking: >- if expected_error_mode != KDC_ERR_GENERIC: >+ if error_code != KDC_ERR_GENERIC: > # Predicting whether an ERR_GENERIC error contains e-data is > # more complicated. > self.assertIsNotNone(edata) >@@ -2242,7 +2255,8 @@ class RawKerberosTest(TestCaseInTempDir): > etype_info2 = self.check_rep_padata(kdc_exchange_dict, > callback_dict, > rep, >- rep_padata) >+ rep_padata, >+ error_code) > > kdc_exchange_dict['preauth_etype_info2'] = etype_info2 > >@@ -2252,10 +2266,10 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_exchange_dict, > callback_dict, > rep, >- rep_padata): >+ rep_padata, >+ error_code): > rep_msg_type = kdc_exchange_dict['rep_msg_type'] > >- expected_error_mode = kdc_exchange_dict['expected_error_mode'] > req_body = kdc_exchange_dict['req_body'] > proposed_etypes = req_body['etype'] > client_as_etypes = kdc_exchange_dict.get('client_as_etypes', []) >@@ -2281,7 +2295,7 @@ class RawKerberosTest(TestCaseInTempDir): > if etype in (kcrypto.Enctype.AES256, kcrypto.Enctype.AES128): > if etype > expected_aes_type: > expected_aes_type = etype >- if etype in (kcrypto.Enctype.RC4,) and expected_error_mode != 0: >+ if etype in (kcrypto.Enctype.RC4,) and error_code != 0: > unexpect_etype_info = False > if etype > expected_rc4_type: > expected_rc4_type = etype >@@ -2292,25 +2306,25 @@ class RawKerberosTest(TestCaseInTempDir): > expect_etype_info2 += (expected_rc4_type,) > > expected_patypes = () >- if sent_fast and expected_error_mode != 0: >+ if sent_fast and error_code != 0: > expected_patypes += (PADATA_FX_ERROR,) > expected_patypes += (PADATA_FX_COOKIE,) > > if rep_msg_type == KRB_TGS_REP: >- if not sent_fast and expected_error_mode != 0: >+ if not sent_fast and error_code != 0: > expected_patypes += (PADATA_PW_SALT,) > else: > sent_claims = self.sent_claims(kdc_exchange_dict) >- if sent_claims and expected_error_mode not in (0, KDC_ERR_GENERIC): >+ if sent_claims and error_code not in (0, KDC_ERR_GENERIC): > expected_patypes += (PADATA_PAC_OPTIONS,) >- elif expected_error_mode != KDC_ERR_GENERIC: >+ elif error_code != KDC_ERR_GENERIC: > if expect_etype_info: > self.assertGreater(len(expect_etype_info2), 0) > expected_patypes += (PADATA_ETYPE_INFO,) > if len(expect_etype_info2) != 0: > expected_patypes += (PADATA_ETYPE_INFO2,) > >- if expected_error_mode != KDC_ERR_PREAUTH_FAILED: >+ if error_code != KDC_ERR_PREAUTH_FAILED: > if sent_fast: > expected_patypes += (PADATA_ENCRYPTED_CHALLENGE,) > else: >@@ -2493,7 +2507,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNone(pk_as_rep19) > return None > >- if expected_error_mode != KDC_ERR_GENERIC: >+ if error_code != KDC_ERR_GENERIC: > if self.strict_checking: > self.assertIsNotNone(etype_info2) > else: >@@ -2506,7 +2520,7 @@ class RawKerberosTest(TestCaseInTempDir): > if unexpect_etype_info: > self.assertIsNone(etype_info) > >- if expected_error_mode != KDC_ERR_GENERIC and self.strict_checking: >+ if error_code != KDC_ERR_GENERIC and self.strict_checking: > self.assertGreaterEqual(len(etype_info2), 1) > self.assertEqual(len(etype_info2), len(expect_etype_info2)) > for i in range(0, len(etype_info2)): >@@ -2533,8 +2547,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(salt) > self.assertEqual(len(salt), 0) > >- if expected_error_mode not in (KDC_ERR_PREAUTH_FAILED, >- KDC_ERR_GENERIC): >+ if error_code not in (KDC_ERR_PREAUTH_FAILED, >+ KDC_ERR_GENERIC): > if sent_fast: > self.assertIsNotNone(enc_challenge) > if self.strict_checking: >@@ -2799,7 +2813,7 @@ class RawKerberosTest(TestCaseInTempDir): > as_rep_usage = KU_AS_REP_ENC_PART > return preauth_key, as_rep_usage > >- if expected_error_mode == 0: >+ if not expected_error_mode: > check_error_fn = None > check_rep_fn = self.generic_check_kdc_rep > else: >-- >2.25.1 > > >From 4670576da39fcdf79224e1fc98f46aa15c6f377f Mon Sep 17 00:00:00 2001 >From: Luke Howard <lukeh@padl.com> >Date: Tue, 31 Aug 2021 17:38:16 +1200 >Subject: [PATCH 210/686] kdc: KRB5KDC_ERR_{C,S}_PRINCIPAL_UNKNOWN if missing > field > >If missing cname or sname in AS-REQ, return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN and >KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN. This matches MIT behaviour. > >[abartlet@samba.org Backported from Heimdal commit 892a1ffcaad98157e945c540b81f65edb14d29bd >and knownfail added. Further adapted knownfail for 4.14 due to conflicts >as the patch that adds a test which crashes old MIT versions is >omitted] > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14770 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >--- > selftest/knownfail_heimdal_kdc | 1 + > source4/heimdal/kdc/kerberos5.c | 4 ++-- > 2 files changed, 3 insertions(+), 2 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index b0981a06002..f5ac4fa2e2b 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -123,3 +123,4 @@ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_no_sname.ad_dc >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index 27d38ad84b7..0fa336e871c 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -996,7 +996,7 @@ _kdc_as_rep(krb5_context context, > flags |= HDB_F_CANON; > > if(b->sname == NULL){ >- ret = KRB5KRB_ERR_GENERIC; >+ ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; > e_text = "No server in request"; > } else{ > ret = _krb5_principalname2krb5_principal (context, >@@ -1012,7 +1012,7 @@ _kdc_as_rep(krb5_context context, > goto out; > } > if(b->cname == NULL){ >- ret = KRB5KRB_ERR_GENERIC; >+ ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; > e_text = "No client in request"; > } else { > ret = _krb5_principalname2krb5_principal (context, >-- >2.25.1 > > >From c3cdd677196832e025ed2b1eca85df0150475628 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 31 Aug 2021 22:38:01 +1200 >Subject: [PATCH 211/686] tests/krb5: Allow KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN for > a missing sname > >This allows our code to still pass with the error code that >MIT and Heimdal have chosen > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14770 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14817 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> > >Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org> >Autobuild-Date(master): Thu Sep 2 14:28:31 UTC 2021 on sn-devel-184 > >[abartlet@samba.org: Backported from 10baaf08523200e47451aa1862430977b0365b59 > to Samba 4.14 due to conflicts in > knownfail as the test which crashes older MIT KDC versions is > omitted] > >Autobuild-User(v4-13-test): Jule Anger <janger@samba.org> >Autobuild-Date(v4-13-test): Thu Sep 16 08:54:13 UTC 2021 on sn-devel-184 >--- > python/samba/tests/krb5/fast_tests.py | 23 +++++++++++++------- > python/samba/tests/krb5/kdc_base_test.py | 6 ++++- > python/samba/tests/krb5/rfc4120_constants.py | 1 + > selftest/knownfail_heimdal_kdc | 3 --- > 4 files changed, 21 insertions(+), 12 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 551790a3e42..2d4b69f8590 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -20,6 +20,7 @@ > import functools > import os > import sys >+import collections > > import ldb > >@@ -37,6 +38,7 @@ from samba.tests.krb5.rfc4120_constants import ( > FX_FAST_ARMOR_AP_REQUEST, > KDC_ERR_ETYPE_NOSUPP, > KDC_ERR_GENERIC, >+ KDC_ERR_S_PRINCIPAL_UNKNOWN, > KDC_ERR_NOT_US, > KDC_ERR_PREAUTH_FAILED, > KDC_ERR_PREAUTH_REQUIRED, >@@ -115,7 +117,7 @@ class FAST_Tests(KDCBaseTest): > self._run_test_sequence([ > { > 'rep_type': KRB_AS_REP, >- 'expected_error_mode': KDC_ERR_GENERIC, >+ 'expected_error_mode': (KDC_ERR_GENERIC, KDC_ERR_S_PRINCIPAL_UNKNOWN), > 'use_fast': False, > 'sname': None, > 'expected_sname': expected_sname >@@ -132,7 +134,7 @@ class FAST_Tests(KDCBaseTest): > self._run_test_sequence([ > { > 'rep_type': KRB_TGS_REP, >- 'expected_error_mode': KDC_ERR_GENERIC, >+ 'expected_error_mode': (KDC_ERR_GENERIC, KDC_ERR_S_PRINCIPAL_UNKNOWN), > 'use_fast': False, > 'gen_tgt_fn': self.get_user_tgt, > 'sname': None, >@@ -169,7 +171,7 @@ class FAST_Tests(KDCBaseTest): > self._run_test_sequence([ > { > 'rep_type': KRB_TGS_REP, >- 'expected_error_mode': KDC_ERR_GENERIC, >+ 'expected_error_mode': (KDC_ERR_GENERIC, KDC_ERR_S_PRINCIPAL_UNKNOWN), > 'use_fast': True, > 'gen_tgt_fn': self.get_user_tgt, > 'fast_armor': None, >@@ -1147,7 +1149,12 @@ class FAST_Tests(KDCBaseTest): > self.assertIn(rep_type, (KRB_AS_REP, KRB_TGS_REP)) > > expected_error_mode = kdc_dict.pop('expected_error_mode') >- self.assertIn(expected_error_mode, range(240)) >+ if expected_error_mode == 0: >+ expected_error_mode = () >+ elif not isinstance(expected_error_mode, collections.abc.Container): >+ expected_error_mode = (expected_error_mode,) >+ for error in expected_error_mode: >+ self.assertIn(error, range(240)) > > use_fast = kdc_dict.pop('use_fast') > self.assertIs(type(use_fast), bool) >@@ -1158,7 +1165,7 @@ class FAST_Tests(KDCBaseTest): > > if fast_armor_type is not None: > self.assertIn('gen_armor_tgt_fn', kdc_dict) >- elif expected_error_mode != KDC_ERR_GENERIC: >+ elif KDC_ERR_GENERIC not in expected_error_mode: > self.assertNotIn('gen_armor_tgt_fn', kdc_dict) > > gen_armor_tgt_fn = kdc_dict.pop('gen_armor_tgt_fn', None) >@@ -1182,7 +1189,7 @@ class FAST_Tests(KDCBaseTest): > self.assertNotIn('gen_tgt_fn', kdc_dict) > tgt = None > >- if expected_error_mode != 0: >+ if len(expected_error_mode) != 0: > check_error_fn = self.generic_check_kdc_error > check_rep_fn = None > else: >@@ -1396,7 +1403,7 @@ class FAST_Tests(KDCBaseTest): > realm=crealm, > sname=sname, > etypes=etypes) >- if expected_error_mode == 0: >+ if len(expected_error_mode) == 0: > self.check_reply(rep, rep_type) > > fast_cookie = None >@@ -1410,7 +1417,7 @@ class FAST_Tests(KDCBaseTest): > else: > fast_cookie = None > >- if expected_error_mode == KDC_ERR_PREAUTH_REQUIRED: >+ if KDC_ERR_PREAUTH_REQUIRED in expected_error_mode: > preauth_etype_info2 = ( > kdc_exchange_dict['preauth_etype_info2']) > else: >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index b148fa01f65..f5c1eba9151 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -21,6 +21,7 @@ import os > from datetime import datetime, timezone > import tempfile > import binascii >+import collections > > from collections import namedtuple > import ldb >@@ -598,7 +599,10 @@ class KDCBaseTest(RawKerberosTest): > """ > self.assertIsNotNone(rep) > self.assertEqual(rep['msg-type'], KRB_ERROR, "rep = {%s}" % rep) >- self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep) >+ if isinstance(expected, collections.abc.Container): >+ self.assertIn(rep['error-code'], expected, "rep = {%s}" % rep) >+ else: >+ self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep) > > def tgs_req(self, cname, sname, realm, ticket, key, etypes): > '''Send a TGS-REQ, returns the response and the decrypted and >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index c70ce309b95..ac2bac4d91e 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -67,6 +67,7 @@ PADATA_SUPPORTED_ETYPES = int( > > # Error codes > KDC_ERR_C_PRINCIPAL_UNKNOWN = 6 >+KDC_ERR_S_PRINCIPAL_UNKNOWN = 7 > KDC_ERR_POLICY = 12 > KDC_ERR_ETYPE_NOSUPP = 14 > KDC_ERR_PREAUTH_FAILED = 24 >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index f5ac4fa2e2b..80b8224f015 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -121,6 +121,3 @@ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_sname.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_sname.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_sname.ad_dc >-^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_no_sname.ad_dc >-- >2.25.1 > > >From 83a9c951cf662096272f6ab66275b655ac338d10 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 14 Sep 2021 11:08:41 +1200 >Subject: [PATCH 212/686] ldb_msg: Don't fail in ldb_msg_copy() if source DN is > NULL > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14645 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14836 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14848 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit c2bbe774ce03661666a1f48922a9ab681ef4f64b) >--- > lib/ldb/common/ldb_msg.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c >index b51e4b1059e..e21dac81b6a 100644 >--- a/lib/ldb/common/ldb_msg.c >+++ b/lib/ldb/common/ldb_msg.c >@@ -876,8 +876,10 @@ struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, > msg2 = ldb_msg_copy_shallow(mem_ctx, msg); > if (msg2 == NULL) return NULL; > >- msg2->dn = ldb_dn_copy(msg2, msg2->dn); >- if (msg2->dn == NULL) goto failed; >+ if (msg2->dn != NULL) { >+ msg2->dn = ldb_dn_copy(msg2, msg2->dn); >+ if (msg2->dn == NULL) goto failed; >+ } > > for (i=0;i<msg2->num_elements;i++) { > struct ldb_message_element *el = &msg2->elements[i]; >-- >2.25.1 > > >From 2154361debe2558ddc6739c3dc052dbd1187fd40 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 11:15:17 +1200 >Subject: [PATCH 213/686] pyldb: Avoid use-after-free in msg_diff() > >Make a deep copy of the message elements in msg_diff() so that if either >of the input messages are deallocated early, the result does not refer >to non-existing elements. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14645 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14836 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14848 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[abartlet@samba.org backported from commit > 19a2af02f57d99db8ed3c6b028c3abdf4b553700 due to conflicts in > the knownfail.d/python-segfaults file] > >Autobuild-User(v4-14-test): Jule Anger <janger@samba.org> >Autobuild-Date(v4-14-test): Wed Sep 29 13:14:22 UTC 2021 on sn-devel-184 > >[jsutton@samba.org Adapted to fix conflicts and remove non-existing > knownfail.d/python-segfaults file] >--- > lib/ldb/pyldb.c | 18 ++++++++++++++++-- > 1 file changed, 16 insertions(+), 2 deletions(-) > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index 92a4e206feb..7c34810795a 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -1811,6 +1811,7 @@ static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args) > struct ldb_message *diff; > struct ldb_context *ldb; > PyObject *py_ret; >+ TALLOC_CTX *mem_ctx = NULL; > > if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new)) > return NULL; >@@ -1825,19 +1826,32 @@ static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args) > return NULL; > } > >+ mem_ctx = talloc_new(NULL); >+ if (mem_ctx == NULL) { >+ PyErr_NoMemory(); >+ return NULL; >+ } >+ > ldb = pyldb_Ldb_AsLdbContext(self); >- ldb_ret = ldb_msg_difference(ldb, ldb, >+ ldb_ret = ldb_msg_difference(ldb, mem_ctx, > pyldb_Message_AsMessage(py_msg_old), > pyldb_Message_AsMessage(py_msg_new), > &diff); > if (ldb_ret != LDB_SUCCESS) { >+ talloc_free(mem_ctx); > PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff"); > return NULL; > } > >+ diff = ldb_msg_copy(mem_ctx, diff); >+ if (diff == NULL) { >+ PyErr_NoMemory(); >+ return NULL; >+ } >+ > py_ret = PyLdbMessage_FromMessage(diff); > >- talloc_unlink(ldb, diff); >+ talloc_free(mem_ctx); > > return py_ret; > } >-- >2.25.1 > > >From 60894b2f304980422e43b9ccbb4d697aae366ded Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 28 Apr 2021 16:48:55 +1200 >Subject: [PATCH 214/686] Fix Python docstrings > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14848 > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Sat Sep 4 00:55:32 UTC 2021 on sn-devel-184 > >(cherry picked from commit 02b187303369d3ce0c19dfb72ffa78f86a3911f0) >--- > lib/ldb/pyldb.c | 2 +- > lib/tdb/pytdb.c | 2 +- > lib/tevent/pytevent.c | 2 +- > source4/librpc/ndr/py_security.c | 2 +- > 4 files changed, 4 insertions(+), 4 deletions(-) > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index 7c34810795a..da1361c0c96 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -863,7 +863,7 @@ static PyMethodDef py_ldb_dn_methods[] = { > "S.get_component_value(num) -> string\n" > "get the attribute value of the specified component as a binary string" }, > { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS, >- "S.get_component_value(num, name, value) -> None\n" >+ "S.set_component(num, name, value) -> None\n" > "set the attribute name and value of the specified component" }, > { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS, > "S.get_rdn_name() -> string\n" >diff --git a/lib/tdb/pytdb.c b/lib/tdb/pytdb.c >index babd6071f10..78a20cc09c4 100644 >--- a/lib/tdb/pytdb.c >+++ b/lib/tdb/pytdb.c >@@ -521,7 +521,7 @@ static PyMethodDef tdb_object_methods[] = { > { "add_flags", (PyCFunction)obj_add_flags, METH_VARARGS, "S.add_flags(flags) -> None" }, > { "remove_flags", (PyCFunction)obj_remove_flags, METH_VARARGS, "S.remove_flags(flags) -> None" }, > #if PY_MAJOR_VERSION >= 3 >- { "keys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.iterkeys() -> iterator" }, >+ { "keys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.keys() -> iterator" }, > #else > { "iterkeys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.iterkeys() -> iterator" }, > #endif >diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c >index 97976df32d3..a46ba02b575 100644 >--- a/lib/tevent/pytevent.c >+++ b/lib/tevent/pytevent.c >@@ -567,7 +567,7 @@ static PyMethodDef py_tevent_context_methods[] = { > { "add_timer", (PyCFunction)py_tevent_context_add_timer, > METH_VARARGS, "S.add_timer(next_event, handler) -> timer" }, > { "add_timer_offset", (PyCFunction)py_tevent_context_add_timer_offset, >- METH_VARARGS, "S.add_timer(offset_seconds, handler) -> timer" }, >+ METH_VARARGS, "S.add_timer_offset(offset_seconds, handler) -> timer" }, > { "add_fd", (PyCFunction)py_tevent_context_add_fd, > METH_VARARGS, "S.add_fd(fd, flags, handler) -> fd" }, > { NULL }, >diff --git a/source4/librpc/ndr/py_security.c b/source4/librpc/ndr/py_security.c >index 37c6a57e00e..f6094339457 100644 >--- a/source4/librpc/ndr/py_security.c >+++ b/source4/librpc/ndr/py_security.c >@@ -442,7 +442,7 @@ static PyMethodDef py_token_extra_methods[] = { > { "has_sid", (PyCFunction)py_token_has_sid, METH_VARARGS, > NULL }, > { "is_anonymous", (PyCFunction)py_token_is_anonymous, METH_NOARGS, >- "S.is_anonymus() -> bool\n" >+ "S.is_anonymous() -> bool\n" > "Check whether this is an anonymous token." }, > { "is_system", (PyCFunction)py_token_is_system, METH_NOARGS, > NULL }, >-- >2.25.1 > > >From 13314faa4fdc9b22739b016e83fc3f84f8030d1d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Sat, 25 Sep 2021 11:12:16 +1200 >Subject: [PATCH 215/686] pyldb: Fix deleting an ldb.Message dn > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14848 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org backported from commit d7af772de88885f46708329ff7bb5798da91d2c7 > due to conflicts in knownfail.d/python-segfaults] > >[jsutton@samba.org Adapted to remove knownfails in non-existing > knownfail.d/python-segfaults file] >--- > lib/ldb/pyldb.c | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index da1361c0c96..22af65e4bfb 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -3728,6 +3728,10 @@ static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure) > static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure) > { > struct ldb_message *msg = pyldb_Message_AsMessage(self); >+ if (value == NULL) { >+ PyErr_SetString(PyExc_AttributeError, "cannot delete dn"); >+ return -1; >+ } > if (!pyldb_Dn_Check(value)) { > PyErr_SetString(PyExc_TypeError, "expected dn"); > return -1; >-- >2.25.1 > > >From 705c61590de2f74804648056f428c7d6b628c90c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Sat, 25 Sep 2021 11:16:09 +1200 >Subject: [PATCH 216/686] pyldb: Fix deleting an ldb.Control critical flag > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14848 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 9d25a21d6024c6c2f8e4634f45e3944d8acbf8b8) > >[jsutton@samba.org Adapted to remove knownfails in non-existing > knownfail.d/python-segfaults file] >--- > lib/ldb/pyldb.c | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index 22af65e4bfb..426f6ecef55 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -206,6 +206,10 @@ static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self, > > static int py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure) > { >+ if (value == NULL) { >+ PyErr_SetString(PyExc_AttributeError, "cannot delete critical flag"); >+ return -1; >+ } > if (PyObject_IsTrue(value)) { > self->data->critical = true; > } else { >-- >2.25.1 > > >From 216990027febf305eb21491ca0479f0391e3722e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Sat, 25 Sep 2021 19:18:39 +1200 >Subject: [PATCH 217/686] s4/torture/drs/python: Fix attribute existence check > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14848 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org backported from commit fb758c32e7633178f42dc2c031667b10c2ca6e90 > due to assertEquals vs assertEqual on the previous line] >--- > source4/torture/drs/python/replica_sync.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source4/torture/drs/python/replica_sync.py b/source4/torture/drs/python/replica_sync.py >index 03292b57805..f787c8f0f11 100644 >--- a/source4/torture/drs/python/replica_sync.py >+++ b/source4/torture/drs/python/replica_sync.py >@@ -140,7 +140,7 @@ objectClass: organizationalUnit > # now check properties of the user > name_cur = ou_cur["ou"][0] > self.assertEquals(ou_cur["isDeleted"][0], b"TRUE") >- self.assertTrue(not(b"objectCategory" in ou_cur)) >+ self.assertTrue(not("objectCategory" in ou_cur)) > self.assertTrue(dodn in str(ou_cur["dn"]), > "OU %s is deleted but it is not located under %s!" % (name_cur, dodn)) > >-- >2.25.1 > > >From dbf383b7607727a186239e1a3029097f93a5902f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Sat, 25 Sep 2021 13:22:05 +1200 >Subject: [PATCH 218/686] pyldb: Add test for an invalid ldb.Message index type > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14848 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit b018e51d2725a23b2fedd3058644b8021f6a6a06) >--- > lib/ldb/tests/python/api.py | 6 ++++++ > selftest/knownfail.d/pyldb | 1 + > 2 files changed, 7 insertions(+) > create mode 100644 selftest/knownfail.d/pyldb > >diff --git a/lib/ldb/tests/python/api.py b/lib/ldb/tests/python/api.py >index e8826b5af3b..cae1b6c8ffd 100755 >--- a/lib/ldb/tests/python/api.py >+++ b/lib/ldb/tests/python/api.py >@@ -2332,6 +2332,12 @@ class LdbMsgTests(TestCase): > def test_notpresent(self): > self.assertRaises(KeyError, lambda: self.msg["foo"]) > >+ def test_invalid(self): >+ try: >+ self.assertRaises(TypeError, lambda: self.msg[42]) >+ except KeyError: >+ self.fail() >+ > def test_del(self): > del self.msg["foo"] > >diff --git a/selftest/knownfail.d/pyldb b/selftest/knownfail.d/pyldb >new file mode 100644 >index 00000000000..8d24c4515d3 >--- /dev/null >+++ b/selftest/knownfail.d/pyldb >@@ -0,0 +1 @@ >+^ldb.python.api.LdbMsgTests.test_invalid >-- >2.25.1 > > >From b0883169807ca5b410116b84537270b4371268e6 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Sat, 25 Sep 2021 13:39:56 +1200 >Subject: [PATCH 219/686] pyldb: Raise TypeError for an invalid ldb.Message > index > >Previously, a TypeError was raised and subsequently overridden by a >KeyError. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14848 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 22353767ca75af9d9e8fa1e7da372dcb5eddfcb7) >--- > lib/ldb/pyldb.c | 22 +++++++--------------- > selftest/knownfail.d/pyldb | 1 - > 2 files changed, 7 insertions(+), 16 deletions(-) > delete mode 100644 selftest/knownfail.d/pyldb > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index 426f6ecef55..b30f011a80a 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -3424,33 +3424,25 @@ static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self, > return obj; > } > >-static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name) >+static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name) > { >- struct ldb_message_element *el; >- const char *name; >+ struct ldb_message_element *el = NULL; >+ const char *name = NULL; > struct ldb_message *msg = pyldb_Message_AsMessage(self); > name = PyStr_AsUTF8(py_name); > if (name == NULL) { >- PyErr_SetNone(PyExc_TypeError); > return NULL; > } >- if (!ldb_attr_cmp(name, "dn")) >+ if (!ldb_attr_cmp(name, "dn")) { > return pyldb_Dn_FromDn(msg->dn); >+ } > el = ldb_msg_find_element(msg, name); > if (el == NULL) { >- return NULL; >- } >- return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements); >-} >- >-static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name) >-{ >- PyObject *ret = py_ldb_msg_getitem_helper(self, py_name); >- if (ret == NULL) { > PyErr_SetString(PyExc_KeyError, "No such element"); > return NULL; > } >- return ret; >+ >+ return PyLdbMessageElement_FromMessageElement(el, msg->elements); > } > > static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs) >diff --git a/selftest/knownfail.d/pyldb b/selftest/knownfail.d/pyldb >deleted file mode 100644 >index 8d24c4515d3..00000000000 >--- a/selftest/knownfail.d/pyldb >+++ /dev/null >@@ -1 +0,0 @@ >-^ldb.python.api.LdbMsgTests.test_invalid >-- >2.25.1 > > >From 8229b909513bcd2e1285d7346c74e960e0477ce3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Sat, 25 Sep 2021 13:48:57 +1200 >Subject: [PATCH 220/686] pyldb: Add tests for ldb.Message containment testing > >These tests verify that the 'in' operator on ldb.Message is consistent >with indexing and the get() method. This means that the 'dn' element >should always be present, lookups should be case-insensitive, and use of >an invalid type should result in a TypeError. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14848 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 865fe238599a732360b77e06e592cb85d459acf8) >--- > lib/ldb/tests/python/api.py | 23 +++++++++++++++++++++++ > selftest/knownfail.d/pyldb | 4 ++++ > 2 files changed, 27 insertions(+) > create mode 100644 selftest/knownfail.d/pyldb > >diff --git a/lib/ldb/tests/python/api.py b/lib/ldb/tests/python/api.py >index cae1b6c8ffd..40f7b1ceb66 100755 >--- a/lib/ldb/tests/python/api.py >+++ b/lib/ldb/tests/python/api.py >@@ -2453,6 +2453,29 @@ class LdbMsgTests(TestCase): > def test_get_unknown_text(self): > self.assertEqual(None, self.msg.text.get("lalalala")) > >+ def test_contains(self): >+ self.msg['foo'] = ['bar'] >+ self.assertIn('foo', self.msg) >+ >+ self.msg['Foo'] = ['bar'] >+ self.assertIn('Foo', self.msg) >+ >+ def test_contains_case(self): >+ self.msg['foo'] = ['bar'] >+ self.assertIn('Foo', self.msg) >+ >+ self.msg['Foo'] = ['bar'] >+ self.assertIn('foo', self.msg) >+ >+ def test_contains_dn(self): >+ self.assertIn('dn', self.msg) >+ >+ def test_contains_dn_case(self): >+ self.assertIn('DN', self.msg) >+ >+ def test_contains_invalid(self): >+ self.assertRaises(TypeError, lambda: None in self.msg) >+ > def test_msg_diff(self): > l = ldb.Ldb() > msgs = l.parse_ldif("dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n") >diff --git a/selftest/knownfail.d/pyldb b/selftest/knownfail.d/pyldb >new file mode 100644 >index 00000000000..34bdac4f682 >--- /dev/null >+++ b/selftest/knownfail.d/pyldb >@@ -0,0 +1,4 @@ >+^ldb.python.api.LdbMsgTests.test_contains_case >+^ldb.python.api.LdbMsgTests.test_contains_dn >+^ldb.python.api.LdbMsgTests.test_contains_dn_case >+^ldb.python.api.LdbMsgTests.test_contains_invalid >-- >2.25.1 > > >From c0b8f183dbf83cf04d42e29d09304e18ff147dcb Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Sat, 25 Sep 2021 14:39:59 +1200 >Subject: [PATCH 221/686] pyldb: Make ldb.Message containment testing > consistent with indexing > >Previously, containment testing using the 'in' operator was handled by >performing an equality comparison between the chosen object and each of >the message's keys in turn. This behaviour was prone to errors due to >not considering differences in case between otherwise equal elements, as >the indexing operations do. > >Containment testing should now be more consistent with the indexing >operations and with the get() method of ldb.Message. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14848 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 860d8902a9c502d4be83396598cf4a53c80fea69) > >[jsutton@samba.org Adapted PyUnicode_AsUTF8() to PyStr_AsUTF8()] >--- > lib/ldb/pyldb.c | 21 +++++++++++++++++++++ > selftest/knownfail.d/pyldb | 4 ---- > 2 files changed, 21 insertions(+), 4 deletions(-) > delete mode 100644 selftest/knownfail.d/pyldb > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index b30f011a80a..0c6e5ad857f 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -3424,6 +3424,22 @@ static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self, > return obj; > } > >+static int py_ldb_msg_contains(PyLdbMessageObject *self, PyObject *py_name) >+{ >+ struct ldb_message_element *el = NULL; >+ const char *name = NULL; >+ struct ldb_message *msg = pyldb_Message_AsMessage(self); >+ name = PyStr_AsUTF8(py_name); >+ if (name == NULL) { >+ return -1; >+ } >+ if (!ldb_attr_cmp(name, "dn")) { >+ return 1; >+ } >+ el = ldb_msg_find_element(msg, name); >+ return el != NULL ? 1 : 0; >+} >+ > static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name) > { > struct ldb_message_element *el = NULL; >@@ -3648,6 +3664,10 @@ static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self) > return pyldb_Message_AsMessage(self)->num_elements; > } > >+static PySequenceMethods py_ldb_msg_sequence = { >+ .sq_contains = (objobjproc)py_ldb_msg_contains, >+}; >+ > static PyMappingMethods py_ldb_msg_mapping = { > .mp_length = (lenfunc)py_ldb_msg_length, > .mp_subscript = (binaryfunc)py_ldb_msg_getitem, >@@ -3825,6 +3845,7 @@ static PyTypeObject PyLdbMessage = { > .tp_name = "ldb.Message", > .tp_methods = py_ldb_msg_methods, > .tp_getset = py_ldb_msg_getset, >+ .tp_as_sequence = &py_ldb_msg_sequence, > .tp_as_mapping = &py_ldb_msg_mapping, > .tp_basicsize = sizeof(PyLdbMessageObject), > .tp_dealloc = (destructor)py_ldb_msg_dealloc, >diff --git a/selftest/knownfail.d/pyldb b/selftest/knownfail.d/pyldb >deleted file mode 100644 >index 34bdac4f682..00000000000 >--- a/selftest/knownfail.d/pyldb >+++ /dev/null >@@ -1,4 +0,0 @@ >-^ldb.python.api.LdbMsgTests.test_contains_case >-^ldb.python.api.LdbMsgTests.test_contains_dn >-^ldb.python.api.LdbMsgTests.test_contains_dn_case >-^ldb.python.api.LdbMsgTests.test_contains_invalid >-- >2.25.1 > > >From 3eea8fb0ef78ffdfd7bed88508e319c746044d5a Mon Sep 17 00:00:00 2001 >From: David Mulder <dmulder@suse.com> >Date: Mon, 14 Sep 2020 11:12:37 -0600 >Subject: [PATCH 222/686] python: Move dsdb_Dn to samdb > >The import dsdb needed for dsdb_Dn causes import >errors when trying to import get_bytes/get_string >in some places. > >Signed-off-by: David Mulder <dmulder@suse.com> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >[abartlet@samba.org backported from commit 85d2ff2f0003b106ca84866b7e7893723f1dd93c > as the PY2 compat code is still in place in Samba 4.13] >--- > python/samba/common.py | 79 ------------------------- > python/samba/dbchecker.py | 2 +- > python/samba/kcc/kcc_utils.py | 2 +- > python/samba/kcc/ldif_import_export.py | 3 +- > python/samba/samdb.py | 75 +++++++++++++++++++++++ > python/samba/tests/common.py | 4 +- > source4/torture/drs/python/repl_rodc.py | 2 +- > 7 files changed, 81 insertions(+), 86 deletions(-) > >diff --git a/python/samba/common.py b/python/samba/common.py >index 8876e4f4faa..a8faa90065d 100644 >--- a/python/samba/common.py >+++ b/python/samba/common.py >@@ -16,13 +16,6 @@ > # along with this program. If not, see <http://www.gnu.org/licenses/>. > # > >- >-import ldb >-from samba import dsdb >-from samba.ndr import ndr_pack >-from samba.dcerpc import misc >-import binascii >- > from samba.compat import PY3 > > >@@ -74,75 +67,3 @@ def normalise_int32(ivalue): > return str(ivalue) > > >-class dsdb_Dn(object): >- '''a class for binary DN''' >- >- def __init__(self, samdb, dnstring, syntax_oid=None): >- '''create a dsdb_Dn''' >- if syntax_oid is None: >- # auto-detect based on string >- if dnstring.startswith("B:"): >- syntax_oid = dsdb.DSDB_SYNTAX_BINARY_DN >- elif dnstring.startswith("S:"): >- syntax_oid = dsdb.DSDB_SYNTAX_STRING_DN >- else: >- syntax_oid = dsdb.DSDB_SYNTAX_OR_NAME >- if syntax_oid in [dsdb.DSDB_SYNTAX_BINARY_DN, dsdb.DSDB_SYNTAX_STRING_DN]: >- # it is a binary DN >- colons = dnstring.split(':') >- if len(colons) < 4: >- raise RuntimeError("Invalid DN %s" % dnstring) >- prefix_len = 4 + len(colons[1]) + int(colons[1]) >- self.prefix = dnstring[0:prefix_len] >- self.binary = self.prefix[3 + len(colons[1]):-1] >- self.dnstring = dnstring[prefix_len:] >- else: >- self.dnstring = dnstring >- self.prefix = '' >- self.binary = '' >- self.dn = ldb.Dn(samdb, self.dnstring) >- >- def __str__(self): >- return self.prefix + str(self.dn.extended_str(mode=1)) >- >- def __cmp__(self, other): >- ''' compare dsdb_Dn values similar to parsed_dn_compare()''' >- dn1 = self >- dn2 = other >- guid1 = dn1.dn.get_extended_component("GUID") >- guid2 = dn2.dn.get_extended_component("GUID") >- >- v = cmp(guid1, guid2) >- if v != 0: >- return v >- v = cmp(dn1.binary, dn2.binary) >- return v >- >- # In Python3, __cmp__ is replaced by these 6 methods >- def __eq__(self, other): >- return self.__cmp__(other) == 0 >- >- def __ne__(self, other): >- return self.__cmp__(other) != 0 >- >- def __lt__(self, other): >- return self.__cmp__(other) < 0 >- >- def __le__(self, other): >- return self.__cmp__(other) <= 0 >- >- def __gt__(self, other): >- return self.__cmp__(other) > 0 >- >- def __ge__(self, other): >- return self.__cmp__(other) >= 0 >- >- def get_binary_integer(self): >- '''return binary part of a dsdb_Dn as an integer, or None''' >- if self.prefix == '': >- return None >- return int(self.binary, 16) >- >- def get_bytes(self): >- '''return binary as a byte string''' >- return binascii.unhexlify(self.binary) >diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py >index 3677564fea0..326aa4158f5 100644 >--- a/python/samba/dbchecker.py >+++ b/python/samba/dbchecker.py >@@ -28,7 +28,7 @@ from samba.dcerpc import misc > from samba.dcerpc import drsuapi > from samba.ndr import ndr_unpack, ndr_pack > from samba.dcerpc import drsblobs >-from samba.common import dsdb_Dn >+from samba.samdb import dsdb_Dn > from samba.dcerpc import security > from samba.descriptor import get_wellknown_sds, get_diff_sds > from samba.auth import system_session, admin_session >diff --git a/python/samba/kcc/kcc_utils.py b/python/samba/kcc/kcc_utils.py >index ef4d706c8e2..99a0c9155bd 100644 >--- a/python/samba/kcc/kcc_utils.py >+++ b/python/samba/kcc/kcc_utils.py >@@ -29,7 +29,7 @@ from samba.dcerpc import ( > drsuapi, > misc, > ) >-from samba.common import dsdb_Dn >+from samba.samdb import dsdb_Dn > from samba.ndr import ndr_unpack, ndr_pack > from collections import defaultdict > >diff --git a/python/samba/kcc/ldif_import_export.py b/python/samba/kcc/ldif_import_export.py >index 86453f1e5c9..7ec553edcb9 100644 >--- a/python/samba/kcc/ldif_import_export.py >+++ b/python/samba/kcc/ldif_import_export.py >@@ -23,8 +23,7 @@ import os > > from samba import Ldb, ldb, read_and_sub_file > from samba.auth import system_session >-from samba.samdb import SamDB >-from samba.common import dsdb_Dn >+from samba.samdb import SamDB, dsdb_Dn > > > class LdifError(Exception): >diff --git a/python/samba/samdb.py b/python/samba/samdb.py >index 0d76d98783e..70d0ca1506b 100644 >--- a/python/samba/samdb.py >+++ b/python/samba/samdb.py >@@ -35,7 +35,9 @@ from samba.common import normalise_int32 > from samba.compat import text_type > from samba.compat import binary_type > from samba.compat import get_bytes >+from samba.common import cmp > from samba.dcerpc import security >+import binascii > > __docformat__ = "restructuredText" > >@@ -1140,3 +1142,76 @@ schemaUpdateNow: 1 > if not full_dn.is_child_of(domain_dn): > full_dn.add_base(domain_dn) > return full_dn >+ >+class dsdb_Dn(object): >+ '''a class for binary DN''' >+ >+ def __init__(self, samdb, dnstring, syntax_oid=None): >+ '''create a dsdb_Dn''' >+ if syntax_oid is None: >+ # auto-detect based on string >+ if dnstring.startswith("B:"): >+ syntax_oid = dsdb.DSDB_SYNTAX_BINARY_DN >+ elif dnstring.startswith("S:"): >+ syntax_oid = dsdb.DSDB_SYNTAX_STRING_DN >+ else: >+ syntax_oid = dsdb.DSDB_SYNTAX_OR_NAME >+ if syntax_oid in [dsdb.DSDB_SYNTAX_BINARY_DN, dsdb.DSDB_SYNTAX_STRING_DN]: >+ # it is a binary DN >+ colons = dnstring.split(':') >+ if len(colons) < 4: >+ raise RuntimeError("Invalid DN %s" % dnstring) >+ prefix_len = 4 + len(colons[1]) + int(colons[1]) >+ self.prefix = dnstring[0:prefix_len] >+ self.binary = self.prefix[3 + len(colons[1]):-1] >+ self.dnstring = dnstring[prefix_len:] >+ else: >+ self.dnstring = dnstring >+ self.prefix = '' >+ self.binary = '' >+ self.dn = ldb.Dn(samdb, self.dnstring) >+ >+ def __str__(self): >+ return self.prefix + str(self.dn.extended_str(mode=1)) >+ >+ def __cmp__(self, other): >+ ''' compare dsdb_Dn values similar to parsed_dn_compare()''' >+ dn1 = self >+ dn2 = other >+ guid1 = dn1.dn.get_extended_component("GUID") >+ guid2 = dn2.dn.get_extended_component("GUID") >+ >+ v = cmp(guid1, guid2) >+ if v != 0: >+ return v >+ v = cmp(dn1.binary, dn2.binary) >+ return v >+ >+ # In Python3, __cmp__ is replaced by these 6 methods >+ def __eq__(self, other): >+ return self.__cmp__(other) == 0 >+ >+ def __ne__(self, other): >+ return self.__cmp__(other) != 0 >+ >+ def __lt__(self, other): >+ return self.__cmp__(other) < 0 >+ >+ def __le__(self, other): >+ return self.__cmp__(other) <= 0 >+ >+ def __gt__(self, other): >+ return self.__cmp__(other) > 0 >+ >+ def __ge__(self, other): >+ return self.__cmp__(other) >= 0 >+ >+ def get_binary_integer(self): >+ '''return binary part of a dsdb_Dn as an integer, or None''' >+ if self.prefix == '': >+ return None >+ return int(self.binary, 16) >+ >+ def get_bytes(self): >+ '''return binary as a byte string''' >+ return binascii.unhexlify(self.binary) >diff --git a/python/samba/tests/common.py b/python/samba/tests/common.py >index 13f3ba2bc7a..2b7d22fd629 100644 >--- a/python/samba/tests/common.py >+++ b/python/samba/tests/common.py >@@ -20,8 +20,8 @@ > import samba > import os > import samba.tests >-from samba.common import normalise_int32, dsdb_Dn >-from samba.samdb import SamDB >+from samba.common import normalise_int32 >+from samba.samdb import SamDB, dsdb_Dn > > > class CommonTests(samba.tests.TestCaseInTempDir): >diff --git a/source4/torture/drs/python/repl_rodc.py b/source4/torture/drs/python/repl_rodc.py >index 8e2b2ef51cf..f27f02814af 100644 >--- a/source4/torture/drs/python/repl_rodc.py >+++ b/source4/torture/drs/python/repl_rodc.py >@@ -37,7 +37,7 @@ from samba.join import DCJoinContext > from samba.dcerpc import drsuapi, misc, drsblobs, security > from samba.drs_utils import drs_DsBind, drs_Replicate > from samba.ndr import ndr_unpack, ndr_pack >-from samba.common import dsdb_Dn >+from samba.samdb import dsdb_Dn > from samba.credentials import Credentials > > import random >-- >2.25.1 > > >From 25c4c97362adc87ef3484e14d4f6b64eceb54828 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Thu, 11 Oct 2018 13:08:38 +1300 >Subject: [PATCH 223/686] python/join: use the provided krbtgt link in > cleanup_old_accounts > >Before we were putting it in an otherwise unused variable, and >deleting the previous krbtgt_dn, if any. > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> >Reviewed-by: David Mulder <dmulder@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 98f6ece5ad03a822180796873197383c17c3c6d9) >--- > python/samba/join.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/join.py b/python/samba/join.py >index 6fe4ee7dc90..080bd1f6aac 100644 >--- a/python/samba/join.py >+++ b/python/samba/join.py >@@ -256,7 +256,7 @@ class DCJoinContext(object): > ctx.del_noerror(res[0].dn, recursive=True) > > if "msDS-Krbtgtlink" in res[0]: >- new_krbtgt_dn = res[0]["msDS-Krbtgtlink"][0] >+ ctx.new_krbtgt_dn = res[0]["msDS-Krbtgtlink"][0] > ctx.del_noerror(ctx.new_krbtgt_dn) > > res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(), >-- >2.25.1 > > >From 5cb0ea8aeab821ac877a514e428f659b97ece22d Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 17 Sep 2021 16:43:00 +1200 >Subject: [PATCH 224/686] autobuild: allow AUTOBUILD_FAIL_IMMEDIATELY=0 (say > from a gitlab variable) > >This allows making a push to do a full test ignoring errors without >needing "HACK!!!" commits on top. > >Use like this: > >git push -o ci.variable='AUTOBUILD_FAIL_IMMEDIATELY=0' > >RN: Samba CI runs can now continue past the first error if AUTOBUILD_FAIL_IMMEDIATELY=0 is set > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14841 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org >Reviewed-by: Noel Power <npower@samba.org> > >[abartlet@samba.org backported from commit b81f6f3d71487085bb355392ce7f8eff2db5bb4d > due to changes in 4.15 and later for the autobuild dependent jobs work > that avoids rebuilding Samba in each task] > >Autobuild-User(v4-14-test): Jule Anger <janger@samba.org> >Autobuild-Date(v4-14-test): Thu Sep 23 08:54:03 UTC 2021 on sn-devel-184 > >(cherry picked from commit f53c532c2292d07ab3374920bd83c1266663038e) > >[jsutton@samba.org Adapted to set FAIL_IMMEDIATELY=0 always for ease of > testing] >--- > script/autobuild.py | 22 +++++++++++----------- > 1 file changed, 11 insertions(+), 11 deletions(-) > >diff --git a/script/autobuild.py b/script/autobuild.py >index 67c18a1aa35..f7a23d53a79 100755 >--- a/script/autobuild.py >+++ b/script/autobuild.py >@@ -97,7 +97,7 @@ tasks = { > # We have 'test' before 'install' because, 'test' should work without 'install (runs ad_dc_ntvfs and all the other envs)' > "samba": [("configure", "./configure.developer --with-selftest-prefix=./bin/ab" + samba_configure_params, "text/plain"), > ("make", "make -j", "text/plain"), >- ("test", "make test FAIL_IMMEDIATELY=1 " >+ ("test", "make test FAIL_IMMEDIATELY=0 " > "TESTS='${PY3_ONLY}" > "--exclude-env=none " > "--exclude-env=nt4_dc " >@@ -128,7 +128,7 @@ tasks = { > "samba-nt4": [("random-sleep", "script/random-sleep.sh 60 600", "text/plain"), > ("configure", "./configure.developer --without-ads --with-selftest-prefix=./bin/ab" + samba_configure_params, "text/plain"), > ("make", "make -j", "text/plain"), >- ("test", "make test FAIL_IMMEDIATELY=1 " >+ ("test", "make test FAIL_IMMEDIATELY=0 " > "TESTS='${PY3_ONLY}" > "--include-env=nt4_dc --include-env=nt4_member'", "text/plain"), > ("install", "make install", "text/plain"), >@@ -139,7 +139,7 @@ tasks = { > "samba-fileserver": [("random-sleep", "script/random-sleep.sh 60 600", "text/plain"), > ("configure", "./configure.developer --without-ad-dc --without-ldap --without-ads --without-json --with-selftest-prefix=./bin/ab" + samba_configure_params, "text/plain"), > ("make", "make -j", "text/plain"), >- ("test", "make test FAIL_IMMEDIATELY=1 " >+ ("test", "make test FAIL_IMMEDIATELY=0 " > "TESTS='${PY3_ONLY}" > "--include-env=fileserver'", "text/plain"), > ("check-clean-tree", "script/clean-source-tree.sh", "text/plain")], >@@ -148,7 +148,7 @@ tasks = { > "samba-ad-dc": [("random-sleep", "script/random-sleep.sh 60 600", "text/plain"), > ("configure", "./configure.developer --with-selftest-prefix=./bin/ab" + samba_configure_params, "text/plain"), > ("make", "make -j", "text/plain"), >- ("test", "make test FAIL_IMMEDIATELY=1 " >+ ("test", "make test FAIL_IMMEDIATELY=0 " > "TESTS='${PY3_ONLY}" > "--include-env=ad_dc " > "--include-env=fl2003dc " >@@ -162,7 +162,7 @@ tasks = { > "samba-ad-dc-2": [("random-sleep", "script/random-sleep.sh 60 600", "text/plain"), > ("configure", "./configure.developer --with-selftest-prefix=./bin/ab" + samba_configure_params, "text/plain"), > ("make", "make -j", "text/plain"), >- ("test", "make test FAIL_IMMEDIATELY=1 " >+ ("test", "make test FAIL_IMMEDIATELY=0 " > "TESTS='${PY3_ONLY}" > "--include-env=chgdcpass " > "--include-env=vampire_2000_dc " >@@ -177,7 +177,7 @@ tasks = { > "samba-ad-dc-backup": [("random-sleep", "script/random-sleep.sh 60 600", "text/plain"), > ("configure", "./configure.developer --with-selftest-prefix=./bin/ab" + samba_configure_params, "text/plain"), > ("make", "make -j", "text/plain"), >- ("test", "make test FAIL_IMMEDIATELY=1 " >+ ("test", "make test FAIL_IMMEDIATELY=0 " > "TESTS='${PY3_ONLY}" > "--include-env=backupfromdc " > "--include-env=restoredc " >@@ -190,7 +190,7 @@ tasks = { > > "samba-test-only": [("configure", "./configure.developer --with-selftest-prefix=./bin/ab --abi-check-disable" + samba_configure_params, "text/plain"), > ("make", "make -j", "text/plain"), >- ("test", 'make test FAIL_IMMEDIATELY=1 TESTS="${TESTS}"', "text/plain")], >+ ("test", 'make test FAIL_IMMEDIATELY=0 TESTS="${TESTS}"', "text/plain")], > > # Test cross-compile infrastructure > "samba-xc": [("random-sleep", "script/random-sleep.sh 60 600", "text/plain"), >@@ -208,7 +208,7 @@ tasks = { > "samba-o3": [("random-sleep", "script/random-sleep.sh 60 600", "text/plain"), > ("configure", "ADDITIONAL_CFLAGS='-O3 -Wp,-D_FORTIFY_SOURCE=2' ./configure.developer --with-selftest-prefix=./bin/ab --abi-check-disable" + samba_configure_params, "text/plain"), > ("make", "make -j", "text/plain"), >- ("test", "make quicktest FAIL_IMMEDIATELY=1 " >+ ("test", "make quicktest FAIL_IMMEDIATELY=0 " > "TESTS='${PY3_ONLY}" > "--include-env=ad_dc'", "text/plain"), > ("install", "make install", "text/plain"), >@@ -269,7 +269,7 @@ tasks = { > ("configure", "./configure.developer --with-selftest-prefix=./bin/ab" + samba_configure_params, "text/plain"), > ("make", "make -j", "text/plain"), > ("test", "make test " >- "FAIL_IMMEDIATELY=1 " >+ "FAIL_IMMEDIATELY=0 " > "TESTS='${PY3_ONLY}" > "--include-env=none'", > "text/plain")], >@@ -280,7 +280,7 @@ tasks = { > ("allstatic-configure", "./configure.developer " + samba_configure_params + " --with-static-modules=ALL", "text/plain"), > ("allstatic-make", "make -j", "text/plain"), > ("allstatic-test", "make test " >- "FAIL_IMMEDIATELY=1 " >+ "FAIL_IMMEDIATELY=0 " > "TESTS='samba3.smb2.create.*nt4_dc'", > "text/plain"), > >@@ -300,7 +300,7 @@ tasks = { > ("make", "make -j", "text/plain"), > # we currently cannot run a full make test, a limited list of tests could be run > # via "make test TESTS=sometests" >- ("test", "make test FAIL_IMMEDIATELY=1 " >+ ("test", "make test FAIL_IMMEDIATELY=0 " > "TESTS='${PY3_ONLY}" > "--include-env=ktest'", "text/plain"), > ("install", "make install", "text/plain"), >-- >2.25.1 > > >From 49bd2501d296416fb2ade62a81ecfbbb01c36bef Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 15:39:19 +1200 >Subject: [PATCH 225/686] krb5pac.idl: Add ticket checksum PAC buffer type > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit ff2f38fae79220e16765e17671972f9a55eb7cce) >--- > librpc/idl/krb5pac.idl | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > >diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl >index f27e7243ee4..711b7f94b6c 100644 >--- a/librpc/idl/krb5pac.idl >+++ b/librpc/idl/krb5pac.idl >@@ -112,7 +112,8 @@ interface krb5pac > PAC_TYPE_KDC_CHECKSUM = 7, > PAC_TYPE_LOGON_NAME = 10, > PAC_TYPE_CONSTRAINED_DELEGATION = 11, >- PAC_TYPE_UPN_DNS_INFO = 12 >+ PAC_TYPE_UPN_DNS_INFO = 12, >+ PAC_TYPE_TICKET_CHECKSUM = 16 > } PAC_TYPE; > > typedef struct { >@@ -128,6 +129,7 @@ interface krb5pac > [case(PAC_TYPE_CONSTRAINED_DELEGATION)][subcontext(0xFFFFFC01)] > PAC_CONSTRAINED_DELEGATION_CTR constrained_delegation; > [case(PAC_TYPE_UPN_DNS_INFO)] PAC_UPN_DNS_INFO upn_dns_info; >+ [case(PAC_TYPE_TICKET_CHECKSUM)] PAC_SIGNATURE_DATA ticket_checksum; > /* when new PAC info types are added they are supposed to be done > in such a way that they are backwards compatible with existing > servers. This makes it safe to just use a [default] for >-- >2.25.1 > > >From f1b19750d1d320ec01ab8da39a94f22e60605f3b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 15:40:59 +1200 >Subject: [PATCH 226/686] security.idl: Add well-known SIDs for FAST > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 0092b4a3ed58b2c256d4dd9117cce927a3edde12) >--- > librpc/idl/security.idl | 3 +++ > 1 file changed, 3 insertions(+) > >diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl >index 5930f448955..e6065a35691 100644 >--- a/librpc/idl/security.idl >+++ b/librpc/idl/security.idl >@@ -292,6 +292,9 @@ interface security > const string SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = "S-1-18-1"; > const string SID_SERVICE_ASSERTED_IDENTITY = "S-1-18-2"; > >+ const string SID_COMPOUNDED_AUTHENTICATION = "S-1-5-21-0-0-0-496"; >+ const string SID_CLAIMS_VALID = "S-1-5-21-0-0-0-497"; >+ > /* > * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx > */ >-- >2.25.1 > > >From 68ae4eff83fc328a07fe6ad19d55bacb10881f22 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 15:46:42 +1200 >Subject: [PATCH 227/686] tests/krb5: Calculate expected salt if not given > explicitly > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit c6badf818e9db44461979a931c74fc5ab6e80132) >--- > python/samba/tests/krb5/as_req_tests.py | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 82ff3f4845c..09160bf6814 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -74,7 +74,7 @@ class AsReqKerberosTests(KDCBaseTest): > expected_cname = cname > expected_srealm = realm > expected_sname = sname >- expected_salt = client_creds.get_forced_salt() >+ expected_salt = client_creds.get_salt() > > if any(etype in client_as_etypes and etype in initial_etypes > for etype in (kcrypto.Enctype.AES256, >@@ -142,7 +142,7 @@ class AsReqKerberosTests(KDCBaseTest): > expected_cname = cname > expected_srealm = realm > expected_sname = sname >- expected_salt = client_creds.get_forced_salt() >+ expected_salt = client_creds.get_salt() > > till = self.get_KerberosTime(offset=36000) > >-- >2.25.1 > > >From b7c05543b245cabf7b5e10f1ec14dfcfd45d140b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 15:50:26 +1200 >Subject: [PATCH 228/686] tests/krb5: Add methods to obtain the length of > checksum types > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 9924dd976183ea62b08f116f8b8bacc698bb9b95) >--- > python/samba/tests/krb5/kcrypto.py | 26 ++++++++++++++++++++++++++ > 1 file changed, 26 insertions(+) > >diff --git a/python/samba/tests/krb5/kcrypto.py b/python/samba/tests/krb5/kcrypto.py >index c861e3cc96e..2a72969de00 100755 >--- a/python/samba/tests/krb5/kcrypto.py >+++ b/python/samba/tests/krb5/kcrypto.py >@@ -478,6 +478,7 @@ class _ChecksumProfile(object): > # define: > # * checksum > # * verify (if verification is not just checksum-and-compare) >+ # * checksum_len > @classmethod > def verify(cls, key, keyusage, text, cksum): > expected = cls.checksum(key, keyusage, text) >@@ -504,6 +505,10 @@ class _SimplifiedChecksum(_ChecksumProfile): > raise ValueError('Wrong key type for checksum') > super(_SimplifiedChecksum, cls).verify(key, keyusage, text, cksum) > >+ @classmethod >+ def checksum_len(cls): >+ return cls.macsize >+ > > class _SHA1AES128(_SimplifiedChecksum): > macsize = 12 >@@ -533,6 +538,10 @@ class _HMACMD5(_ChecksumProfile): > raise ValueError('Wrong key type for checksum') > super(_HMACMD5, cls).verify(key, keyusage, text, cksum) > >+ @classmethod >+ def checksum_len(cls): >+ return hashes.MD5.digest_size >+ > > class _MD5(_ChecksumProfile): > @classmethod >@@ -540,6 +549,10 @@ class _MD5(_ChecksumProfile): > # This is unkeyed! > return SIMPLE_HASH(text, hashes.MD5) > >+ @classmethod >+ def checksum_len(cls): >+ return hashes.MD5.digest_size >+ > > class _SHA1(_ChecksumProfile): > @classmethod >@@ -547,6 +560,10 @@ class _SHA1(_ChecksumProfile): > # This is unkeyed! > return SIMPLE_HASH(text, hashes.SHA1) > >+ @classmethod >+ def checksum_len(cls): >+ return hashes.SHA1.digest_size >+ > > class _CRC32(_ChecksumProfile): > @classmethod >@@ -555,6 +572,10 @@ class _CRC32(_ChecksumProfile): > cksum = (~crc32(text, 0xffffffff)) & 0xffffffff > return pack('<I', cksum) > >+ @classmethod >+ def checksum_len(cls): >+ return 4 >+ > > _enctype_table = { > Enctype.DES3: _DES3CBC, >@@ -643,6 +664,11 @@ def verify_checksum(cksumtype, key, keyusage, text, cksum): > c.verify(key, keyusage, text, cksum) > > >+def checksum_len(cksumtype): >+ c = _get_checksum_profile(cksumtype) >+ return c.checksum_len() >+ >+ > def prfplus(key, pepper, ln): > # Produce ln bytes of output using the RFC 6113 PRF+ function. > out = b'' >-- >2.25.1 > > >From db64a008cfcedde6942ba89982897dc5dfc77004 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 15:57:26 +1200 >Subject: [PATCH 229/686] tests/krb5: Use signed integers to represent key > version numbers in ASN.1 > >As specified in 'MS-KILE 3.1.5.8: Key Version Numbers', Windows uses >signed 32-bit integers to represent key version numbers. This makes a >difference for an RODC with a msDS-SecondaryKrbTgtNumber greater than >32767, where the kvno should be encoded in four bytes rather than five. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 448b661bf8815a05f534926d8ee8d6f57d123c2c) >--- > python/samba/tests/krb5/raw_testcase.py | 2 +- > python/samba/tests/krb5/rfc4120.asn1 | 2 +- > python/samba/tests/krb5/rfc4120_pyasn1.py | 2 +- > 3 files changed, 3 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 6db17f2a118..c5ee5eb6083 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -995,7 +995,7 @@ class RawKerberosTest(TestCaseInTempDir): > def EncryptedData_create(self, key, usage, plaintext): > # EncryptedData ::= SEQUENCE { > # etype [0] Int32 -- EncryptionType --, >- # kvno [1] UInt32 OPTIONAL, >+ # kvno [1] Int32 OPTIONAL, > # cipher [2] OCTET STRING -- ciphertext > # } > ciphertext = key.encrypt(usage, plaintext) >diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 >index f47c1d00202..a37011ae932 100644 >--- a/python/samba/tests/krb5/rfc4120.asn1 >+++ b/python/samba/tests/krb5/rfc4120.asn1 >@@ -124,7 +124,7 @@ KerberosFlags ::= BIT STRING (SIZE (1..32)) > > EncryptedData ::= SEQUENCE { > etype [0] EncryptionType, --Int32 EncryptionType -- >- kvno [1] UInt32 OPTIONAL, >+ kvno [1] Int32 OPTIONAL, > cipher [2] OCTET STRING -- ciphertext > } > >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1.py b/python/samba/tests/krb5/rfc4120_pyasn1.py >index 39ec8ed7982..a9e4bcbb18f 100644 >--- a/python/samba/tests/krb5/rfc4120_pyasn1.py >+++ b/python/samba/tests/krb5/rfc4120_pyasn1.py >@@ -120,7 +120,7 @@ class EncryptedData(univ.Sequence): > > EncryptedData.componentType = namedtype.NamedTypes( > namedtype.NamedType('etype', EncryptionType().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >- namedtype.OptionalNamedType('kvno', UInt32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('kvno', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), > namedtype.NamedType('cipher', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) > ) > >-- >2.25.1 > > >From d9f866104068b847464e9d004efff858e7ad416f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:05:39 +1200 >Subject: [PATCH 230/686] tests/krb5: Add KDCOptions flag for constrained > delegation > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 08086c43987abecc588ebd32ec846ff7e27a83b6) >--- > python/samba/tests/krb5/rfc4120.asn1 | 1 + > python/samba/tests/krb5/rfc4120_pyasn1.py | 1 + > 2 files changed, 2 insertions(+) > >diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 >index a37011ae932..e0831e1f86f 100644 >--- a/python/samba/tests/krb5/rfc4120.asn1 >+++ b/python/samba/tests/krb5/rfc4120.asn1 >@@ -632,6 +632,7 @@ KDCOptionsValues ::= BIT STRING { -- KerberosFlags > opt-hardware-auth(11), > unused12(12), > unused13(13), >+ cname-in-addl-tkt(14), > -- Canonicalize is used by RFC 6806 > canonicalize(15), > -- 26 was unused in 1510 >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1.py b/python/samba/tests/krb5/rfc4120_pyasn1.py >index a9e4bcbb18f..348dd8c63fb 100644 >--- a/python/samba/tests/krb5/rfc4120_pyasn1.py >+++ b/python/samba/tests/krb5/rfc4120_pyasn1.py >@@ -649,6 +649,7 @@ KDCOptionsValues.namedValues = namedval.NamedValues( > ('opt-hardware-auth', 11), > ('unused12', 12), > ('unused13', 13), >+ ('cname-in-addl-tkt', 14), > ('canonicalize', 15), > ('disable-transited-check', 26), > ('renewable-ok', 27), >-- >2.25.1 > > >From 95b487b06732769a42681294c3f19fc9bf6a2b11 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:21:55 +1200 >Subject: [PATCH 231/686] tests/krb5: Use more compact dict lookup > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 3fd73b65a3db405db5a0a82cca6c808763d4f437) >--- > python/samba/tests/krb5/raw_testcase.py | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index c5ee5eb6083..0ec0f65c6d6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -305,7 +305,7 @@ class KerberosCredentials(Credentials): > > def get_forced_key(self, etype): > etype = int(etype) >- return self.forced_keys.get(etype, None) >+ return self.forced_keys.get(etype) > > def set_forced_salt(self, salt): > self.forced_salt = bytes(salt) >@@ -830,7 +830,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(value) > > def getElementValue(self, obj, elem): >- return obj.get(elem, None) >+ return obj.get(elem) > > def assertElementMissing(self, obj, elem): > v = self.getElementValue(obj, elem) >@@ -942,7 +942,7 @@ class RawKerberosTest(TestCaseInTempDir): > def PasswordKey_from_etype_info2(self, creds, etype_info2, kvno=None): > e = etype_info2['etype'] > >- salt = etype_info2.get('salt', None) >+ salt = etype_info2.get('salt') > > if e == kcrypto.Enctype.RC4: > nthash = creds.get_nt_hash() >-- >2.25.1 > > >From fc401c2b2b4f558a7e45a3ba5698eebac82f90f9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:31:56 +1200 >Subject: [PATCH 232/686] tests/krb5: Replace expected_cname_private with > expected_anon parameter > >This is used in the case where the KDC returns 'WELLKNOWN/ANONYMOUS' as >the cname, and makes the reply checking logic easier to follow. This >also removes the need to fetch the client credentials in the test >methods. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit bf55786fcd9a96daa9002661d6f5d9b3502ed8a7) >--- > python/samba/tests/krb5/fast_tests.py | 33 +++++------------------- > python/samba/tests/krb5/raw_testcase.py | 34 ++++++++++++------------- > 2 files changed, 24 insertions(+), 43 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 2d4b69f8590..b371ab617aa 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -49,7 +49,6 @@ from samba.tests.krb5.rfc4120_constants import ( > KU_TICKET, > NT_PRINCIPAL, > NT_SRV_INST, >- NT_WELLKNOWN, > PADATA_FX_COOKIE, > PADATA_FX_FAST, > PADATA_PAC_OPTIONS >@@ -985,14 +984,6 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_hide_client_names(self): >- user_creds = self.get_client_creds() >- user_name = user_creds.get_username() >- user_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >- names=[user_name]) >- >- expected_cname = self.PrincipalName_create( >- name_type=NT_WELLKNOWN, names=['WELLKNOWN', 'ANONYMOUS']) >- > self._run_test_sequence([ > { > 'rep_type': KRB_AS_REP, >@@ -1001,7 +992,7 @@ class FAST_Tests(KDCBaseTest): > 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, > 'gen_armor_tgt_fn': self.get_mach_tgt, > 'fast_options': '01', # hide client names >- 'expected_cname': expected_cname >+ 'expected_anon': True > }, > { > 'rep_type': KRB_AS_REP, >@@ -1011,20 +1002,11 @@ class FAST_Tests(KDCBaseTest): > 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, > 'gen_armor_tgt_fn': self.get_mach_tgt, > 'fast_options': '01', # hide client names >- 'expected_cname': expected_cname, >- 'expected_cname_private': user_cname >+ 'expected_anon': True > } > ]) > > def test_fast_tgs_hide_client_names(self): >- user_creds = self.get_client_creds() >- user_name = user_creds.get_username() >- user_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >- names=[user_name]) >- >- expected_cname = self.PrincipalName_create( >- name_type=NT_WELLKNOWN, names=['WELLKNOWN', 'ANONYMOUS']) >- > self._run_test_sequence([ > { > 'rep_type': KRB_TGS_REP, >@@ -1033,8 +1015,7 @@ class FAST_Tests(KDCBaseTest): > 'gen_tgt_fn': self.get_user_tgt, > 'fast_armor': None, > 'fast_options': '01', # hide client names >- 'expected_cname': expected_cname, >- 'expected_cname_private': user_cname >+ 'expected_anon': True > } > ]) > >@@ -1216,8 +1197,8 @@ class FAST_Tests(KDCBaseTest): > srealm = target_realm > > expected_cname = kdc_dict.pop('expected_cname', client_cname) >- expected_cname_private = kdc_dict.pop('expected_cname_private', >- None) >+ expected_anon = kdc_dict.pop('expected_anon', >+ False) > expected_crealm = kdc_dict.pop('expected_crealm', client_realm) > expected_sname = kdc_dict.pop('expected_sname', sname) > expected_srealm = kdc_dict.pop('expected_srealm', srealm) >@@ -1341,7 +1322,7 @@ class FAST_Tests(KDCBaseTest): > kdc_exchange_dict = self.as_exchange_dict( > expected_crealm=expected_crealm, > expected_cname=expected_cname, >- expected_cname_private=expected_cname_private, >+ expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, > ticket_decryption_key=krbtgt_decryption_key, >@@ -1370,7 +1351,7 @@ class FAST_Tests(KDCBaseTest): > kdc_exchange_dict = self.tgs_exchange_dict( > expected_crealm=expected_crealm, > expected_cname=expected_cname, >- expected_cname_private=expected_cname_private, >+ expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, > ticket_decryption_key=target_decryption_key, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 0ec0f65c6d6..e4dbb10d135 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1721,7 +1721,7 @@ class RawKerberosTest(TestCaseInTempDir): > def as_exchange_dict(self, > expected_crealm=None, > expected_cname=None, >- expected_cname_private=None, >+ expected_anon=False, > expected_srealm=None, > expected_sname=None, > ticket_decryption_key=None, >@@ -1759,6 +1759,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'rep_encpart_asn1Spec': krb5_asn1.EncASRepPart, > 'expected_crealm': expected_crealm, > 'expected_cname': expected_cname, >+ 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, > 'ticket_decryption_key': ticket_decryption_key, >@@ -1784,10 +1785,6 @@ class RawKerberosTest(TestCaseInTempDir): > 'inner_req': inner_req, > 'outer_req': outer_req > } >- if expected_cname_private is not None: >- kdc_exchange_dict['expected_cname_private'] = ( >- expected_cname_private) >- > if callback_dict is None: > callback_dict = {} > >@@ -1796,7 +1793,7 @@ class RawKerberosTest(TestCaseInTempDir): > def tgs_exchange_dict(self, > expected_crealm=None, > expected_cname=None, >- expected_cname_private=None, >+ expected_anon=False, > expected_srealm=None, > expected_sname=None, > ticket_decryption_key=None, >@@ -1834,6 +1831,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'rep_encpart_asn1Spec': krb5_asn1.EncTGSRepPart, > 'expected_crealm': expected_crealm, > 'expected_cname': expected_cname, >+ 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, > 'ticket_decryption_key': ticket_decryption_key, >@@ -1859,10 +1857,6 @@ class RawKerberosTest(TestCaseInTempDir): > 'inner_req': inner_req, > 'outer_req': outer_req > } >- if expected_cname_private is not None: >- kdc_exchange_dict['expected_cname_private'] = ( >- expected_cname_private) >- > if callback_dict is None: > callback_dict = {} > >@@ -1874,7 +1868,7 @@ class RawKerberosTest(TestCaseInTempDir): > rep): > > expected_crealm = kdc_exchange_dict['expected_crealm'] >- expected_cname = kdc_exchange_dict['expected_cname'] >+ expected_anon = kdc_exchange_dict['expected_anon'] > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] > ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] >@@ -1888,6 +1882,12 @@ class RawKerberosTest(TestCaseInTempDir): > padata = self.getElementValue(rep, 'padata') > if self.strict_checking: > self.assertElementEqualUTF8(rep, 'crealm', expected_crealm) >+ if expected_anon: >+ expected_cname = self.PrincipalName_create( >+ name_type=NT_WELLKNOWN, >+ names=['WELLKNOWN', 'ANONYMOUS']) >+ else: >+ expected_cname = kdc_exchange_dict['expected_cname'] > self.assertElementEqualPrincipal(rep, 'cname', expected_cname) > self.assertElementPresent(rep, 'ticket') > ticket = self.getElementValue(rep, 'ticket') >@@ -2042,14 +2042,11 @@ class RawKerberosTest(TestCaseInTempDir): > and kdc_options[canon_pos] == '1') > > expected_crealm = kdc_exchange_dict['expected_crealm'] >+ expected_cname = kdc_exchange_dict['expected_cname'] > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] > ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] > >- try: >- expected_cname = kdc_exchange_dict['expected_cname_private'] >- except KeyError: >- expected_cname = kdc_exchange_dict['expected_cname'] > > ticket = self.getElementValue(rep, 'ticket') > >@@ -2182,7 +2179,7 @@ class RawKerberosTest(TestCaseInTempDir): > > rep_msg_type = kdc_exchange_dict['rep_msg_type'] > >- expected_cname = kdc_exchange_dict['expected_cname'] >+ expected_anon = kdc_exchange_dict['expected_anon'] > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] > expected_error_mode = kdc_exchange_dict['expected_error_mode'] >@@ -2203,7 +2200,10 @@ class RawKerberosTest(TestCaseInTempDir): > # error-code checked above > if self.strict_checking: > self.assertElementMissing(rep, 'crealm') >- if expected_cname['name-type'] == NT_WELLKNOWN and not inner: >+ if expected_anon and not inner: >+ expected_cname = self.PrincipalName_create( >+ name_type=NT_WELLKNOWN, >+ names=['WELLKNOWN', 'ANONYMOUS']) > self.assertElementEqualPrincipal(rep, 'cname', expected_cname) > else: > self.assertElementMissing(rep, 'cname') >-- >2.25.1 > > >From 8af67a59f8686eb799910aeda95b9a388a2aa380 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:34:02 +1200 >Subject: [PATCH 233/686] tests/krb5: Allow specifying an OU to create accounts > in > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 7aae0e9b100b8cb7d1da78b8cb9a4a5c20acffbd) >--- > python/samba/tests/krb5/kdc_base_test.py | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index f5c1eba9151..efe11da8468 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -151,12 +151,16 @@ class KDCBaseTest(RawKerberosTest): > return default_enctypes > > def create_account(self, ldb, name, machine_account=False, >- spn=None, upn=None, additional_details=None): >+ spn=None, upn=None, additional_details=None, >+ ou=None): > '''Create an account for testing. > The dn of the created account is added to self.accounts, > which is used by tearDownClass to clean up the created accounts. > ''' >- dn = "cn=%s,%s" % (name, ldb.domain_dn()) >+ if ou is None: >+ ou = ldb.domain_dn() >+ >+ dn = "CN=%s,%s" % (name, ou) > > # remove the account if it exists, this will happen if a previous test > # run failed >-- >2.25.1 > > >From eb12cafeb94b72b2f938bd9561a0f8ca57838cef Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:34:46 +1200 >Subject: [PATCH 234/686] tests/krb5: Allow specifying additional User Account > Control flags for account > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 9aa900857441ea7e1c2d6c60bfa1ddeb142bf3e3) >--- > python/samba/tests/krb5/kdc_base_test.py | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index efe11da8468..bd5bacfaca1 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -152,7 +152,7 @@ class KDCBaseTest(RawKerberosTest): > > def create_account(self, ldb, name, machine_account=False, > spn=None, upn=None, additional_details=None, >- ou=None): >+ ou=None, account_control=0): > '''Create an account for testing. > The dn of the created account is added to self.accounts, > which is used by tearDownClass to clean up the created accounts. >@@ -168,11 +168,11 @@ class KDCBaseTest(RawKerberosTest): > if machine_account: > object_class = "computer" > account_name = "%s$" % name >- account_control = str(UF_WORKSTATION_TRUST_ACCOUNT) >+ account_control |= UF_WORKSTATION_TRUST_ACCOUNT > else: > object_class = "user" > account_name = name >- account_control = str(UF_NORMAL_ACCOUNT) >+ account_control |= UF_NORMAL_ACCOUNT > > password = generate_random_password(32, 32) > utf16pw = ('"%s"' % password).encode('utf-16-le') >@@ -181,7 +181,7 @@ class KDCBaseTest(RawKerberosTest): > "dn": dn, > "objectclass": object_class, > "sAMAccountName": account_name, >- "userAccountControl": account_control, >+ "userAccountControl": str(account_control), > "unicodePwd": utf16pw} > if spn is not None: > details["servicePrincipalName"] = spn >-- >2.25.1 > > >From df32ec5e7cfaaeab7ef550abadfbc3899af688fc Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:35:58 +1200 >Subject: [PATCH 235/686] tests/krb5: Keep track of account DN in credentials > object > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 9973b51e48a5d5f3e33c6e0da46e6231a42bd77a) >--- > python/samba/tests/krb5/kdc_base_test.py | 2 ++ > python/samba/tests/krb5/raw_testcase.py | 8 ++++++++ > 2 files changed, 10 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index bd5bacfaca1..b52452358cc 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -201,6 +201,7 @@ class KDCBaseTest(RawKerberosTest): > creds.set_workstation(name) > else: > creds.set_workstation('') >+ creds.set_dn(dn) > # > # Save the account name so it can be deleted in tearDownClass > self.accounts.add(dn) >@@ -441,6 +442,7 @@ class KDCBaseTest(RawKerberosTest): > > kvno = int(res[0]['msDS-KeyVersionNumber'][0]) > creds.set_kvno(kvno) >+ creds.set_dn(dn) > > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e4dbb10d135..e62fad3d187 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -261,6 +261,8 @@ class KerberosCredentials(Credentials): > > self.forced_salt = None > >+ self.dn = None >+ > def set_as_supported_enctypes(self, value): > self.as_supported_enctypes = int(value) > >@@ -327,6 +329,12 @@ class KerberosCredentials(Credentials): > > return salt_string.encode('utf-8') > >+ def set_dn(self, dn): >+ self.dn = dn >+ >+ def get_dn(self): >+ return self.dn >+ > > class KerberosTicketCreds: > def __init__(self, ticket, session_key, >-- >2.25.1 > > >From 0976e0edff45b2a90823c1d63bf0c6676b286b4c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 2 Sep 2021 14:27:00 +1200 >Subject: [PATCH 236/686] tests/krb5: Move padata generation methods to base > class > >This allows them to be used directly from RawKerberosTest. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 1f23b16ef3a900a1bda01bf2a5a3a3847e2e79d1) >--- > python/samba/tests/krb5/fast_tests.py | 14 -------------- > python/samba/tests/krb5/raw_testcase.py | 13 +++++++++++++ > 2 files changed, 13 insertions(+), 14 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index b371ab617aa..4fc297c1e34 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -51,7 +51,6 @@ from samba.tests.krb5.rfc4120_constants import ( > NT_SRV_INST, > PADATA_FX_COOKIE, > PADATA_FX_FAST, >- PADATA_PAC_OPTIONS > ) > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > import samba.tests.krb5.kcrypto as kcrypto >@@ -1466,19 +1465,6 @@ class FAST_Tests(KDCBaseTest): > > return self.PA_DATA_create(PADATA_FX_COOKIE, cookie) > >- def get_pa_pac_request(self, request_pac=True): >- pac_request = self.KERB_PA_PAC_REQUEST_create(request_pac) >- >- return pac_request >- >- def get_pa_pac_options(self, options): >- pac_options = self.PA_PAC_OPTIONS_create(options) >- pac_options = self.der_encode(pac_options, >- asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >- pac_options = self.PA_DATA_create(PADATA_PAC_OPTIONS, pac_options) >- >- return pac_options >- > def check_kdc_fast_support(self): > # Check that the KDC supports FAST > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e62fad3d187..b724baf5cf8 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1151,6 +1151,19 @@ class RawKerberosTest(TestCaseInTempDir): > pa_data = self.PA_DATA_create(PADATA_PAC_REQUEST, pa_pac) > return pa_data > >+ def get_pa_pac_request(self, request_pac=True): >+ pac_request = self.KERB_PA_PAC_REQUEST_create(request_pac) >+ >+ return pac_request >+ >+ def get_pa_pac_options(self, options): >+ pac_options = self.PA_PAC_OPTIONS_create(options) >+ pac_options = self.der_encode(pac_options, >+ asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >+ pac_options = self.PA_DATA_create(PADATA_PAC_OPTIONS, pac_options) >+ >+ return pac_options >+ > def KDC_REQ_BODY_create(self, > kdc_options, > cname, >-- >2.25.1 > > >From ae5d05d48f97ecc27800067b867dc2254c6ae150 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 2 Sep 2021 14:36:42 +1200 >Subject: [PATCH 237/686] tests/krb5: add options to kdc_exchange_dict to > specify including PAC-REQUEST or PAC-OPTIONS > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit c0db1ba54d238d4b2da8895215d8314b068ce09c) >--- > python/samba/tests/krb5/raw_testcase.py | 40 +++++++++++++++++++++---- > 1 file changed, 34 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b724baf5cf8..58f246606d7 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1574,6 +1574,9 @@ class RawKerberosTest(TestCaseInTempDir): > expected_error_mode = kdc_exchange_dict['expected_error_mode'] > kdc_options = kdc_exchange_dict['kdc_options'] > >+ pac_request = kdc_exchange_dict['pac_request'] >+ pac_options = kdc_exchange_dict['pac_options'] >+ > # Parameters specific to the inner request body > inner_req = kdc_exchange_dict['inner_req'] > >@@ -1619,6 +1622,14 @@ class RawKerberosTest(TestCaseInTempDir): > else: > del req_body[key] > >+ additional_padata = [] >+ if pac_request is not None: >+ pa_pac_request = self.KERB_PA_PAC_REQUEST_create(pac_request) >+ additional_padata.append(pa_pac_request) >+ if pac_options is not None: >+ pa_pac_options = self.get_pa_pac_options(pac_options) >+ additional_padata.append(pa_pac_options) >+ > if req_msg_type == KRB_AS_REQ: > tgs_req = None > tgs_req_padata = None >@@ -1637,6 +1648,8 @@ class RawKerberosTest(TestCaseInTempDir): > fast_padata, req_body = generate_fast_padata_fn(kdc_exchange_dict, > callback_dict, > req_body) >+ >+ fast_padata += additional_padata > else: > fast_padata = [] > >@@ -1701,6 +1714,9 @@ class RawKerberosTest(TestCaseInTempDir): > if outer_padata is not None: > padata += outer_padata > >+ if fast is None: >+ padata += additional_padata >+ > if not padata: > padata = None > >@@ -1766,7 +1782,9 @@ class RawKerberosTest(TestCaseInTempDir): > auth_data=None, > kdc_options='', > inner_req=None, >- outer_req=None): >+ outer_req=None, >+ pac_request=None, >+ pac_options=None): > if expected_error_mode == 0: > expected_error_mode = () > elif not isinstance(expected_error_mode, collections.abc.Container): >@@ -1804,7 +1822,9 @@ class RawKerberosTest(TestCaseInTempDir): > 'auth_data': auth_data, > 'kdc_options': kdc_options, > 'inner_req': inner_req, >- 'outer_req': outer_req >+ 'outer_req': outer_req, >+ 'pac_request': pac_request, >+ 'pac_options': pac_options > } > if callback_dict is None: > callback_dict = {} >@@ -1838,7 +1858,9 @@ class RawKerberosTest(TestCaseInTempDir): > body_checksum_type=None, > kdc_options='', > inner_req=None, >- outer_req=None): >+ outer_req=None, >+ pac_request=None, >+ pac_options=None): > if expected_error_mode == 0: > expected_error_mode = () > elif not isinstance(expected_error_mode, collections.abc.Container): >@@ -1876,7 +1898,9 @@ class RawKerberosTest(TestCaseInTempDir): > 'authenticator_subkey': authenticator_subkey, > 'kdc_options': kdc_options, > 'inner_req': inner_req, >- 'outer_req': outer_req >+ 'outer_req': outer_req, >+ 'pac_request': pac_request, >+ 'pac_options': pac_options > } > if callback_dict is None: > callback_dict = {} >@@ -2820,7 +2844,9 @@ class RawKerberosTest(TestCaseInTempDir): > padata, > kdc_options, > preauth_key=None, >- ticket_decryption_key=None): >+ ticket_decryption_key=None, >+ pac_request=None, >+ pac_options=None): > > def _generate_padata_copy(_kdc_exchange_dict, > _callback_dict, >@@ -2860,7 +2886,9 @@ class RawKerberosTest(TestCaseInTempDir): > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, > expected_salt=expected_salt, >- kdc_options=str(kdc_options)) >+ kdc_options=str(kdc_options), >+ pac_request=pac_request, >+ pac_options=pac_options) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, > cname=cname, >-- >2.25.1 > > >From 08db4968e11c52c4de8c36b64af42a713c478cf9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 2 Sep 2021 14:37:27 +1200 >Subject: [PATCH 238/686] tests/krb5: Don't create PAC request manually in > as_req_tests > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit bc21ba2592093c765751ed3e8083dcd3512997f8) >--- > python/samba/tests/krb5/as_req_tests.py | 35 ++++++++----------------- > 1 file changed, 11 insertions(+), 24 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 09160bf6814..35f88a0c920 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -56,7 +56,7 @@ class AsReqKerberosTests(KDCBaseTest): > > def _test_as_req_nopreauth(self, > initial_etypes, >- initial_padata=None, >+ pac=None, > initial_kdc_options=None): > client_creds = self.get_client_creds() > client_account = client_creds.get_username() >@@ -84,27 +84,19 @@ class AsReqKerberosTests(KDCBaseTest): > else: > expected_error_mode = KDC_ERR_ETYPE_NOSUPP > >- def _generate_padata_copy(_kdc_exchange_dict, >- _callback_dict, >- req_body): >- return initial_padata, req_body >- >- generate_padata_fn = (_generate_padata_copy >- if initial_padata is not None >- else None) >- > kdc_exchange_dict = self.as_exchange_dict( > expected_crealm=expected_crealm, > expected_cname=expected_cname, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >- generate_padata_fn=generate_padata_fn, >+ generate_padata_fn=None, > check_error_fn=self.generic_check_kdc_error, > check_rep_fn=None, > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, > expected_salt=expected_salt, >- kdc_options=str(initial_kdc_options)) >+ kdc_options=str(initial_kdc_options), >+ pac_request=pac) > > self._generic_kdc_exchange(kdc_exchange_dict, > cname=cname, >@@ -114,13 +106,8 @@ class AsReqKerberosTests(KDCBaseTest): > > def _test_as_req_no_preauth_with_args(self, etype_idx, pac): > name, etypes = self.etype_test_permutation_by_idx(etype_idx) >- if pac is None: >- padata = None >- else: >- pa_pac = self.KERB_PA_PAC_REQUEST_create(pac) >- padata = [pa_pac] > self._test_as_req_nopreauth( >- initial_padata=padata, >+ pac=pac, > initial_etypes=etypes, > initial_kdc_options=krb5_asn1.KDCOptions('forwardable')) > >@@ -146,8 +133,6 @@ class AsReqKerberosTests(KDCBaseTest): > > till = self.get_KerberosTime(offset=36000) > >- pa_pac = self.KERB_PA_PAC_REQUEST_create(True) >- initial_padata = [pa_pac] > initial_etypes = client_as_etypes > initial_kdc_options = krb5_asn1.KDCOptions('forwardable') > initial_error_mode = KDC_ERR_PREAUTH_REQUIRED >@@ -164,8 +149,9 @@ class AsReqKerberosTests(KDCBaseTest): > expected_sname, > expected_salt, > initial_etypes, >- initial_padata, >- initial_kdc_options) >+ None, >+ initial_kdc_options, >+ pac_request=True) > etype_info2 = kdc_exchange_dict['preauth_etype_info2'] > self.assertIsNotNone(etype_info2) > >@@ -183,7 +169,7 @@ class AsReqKerberosTests(KDCBaseTest): > > pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts) > >- preauth_padata = [pa_ts, pa_pac] >+ preauth_padata = [pa_ts] > preauth_etypes = client_as_etypes > preauth_kdc_options = krb5_asn1.KDCOptions('forwardable') > preauth_error_mode = 0 # AS-REP >@@ -207,7 +193,8 @@ class AsReqKerberosTests(KDCBaseTest): > preauth_padata, > preauth_kdc_options, > preauth_key=preauth_key, >- ticket_decryption_key=krbtgt_decryption_key) >+ ticket_decryption_key=krbtgt_decryption_key, >+ pac_request=True) > self.assertIsNotNone(as_rep) > > if __name__ == "__main__": >-- >2.25.1 > > >From 424f5b4633d42e2c83332718d15d4d8187b04ba0 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 2 Sep 2021 14:38:33 +1200 >Subject: [PATCH 239/686] tests/krb5: Don't create PAC request or options > manually in fast_tests > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 7556a4dfa64650939aef14a2fc4d10b9ed3d29f7) >--- > python/samba/tests/krb5/fast_tests.py | 22 +++++++++------------- > 1 file changed, 9 insertions(+), 13 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 4fc297c1e34..e10db90a57e 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1093,8 +1093,6 @@ class FAST_Tests(KDCBaseTest): > 'canonicalize,' > 'renewable-ok')) > >- pac_request = self.get_pa_pac_request() >- > client_creds = self.get_client_creds() > target_creds = self.get_service_creds() > krbtgt_creds = self.get_krbtgt_creds() >@@ -1250,7 +1248,7 @@ class FAST_Tests(KDCBaseTest): > _callback_dict, > req_body, > padata): >- return padata, req_body >+ return list(padata), req_body > > def _check_padata_preauth_key(_kdc_exchange_dict, > _callback_dict, >@@ -1260,15 +1258,9 @@ class FAST_Tests(KDCBaseTest): > return preauth_key, as_rep_usage > > pac_options = kdc_dict.pop('pac_options', '1') # claims support >- pac_options = self.get_pa_pac_options(pac_options) > > kdc_options = kdc_dict.pop('kdc_options', kdc_options_default) > >- if rep_type == KRB_AS_REP: >- padata = [pac_request, pac_options] >- else: >- padata = [pac_options] >- > gen_padata_fn = kdc_dict.pop('gen_padata_fn', None) > if gen_padata_fn is not None: > self.assertEqual(KRB_AS_REP, rep_type) >@@ -1278,10 +1270,10 @@ class FAST_Tests(KDCBaseTest): > client_creds, > preauth_etype_info2[0], > client_creds.get_kvno()) >- gen_padata = gen_padata_fn(preauth_key, armor_key) >- padata.insert(0, gen_padata) >+ padata = [gen_padata_fn(preauth_key, armor_key)] > else: > preauth_key = None >+ padata = [] > > if rep_type == KRB_AS_REP: > check_padata_fn = _check_padata_preauth_key >@@ -1345,7 +1337,9 @@ class FAST_Tests(KDCBaseTest): > armor_subkey=armor_subkey, > kdc_options=kdc_options, > inner_req=inner_req, >- outer_req=outer_req) >+ outer_req=outer_req, >+ pac_request=True, >+ pac_options=pac_options) > else: # KRB_TGS_REP > kdc_exchange_dict = self.tgs_exchange_dict( > expected_crealm=expected_crealm, >@@ -1374,7 +1368,9 @@ class FAST_Tests(KDCBaseTest): > body_checksum_type=None, > kdc_options=kdc_options, > inner_req=inner_req, >- outer_req=outer_req) >+ outer_req=outer_req, >+ pac_request=None, >+ pac_options=pac_options) > > repeat = kdc_dict.pop('repeat', 1) > for _ in range(repeat): >-- >2.25.1 > > >From cf581249b1c7fe5fe88a7309461376a68e3551cc Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 17:46:02 +1200 >Subject: [PATCH 240/686] tests/krb5: Remove magic constants > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 571265257f335ba7f6f1b46daa0d657b8a8dff2b) >--- > python/samba/tests/krb5/fast_tests.py | 2 +- > python/samba/tests/krb5/kdc_base_test.py | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index e10db90a57e..29a666aad5e 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1466,7 +1466,7 @@ class FAST_Tests(KDCBaseTest): > > samdb = self.get_samdb() > >- krbtgt_rid = 502 >+ krbtgt_rid = security.DOMAIN_RID_KRBTGT > krbtgt_sid = '%s-%d' % (samdb.get_domain_sid(), krbtgt_rid) > > res = samdb.search(base='<SID=%s>' % krbtgt_sid, >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index b52452358cc..ac43b2eae1a 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -425,7 +425,7 @@ class KDCBaseTest(RawKerberosTest): > def download_krbtgt_creds(): > samdb = self.get_samdb() > >- krbtgt_rid = 502 >+ krbtgt_rid = security.DOMAIN_RID_KRBTGT > krbtgt_sid = '%s-%d' % (samdb.get_domain_sid(), krbtgt_rid) > > res = samdb.search(base='<SID=%s>' % krbtgt_sid, >-- >2.25.1 > > >From f6eb34a2d06e69ab00f8e33ad2c168d8a626340c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:13:11 +1200 >Subject: [PATCH 241/686] tests/krb5: Allow specifying ticket flags expected to > be set or reset > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 85ddfc1afcf21797dab15431a5f375444c4d316e) >--- > python/samba/tests/krb5/fast_tests.py | 11 +++++++ > python/samba/tests/krb5/raw_testcase.py | 40 +++++++++++++++++++++++-- > 2 files changed, 49 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 29a666aad5e..687f7532a64 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1309,6 +1309,13 @@ class FAST_Tests(KDCBaseTest): > inner_req = kdc_dict.pop('inner_req', None) > outer_req = kdc_dict.pop('outer_req', None) > >+ expected_flags = kdc_dict.pop('expected_flags', None) >+ if expected_flags is not None: >+ expected_flags = krb5_asn1.KDCOptions(expected_flags) >+ unexpected_flags = kdc_dict.pop('unexpected_flags', None) >+ if unexpected_flags is not None: >+ unexpected_flags = krb5_asn1.KDCOptions(unexpected_flags) >+ > if rep_type == KRB_AS_REP: > kdc_exchange_dict = self.as_exchange_dict( > expected_crealm=expected_crealm, >@@ -1316,6 +1323,8 @@ class FAST_Tests(KDCBaseTest): > expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > ticket_decryption_key=krbtgt_decryption_key, > generate_fast_fn=generate_fast_fn, > generate_fast_armor_fn=generate_fast_armor_fn, >@@ -1347,6 +1356,8 @@ class FAST_Tests(KDCBaseTest): > expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > ticket_decryption_key=target_decryption_key, > generate_fast_fn=generate_fast_fn, > generate_fast_armor_fn=generate_fast_armor_fn, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 58f246606d7..268f6ccc6bb 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -896,6 +896,24 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertIsNone(v) > >+ def assertElementFlags(self, obj, elem, expected, unexpected): >+ v = self.getElementValue(obj, elem) >+ self.assertIsNotNone(v) >+ if expected is not None: >+ self.assertIsInstance(expected, krb5_asn1.KDCOptions) >+ for i, flag in enumerate(expected): >+ if flag == 1: >+ self.assertEqual('1', v[i], >+ f"'{expected.namedValues[i]}' " >+ f"expected in {v}") >+ if unexpected is not None: >+ self.assertIsInstance(unexpected, krb5_asn1.KDCOptions) >+ for i, flag in enumerate(unexpected): >+ if flag == 1: >+ self.assertEqual('0', v[i], >+ f"'{unexpected.namedValues[i]}' " >+ f"unexpected in {v}") >+ > def get_KerberosTimeWithUsec(self, epoch=None, offset=None): > if epoch is None: > epoch = time.time() >@@ -1761,6 +1779,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_anon=False, > expected_srealm=None, > expected_sname=None, >+ expected_flags=None, >+ unexpected_flags=None, > ticket_decryption_key=None, > generate_fast_fn=None, > generate_fast_armor_fn=None, >@@ -1801,6 +1821,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, >+ 'expected_flags': expected_flags, >+ 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, > 'generate_fast_fn': generate_fast_fn, > 'generate_fast_armor_fn': generate_fast_armor_fn, >@@ -1837,6 +1859,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_anon=False, > expected_srealm=None, > expected_sname=None, >+ expected_flags=None, >+ unexpected_flags=None, > ticket_decryption_key=None, > generate_fast_fn=None, > generate_fast_armor_fn=None, >@@ -1877,6 +1901,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, >+ 'expected_flags': expected_flags, >+ 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, > 'generate_fast_fn': generate_fast_fn, > 'generate_fast_armor_fn': generate_fast_armor_fn, >@@ -2092,6 +2118,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_sname = kdc_exchange_dict['expected_sname'] > ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] > >+ expected_flags = kdc_exchange_dict.get('expected_flags') >+ unexpected_flags = kdc_exchange_dict.get('unexpected_flags') > > ticket = self.getElementValue(rep, 'ticket') > >@@ -2101,7 +2129,9 @@ class RawKerberosTest(TestCaseInTempDir): > > ticket_session_key = None > if ticket_private is not None: >- self.assertElementPresent(ticket_private, 'flags') >+ self.assertElementFlags(ticket_private, 'flags', >+ expected_flags, >+ unexpected_flags) > self.assertElementPresent(ticket_private, 'key') > ticket_key = self.getElementValue(ticket_private, 'key') > self.assertIsNotNone(ticket_key) >@@ -2137,7 +2167,9 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_exchange_dict['nonce']) > # TODO self.assertElementPresent(encpart_private, > # 'key-expiration') >- self.assertElementPresent(encpart_private, 'flags') >+ self.assertElementFlags(ticket_private, 'flags', >+ expected_flags, >+ unexpected_flags) > self.assertElementPresent(encpart_private, 'authtime') > if self.strict_checking: > self.assertElementPresent(encpart_private, 'starttime') >@@ -2843,6 +2875,8 @@ class RawKerberosTest(TestCaseInTempDir): > etypes, > padata, > kdc_options, >+ expected_flags=None, >+ unexpected_flags=None, > preauth_key=None, > ticket_decryption_key=None, > pac_request=None, >@@ -2886,6 +2920,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, > expected_salt=expected_salt, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > kdc_options=str(kdc_options), > pac_request=pac_request, > pac_options=pac_options) >-- >2.25.1 > > >From 074475a36d186c62d757fb2311a6b74853aa9015 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:15:17 +1200 >Subject: [PATCH 242/686] tests/krb5: Make time assertion less strict > >This assertion could fail if there was a time difference between the KDC >and the client. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 1974b872fb5a7da052305d01e2f1efc8d0637078) >--- > python/samba/tests/krb5/raw_testcase.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 268f6ccc6bb..5ae8fe4ba41 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2559,7 +2559,7 @@ class RawKerberosTest(TestCaseInTempDir): > current_time = time.time() > > self.assertLess(current_time - 300, rep_time) >- self.assertLess(rep_time, current_time) >+ self.assertLess(rep_time, current_time + 300) > > if all(etype not in client_as_etypes or etype not in proposed_etypes > for etype in (kcrypto.Enctype.AES256, >-- >2.25.1 > > >From 2c886e09480f88951c5a07683b48df6458726af6 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:34:20 +1200 >Subject: [PATCH 243/686] tests/krb5: Allow Kerberos requests to be sent to DC > or RODC > >If run inside the 'rodc' testing environment, 'DC_SERVER' and 'SERVER' >refer to the hostnames of the DC and RODC respectively, and this commit >allows either one of them to be used as the KDC for Kerberos exchanges. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 0afb548a0a3221730c4a81d51bc31e99ec90e334) >--- > python/samba/tests/krb5/kdc_base_test.py | 2 +- > python/samba/tests/krb5/raw_testcase.py | 39 +++++++++++++++--------- > 2 files changed, 26 insertions(+), 15 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index ac43b2eae1a..0755040a87a 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -116,7 +116,7 @@ class KDCBaseTest(RawKerberosTest): > lp = self.get_lp() > > session = system_session() >- type(self)._ldb = SamDB(url="ldap://%s" % self.host, >+ type(self)._ldb = SamDB(url="ldap://%s" % self.dc_host, > session_info=session, > credentials=creds, > lp=lp) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 5ae8fe4ba41..c03600f765b 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -418,6 +418,7 @@ class RawKerberosTest(TestCaseInTempDir): > super().setUpClass() > > cls.host = samba.tests.env_get_var_value('SERVER') >+ cls.dc_host = samba.tests.env_get_var_value('DC_SERVER') > > # A dictionary containing credentials that have already been > # obtained. >@@ -452,10 +453,10 @@ class RawKerberosTest(TestCaseInTempDir): > if self.do_hexdump: > sys.stderr.write("disconnect[%s]\n" % reason) > >- def _connect_tcp(self): >+ def _connect_tcp(self, host): > tcp_port = 88 > try: >- self.a = socket.getaddrinfo(self.host, tcp_port, socket.AF_UNSPEC, >+ self.a = socket.getaddrinfo(host, tcp_port, socket.AF_UNSPEC, > socket.SOCK_STREAM, socket.SOL_TCP, > 0) > self.s = socket.socket(self.a[0][0], self.a[0][1], self.a[0][2]) >@@ -468,11 +469,11 @@ class RawKerberosTest(TestCaseInTempDir): > self.s.close() > raise > >- def connect(self): >+ def connect(self, host): > self.assertNotConnected() >- self._connect_tcp() >+ self._connect_tcp(host) > if self.do_hexdump: >- sys.stderr.write("connected[%s]\n" % self.host) >+ sys.stderr.write("connected[%s]\n" % host) > > def env_get_var(self, varname, prefix, > fallback_default=True, >@@ -819,8 +820,10 @@ class RawKerberosTest(TestCaseInTempDir): > req, > asn1_print=None, > hexdump=None, >- timeout=None): >- self.connect() >+ timeout=None, >+ to_rodc=False): >+ host = self.host if to_rodc else self.dc_host >+ self.connect(host) > try: > self.send_pdu(req, asn1_print=asn1_print, hexdump=hexdump) > rep = self.recv_pdu( >@@ -1747,7 +1750,9 @@ class RawKerberosTest(TestCaseInTempDir): > req_body=req_body, > asn1Spec=req_asn1Spec()) > >- rep = self.send_recv_transaction(req_decoded) >+ to_rodc = kdc_exchange_dict['to_rodc'] >+ >+ rep = self.send_recv_transaction(req_decoded, to_rodc=to_rodc) > self.assertIsNotNone(rep) > > msg_type = self.getElementValue(rep, 'msg-type') >@@ -1804,7 +1809,8 @@ class RawKerberosTest(TestCaseInTempDir): > inner_req=None, > outer_req=None, > pac_request=None, >- pac_options=None): >+ pac_options=None, >+ to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () > elif not isinstance(expected_error_mode, collections.abc.Container): >@@ -1846,7 +1852,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'inner_req': inner_req, > 'outer_req': outer_req, > 'pac_request': pac_request, >- 'pac_options': pac_options >+ 'pac_options': pac_options, >+ 'to_rodc': to_rodc > } > if callback_dict is None: > callback_dict = {} >@@ -1884,7 +1891,8 @@ class RawKerberosTest(TestCaseInTempDir): > inner_req=None, > outer_req=None, > pac_request=None, >- pac_options=None): >+ pac_options=None, >+ to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () > elif not isinstance(expected_error_mode, collections.abc.Container): >@@ -1926,7 +1934,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'inner_req': inner_req, > 'outer_req': outer_req, > 'pac_request': pac_request, >- 'pac_options': pac_options >+ 'pac_options': pac_options, >+ 'to_rodc': to_rodc > } > if callback_dict is None: > callback_dict = {} >@@ -2880,7 +2889,8 @@ class RawKerberosTest(TestCaseInTempDir): > preauth_key=None, > ticket_decryption_key=None, > pac_request=None, >- pac_options=None): >+ pac_options=None, >+ to_rodc=False): > > def _generate_padata_copy(_kdc_exchange_dict, > _callback_dict, >@@ -2924,7 +2934,8 @@ class RawKerberosTest(TestCaseInTempDir): > unexpected_flags=unexpected_flags, > kdc_options=str(kdc_options), > pac_request=pac_request, >- pac_options=pac_options) >+ pac_options=pac_options, >+ to_rodc=to_rodc) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, > cname=cname, >-- >2.25.1 > > >From ab360428d1443302b9934bb953808e1adc1fd3e9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:43:41 +1200 >Subject: [PATCH 244/686] tests/krb5: Check for presence of 'renew-till' > element > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 9cba5f9a1b098e49315e2e3d4c0b626884c04a64) >--- > python/samba/tests/krb5/raw_testcase.py | 15 +++++++++++++-- > 1 file changed, 13 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index c03600f765b..45ce3c092ad 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2120,6 +2120,9 @@ class RawKerberosTest(TestCaseInTempDir): > canon_pos = len(tuple(krb5_asn1.KDCOptions('canonicalize'))) - 1 > canonicalize = (canon_pos < len(kdc_options) > and kdc_options[canon_pos] == '1') >+ renewable_pos = len(tuple(krb5_asn1.KDCOptions('renewable'))) - 1 >+ renewable = (renewable_pos < len(kdc_options) >+ and kdc_options[renewable_pos] == '1') > > expected_crealm = kdc_exchange_dict['expected_crealm'] > expected_cname = kdc_exchange_dict['expected_cname'] >@@ -2158,7 +2161,11 @@ class RawKerberosTest(TestCaseInTempDir): > if self.strict_checking: > self.assertElementPresent(ticket_private, 'starttime') > self.assertElementPresent(ticket_private, 'endtime') >- # TODO self.assertElementPresent(ticket_private, 'renew-till') >+ if renewable: >+ if self.strict_checking: >+ self.assertElementPresent(ticket_private, 'renew-till') >+ else: >+ self.assertElementMissing(ticket_private, 'renew-till') > # TODO self.assertElementMissing(ticket_private, 'caddr') > self.assertElementPresent(ticket_private, 'authorization-data') > >@@ -2183,7 +2190,11 @@ class RawKerberosTest(TestCaseInTempDir): > if self.strict_checking: > self.assertElementPresent(encpart_private, 'starttime') > self.assertElementPresent(encpart_private, 'endtime') >- # TODO self.assertElementPresent(encpart_private, 'renew-till') >+ if renewable: >+ if self.strict_checking: >+ self.assertElementPresent(encpart_private, 'renew-till') >+ else: >+ self.assertElementMissing(encpart_private, 'renew-till') > self.assertElementEqualUTF8(encpart_private, 'srealm', > expected_srealm) > self.assertElementEqualPrincipal(encpart_private, 'sname', >-- >2.25.1 > > >From 7f34f74fdd54a2183357bf6279c4430576dd59fc Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:45:57 +1200 >Subject: [PATCH 245/686] tests/krb5: Check 'caddr' element > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit d3106a8d35225e826d548d3bea0d42edc3998c38) >--- > python/samba/tests/krb5/raw_testcase.py | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 45ce3c092ad..9e47897dd76 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2166,7 +2166,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(ticket_private, 'renew-till') > else: > self.assertElementMissing(ticket_private, 'renew-till') >- # TODO self.assertElementMissing(ticket_private, 'caddr') >+ if self.strict_checking: >+ self.assertElementEqual(ticket_private, 'caddr', []) > self.assertElementPresent(ticket_private, 'authorization-data') > > encpart_session_key = None >@@ -2199,7 +2200,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_srealm) > self.assertElementEqualPrincipal(encpart_private, 'sname', > expected_sname) >- # TODO self.assertElementMissing(encpart_private, 'caddr') >+ if self.strict_checking: >+ self.assertElementEqual(encpart_private, 'caddr', []) > > sent_claims = self.sent_claims(kdc_exchange_dict) > >-- >2.25.1 > > >From 07b0e4223501bfc6dbb87b355854d6182c6eb172 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:47:27 +1200 >Subject: [PATCH 246/686] tests/krb5: Check for presence of 'key-expiration' > element > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit c3b746290278f7b5c1dea676e3fa28b9f15bcf94) >--- > python/samba/tests/krb5/raw_testcase.py | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 9e47897dd76..e754794e48b 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2130,6 +2130,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_sname = kdc_exchange_dict['expected_sname'] > ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] > >+ rep_msg_type = kdc_exchange_dict['rep_msg_type'] >+ > expected_flags = kdc_exchange_dict.get('expected_flags') > unexpected_flags = kdc_exchange_dict.get('unexpected_flags') > >@@ -2182,8 +2184,13 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(encpart_private, 'last-req') > self.assertElementEqual(encpart_private, 'nonce', > kdc_exchange_dict['nonce']) >- # TODO self.assertElementPresent(encpart_private, >- # 'key-expiration') >+ if rep_msg_type == KRB_AS_REP: >+ if self.strict_checking: >+ self.assertElementPresent(encpart_private, >+ 'key-expiration') >+ else: >+ self.assertElementMissing(encpart_private, >+ 'key-expiration') > self.assertElementFlags(ticket_private, 'flags', > expected_flags, > unexpected_flags) >-- >2.25.1 > > >From 78578a25898d9d4464ecd4f072737732006f465f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 3 Sep 2021 09:18:32 +1200 >Subject: [PATCH 247/686] tests/krb5: Create testing accounts in appropriate > containers > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Tue Sep 14 00:01:44 UTC 2021 on sn-devel-184 > >(cherry picked from commit 01378a52a1cf0b6855492673455013d5719be45b) >--- > python/samba/tests/krb5/kdc_base_test.py | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 0755040a87a..49a3227c26e 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -34,6 +34,8 @@ from samba.drs_utils import drsuapi_connect > from samba.dsdb import ( > DS_DOMAIN_FUNCTION_2000, > DS_DOMAIN_FUNCTION_2008, >+ DS_GUID_COMPUTERS_CONTAINER, >+ DS_GUID_USERS_CONTAINER, > UF_WORKSTATION_TRUST_ACCOUNT, > UF_NORMAL_ACCOUNT > ) >@@ -158,7 +160,10 @@ class KDCBaseTest(RawKerberosTest): > which is used by tearDownClass to clean up the created accounts. > ''' > if ou is None: >- ou = ldb.domain_dn() >+ guid = (DS_GUID_COMPUTERS_CONTAINER if machine_account >+ else DS_GUID_USERS_CONTAINER) >+ >+ ou = ldb.get_wellknown_dn(ldb.get_default_basedn(), guid) > > dn = "CN=%s,%s" % (name, ou) > >-- >2.25.1 > > >From c6f62294aab668d3ef9436c624400b407067ec40 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:26:43 +1200 >Subject: [PATCH 248/686] tests/krb5: Allow specifying status code to be > checked > >This allows us to check the status code that may be sent in an error >reply to a TGS-REQ message. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 4ba5e82ae53410ec9a0bc7d47b181a88c15d9387) >--- > python/samba/tests/krb5/raw_testcase.py | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e754794e48b..f65811243ba 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1798,6 +1798,7 @@ class RawKerberosTest(TestCaseInTempDir): > check_kdc_private_fn=None, > callback_dict=None, > expected_error_mode=0, >+ expected_status=None, > client_as_etypes=None, > expected_salt=None, > authenticator_subkey=None, >@@ -1841,6 +1842,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'check_kdc_private_fn': check_kdc_private_fn, > 'callback_dict': callback_dict, > 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, > 'client_as_etypes': client_as_etypes, > 'expected_salt': expected_salt, > 'authenticator_subkey': authenticator_subkey, >@@ -1879,6 +1881,7 @@ class RawKerberosTest(TestCaseInTempDir): > check_padata_fn=None, > check_kdc_private_fn=None, > expected_error_mode=0, >+ expected_status=None, > callback_dict=None, > tgt=None, > armor_key=None, >@@ -1923,6 +1926,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'check_kdc_private_fn': check_kdc_private_fn, > 'callback_dict': callback_dict, > 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, > 'tgt': tgt, > 'body_checksum_type': body_checksum_type, > 'armor_key': armor_key, >@@ -2540,7 +2544,12 @@ class RawKerberosTest(TestCaseInTempDir): > status = int.from_bytes(pw_salt[:4], 'little') > flags = int.from_bytes(pw_salt[8:], 'little') > >+ expected_status = kdc_exchange_dict['expected_status'] >+ self.assertEqual(expected_status, status) >+ > self.assertEqual(3, flags) >+ else: >+ self.assertIsNone(kdc_exchange_dict.get('expected_status')) > > if enc_challenge is not None: > if not sent_enc_challenge: >-- >2.25.1 > > >From 633c8db5789c7b2bba0d2b06abfaa559aa13398e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 3 Sep 2021 09:40:02 +1200 >Subject: [PATCH 249/686] tests/krb5: Get expected cname from TGT for TGS-REQ > messages > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit a5186f92803009c81eca2957e1bf2eb0ff7b6dff) >--- > python/samba/tests/krb5/fast_tests.py | 15 +++++++-------- > 1 file changed, 7 insertions(+), 8 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 687f7532a64..e1ba4628994 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -179,18 +179,12 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_simple_tgs_wrong_principal(self): >- mach_creds = self.get_mach_creds() >- mach_name = mach_creds.get_username() >- expected_cname = self.PrincipalName_create( >- name_type=NT_PRINCIPAL, names=[mach_name]) >- > self._run_test_sequence([ > { > 'rep_type': KRB_TGS_REP, > 'expected_error_mode': 0, > 'use_fast': False, >- 'gen_tgt_fn': self.get_mach_tgt, >- 'expected_cname': expected_cname >+ 'gen_tgt_fn': self.get_mach_tgt > } > ]) > >@@ -1193,7 +1187,12 @@ class FAST_Tests(KDCBaseTest): > else: # KRB_TGS_REP > srealm = target_realm > >- expected_cname = kdc_dict.pop('expected_cname', client_cname) >+ if rep_type == KRB_TGS_REP: >+ tgt_cname = tgt.cname >+ else: >+ tgt_cname = client_cname >+ >+ expected_cname = kdc_dict.pop('expected_cname', tgt_cname) > expected_anon = kdc_dict.pop('expected_anon', > False) > expected_crealm = kdc_dict.pop('expected_crealm', client_realm) >-- >2.25.1 > > >From c9cfe7b9a4c3ff6e4a9b7eb62101cbda37b747a9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 3 Sep 2021 09:55:10 +1200 >Subject: [PATCH 250/686] tests/krb5: Get encpart decryption key from > kdc_exchange_dict > >Instead of using check_padata_fn to get the encpart decryption key, we >can get the key from the AS-REQ preauth phase or from the TGT, depending >on whether the message is an AS-REQ or a TGS-REQ. This allows removal of >check_padata_fn and some duplicated code. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 0e99382d73f44eed7e19e83e430938d587e762d0) >--- > python/samba/tests/krb5/fast_tests.py | 18 +--- > python/samba/tests/krb5/raw_testcase.py | 122 ++++++++++-------------- > 2 files changed, 54 insertions(+), 86 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index e1ba4628994..12235cd439e 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -45,7 +45,6 @@ from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, > KRB_AS_REP, > KRB_TGS_REP, >- KU_AS_REP_ENC_PART, > KU_TICKET, > NT_PRINCIPAL, > NT_SRV_INST, >@@ -1114,8 +1113,6 @@ class FAST_Tests(KDCBaseTest): > fast_cookie = None > preauth_etype_info2 = None > >- preauth_key = None >- > for kdc_dict in test_sequence: > rep_type = kdc_dict.pop('rep_type') > self.assertIn(rep_type, (KRB_AS_REP, KRB_TGS_REP)) >@@ -1249,13 +1246,6 @@ class FAST_Tests(KDCBaseTest): > padata): > return list(padata), req_body > >- def _check_padata_preauth_key(_kdc_exchange_dict, >- _callback_dict, >- _rep, >- _padata): >- as_rep_usage = KU_AS_REP_ENC_PART >- return preauth_key, as_rep_usage >- > pac_options = kdc_dict.pop('pac_options', '1') # claims support > > kdc_options = kdc_dict.pop('kdc_options', kdc_options_default) >@@ -1274,11 +1264,6 @@ class FAST_Tests(KDCBaseTest): > preauth_key = None > padata = [] > >- if rep_type == KRB_AS_REP: >- check_padata_fn = _check_padata_preauth_key >- else: >- check_padata_fn = self.check_simple_tgs_padata >- > if use_fast: > inner_padata = padata > outer_padata = [] >@@ -1332,13 +1317,13 @@ class FAST_Tests(KDCBaseTest): > generate_padata_fn=generate_padata_fn, > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, >- check_padata_fn=check_padata_fn, > check_kdc_private_fn=self.generic_check_kdc_private, > callback_dict={}, > expected_error_mode=expected_error_mode, > client_as_etypes=etypes, > expected_salt=expected_salt, > authenticator_subkey=authenticator_subkey, >+ preauth_key=preauth_key, > auth_data=auth_data, > armor_key=armor_key, > armor_tgt=armor_tgt, >@@ -1365,7 +1350,6 @@ class FAST_Tests(KDCBaseTest): > generate_padata_fn=generate_padata_fn, > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, >- check_padata_fn=check_padata_fn, > check_kdc_private_fn=self.generic_check_kdc_private, > expected_error_mode=expected_error_mode, > callback_dict={}, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index f65811243ba..164d06b9788 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1794,7 +1794,6 @@ class RawKerberosTest(TestCaseInTempDir): > generate_padata_fn=None, > check_error_fn=None, > check_rep_fn=None, >- check_padata_fn=None, > check_kdc_private_fn=None, > callback_dict=None, > expected_error_mode=0, >@@ -1802,6 +1801,7 @@ class RawKerberosTest(TestCaseInTempDir): > client_as_etypes=None, > expected_salt=None, > authenticator_subkey=None, >+ preauth_key=None, > armor_key=None, > armor_tgt=None, > armor_subkey=None, >@@ -1838,7 +1838,6 @@ class RawKerberosTest(TestCaseInTempDir): > 'generate_padata_fn': generate_padata_fn, > 'check_error_fn': check_error_fn, > 'check_rep_fn': check_rep_fn, >- 'check_padata_fn': check_padata_fn, > 'check_kdc_private_fn': check_kdc_private_fn, > 'callback_dict': callback_dict, > 'expected_error_mode': expected_error_mode, >@@ -1846,6 +1845,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'client_as_etypes': client_as_etypes, > 'expected_salt': expected_salt, > 'authenticator_subkey': authenticator_subkey, >+ 'preauth_key': preauth_key, > 'armor_key': armor_key, > 'armor_tgt': armor_tgt, > 'armor_subkey': armor_subkey, >@@ -1878,7 +1878,6 @@ class RawKerberosTest(TestCaseInTempDir): > generate_padata_fn=None, > check_error_fn=None, > check_rep_fn=None, >- check_padata_fn=None, > check_kdc_private_fn=None, > expected_error_mode=0, > expected_status=None, >@@ -1922,7 +1921,6 @@ class RawKerberosTest(TestCaseInTempDir): > 'generate_padata_fn': generate_padata_fn, > 'check_error_fn': check_error_fn, > 'check_rep_fn': check_rep_fn, >- 'check_padata_fn': check_padata_fn, > 'check_kdc_private_fn': check_kdc_private_fn, > 'callback_dict': callback_dict, > 'expected_error_mode': expected_error_mode, >@@ -1956,7 +1954,6 @@ class RawKerberosTest(TestCaseInTempDir): > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] > ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] >- check_padata_fn = kdc_exchange_dict['check_padata_fn'] > check_kdc_private_fn = kdc_exchange_dict['check_kdc_private_fn'] > rep_encpart_asn1Spec = kdc_exchange_dict['rep_encpart_asn1Spec'] > msg_type = kdc_exchange_dict['rep_msg_type'] >@@ -2004,41 +2001,37 @@ class RawKerberosTest(TestCaseInTempDir): > > ticket_checksum = None > >- encpart_decryption_key = None >- self.assertIsNotNone(check_padata_fn) >- if check_padata_fn is not None: >- # See if we can get the decryption key from the preauth phase >- encpart_decryption_key, encpart_decryption_usage = ( >- check_padata_fn(kdc_exchange_dict, callback_dict, >- rep, padata)) >- >- if armor_key is not None: >- pa_dict = self.get_pa_dict(padata) >- >- if PADATA_FX_FAST in pa_dict: >- fx_fast_data = pa_dict[PADATA_FX_FAST] >- fast_response = self.check_fx_fast_data(kdc_exchange_dict, >- fx_fast_data, >- armor_key, >- finished=True) >- >- if 'strengthen-key' in fast_response: >- strengthen_key = self.EncryptionKey_import( >- fast_response['strengthen-key']) >- encpart_decryption_key = ( >- self.generate_strengthen_reply_key( >- strengthen_key, >- encpart_decryption_key)) >- >- fast_finished = fast_response.get('finished', None) >- if fast_finished is not None: >- ticket_checksum = fast_finished['ticket-checksum'] >- >- self.check_rep_padata(kdc_exchange_dict, >- callback_dict, >- rep, >- fast_response['padata'], >- error_code=0) >+ # Get the decryption key for the encrypted part >+ encpart_decryption_key, encpart_decryption_usage = ( >+ self.get_preauth_key(kdc_exchange_dict)) >+ >+ if armor_key is not None: >+ pa_dict = self.get_pa_dict(padata) >+ >+ if PADATA_FX_FAST in pa_dict: >+ fx_fast_data = pa_dict[PADATA_FX_FAST] >+ fast_response = self.check_fx_fast_data(kdc_exchange_dict, >+ fx_fast_data, >+ armor_key, >+ finished=True) >+ >+ if 'strengthen-key' in fast_response: >+ strengthen_key = self.EncryptionKey_import( >+ fast_response['strengthen-key']) >+ encpart_decryption_key = ( >+ self.generate_strengthen_reply_key( >+ strengthen_key, >+ encpart_decryption_key)) >+ >+ fast_finished = fast_response.get('finished') >+ if fast_finished is not None: >+ ticket_checksum = fast_finished['ticket-checksum'] >+ >+ self.check_rep_padata(kdc_exchange_dict, >+ callback_dict, >+ rep, >+ fast_response['padata'], >+ error_code=0) > > ticket_private = None > self.assertIsNotNone(ticket_decryption_key) >@@ -2558,13 +2551,7 @@ class RawKerberosTest(TestCaseInTempDir): > armor_key = kdc_exchange_dict['armor_key'] > self.assertIsNotNone(armor_key) > >- check_padata_fn = kdc_exchange_dict['check_padata_fn'] >- padata = self.getElementValue(rep, 'padata') >- self.assertIsNotNone(check_padata_fn) >- preauth_key, _ = check_padata_fn(kdc_exchange_dict, >- callback_dict, >- rep, >- padata) >+ preauth_key, _ = self.get_preauth_key(kdc_exchange_dict) > > kdc_challenge_key = self.generate_kdc_challenge_key( > armor_key, preauth_key) >@@ -2790,21 +2777,25 @@ class RawKerberosTest(TestCaseInTempDir): > > return padata, req_body > >- def check_simple_tgs_padata(self, >- kdc_exchange_dict, >- callback_dict, >- rep, >- padata): >- tgt = kdc_exchange_dict['tgt'] >- authenticator_subkey = kdc_exchange_dict['authenticator_subkey'] >- if authenticator_subkey is not None: >- subkey = authenticator_subkey >- subkey_usage = KU_TGS_REP_ENC_PART_SUB_KEY >- else: >- subkey = tgt.session_key >- subkey_usage = KU_TGS_REP_ENC_PART_SESSION >+ def get_preauth_key(self, kdc_exchange_dict): >+ msg_type = kdc_exchange_dict['rep_msg_type'] >+ >+ if msg_type == KRB_AS_REP: >+ key = kdc_exchange_dict['preauth_key'] >+ usage = KU_AS_REP_ENC_PART >+ else: # KRB_TGS_REP >+ authenticator_subkey = kdc_exchange_dict['authenticator_subkey'] >+ if authenticator_subkey is not None: >+ key = authenticator_subkey >+ usage = KU_TGS_REP_ENC_PART_SUB_KEY >+ else: >+ tgt = kdc_exchange_dict['tgt'] >+ key = tgt.session_key >+ usage = KU_TGS_REP_ENC_PART_SESSION >+ >+ self.assertIsNotNone(key) > >- return subkey, subkey_usage >+ return key, usage > > def generate_armor_key(self, subkey, session_key): > armor_key = kcrypto.cf2(subkey.key, >@@ -2926,13 +2917,6 @@ class RawKerberosTest(TestCaseInTempDir): > req_body): > return padata, req_body > >- def _check_padata_preauth_key(_kdc_exchange_dict, >- _callback_dict, >- rep, >- padata): >- as_rep_usage = KU_AS_REP_ENC_PART >- return preauth_key, as_rep_usage >- > if not expected_error_mode: > check_error_fn = None > check_rep_fn = self.generic_check_kdc_rep >@@ -2954,13 +2938,13 @@ class RawKerberosTest(TestCaseInTempDir): > generate_padata_fn=generate_padata_fn, > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, >- check_padata_fn=_check_padata_preauth_key, > check_kdc_private_fn=self.generic_check_kdc_private, > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, > expected_salt=expected_salt, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, >+ preauth_key=preauth_key, > kdc_options=str(kdc_options), > pac_request=pac_request, > pac_options=pac_options, >-- >2.25.1 > > >From d7a8dba997028c0bf654da8f69694feabff26855 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 3 Sep 2021 15:36:24 +1200 >Subject: [PATCH 251/686] tests/krb5: Add get_cached_creds() method to create > persistent accounts for testing > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit c9fd8ffd8927ef42fd555e690f966f65aa01332e) >--- > python/samba/tests/krb5/fast_tests.py | 2 +- > python/samba/tests/krb5/kdc_base_test.py | 191 +++++++++++++++-------- > 2 files changed, 125 insertions(+), 68 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 12235cd439e..106b9b1fb78 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1108,7 +1108,7 @@ class FAST_Tests(KDCBaseTest): > target_sname = self.PrincipalName_create( > name_type=NT_SRV_INST, names=[target_service, target_username]) > target_decryption_key = self.TicketDecryptionKey_from_creds( >- target_creds, etype=kcrypto.Enctype.RC4) >+ target_creds) > > fast_cookie = None > preauth_etype_info2 = None >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 49a3227c26e..b2b9d87c3af 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -22,6 +22,7 @@ from datetime import datetime, timezone > import tempfile > import binascii > import collections >+import secrets > > from collections import namedtuple > import ldb >@@ -37,7 +38,10 @@ from samba.dsdb import ( > DS_GUID_COMPUTERS_CONTAINER, > DS_GUID_USERS_CONTAINER, > UF_WORKSTATION_TRUST_ACCOUNT, >- UF_NORMAL_ACCOUNT >+ UF_NO_AUTH_DATA_REQUIRED, >+ UF_NORMAL_ACCOUNT, >+ UF_NOT_DELEGATED, >+ UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION > ) > from samba.ndr import ndr_pack, ndr_unpack > from samba import net >@@ -88,9 +92,17 @@ class KDCBaseTest(RawKerberosTest): > > cls._functional_level = None > >+ # An identifier to ensure created accounts have unique names. Windows >+ # caches accounts based on usernames, so account names being different >+ # across test runs avoids previous test runs affecting the results. >+ cls.account_base = f'krb5_{secrets.token_hex(5)}_' >+ cls.account_id = 0 >+ > # A set containing DNs of accounts created as part of testing. > cls.accounts = set() > >+ cls.account_cache = {} >+ > @classmethod > def tearDownClass(cls): > # Clean up any accounts created by create_account. This is >@@ -322,24 +334,113 @@ class KDCBaseTest(RawKerberosTest): > creds.set_tgs_supported_enctypes(supported_enctypes) > creds.set_ap_supported_enctypes(supported_enctypes) > >- def get_client_creds(self, >- allow_missing_password=False, >- allow_missing_keys=True): >- def create_client_account(): >- samdb = self.get_samdb() >+ def get_cached_creds(self, *, >+ machine_account, >+ opts=None): >+ if opts is None: >+ opts = {} >+ >+ opts_default = { >+ 'no_auth_data_required': False, >+ 'supported_enctypes': None, >+ 'not_delegated': False, >+ 'allowed_to_delegate_to': None, >+ 'trusted_to_auth_for_delegation': False, >+ 'fast_support': False >+ } >+ >+ account_opts = { >+ 'machine_account': machine_account, >+ **opts_default, >+ **opts >+ } >+ >+ cache_key = tuple(sorted(account_opts.items())) >+ >+ creds = self.account_cache.get(cache_key) >+ if creds is None: >+ creds = self.create_account_opts(**account_opts) >+ self.account_cache[cache_key] = creds >+ >+ return creds >+ >+ def create_account_opts(self, *, >+ machine_account, >+ no_auth_data_required, >+ supported_enctypes, >+ not_delegated, >+ allowed_to_delegate_to, >+ trusted_to_auth_for_delegation, >+ fast_support): >+ if machine_account: >+ self.assertFalse(not_delegated) >+ else: >+ self.assertIsNone(allowed_to_delegate_to) >+ self.assertFalse(trusted_to_auth_for_delegation) > >- creds, dn = self.create_account(samdb, 'kdctestclient') >+ samdb = self.get_samdb() > >- res = samdb.search(base=dn, >- scope=ldb.SCOPE_BASE, >- attrs=['msDS-KeyVersionNumber']) >- kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >- creds.set_kvno(kvno) >+ user_name = self.account_base + str(self.account_id) >+ type(self).account_id += 1 > >- keys = self.get_keys(samdb, dn) >- self.creds_set_keys(creds, keys) >+ user_account_control = 0 >+ if trusted_to_auth_for_delegation: >+ user_account_control |= UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION >+ if not_delegated: >+ user_account_control |= UF_NOT_DELEGATED >+ if no_auth_data_required: >+ user_account_control |= UF_NO_AUTH_DATA_REQUIRED > >- return creds >+ details = {} >+ >+ enctypes = supported_enctypes >+ if fast_support: >+ fast_bits = (security.KERB_ENCTYPE_FAST_SUPPORTED | >+ security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >+ security.KERB_ENCTYPE_CLAIMS_SUPPORTED) >+ enctypes = (enctypes or 0) | fast_bits >+ >+ if enctypes is not None: >+ details['msDS-SupportedEncryptionTypes'] = str(enctypes) >+ >+ if allowed_to_delegate_to: >+ details['msDS-AllowedToDelegateTo'] = allowed_to_delegate_to >+ >+ if machine_account: >+ spn = 'host/' + user_name >+ else: >+ spn = None >+ >+ creds, dn = self.create_account(samdb, user_name, >+ machine_account=machine_account, >+ spn=spn, >+ additional_details=details, >+ account_control=user_account_control) >+ >+ res = samdb.search(base=dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KeyVersionNumber']) >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ creds.set_kvno(kvno) >+ >+ keys = self.get_keys(samdb, dn) >+ self.creds_set_keys(creds, keys) >+ >+ if machine_account: >+ if supported_enctypes is not None: >+ tgs_enctypes = supported_enctypes >+ else: >+ tgs_enctypes = security.KERB_ENCTYPE_RC4_HMAC_MD5 >+ >+ creds.set_tgs_supported_enctypes(tgs_enctypes) >+ >+ return creds >+ >+ def get_client_creds(self, >+ allow_missing_password=False, >+ allow_missing_keys=True): >+ def create_client_account(): >+ return self.get_cached_creds(machine_account=False) > > c = self._get_krb5_creds(prefix='CLIENT', > allow_missing_password=allow_missing_password, >@@ -351,32 +452,8 @@ class KDCBaseTest(RawKerberosTest): > allow_missing_password=False, > allow_missing_keys=True): > def create_mach_account(): >- samdb = self.get_samdb() >- >- mach_name = 'kdctestmac' >- details = { >- 'msDS-SupportedEncryptionTypes': str( >- security.KERB_ENCTYPE_FAST_SUPPORTED | >- security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >- security.KERB_ENCTYPE_CLAIMS_SUPPORTED >- ) >- } >- >- creds, dn = self.create_account(samdb, mach_name, >- machine_account=True, >- spn='host/' + mach_name, >- additional_details=details) >- >- res = samdb.search(base=dn, >- scope=ldb.SCOPE_BASE, >- attrs=['msDS-KeyVersionNumber']) >- kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >- creds.set_kvno(kvno) >- >- keys = self.get_keys(samdb, dn) >- self.creds_set_keys(creds, keys) >- >- return creds >+ return self.get_cached_creds(machine_account=True, >+ opts={'fast_support': True}) > > c = self._get_krb5_creds(prefix='MAC', > allow_missing_password=allow_missing_password, >@@ -388,32 +465,12 @@ class KDCBaseTest(RawKerberosTest): > allow_missing_password=False, > allow_missing_keys=True): > def create_service_account(): >- samdb = self.get_samdb() >- >- mach_name = 'kdctestservice' >- details = { >- 'msDS-SupportedEncryptionTypes': str( >- security.KERB_ENCTYPE_FAST_SUPPORTED | >- security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >- security.KERB_ENCTYPE_CLAIMS_SUPPORTED >- ) >- } >- >- creds, dn = self.create_account(samdb, mach_name, >- machine_account=True, >- spn='host/' + mach_name, >- additional_details=details) >- >- res = samdb.search(base=dn, >- scope=ldb.SCOPE_BASE, >- attrs=['msDS-KeyVersionNumber']) >- kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >- creds.set_kvno(kvno) >- >- keys = self.get_keys(samdb, dn) >- self.creds_set_keys(creds, keys) >- >- return creds >+ return self.get_cached_creds( >+ machine_account=True, >+ opts={ >+ 'trusted_to_auth_for_delegation': True, >+ 'fast_support': True >+ }) > > c = self._get_krb5_creds(prefix='SERVICE', > allow_missing_password=allow_missing_password, >-- >2.25.1 > > >From 799340e07ac739a8516de8ecf901c078857db384 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 8 Sep 2021 11:28:52 +1200 >Subject: [PATCH 252/686] tests/krb5: Generate padata for FAST tests > >This gives us access to parameters of kdc_exchange_dict and enables us >to simplify the logic. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 943079fd94fec66cdc2ba4ea1b2beb2971473004) >--- > python/samba/tests/krb5/fast_tests.py | 101 ++++++++++++++++---------- > 1 file changed, 61 insertions(+), 40 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 106b9b1fb78..8024b92f445 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1017,19 +1017,6 @@ class FAST_Tests(KDCBaseTest): > # challenge is only considered a replay if the ciphertext is identical > # to a previous challenge. Windows does not perform this check. > >- class GenerateEncChallengePadataReplay: >- def __init__(replay): >- replay._padata = None >- >- def __call__(replay, key, armor_key): >- if replay._padata is None: >- client_challenge_key = ( >- self.generate_client_challenge_key(armor_key, key)) >- replay._padata = self.get_challenge_pa_data( >- client_challenge_key) >- >- return replay._padata >- > self._run_test_sequence([ > { > 'rep_type': KRB_AS_REP, >@@ -1042,28 +1029,72 @@ class FAST_Tests(KDCBaseTest): > 'rep_type': KRB_AS_REP, > 'expected_error_mode': 0, > 'use_fast': True, >- 'gen_padata_fn': GenerateEncChallengePadataReplay(), >+ 'gen_padata_fn': self.generate_enc_challenge_padata_replay, > 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, > 'gen_armor_tgt_fn': self.get_mach_tgt, > 'repeat': 2 > } > ]) > >- def generate_enc_timestamp_padata(self, key, _armor_key): >- return self.get_enc_timestamp_pa_data_from_key(key) >+ def generate_enc_timestamp_padata(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body): >+ key = kdc_exchange_dict['preauth_key'] >+ >+ padata = self.get_enc_timestamp_pa_data_from_key(key) >+ return [padata], req_body >+ >+ def generate_enc_challenge_padata(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body, >+ skew=0): >+ armor_key = kdc_exchange_dict['armor_key'] >+ key = kdc_exchange_dict['preauth_key'] > >- def generate_enc_challenge_padata(self, key, armor_key, skew=0): > client_challenge_key = ( > self.generate_client_challenge_key(armor_key, key)) >- return self.get_challenge_pa_data(client_challenge_key, skew=skew) >+ padata = self.get_challenge_pa_data(client_challenge_key, skew=skew) >+ return [padata], req_body >+ >+ def generate_enc_challenge_padata_wrong_key_kdc(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body): >+ armor_key = kdc_exchange_dict['armor_key'] >+ key = kdc_exchange_dict['preauth_key'] > >- def generate_enc_challenge_padata_wrong_key_kdc(self, key, armor_key): > kdc_challenge_key = ( > self.generate_kdc_challenge_key(armor_key, key)) >- return self.get_challenge_pa_data(kdc_challenge_key) >+ padata = self.get_challenge_pa_data(kdc_challenge_key) >+ return [padata], req_body > >- def generate_enc_challenge_padata_wrong_key(self, key, _armor_key): >- return self.get_challenge_pa_data(key) >+ def generate_enc_challenge_padata_wrong_key(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body): >+ key = kdc_exchange_dict['preauth_key'] >+ >+ padata = self.get_challenge_pa_data(key) >+ return [padata], req_body >+ >+ def generate_enc_challenge_padata_replay(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body): >+ padata = callback_dict.get('replay_padata') >+ >+ if padata is None: >+ armor_key = kdc_exchange_dict['armor_key'] >+ key = kdc_exchange_dict['preauth_key'] >+ >+ client_challenge_key = ( >+ self.generate_client_challenge_key(armor_key, key)) >+ padata = self.get_challenge_pa_data(client_challenge_key) >+ callback_dict['replay_padata'] = padata >+ >+ return [padata], req_body > > def generate_empty_fast(self, > _kdc_exchange_dict, >@@ -1251,35 +1282,25 @@ class FAST_Tests(KDCBaseTest): > kdc_options = kdc_dict.pop('kdc_options', kdc_options_default) > > gen_padata_fn = kdc_dict.pop('gen_padata_fn', None) >- if gen_padata_fn is not None: >- self.assertEqual(KRB_AS_REP, rep_type) >+ >+ if rep_type == KRB_AS_REP and gen_padata_fn is not None: > self.assertIsNotNone(preauth_etype_info2) > > preauth_key = self.PasswordKey_from_etype_info2( > client_creds, > preauth_etype_info2[0], > client_creds.get_kvno()) >- padata = [gen_padata_fn(preauth_key, armor_key)] > else: > preauth_key = None >- padata = [] > > if use_fast: >- inner_padata = padata >- outer_padata = [] >+ generate_fast_padata_fn = gen_padata_fn >+ generate_padata_fn = (functools.partial(_generate_padata_copy, >+ padata=[fast_cookie]) >+ if fast_cookie is not None else None) > else: >- inner_padata = [] >- outer_padata = padata >- >- if use_fast and fast_cookie is not None: >- outer_padata.append(fast_cookie) >- >- generate_fast_padata_fn = (functools.partial(_generate_padata_copy, >- padata=inner_padata) >- if inner_padata else None) >- generate_padata_fn = (functools.partial(_generate_padata_copy, >- padata=outer_padata) >- if outer_padata else None) >+ generate_fast_padata_fn = None >+ generate_padata_fn = gen_padata_fn > > gen_authdata_fn = kdc_dict.pop('gen_authdata_fn', None) > if gen_authdata_fn is not None: >-- >2.25.1 > > >From a7b6e26007e0114ae53c2712b817c4f78994d80a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 21:14:18 +1200 >Subject: [PATCH 253/686] tests/krb5: Sign-extend kvno from 32-bit integer > >This helps to avoid problems with RODC kvnos that have the high bit set. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 7bc52cecb442c4bcbd39372a8b98bb033e4d1540) >--- > python/samba/tests/krb5/raw_testcase.py | 3 +++ > 1 file changed, 3 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 164d06b9788..cca38fb9480 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -294,6 +294,9 @@ class KerberosCredentials(Credentials): > return self._get_krb5_etypes(self.ap_supported_enctypes) > > def set_kvno(self, kvno): >+ # Sign-extend from 32 bits. >+ if kvno & 1 << 31: >+ kvno |= -1 << 31 > self.kvno = kvno > > def get_kvno(self): >-- >2.25.1 > > >From f89d914da32752f4b6b86cac3f7bdf659db1c769 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 20:20:23 +1200 >Subject: [PATCH 254/686] tests/krb5: Add method to get RODC krbtgt credentials > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit a5bf7aad54b7053417a24ae0918ee42ceed7bf21) >--- > python/samba/tests/krb5/kdc_base_test.py | 74 ++++++++++++++++++++++++ > 1 file changed, 74 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index b2b9d87c3af..fd2e4d08cd3 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -89,6 +89,7 @@ class KDCBaseTest(RawKerberosTest): > cls._lp = None > > cls._ldb = None >+ cls._rodc_ldb = None > > cls._functional_level = None > >@@ -137,6 +138,30 @@ class KDCBaseTest(RawKerberosTest): > > return self._ldb > >+ def get_rodc_samdb(self): >+ if self._rodc_ldb is None: >+ creds = self.get_admin_creds() >+ lp = self.get_lp() >+ >+ session = system_session() >+ type(self)._rodc_ldb = SamDB(url="ldap://%s" % self.host, >+ session_info=session, >+ credentials=creds, >+ lp=lp, >+ am_rodc=True) >+ >+ return self._rodc_ldb >+ >+ def get_server_dn(self, samdb): >+ server = samdb.get_serverName() >+ >+ res = samdb.search(base=server, >+ scope=ldb.SCOPE_BASE, >+ attrs=['serverReference']) >+ dn = ldb.Dn(samdb, res[0]['serverReference'][0].decode('utf8')) >+ >+ return dn >+ > def get_domain_functional_level(self, ldb): > if self._functional_level is None: > res = ldb.search(base='', >@@ -478,6 +503,55 @@ class KDCBaseTest(RawKerberosTest): > fallback_creds_fn=create_service_account) > return c > >+ def get_rodc_krbtgt_creds(self, >+ require_keys=True, >+ require_strongest_key=False): >+ if require_strongest_key: >+ self.assertTrue(require_keys) >+ >+ def download_rodc_krbtgt_creds(): >+ samdb = self.get_samdb() >+ rodc_samdb = self.get_rodc_samdb() >+ >+ rodc_dn = self.get_server_dn(rodc_samdb) >+ >+ res = samdb.search(rodc_dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KrbTgtLink']) >+ krbtgt_dn = res[0]['msDS-KrbTgtLink'][0] >+ >+ res = samdb.search(krbtgt_dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['sAMAccountName', >+ 'msDS-KeyVersionNumber', >+ 'msDS-SecondaryKrbTgtNumber']) >+ krbtgt_dn = res[0].dn >+ username = str(res[0]['sAMAccountName']) >+ >+ creds = KerberosCredentials() >+ creds.set_domain(self.env_get_var('DOMAIN', 'RODC_KRBTGT')) >+ creds.set_realm(self.env_get_var('REALM', 'RODC_KRBTGT')) >+ creds.set_username(username) >+ >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ krbtgt_number = int(res[0]['msDS-SecondaryKrbTgtNumber'][0]) >+ >+ rodc_kvno = krbtgt_number << 16 | kvno >+ creds.set_kvno(rodc_kvno) >+ creds.set_dn(krbtgt_dn) >+ >+ keys = self.get_keys(samdb, krbtgt_dn) >+ self.creds_set_keys(creds, keys) >+ >+ return creds >+ >+ c = self._get_krb5_creds(prefix='RODC_KRBTGT', >+ allow_missing_password=True, >+ allow_missing_keys=not require_keys, >+ require_strongest_key=require_strongest_key, >+ fallback_creds_fn=download_rodc_krbtgt_creds) >+ return c >+ > def get_krbtgt_creds(self, > require_keys=True, > require_strongest_key=False): >-- >2.25.1 > > >From b792fc97ba7f47e1908b14a88f29d764e26f4422 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 20:58:01 +1200 >Subject: [PATCH 255/686] tests/krb5: Add get_secrets() method to get the > secret attributes of a DN > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit af633992e31e839cdd7f77740c1f25d129be2f79) >--- > python/samba/tests/krb5/kdc_base_test.py | 26 +++++++++++++++++++----- > 1 file changed, 21 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index fd2e4d08cd3..3681d26bb83 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -250,7 +250,9 @@ class KDCBaseTest(RawKerberosTest): > > return (creds, dn) > >- def get_keys(self, samdb, dn): >+ def get_secrets(self, samdb, dn, >+ destination_dsa_guid, >+ source_dsa_invocation_id): > admin_creds = self.get_admin_creds() > > dns_hostname = samdb.host_dns_name() >@@ -258,15 +260,13 @@ class KDCBaseTest(RawKerberosTest): > self.get_lp(), > admin_creds) > >- destination_dsa_guid = misc.GUID(samdb.get_ntds_GUID()) >- > req = drsuapi.DsGetNCChangesRequest8() > > req.destination_dsa_guid = destination_dsa_guid >- req.source_dsa_invocation_id = misc.GUID() >+ req.source_dsa_invocation_id = source_dsa_invocation_id > > naming_context = drsuapi.DsReplicaObjectIdentifier() >- naming_context.dn = str(dn) >+ naming_context.dn = dn > > req.naming_context = naming_context > >@@ -299,9 +299,25 @@ class KDCBaseTest(RawKerberosTest): > req.mapping_ctr.mappings = None > > _, ctr = bind.DsGetNCChanges(handle, 8, req) >+ >+ self.assertEqual(1, ctr.object_count) >+ > identifier = ctr.first_object.object.identifier > attributes = ctr.first_object.object.attribute_ctr.attributes > >+ self.assertEqual(dn, identifier.dn) >+ >+ return bind, identifier, attributes >+ >+ def get_keys(self, samdb, dn): >+ admin_creds = self.get_admin_creds() >+ >+ bind, identifier, attributes = self.get_secrets( >+ samdb, >+ str(dn), >+ destination_dsa_guid=misc.GUID(samdb.get_ntds_GUID()), >+ source_dsa_invocation_id=misc.GUID()) >+ > rid = identifier.sid.split()[1] > > net_ctx = net.Net(admin_creds) >-- >2.25.1 > > >From 362772d3bfa7eddd90d1223ab56bb7197ab182fc Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 22:13:24 +1200 >Subject: [PATCH 256/686] tests/krb5: Allow replicating accounts to the RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 3cc9e77f38f6698aa01abca4285a520c7c0cd2ac) >--- > python/samba/tests/krb5/kdc_base_test.py | 141 ++++++++++++++++++++++- > 1 file changed, 139 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 3681d26bb83..56102cfc4ea 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -31,8 +31,9 @@ from samba import generate_random_password > from samba.auth import system_session > from samba.credentials import Credentials, SPECIFIED, MUST_USE_KERBEROS > from samba.dcerpc import drsblobs, drsuapi, misc, krb5pac, krb5ccache, security >-from samba.drs_utils import drsuapi_connect >+from samba.drs_utils import drs_Replicate, drsuapi_connect > from samba.dsdb import ( >+ DSDB_SYNTAX_BINARY_DN, > DS_DOMAIN_FUNCTION_2000, > DS_DOMAIN_FUNCTION_2008, > DS_GUID_COMPUTERS_CONTAINER, >@@ -45,7 +46,7 @@ from samba.dsdb import ( > ) > from samba.ndr import ndr_pack, ndr_unpack > from samba import net >-from samba.samdb import SamDB >+from samba.samdb import SamDB, dsdb_Dn > > from samba.tests import delete_force > import samba.tests.krb5.kcrypto as kcrypto >@@ -104,12 +105,20 @@ class KDCBaseTest(RawKerberosTest): > > cls.account_cache = {} > >+ cls.ldb_cleanups = [] >+ > @classmethod > def tearDownClass(cls): > # Clean up any accounts created by create_account. This is > # done in tearDownClass() rather than tearDown(), so that > # accounts need only be created once for permutation tests. > if cls._ldb is not None: >+ for cleanup in reversed(cls.ldb_cleanups): >+ try: >+ cls._ldb.modify(cleanup) >+ except ldb.LdbError: >+ pass >+ > for dn in cls.accounts: > delete_force(cls._ldb, dn) > super().tearDownClass() >@@ -250,6 +259,76 @@ class KDCBaseTest(RawKerberosTest): > > return (creds, dn) > >+ def replicate_account_to_rodc(self, dn): >+ samdb = self.get_samdb() >+ rodc_samdb = self.get_rodc_samdb() >+ >+ repl_val = f'{samdb.get_dsServiceName()}:{dn}:SECRETS_ONLY' >+ >+ msg = ldb.Message() >+ msg.dn = ldb.Dn(rodc_samdb, '') >+ msg['replicateSingleObject'] = ldb.MessageElement( >+ repl_val, >+ ldb.FLAG_MOD_REPLACE, >+ 'replicateSingleObject') >+ >+ try: >+ # Try replication using the replicateSingleObject rootDSE >+ # operation. >+ rodc_samdb.modify(msg) >+ except ldb.LdbError as err: >+ enum, estr = err.args >+ self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM) >+ self.assertIn('rootdse_modify: unknown attribute to change!', >+ estr) >+ >+ # If that method wasn't supported, we may be in the rodc:local test >+ # environment, where we can try replicating to the local database. >+ >+ lp = self.get_lp() >+ >+ rodc_creds = Credentials() >+ rodc_creds.guess(lp) >+ rodc_creds.set_machine_account(lp) >+ >+ local_samdb = SamDB(url=None, session_info=system_session(), >+ credentials=rodc_creds, lp=lp) >+ >+ destination_dsa_guid = misc.GUID(local_samdb.get_ntds_GUID()) >+ >+ repl = drs_Replicate(f'ncacn_ip_tcp:{self.dc_host}[seal]', >+ lp, rodc_creds, >+ local_samdb, destination_dsa_guid) >+ >+ source_dsa_invocation_id = misc.GUID(samdb.invocation_id) >+ >+ repl.replicate(dn, >+ source_dsa_invocation_id, >+ destination_dsa_guid, >+ exop=drsuapi.DRSUAPI_EXOP_REPL_SECRET, >+ rodc=True) >+ >+ def check_revealed(self, dn, rodc_dn, revealed=True): >+ samdb = self.get_samdb() >+ >+ res = samdb.search(base=rodc_dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-RevealedUsers']) >+ >+ revealed_users = res[0].get('msDS-RevealedUsers') >+ if revealed_users is None: >+ self.assertFalse(revealed) >+ return >+ >+ revealed_dns = set(str(dsdb_Dn(samdb, str(user), >+ syntax_oid=DSDB_SYNTAX_BINARY_DN).dn) >+ for user in revealed_users) >+ >+ if revealed: >+ self.assertIn(str(dn), revealed_dns) >+ else: >+ self.assertNotIn(str(dn), revealed_dns) >+ > def get_secrets(self, samdb, dn, > destination_dsa_guid, > source_dsa_invocation_id): >@@ -375,6 +454,29 @@ class KDCBaseTest(RawKerberosTest): > creds.set_tgs_supported_enctypes(supported_enctypes) > creds.set_ap_supported_enctypes(supported_enctypes) > >+ def add_to_group(self, account_dn, group_dn, group_attr): >+ samdb = self.get_samdb() >+ >+ res = samdb.search(base=group_dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=[group_attr]) >+ orig_msg = res[0] >+ >+ members = list(orig_msg[group_attr]) >+ members.append(account_dn) >+ >+ msg = ldb.Message() >+ msg.dn = group_dn >+ msg[group_attr] = ldb.MessageElement(members, >+ ldb.FLAG_MOD_REPLACE, >+ group_attr) >+ >+ cleanup = samdb.msg_diff(msg, orig_msg) >+ self.ldb_cleanups.append(cleanup) >+ samdb.modify(msg) >+ >+ return cleanup >+ > def get_cached_creds(self, *, > machine_account, > opts=None): >@@ -382,6 +484,9 @@ class KDCBaseTest(RawKerberosTest): > opts = {} > > opts_default = { >+ 'allowed_replication': False, >+ 'denied_replication': False, >+ 'revealed_to_rodc': False, > 'no_auth_data_required': False, > 'supported_enctypes': None, > 'not_delegated': False, >@@ -407,6 +512,9 @@ class KDCBaseTest(RawKerberosTest): > > def create_account_opts(self, *, > machine_account, >+ allowed_replication, >+ denied_replication, >+ revealed_to_rodc, > no_auth_data_required, > supported_enctypes, > not_delegated, >@@ -420,6 +528,9 @@ class KDCBaseTest(RawKerberosTest): > self.assertFalse(trusted_to_auth_for_delegation) > > samdb = self.get_samdb() >+ rodc_samdb = self.get_rodc_samdb() >+ >+ rodc_dn = self.get_server_dn(rodc_samdb) > > user_name = self.account_base + str(self.account_id) > type(self).account_id += 1 >@@ -475,6 +586,32 @@ class KDCBaseTest(RawKerberosTest): > > creds.set_tgs_supported_enctypes(tgs_enctypes) > >+ # Handle secret replication to the RODC. >+ >+ if allowed_replication or revealed_to_rodc: >+ # Allow replicating this account's secrets if requested, or allow >+ # it only temporarily if we're about to replicate them. >+ allowed_cleanup = self.add_to_group( >+ dn, rodc_dn, >+ 'msDS-RevealOnDemandGroup') >+ >+ if revealed_to_rodc: >+ # Replicate this account's secrets to the RODC. >+ self.replicate_account_to_rodc(dn) >+ >+ if not allowed_replication: >+ # If we don't want replicating secrets to be allowed for this >+ # account, disable it again. >+ samdb.modify(allowed_cleanup) >+ >+ self.check_revealed(dn, >+ rodc_dn, >+ revealed=revealed_to_rodc) >+ >+ if denied_replication: >+ # Deny replicating this account's secrets to the RODC. >+ self.add_to_group(dn, rodc_dn, 'msDS-NeverRevealGroup') >+ > return creds > > def get_client_creds(self, >-- >2.25.1 > > >From 90355a8748a66ece047eaac14c1cee4d5c2d0b13 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 21:24:05 +1200 >Subject: [PATCH 257/686] tests/krb5: Create RODC account for testing > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit ef5666bc51ca80e1acdadd525a9c61762756c8e3) >--- > python/samba/tests/krb5/kdc_base_test.py | 114 +++++++++++++++++++++++ > 1 file changed, 114 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 56102cfc4ea..892d3aaf41f 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -42,8 +42,10 @@ from samba.dsdb import ( > UF_NO_AUTH_DATA_REQUIRED, > UF_NORMAL_ACCOUNT, > UF_NOT_DELEGATED, >+ UF_PARTIAL_SECRETS_ACCOUNT, > UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION > ) >+from samba.join import DCJoinContext > from samba.ndr import ndr_pack, ndr_unpack > from samba import net > from samba.samdb import SamDB, dsdb_Dn >@@ -105,6 +107,8 @@ class KDCBaseTest(RawKerberosTest): > > cls.account_cache = {} > >+ cls._rodc_ctx = None >+ > cls.ldb_cleanups = [] > > @classmethod >@@ -121,6 +125,10 @@ class KDCBaseTest(RawKerberosTest): > > for dn in cls.accounts: > delete_force(cls._ldb, dn) >+ >+ if cls._rodc_ctx is not None: >+ cls._rodc_ctx.cleanup_old_join(force=True) >+ > super().tearDownClass() > > def setUp(self): >@@ -171,6 +179,25 @@ class KDCBaseTest(RawKerberosTest): > > return dn > >+ def get_mock_rodc_ctx(self): >+ if self._rodc_ctx is None: >+ admin_creds = self.get_admin_creds() >+ lp = self.get_lp() >+ >+ rodc_name = 'KRB5RODC' >+ site_name = 'Default-First-Site-Name' >+ >+ type(self)._rodc_ctx = DCJoinContext(server=self.dc_host, >+ creds=admin_creds, >+ lp=lp, >+ site=site_name, >+ netbios_name=rodc_name, >+ targetdir=None, >+ domain=None) >+ self.create_rodc(self._rodc_ctx) >+ >+ return self._rodc_ctx >+ > def get_domain_functional_level(self, ldb): > if self._functional_level is None: > res = ldb.search(base='', >@@ -259,6 +286,49 @@ class KDCBaseTest(RawKerberosTest): > > return (creds, dn) > >+ def create_rodc(self, ctx): >+ ctx.nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn] >+ ctx.full_nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn] >+ ctx.krbtgt_dn = f'CN=krbtgt_{ctx.myname},CN=Users,{ctx.base_dn}' >+ >+ ctx.never_reveal_sid = [f'<SID={ctx.domsid}-{security.DOMAIN_RID_RODC_DENY}>', >+ f'<SID={security.SID_BUILTIN_ADMINISTRATORS}>', >+ f'<SID={security.SID_BUILTIN_SERVER_OPERATORS}>', >+ f'<SID={security.SID_BUILTIN_BACKUP_OPERATORS}>', >+ f'<SID={security.SID_BUILTIN_ACCOUNT_OPERATORS}>'] >+ ctx.reveal_sid = f'<SID={ctx.domsid}-{security.DOMAIN_RID_RODC_ALLOW}>' >+ >+ mysid = ctx.get_mysid() >+ admin_dn = f'<SID={mysid}>' >+ ctx.managedby = admin_dn >+ >+ ctx.userAccountControl = (UF_WORKSTATION_TRUST_ACCOUNT | >+ UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION | >+ UF_PARTIAL_SECRETS_ACCOUNT) >+ >+ ctx.connection_dn = f'CN=RODC Connection (FRS),{ctx.ntds_dn}' >+ ctx.secure_channel_type = misc.SEC_CHAN_RODC >+ ctx.RODC = True >+ ctx.replica_flags = (drsuapi.DRSUAPI_DRS_INIT_SYNC | >+ drsuapi.DRSUAPI_DRS_PER_SYNC | >+ drsuapi.DRSUAPI_DRS_GET_ANC | >+ drsuapi.DRSUAPI_DRS_NEVER_SYNCED | >+ drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING) >+ ctx.domain_replica_flags = ctx.replica_flags | drsuapi.DRSUAPI_DRS_CRITICAL_ONLY >+ >+ ctx.build_nc_lists() >+ >+ ctx.cleanup_old_join() >+ >+ try: >+ ctx.join_add_objects() >+ except Exception: >+ # cleanup the failed join (checking we still have a live LDB >+ # connection to the remote DC first) >+ ctx.refresh_ldb_connection() >+ ctx.cleanup_old_join() >+ raise >+ > def replicate_account_to_rodc(self, dn): > samdb = self.get_samdb() > rodc_samdb = self.get_rodc_samdb() >@@ -705,6 +775,50 @@ class KDCBaseTest(RawKerberosTest): > fallback_creds_fn=download_rodc_krbtgt_creds) > return c > >+ def get_mock_rodc_krbtgt_creds(self, >+ require_keys=True, >+ require_strongest_key=False): >+ if require_strongest_key: >+ self.assertTrue(require_keys) >+ >+ def create_rodc_krbtgt_account(): >+ samdb = self.get_samdb() >+ >+ rodc_ctx = self.get_mock_rodc_ctx() >+ >+ krbtgt_dn = rodc_ctx.new_krbtgt_dn >+ >+ res = samdb.search(base=ldb.Dn(samdb, krbtgt_dn), >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KeyVersionNumber', >+ 'msDS-SecondaryKrbTgtNumber']) >+ dn = res[0].dn >+ username = str(rodc_ctx.krbtgt_name) >+ >+ creds = KerberosCredentials() >+ creds.set_domain(self.env_get_var('DOMAIN', 'RODC_KRBTGT')) >+ creds.set_realm(self.env_get_var('REALM', 'RODC_KRBTGT')) >+ creds.set_username(username) >+ >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ krbtgt_number = int(res[0]['msDS-SecondaryKrbTgtNumber'][0]) >+ >+ rodc_kvno = krbtgt_number << 16 | kvno >+ creds.set_kvno(rodc_kvno) >+ creds.set_dn(dn) >+ >+ keys = self.get_keys(samdb, dn) >+ self.creds_set_keys(creds, keys) >+ >+ return creds >+ >+ c = self._get_krb5_creds(prefix='MOCK_RODC_KRBTGT', >+ allow_missing_password=True, >+ allow_missing_keys=not require_keys, >+ require_strongest_key=require_strongest_key, >+ fallback_creds_fn=create_rodc_krbtgt_account) >+ return c >+ > def get_krbtgt_creds(self, > require_keys=True, > require_strongest_key=False): >-- >2.25.1 > > >From 55cbfaf178bb739b74e894cb9fbf15256f4d151e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 21:24:31 +1200 >Subject: [PATCH 258/686] tests/krb5: Allow replicating accounts to the created > RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 35292bd32225b39ad7a03c3aa53027458f0671eb) >--- > python/samba/tests/krb5/kdc_base_test.py | 50 ++++++++++++++++++++++++ > 1 file changed, 50 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 892d3aaf41f..0e138352b06 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -378,6 +378,16 @@ class KDCBaseTest(RawKerberosTest): > exop=drsuapi.DRSUAPI_EXOP_REPL_SECRET, > rodc=True) > >+ def reveal_account_to_mock_rodc(self, dn): >+ samdb = self.get_samdb() >+ rodc_ctx = self.get_mock_rodc_ctx() >+ >+ self.get_secrets( >+ samdb, >+ dn, >+ destination_dsa_guid=rodc_ctx.ntds_guid, >+ source_dsa_invocation_id=misc.GUID(samdb.invocation_id)) >+ > def check_revealed(self, dn, rodc_dn, revealed=True): > samdb = self.get_samdb() > >@@ -555,8 +565,11 @@ class KDCBaseTest(RawKerberosTest): > > opts_default = { > 'allowed_replication': False, >+ 'allowed_replication_mock': False, > 'denied_replication': False, >+ 'denied_replication_mock': False, > 'revealed_to_rodc': False, >+ 'revealed_to_mock_rodc': False, > 'no_auth_data_required': False, > 'supported_enctypes': None, > 'not_delegated': False, >@@ -583,8 +596,11 @@ class KDCBaseTest(RawKerberosTest): > def create_account_opts(self, *, > machine_account, > allowed_replication, >+ allowed_replication_mock, > denied_replication, >+ denied_replication_mock, > revealed_to_rodc, >+ revealed_to_mock_rodc, > no_auth_data_required, > supported_enctypes, > not_delegated, >@@ -682,6 +698,40 @@ class KDCBaseTest(RawKerberosTest): > # Deny replicating this account's secrets to the RODC. > self.add_to_group(dn, rodc_dn, 'msDS-NeverRevealGroup') > >+ # Handle secret replication to the mock RODC. >+ >+ if allowed_replication_mock or revealed_to_mock_rodc: >+ # Allow replicating this account's secrets if requested, or allow >+ # it only temporarily if we want to add the account to the mock >+ # RODC's msDS-RevealedUsers. >+ rodc_ctx = self.get_mock_rodc_ctx() >+ mock_rodc_dn = ldb.Dn(samdb, rodc_ctx.acct_dn) >+ >+ allowed_mock_cleanup = self.add_to_group( >+ dn, mock_rodc_dn, >+ 'msDS-RevealOnDemandGroup') >+ >+ if revealed_to_mock_rodc: >+ # Request replicating this account's secrets to the mock RODC, >+ # which updates msDS-RevealedUsers. >+ self.reveal_account_to_mock_rodc(dn) >+ >+ if not allowed_replication_mock: >+ # If we don't want replicating secrets to be allowed for this >+ # account, disable it again. >+ samdb.modify(allowed_mock_cleanup) >+ >+ self.check_revealed(dn, >+ mock_rodc_dn, >+ revealed=revealed_to_mock_rodc) >+ >+ if denied_replication_mock: >+ # Deny replicating this account's secrets to the mock RODC. >+ rodc_ctx = self.get_mock_rodc_ctx() >+ mock_rodc_dn = ldb.Dn(samdb, rodc_ctx.acct_dn) >+ >+ self.add_to_group(dn, mock_rodc_dn, 'msDS-NeverRevealGroup') >+ > return creds > > def get_client_creds(self, >-- >2.25.1 > > >From f092170307582c2dff9feb6e78c9fbe9ecc47d84 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 10 Sep 2021 14:02:22 +1200 >Subject: [PATCH 259/686] python/join: Check for correct msDS-KrbTgtLink > attribute > >Previously, the wrong case was used when checking for this attribute, >which meant krbtgt accounts were not being cleaned up. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Noel Power <npower@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 21a7717359082feaddfdf42788648c3d7574c28e) >--- > python/samba/join.py | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > >diff --git a/python/samba/join.py b/python/samba/join.py >index 080bd1f6aac..80ed11d854f 100644 >--- a/python/samba/join.py >+++ b/python/samba/join.py >@@ -255,8 +255,9 @@ class DCJoinContext(object): > > ctx.del_noerror(res[0].dn, recursive=True) > >- if "msDS-Krbtgtlink" in res[0]: >- ctx.new_krbtgt_dn = res[0]["msDS-Krbtgtlink"][0] >+ krbtgt_dn = res[0].get('msDS-KrbTgtLink', idx=0) >+ if krbtgt_dn is not None: >+ ctx.new_krbtgt_dn = krbtgt_dn > ctx.del_noerror(ctx.new_krbtgt_dn) > > res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(), >@@ -334,7 +335,7 @@ class DCJoinContext(object): > attrs=["msDS-krbTgtLink", "userAccountControl", "serverReferenceBL", "rIDSetReferences"]) > if len(res) == 0: > raise Exception("Could not find domain member account '%s' to promote to a DC, use 'samba-tool domain join' instead'" % ctx.samname) >- if "msDS-krbTgtLink" in res[0] or "serverReferenceBL" in res[0] or "rIDSetReferences" in res[0]: >+ if "msDS-KrbTgtLink" in res[0] or "serverReferenceBL" in res[0] or "rIDSetReferences" in res[0]: > raise Exception("Account '%s' appears to be an active DC, use 'samba-tool domain join' if you must re-create this account" % ctx.samname) > if (int(res[0]["userAccountControl"][0]) & (samba.dsdb.UF_WORKSTATION_TRUST_ACCOUNT | > samba.dsdb.UF_SERVER_TRUST_ACCOUNT) == 0): >-- >2.25.1 > > >From 26822cafe852d7e38df8aecb5b9e169cdbeddaad Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 15 Sep 2021 20:56:28 +1200 >Subject: [PATCH 260/686] tests/krb5: Add helper method for modifying PACs > >This method can remove or replace a PAC in an authorization-data >container, while additionally returning the original PAC. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a281ae09bcf35277c830c4112567c72233fd66b8) >--- > python/samba/tests/krb5/raw_testcase.py | 45 +++++++++++++++++++++++++ > 1 file changed, 45 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index cca38fb9480..b7df1ac0879 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -42,6 +42,8 @@ from samba.tests import TestCaseInTempDir > > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( >+ AD_IF_RELEVANT, >+ AD_WIN2K_PAC, > FX_FAST_ARMOR_AP_REQUEST, > KDC_ERR_GENERIC, > KDC_ERR_PREAUTH_FAILED, >@@ -2848,6 +2850,49 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_blob) > self.assertEqual(expected_checksum, checksum) > >+ def replace_pac(self, auth_data, new_pac, expect_pac=True): >+ if new_pac is not None: >+ self.assertElementEqual(new_pac, 'ad-type', AD_WIN2K_PAC) >+ self.assertElementPresent(new_pac, 'ad-data') >+ >+ new_auth_data = [] >+ >+ ad_relevant = None >+ old_pac = None >+ >+ for authdata_elem in auth_data: >+ if authdata_elem['ad-type'] == AD_IF_RELEVANT: >+ ad_relevant = self.der_decode( >+ authdata_elem['ad-data'], >+ asn1Spec=krb5_asn1.AD_IF_RELEVANT()) >+ >+ relevant_elems = [] >+ for relevant_elem in ad_relevant: >+ if relevant_elem['ad-type'] == AD_WIN2K_PAC: >+ self.assertIsNone(old_pac, 'Multiple PACs detected') >+ old_pac = relevant_elem['ad-data'] >+ >+ if new_pac is not None: >+ relevant_elems.append(new_pac) >+ else: >+ relevant_elems.append(relevant_elem) >+ if expect_pac: >+ self.assertIsNotNone(old_pac, 'Expected PAC') >+ >+ ad_relevant = self.der_encode( >+ relevant_elems, >+ asn1Spec=krb5_asn1.AD_IF_RELEVANT()) >+ >+ authdata_elem = self.AuthorizationData_create(AD_IF_RELEVANT, >+ ad_relevant) >+ >+ new_auth_data.append(authdata_elem) >+ >+ if expect_pac: >+ self.assertIsNotNone(ad_relevant, 'Expected AD-RELEVANT') >+ >+ return new_auth_data, old_pac >+ > def get_outer_pa_dict(self, kdc_exchange_dict): > return self.get_pa_dict(kdc_exchange_dict['req_padata']) > >-- >2.25.1 > > >From 830ffa864e2db8cc1803e015f51ddb889d605378 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:22:28 +1200 >Subject: [PATCH 261/686] tests/krb5: Check correct flags element > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 0061fa2c2a26d990ed2e47441bca8797fc9be356) >--- > python/samba/tests/krb5/raw_testcase.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b7df1ac0879..632f69794e6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2193,7 +2193,7 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertElementMissing(encpart_private, > 'key-expiration') >- self.assertElementFlags(ticket_private, 'flags', >+ self.assertElementFlags(encpart_private, 'flags', > expected_flags, > unexpected_flags) > self.assertElementPresent(encpart_private, 'authtime') >-- >2.25.1 > > >From d889150033fca44536fdf0d45d6517812f8ff293 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:13:09 +1200 >Subject: [PATCH 262/686] tests/krb5: Refactor tgs_req() to use > _generic_kdc_exchange > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 2a4d53dc12aa785f696e53ae3376f67375ce455f) >--- > python/samba/tests/krb5/kdc_base_test.py | 78 +++++++++++++----------- > python/samba/tests/krb5/kdc_tgs_tests.py | 3 +- > python/samba/tests/krb5/raw_testcase.py | 1 - > source4/selftest/tests.py | 18 ++++-- > 4 files changed, 58 insertions(+), 42 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 0e138352b06..6a370d3036e 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -52,7 +52,11 @@ from samba.samdb import SamDB, dsdb_Dn > > from samba.tests import delete_force > import samba.tests.krb5.kcrypto as kcrypto >-from samba.tests.krb5.raw_testcase import KerberosCredentials, RawKerberosTest >+from samba.tests.krb5.raw_testcase import ( >+ KerberosCredentials, >+ KerberosTicketCreds, >+ RawKerberosTest >+) > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > AD_IF_RELEVANT, >@@ -66,7 +70,6 @@ from samba.tests.krb5.rfc4120_constants import ( > KU_AS_REP_ENC_PART, > KU_ENC_CHALLENGE_CLIENT, > KU_PA_ENC_TIMESTAMP, >- KU_TGS_REP_ENC_PART_SUB_KEY, > KU_TICKET, > NT_PRINCIPAL, > NT_SRV_HST, >@@ -1063,49 +1066,56 @@ class KDCBaseTest(RawKerberosTest): > else: > self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep) > >- def tgs_req(self, cname, sname, realm, ticket, key, etypes): >+ def tgs_req(self, cname, sname, realm, ticket, key, etypes, >+ expected_error_mode=0): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' > > kdc_options = "0" >- till = self.get_KerberosTime(offset=36000) >- padata = [] > > subkey = self.RandomKey(key.etype) > > (ctime, cusec) = self.get_KerberosTimeWithUsec() > >- req = self.TGS_REQ_create(padata=padata, >- cusec=cusec, >- ctime=ctime, >- ticket=ticket, >- kdc_options=str(kdc_options), >- cname=cname, >- realm=realm, >- sname=sname, >- from_time=None, >- till_time=till, >- renew_time=None, >- nonce=0x7ffffffe, >- etypes=etypes, >- addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, >- additional_tickets=None, >- ticket_session_key=key, >- authenticator_subkey=subkey) >- rep = self.send_recv_transaction(req) >- self.assertIsNotNone(rep) >+ tgt = KerberosTicketCreds(ticket, >+ key, >+ crealm=realm, >+ cname=cname) > >- msg_type = rep['msg-type'] >- enc_part = None >- if msg_type == KRB_TGS_REP: >- enc_part = subkey.decrypt( >- KU_TGS_REP_ENC_PART_SUB_KEY, rep['enc-part']['cipher']) >- enc_part = self.der_decode( >- enc_part, asn1Spec=krb5_asn1.EncTGSRepPart()) >- return (rep, enc_part) >+ if not expected_error_mode: >+ check_error_fn = None >+ check_rep_fn = self.generic_check_kdc_rep >+ else: >+ check_error_fn = self.generic_check_kdc_error >+ check_rep_fn = None >+ >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=realm, >+ expected_cname=cname, >+ expected_srealm=realm, >+ expected_sname=sname, >+ expected_error_mode=expected_error_mode, >+ check_error_fn=check_error_fn, >+ check_rep_fn=check_rep_fn, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ tgt=tgt, >+ authenticator_subkey=subkey, >+ kdc_options=str(kdc_options)) >+ >+ rep = self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=None, >+ realm=realm, >+ sname=sname, >+ etypes=etypes) >+ >+ if expected_error_mode: >+ enc_part = None >+ else: >+ ticket_creds = kdc_exchange_dict['rep_ticket_creds'] >+ enc_part = ticket_creds.encpart_private >+ >+ return rep, enc_part > > # Named tuple to contain values of interest when the PAC is decoded. > PacData = namedtuple( >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 97f9dd41339..dad9e6b88df 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -84,7 +84,8 @@ class KdcTgsTests(KDCBaseTest): > name_type=NT_PRINCIPAL, > names=["host", samdb.host_dns_name()]) > >- (rep, enc_part) = self.tgs_req(cname, sname, realm, ticket, key, etype) >+ (rep, enc_part) = self.tgs_req(cname, sname, realm, ticket, key, etype, >+ expected_error_mode=KDC_ERR_BADMATCH) > > self.assertIsNone( > enc_part, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 632f69794e6..7eba62b4022 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2039,7 +2039,6 @@ class RawKerberosTest(TestCaseInTempDir): > error_code=0) > > ticket_private = None >- self.assertIsNotNone(ticket_decryption_key) > if ticket_decryption_key is not None: > self.assertElementEqual(ticket_encpart, 'etype', > ticket_decryption_key.etype) >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 0b01639c041..979dd5124b2 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -726,22 +726,26 @@ planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_rpc", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > > for env in ["ad_dc", smbv1_disabled_testenv]: >@@ -1268,7 +1272,8 @@ planpythontestsuite( > "samba.tests.krb5.kdc_tgs_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > planpythontestsuite( > "ad_dc", >@@ -1283,7 +1288,8 @@ planpythontestsuite( > "samba.tests.krb5.ms_kile_client_principal_lookup_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > > for env in [ >-- >2.25.1 > > >From 3f1977e5a767734a471c04232f0ba789a44be4e4 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:16:27 +1200 >Subject: [PATCH 263/686] tests/krb5: Allow tgs_req() to send additional padata > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1f0654b8facf3b9b2288d2569a573ff3a5ca4a82) >--- > python/samba/tests/krb5/kdc_base_test.py | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 6a370d3036e..57ef1bceb49 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1067,7 +1067,7 @@ class KDCBaseTest(RawKerberosTest): > self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep) > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, >- expected_error_mode=0): >+ expected_error_mode=0, padata=None): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1090,6 +1090,12 @@ class KDCBaseTest(RawKerberosTest): > check_error_fn = self.generic_check_kdc_error > check_rep_fn = None > >+ def generate_padata(_kdc_exchange_dict, >+ _callback_dict, >+ req_body): >+ >+ return padata, req_body >+ > kdc_exchange_dict = self.tgs_exchange_dict( > expected_crealm=realm, > expected_cname=cname, >@@ -1099,6 +1105,7 @@ class KDCBaseTest(RawKerberosTest): > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, > check_kdc_private_fn=self.generic_check_kdc_private, >+ generate_padata_fn=generate_padata if padata is not None else None, > tgt=tgt, > authenticator_subkey=subkey, > kdc_options=str(kdc_options)) >-- >2.25.1 > > >From 5ef072a5750040f3c7d69ab8a26ddf9a8ab9ddfb Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:18:12 +1200 >Subject: [PATCH 264/686] tests/krb5: Allow tgs_req() to specify different > kdc-options > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1a3426da54463c3e454c1b76c3df4e96882e6aa9) >--- > python/samba/tests/krb5/kdc_base_test.py | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 57ef1bceb49..c448f127c0c 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1067,13 +1067,11 @@ class KDCBaseTest(RawKerberosTest): > self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep) > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, >- expected_error_mode=0, padata=None): >+ expected_error_mode=0, padata=None, kdc_options=0): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' > >- kdc_options = "0" >- > subkey = self.RandomKey(key.etype) > > (ctime, cusec) = self.get_KerberosTimeWithUsec() >-- >2.25.1 > > >From 24442c8f954ab571bf7950fcb3293377a8ee8c1c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:25:01 +1200 >Subject: [PATCH 265/686] tests/krb5: Allow tgs_req() to send requests to the > RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 6403a09d94ab54f89d6e50601ae6b19ab7e6aae7) >--- > python/samba/tests/krb5/kdc_base_test.py | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index c448f127c0c..5ef08eb32fe 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1067,7 +1067,8 @@ class KDCBaseTest(RawKerberosTest): > self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep) > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, >- expected_error_mode=0, padata=None, kdc_options=0): >+ expected_error_mode=0, padata=None, kdc_options=0, >+ to_rodc=False): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1106,7 +1107,8 @@ class KDCBaseTest(RawKerberosTest): > generate_padata_fn=generate_padata if padata is not None else None, > tgt=tgt, > authenticator_subkey=subkey, >- kdc_options=str(kdc_options)) >+ kdc_options=str(kdc_options), >+ to_rodc=to_rodc) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, > cname=None, >-- >2.25.1 > > >From c18d3cb70884af92c9a5b398a3de3a50f7c75def Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:52:46 +1200 >Subject: [PATCH 266/686] tests/krb5: Allow as_req() to specify different > kdc-options > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a5e62d681d81a422bac7bd89dc27ef2314d77457) >--- > python/samba/tests/krb5/kdc_base_test.py | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 5ef08eb32fe..ae62c9d5fc6 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -913,12 +913,11 @@ class KDCBaseTest(RawKerberosTest): > fallback_creds_fn=download_krbtgt_creds) > return c > >- def as_req(self, cname, sname, realm, etypes, padata=None): >+ def as_req(self, cname, sname, realm, etypes, padata=None, kdc_options=0): > '''Send a Kerberos AS_REQ, returns the undecoded response > ''' > > till = self.get_KerberosTime(offset=36000) >- kdc_options = 0 > > req = self.AS_REQ_create(padata=padata, > kdc_options=str(kdc_options), >-- >2.25.1 > > >From dcc4a3fecb923970de77259fb2b9fe1bc0e79e5a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 12:06:51 +1200 >Subject: [PATCH 267/686] tests/krb5: Use PAC buffer type constants from > krb5pac.idl > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 3504e99dc5bcc206ca2964012b7fdca541555416) >--- > python/samba/tests/krb5/kdc_base_test.py | 13 +++---------- > 1 file changed, 3 insertions(+), 10 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index ae62c9d5fc6..2cebd9ef0cf 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1127,13 +1127,6 @@ class KDCBaseTest(RawKerberosTest): > PacData = namedtuple( > "PacData", > "account_name account_sid logon_name upn domain_name") >- PAC_LOGON_INFO = 1 >- PAC_CREDENTIAL_INFO = 2 >- PAC_SRV_CHECKSUM = 6 >- PAC_KDC_CHECKSUM = 7 >- PAC_LOGON_NAME = 10 >- PAC_CONSTRAINED_DELEGATION = 11 >- PAC_UPN_DNS_INFO = 12 > > def get_pac_data(self, authorization_data): > '''Decode the PAC element contained in the authorization-data element >@@ -1154,15 +1147,15 @@ class KDCBaseTest(RawKerberosTest): > for ad in (x for x in buf if x['ad-type'] == AD_WIN2K_PAC): > pb = ndr_unpack(krb5pac.PAC_DATA, ad['ad-data']) > for pac in pb.buffers: >- if pac.type == self.PAC_LOGON_INFO: >+ if pac.type == krb5pac.PAC_TYPE_LOGON_INFO: > account_name = ( > pac.info.info.info3.base.account_name) > user_sid = ( > str(pac.info.info.info3.base.domain_sid) > + "-" + str(pac.info.info.info3.base.rid)) >- elif pac.type == self.PAC_LOGON_NAME: >+ elif pac.type == krb5pac.PAC_TYPE_LOGON_NAME: > logon_name = pac.info.account_name >- elif pac.type == self.PAC_UPN_DNS_INFO: >+ elif pac.type == krb5pac.PAC_TYPE_UPN_DNS_INFO: > upn = pac.info.upn_name > domain_name = pac.info.dns_domain_name > >-- >2.25.1 > > >From b91102fbc5712ffc9ec56559a97ad9b0acef6e09 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 12:13:51 +1200 >Subject: [PATCH 268/686] tests/krb5: Don't manually create PAC request and > options in fast_tests > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit c226029655ca361560d93298a6729a021f2f6b75) >--- > python/samba/tests/krb5/fast_tests.py | 17 +++++++++-------- > python/samba/tests/krb5/raw_testcase.py | 5 ----- > 2 files changed, 9 insertions(+), 13 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 8024b92f445..dedf7a57a4b 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1553,10 +1553,7 @@ class FAST_Tests(KDCBaseTest): > 'canonicalize,' > 'renewable-ok')) > >- pac_request = self.get_pa_pac_request() >- pac_options = self.get_pa_pac_options('1') # supports claims >- >- padata = [pac_request, pac_options] >+ pac_options = '1' # supports claims > > rep, kdc_exchange_dict = self._test_as_exchange( > cname=cname, >@@ -1571,10 +1568,12 @@ class FAST_Tests(KDCBaseTest): > expected_sname=sname, > expected_salt=salt, > etypes=etype, >- padata=padata, >+ padata=None, > kdc_options=kdc_options, > preauth_key=None, >- ticket_decryption_key=ticket_decryption_key) >+ ticket_decryption_key=ticket_decryption_key, >+ pac_request=True, >+ pac_options=pac_options) > self.check_pre_authentication(rep) > > etype_info2 = kdc_exchange_dict['preauth_etype_info2'] >@@ -1585,7 +1584,7 @@ class FAST_Tests(KDCBaseTest): > > ts_enc_padata = self.get_enc_timestamp_pa_data(creds, rep) > >- padata = [ts_enc_padata, pac_request, pac_options] >+ padata = [ts_enc_padata] > > expected_realm = realm.upper() > >@@ -1608,7 +1607,9 @@ class FAST_Tests(KDCBaseTest): > padata=padata, > kdc_options=kdc_options, > preauth_key=preauth_key, >- ticket_decryption_key=ticket_decryption_key) >+ ticket_decryption_key=ticket_decryption_key, >+ pac_request=True, >+ pac_options=pac_options) > self.check_as_reply(rep) > > tgt = rep['ticket'] >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 7eba62b4022..39821240941 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1177,11 +1177,6 @@ class RawKerberosTest(TestCaseInTempDir): > pa_data = self.PA_DATA_create(PADATA_PAC_REQUEST, pa_pac) > return pa_data > >- def get_pa_pac_request(self, request_pac=True): >- pac_request = self.KERB_PA_PAC_REQUEST_create(request_pac) >- >- return pac_request >- > def get_pa_pac_options(self, options): > pac_options = self.PA_PAC_OPTIONS_create(options) > pac_options = self.der_encode(pac_options, >-- >2.25.1 > > >From 6569942134708ad1e0db3b4fbf8b9e0f27c12d2a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 12:19:28 +1200 >Subject: [PATCH 269/686] tests/krb5: Set DN of created accounts to ldb.Dn type > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7645dfa5bedee7ef3f7debbf0fa7600bd1c4bd79) >--- > python/samba/tests/krb5/kdc_base_test.py | 14 +++++++------- > 1 file changed, 7 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 2cebd9ef0cf..e510ccbe46e 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -228,7 +228,7 @@ class KDCBaseTest(RawKerberosTest): > > return default_enctypes > >- def create_account(self, ldb, name, machine_account=False, >+ def create_account(self, samdb, name, machine_account=False, > spn=None, upn=None, additional_details=None, > ou=None, account_control=0): > '''Create an account for testing. >@@ -239,13 +239,13 @@ class KDCBaseTest(RawKerberosTest): > guid = (DS_GUID_COMPUTERS_CONTAINER if machine_account > else DS_GUID_USERS_CONTAINER) > >- ou = ldb.get_wellknown_dn(ldb.get_default_basedn(), guid) >+ ou = samdb.get_wellknown_dn(samdb.get_default_basedn(), guid) > > dn = "CN=%s,%s" % (name, ou) > > # remove the account if it exists, this will happen if a previous test > # run failed >- delete_force(ldb, dn) >+ delete_force(samdb, dn) > if machine_account: > object_class = "computer" > account_name = "%s$" % name >@@ -270,19 +270,19 @@ class KDCBaseTest(RawKerberosTest): > details["userPrincipalName"] = upn > if additional_details is not None: > details.update(additional_details) >- ldb.add(details) >+ samdb.add(details) > > creds = KerberosCredentials() > creds.guess(self.get_lp()) >- creds.set_realm(ldb.domain_dns_name().upper()) >- creds.set_domain(ldb.domain_netbios_name().upper()) >+ creds.set_realm(samdb.domain_dns_name().upper()) >+ creds.set_domain(samdb.domain_netbios_name().upper()) > creds.set_password(password) > creds.set_username(account_name) > if machine_account: > creds.set_workstation(name) > else: > creds.set_workstation('') >- creds.set_dn(dn) >+ creds.set_dn(ldb.Dn(samdb, dn)) > # > # Save the account name so it can be deleted in tearDownClass > self.accounts.add(dn) >-- >2.25.1 > > >From 54fd41580cfc1ca1d95bcb3f57a16fb781d207a7 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 12:38:38 +1200 >Subject: [PATCH 270/686] tests/krb5: Allow get_service_ticket() to get tickets > from the RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 5d3a135c2326edc9ca8f56bea24d2f52320f4fd6) >--- > python/samba/tests/krb5/fast_tests.py | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index dedf7a57a4b..74fe11c5a90 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1497,7 +1497,7 @@ class FAST_Tests(KDCBaseTest): > self.assertTrue( > security.KERB_ENCTYPE_CLAIMS_SUPPORTED & krbtgt_etypes) > >- def get_service_ticket(self, tgt, target_creds, service='host'): >+ def get_service_ticket(self, tgt, target_creds, service='host', to_rodc=False): > etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) > > key = tgt.session_key >@@ -1510,7 +1510,7 @@ class FAST_Tests(KDCBaseTest): > sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, > names=[service, target_name]) > >- rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype) >+ rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype, to_rodc=to_rodc) > > service_ticket = rep['ticket'] > >-- >2.25.1 > > >From 9e52d176b8f7c7889e5752abe4a69ecdfe4427b7 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 12:41:46 +1200 >Subject: [PATCH 271/686] tests/krb5: Allow get_tgt() to get tickets from the > RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 2d69805b1e3a8022f1418605e5f29ae0bbaa4a06) >--- > python/samba/tests/krb5/fast_tests.py | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 74fe11c5a90..9109a63d704 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1530,7 +1530,7 @@ class FAST_Tests(KDCBaseTest): > > return service_ticket_creds > >- def get_tgt(self, creds): >+ def get_tgt(self, creds, to_rodc=False): > user_name = creds.get_username() > realm = creds.get_realm() > >@@ -1544,7 +1544,10 @@ class FAST_Tests(KDCBaseTest): > > till = self.get_KerberosTime(offset=36000) > >- krbtgt_creds = self.get_krbtgt_creds() >+ if to_rodc: >+ krbtgt_creds = self.get_rodc_krbtgt_creds() >+ else: >+ krbtgt_creds = self.get_krbtgt_creds() > ticket_decryption_key = ( > self.TicketDecryptionKey_from_creds(krbtgt_creds)) > >@@ -1573,7 +1576,8 @@ class FAST_Tests(KDCBaseTest): > preauth_key=None, > ticket_decryption_key=ticket_decryption_key, > pac_request=True, >- pac_options=pac_options) >+ pac_options=pac_options, >+ to_rodc=to_rodc) > self.check_pre_authentication(rep) > > etype_info2 = kdc_exchange_dict['preauth_etype_info2'] >@@ -1609,7 +1613,8 @@ class FAST_Tests(KDCBaseTest): > preauth_key=preauth_key, > ticket_decryption_key=ticket_decryption_key, > pac_request=True, >- pac_options=pac_options) >+ pac_options=pac_options, >+ to_rodc=to_rodc) > self.check_as_reply(rep) > > tgt = rep['ticket'] >-- >2.25.1 > > >From 5d72fd7654d489d1e6b50a3fd607ac324d0bb2e4 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 13:14:06 +1200 >Subject: [PATCH 272/686] tests/krb5: Allow get_tgt() to specify different > kdc-options > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 4ecfa82e71b0dd5b71aa97973033c5c72257a0c3) >--- > python/samba/tests/krb5/fast_tests.py | 8 +++++--- > 1 file changed, 5 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 9109a63d704..826c3536fb9 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1530,7 +1530,7 @@ class FAST_Tests(KDCBaseTest): > > return service_ticket_creds > >- def get_tgt(self, creds, to_rodc=False): >+ def get_tgt(self, creds, to_rodc=False, kdc_options=None): > user_name = creds.get_username() > realm = creds.get_realm() > >@@ -1551,10 +1551,12 @@ class FAST_Tests(KDCBaseTest): > ticket_decryption_key = ( > self.TicketDecryptionKey_from_creds(krbtgt_creds)) > >- kdc_options = str(krb5_asn1.KDCOptions('forwardable,' >+ if kdc_options is None: >+ kdc_options = krb5_asn1.KDCOptions('forwardable,' > 'renewable,' > 'canonicalize,' >- 'renewable-ok')) >+ 'renewable-ok') >+ kdc_options = str(kdc_options) > > pac_options = '1' # supports claims > >-- >2.25.1 > > >From b18f19ecb2f4f15a9350f77cf453d6d14cb1de35 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 13:14:45 +1200 >Subject: [PATCH 273/686] tests/krb5: Allow get_tgt() to specify expected and > unexpected flags > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 035a8f198555ad1eedf8e2e6c565fbbbe4fbe7ce) >--- > python/samba/tests/krb5/fast_tests.py | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 826c3536fb9..fd96c2b9c1a 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1530,7 +1530,8 @@ class FAST_Tests(KDCBaseTest): > > return service_ticket_creds > >- def get_tgt(self, creds, to_rodc=False, kdc_options=None): >+ def get_tgt(self, creds, to_rodc=False, kdc_options=None, >+ expected_flags=None, unexpected_flags=None): > user_name = creds.get_username() > realm = creds.get_realm() > >@@ -1572,6 +1573,8 @@ class FAST_Tests(KDCBaseTest): > expected_srealm=realm, > expected_sname=sname, > expected_salt=salt, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > etypes=etype, > padata=None, > kdc_options=kdc_options, >-- >2.25.1 > > >From 0a2619a473737b73d5d7043da914b293a5f00930 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 13:24:46 +1200 >Subject: [PATCH 274/686] tests/krb5: Move get_tgt() and get_service_ticket() > to kdc_base_test > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 59c1043be25b92db75ab5676601cb15426ef37a3) >--- > python/samba/tests/krb5/fast_tests.py | 141 ---------------------- > python/samba/tests/krb5/kdc_base_test.py | 144 +++++++++++++++++++++++ > 2 files changed, 144 insertions(+), 141 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index fd96c2b9c1a..a74dc2a3cd0 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1497,147 +1497,6 @@ class FAST_Tests(KDCBaseTest): > self.assertTrue( > security.KERB_ENCTYPE_CLAIMS_SUPPORTED & krbtgt_etypes) > >- def get_service_ticket(self, tgt, target_creds, service='host', to_rodc=False): >- etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >- >- key = tgt.session_key >- ticket = tgt.ticket >- >- cname = tgt.cname >- realm = tgt.crealm >- >- target_name = target_creds.get_username()[:-1] >- sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >- names=[service, target_name]) >- >- rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype, to_rodc=to_rodc) >- >- service_ticket = rep['ticket'] >- >- ticket_etype = service_ticket['enc-part']['etype'] >- target_key = self.TicketDecryptionKey_from_creds(target_creds, >- etype=ticket_etype) >- >- session_key = self.EncryptionKey_import(enc_part['key']) >- >- service_ticket_creds = KerberosTicketCreds(service_ticket, >- session_key, >- crealm=realm, >- cname=cname, >- srealm=realm, >- sname=sname, >- decryption_key=target_key) >- >- return service_ticket_creds >- >- def get_tgt(self, creds, to_rodc=False, kdc_options=None, >- expected_flags=None, unexpected_flags=None): >- user_name = creds.get_username() >- realm = creds.get_realm() >- >- salt = creds.get_salt() >- >- etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >- cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >- names=[user_name]) >- sname = self.PrincipalName_create(name_type=NT_SRV_INST, >- names=['krbtgt', realm]) >- >- till = self.get_KerberosTime(offset=36000) >- >- if to_rodc: >- krbtgt_creds = self.get_rodc_krbtgt_creds() >- else: >- krbtgt_creds = self.get_krbtgt_creds() >- ticket_decryption_key = ( >- self.TicketDecryptionKey_from_creds(krbtgt_creds)) >- >- if kdc_options is None: >- kdc_options = krb5_asn1.KDCOptions('forwardable,' >- 'renewable,' >- 'canonicalize,' >- 'renewable-ok') >- kdc_options = str(kdc_options) >- >- pac_options = '1' # supports claims >- >- rep, kdc_exchange_dict = self._test_as_exchange( >- cname=cname, >- realm=realm, >- sname=sname, >- till=till, >- client_as_etypes=etype, >- expected_error_mode=KDC_ERR_PREAUTH_REQUIRED, >- expected_crealm=realm, >- expected_cname=cname, >- expected_srealm=realm, >- expected_sname=sname, >- expected_salt=salt, >- expected_flags=expected_flags, >- unexpected_flags=unexpected_flags, >- etypes=etype, >- padata=None, >- kdc_options=kdc_options, >- preauth_key=None, >- ticket_decryption_key=ticket_decryption_key, >- pac_request=True, >- pac_options=pac_options, >- to_rodc=to_rodc) >- self.check_pre_authentication(rep) >- >- etype_info2 = kdc_exchange_dict['preauth_etype_info2'] >- >- preauth_key = self.PasswordKey_from_etype_info2(creds, >- etype_info2[0], >- creds.get_kvno()) >- >- ts_enc_padata = self.get_enc_timestamp_pa_data(creds, rep) >- >- padata = [ts_enc_padata] >- >- expected_realm = realm.upper() >- >- expected_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=['krbtgt', realm.upper()]) >- >- rep, kdc_exchange_dict = self._test_as_exchange( >- cname=cname, >- realm=realm, >- sname=sname, >- till=till, >- client_as_etypes=etype, >- expected_error_mode=0, >- expected_crealm=expected_realm, >- expected_cname=cname, >- expected_srealm=expected_realm, >- expected_sname=expected_sname, >- expected_salt=salt, >- etypes=etype, >- padata=padata, >- kdc_options=kdc_options, >- preauth_key=preauth_key, >- ticket_decryption_key=ticket_decryption_key, >- pac_request=True, >- pac_options=pac_options, >- to_rodc=to_rodc) >- self.check_as_reply(rep) >- >- tgt = rep['ticket'] >- >- enc_part = self.get_as_rep_enc_data(preauth_key, rep) >- session_key = self.EncryptionKey_import(enc_part['key']) >- >- ticket_creds = KerberosTicketCreds( >- tgt, >- session_key, >- crealm=realm, >- cname=cname, >- srealm=realm, >- sname=sname, >- decryption_key=ticket_decryption_key) >- >- return ticket_creds, enc_part >- > def get_mach_tgt(self): > if self.mach_tgt is None: > mach_creds = self.get_mach_creds() >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index e510ccbe46e..fbcc89a9b31 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -73,6 +73,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KU_TICKET, > NT_PRINCIPAL, > NT_SRV_HST, >+ NT_SRV_INST, > PADATA_ENCRYPTED_CHALLENGE, > PADATA_ENC_TIMESTAMP, > PADATA_ETYPE_INFO2, >@@ -1123,6 +1124,149 @@ class KDCBaseTest(RawKerberosTest): > > return rep, enc_part > >+ def get_service_ticket(self, tgt, target_creds, service='host', >+ to_rodc=False): >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ >+ key = tgt.session_key >+ ticket = tgt.ticket >+ >+ cname = tgt.cname >+ realm = tgt.crealm >+ >+ target_name = target_creds.get_username()[:-1] >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[service, target_name]) >+ >+ rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype, >+ to_rodc=to_rodc) >+ >+ service_ticket = rep['ticket'] >+ >+ ticket_etype = service_ticket['enc-part']['etype'] >+ target_key = self.TicketDecryptionKey_from_creds(target_creds, >+ etype=ticket_etype) >+ >+ session_key = self.EncryptionKey_import(enc_part['key']) >+ >+ service_ticket_creds = KerberosTicketCreds(service_ticket, >+ session_key, >+ crealm=realm, >+ cname=cname, >+ srealm=realm, >+ sname=sname, >+ decryption_key=target_key) >+ >+ return service_ticket_creds >+ >+ def get_tgt(self, creds, to_rodc=False, kdc_options=None, >+ expected_flags=None, unexpected_flags=None): >+ user_name = creds.get_username() >+ realm = creds.get_realm() >+ >+ salt = creds.get_salt() >+ >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ sname = self.PrincipalName_create(name_type=NT_SRV_INST, >+ names=['krbtgt', realm]) >+ >+ till = self.get_KerberosTime(offset=36000) >+ >+ if to_rodc: >+ krbtgt_creds = self.get_rodc_krbtgt_creds() >+ else: >+ krbtgt_creds = self.get_krbtgt_creds() >+ ticket_decryption_key = ( >+ self.TicketDecryptionKey_from_creds(krbtgt_creds)) >+ >+ if kdc_options is None: >+ kdc_options = krb5_asn1.KDCOptions('forwardable,' >+ 'renewable,' >+ 'canonicalize,' >+ 'renewable-ok') >+ kdc_options = str(kdc_options) >+ >+ pac_options = '1' # supports claims >+ >+ rep, kdc_exchange_dict = self._test_as_exchange( >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ till=till, >+ client_as_etypes=etype, >+ expected_error_mode=KDC_ERR_PREAUTH_REQUIRED, >+ expected_crealm=realm, >+ expected_cname=cname, >+ expected_srealm=realm, >+ expected_sname=sname, >+ expected_salt=salt, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, >+ etypes=etype, >+ padata=None, >+ kdc_options=kdc_options, >+ preauth_key=None, >+ ticket_decryption_key=ticket_decryption_key, >+ pac_request=True, >+ pac_options=pac_options, >+ to_rodc=to_rodc) >+ self.check_pre_authentication(rep) >+ >+ etype_info2 = kdc_exchange_dict['preauth_etype_info2'] >+ >+ preauth_key = self.PasswordKey_from_etype_info2(creds, >+ etype_info2[0], >+ creds.get_kvno()) >+ >+ ts_enc_padata = self.get_enc_timestamp_pa_data(creds, rep) >+ >+ padata = [ts_enc_padata] >+ >+ expected_realm = realm.upper() >+ >+ expected_sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=['krbtgt', realm.upper()]) >+ >+ rep, kdc_exchange_dict = self._test_as_exchange( >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ till=till, >+ client_as_etypes=etype, >+ expected_error_mode=0, >+ expected_crealm=expected_realm, >+ expected_cname=cname, >+ expected_srealm=expected_realm, >+ expected_sname=expected_sname, >+ expected_salt=salt, >+ etypes=etype, >+ padata=padata, >+ kdc_options=kdc_options, >+ preauth_key=preauth_key, >+ ticket_decryption_key=ticket_decryption_key, >+ pac_request=True, >+ pac_options=pac_options, >+ to_rodc=to_rodc) >+ self.check_as_reply(rep) >+ >+ tgt = rep['ticket'] >+ >+ enc_part = self.get_as_rep_enc_data(preauth_key, rep) >+ session_key = self.EncryptionKey_import(enc_part['key']) >+ >+ ticket_creds = KerberosTicketCreds( >+ tgt, >+ session_key, >+ crealm=realm, >+ cname=cname, >+ srealm=realm, >+ sname=sname, >+ decryption_key=ticket_decryption_key) >+ >+ return ticket_creds, enc_part >+ > # Named tuple to contain values of interest when the PAC is decoded. > PacData = namedtuple( > "PacData", >-- >2.25.1 > > >From 2abd3f3aa04416bd9d0e1838ef2c9036062e6188 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 11:51:05 +1200 >Subject: [PATCH 275/686] tests/krb5: Return encpart from get_tgt() as part of > KerberosTicketCreds > >The encpart is already contained in ticket_creds, so it no longer needs >to be returned as a separate value. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 6193f7433b15579aa32b26a146287923c9d3844d) >--- > python/samba/tests/krb5/fast_tests.py | 8 ++------ > python/samba/tests/krb5/kdc_base_test.py | 16 ++-------------- > 2 files changed, 4 insertions(+), 20 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index a74dc2a3cd0..42e75e7513c 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -67,11 +67,9 @@ class FAST_Tests(KDCBaseTest): > super().setUpClass() > > cls.user_tgt = None >- cls.user_enc_part = None > cls.user_service_ticket = None > > cls.mach_tgt = None >- cls.mach_enc_part = None > cls.mach_service_ticket = None > > def setUp(self): >@@ -1500,16 +1498,14 @@ class FAST_Tests(KDCBaseTest): > def get_mach_tgt(self): > if self.mach_tgt is None: > mach_creds = self.get_mach_creds() >- type(self).mach_tgt, type(self).mach_enc_part = ( >- self.get_tgt(mach_creds)) >+ type(self).mach_tgt = self.get_tgt(mach_creds) > > return self.mach_tgt > > def get_user_tgt(self): > if self.user_tgt is None: > user_creds = self.get_client_creds() >- type(self).user_tgt, type(self).user_enc_part = ( >- self.get_tgt(user_creds)) >+ type(self).user_tgt = self.get_tgt(user_creds) > > return self.user_tgt > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index fbcc89a9b31..28d34210fce 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1251,21 +1251,9 @@ class KDCBaseTest(RawKerberosTest): > to_rodc=to_rodc) > self.check_as_reply(rep) > >- tgt = rep['ticket'] >+ ticket_creds = kdc_exchange_dict['rep_ticket_creds'] > >- enc_part = self.get_as_rep_enc_data(preauth_key, rep) >- session_key = self.EncryptionKey_import(enc_part['key']) >- >- ticket_creds = KerberosTicketCreds( >- tgt, >- session_key, >- crealm=realm, >- cname=cname, >- srealm=realm, >- sname=sname, >- decryption_key=ticket_decryption_key) >- >- return ticket_creds, enc_part >+ return ticket_creds > > # Named tuple to contain values of interest when the PAC is decoded. > PacData = namedtuple( >-- >2.25.1 > > >From eb3102c7977e40013d42279781f919e81f2fd12b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 11:51:20 +1200 >Subject: [PATCH 276/686] tests/krb5: Cache obtained tickets > >Now tickets obtained with get_tgt() and get_service_ticket() make use of >a cache so they can be reused, unless the 'fresh' parameter is specified >as true. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 419e4061ced466ec7e5e23f815823b540ef4751c) >--- > python/samba/tests/krb5/kdc_base_test.py | 29 ++++++++++++++++++++++-- > 1 file changed, 27 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 28d34210fce..59175c7bb2f 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -110,6 +110,7 @@ class KDCBaseTest(RawKerberosTest): > cls.accounts = set() > > cls.account_cache = {} >+ cls.tkt_cache = {} > > cls._rodc_ctx = None > >@@ -1125,7 +1126,17 @@ class KDCBaseTest(RawKerberosTest): > return rep, enc_part > > def get_service_ticket(self, tgt, target_creds, service='host', >- to_rodc=False): >+ to_rodc=False, fresh=False): >+ user_name = tgt.cname['name-string'][0] >+ target_name = target_creds.get_username() >+ cache_key = (user_name, target_name, service, to_rodc) >+ >+ if not fresh: >+ ticket = self.tkt_cache.get(cache_key) >+ >+ if ticket is not None: >+ return ticket >+ > etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) > > key = tgt.session_key >@@ -1157,11 +1168,23 @@ class KDCBaseTest(RawKerberosTest): > sname=sname, > decryption_key=target_key) > >+ self.tkt_cache[cache_key] = service_ticket_creds >+ > return service_ticket_creds > > def get_tgt(self, creds, to_rodc=False, kdc_options=None, >- expected_flags=None, unexpected_flags=None): >+ expected_flags=None, unexpected_flags=None, >+ fresh=False): > user_name = creds.get_username() >+ cache_key = (user_name, to_rodc, kdc_options, >+ expected_flags, unexpected_flags) >+ >+ if not fresh: >+ tgt = self.tkt_cache.get(cache_key) >+ >+ if tgt is not None: >+ return tgt >+ > realm = creds.get_realm() > > salt = creds.get_salt() >@@ -1253,6 +1276,8 @@ class KDCBaseTest(RawKerberosTest): > > ticket_creds = kdc_exchange_dict['rep_ticket_creds'] > >+ self.tkt_cache[cache_key] = ticket_creds >+ > return ticket_creds > > # Named tuple to contain values of interest when the PAC is decoded. >-- >2.25.1 > > >From 0a4aa4aaf83f74b8902a1ffda60b1a0d1c0afe80 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 16:54:57 +1200 >Subject: [PATCH 277/686] tests/krb5: Add methods for creating zeroed checksums > and verifying checksums > >Creating a zeroed checksum is needed for signing a PAC. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a562882b15125902c5d89f094b8c9b1150f5d010) >--- > python/samba/tests/krb5/raw_testcase.py | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 39821240941..be49f16b1f7 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -232,12 +232,29 @@ class Krb5EncryptionKey: > plaintext = kcrypto.decrypt(self.key, usage, ciphertext) > return plaintext > >+ def make_zeroed_checksum(self, ctype=None): >+ if ctype is None: >+ ctype = self.ctype >+ >+ checksum_len = kcrypto.checksum_len(ctype) >+ return bytes(checksum_len) >+ > def make_checksum(self, usage, plaintext, ctype=None): > if ctype is None: > ctype = self.ctype > cksum = kcrypto.make_checksum(ctype, self.key, usage, plaintext) > return cksum > >+ def verify_checksum(self, usage, plaintext, ctype, cksum): >+ if self.ctype != ctype: >+ raise AssertionError(f'{self.ctype} != {ctype}') >+ >+ kcrypto.verify_checksum(ctype, >+ self.key, >+ usage, >+ plaintext, >+ cksum) >+ > def export_obj(self): > EncryptionKey_obj = { > 'keytype': self.etype, >-- >2.25.1 > > >From aeaf13c03ca1700b53ab857dba0ae563d6339c09 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 17:20:22 +1200 >Subject: [PATCH 278/686] tests/krb5: Add RodcPacEncryptionKey type allowing > for RODC PAC signatures > >Signatures created by an RODC have an RODCIdentifier appended to them >identifying the RODC's krbtgt account. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Tue Sep 21 23:55:39 UTC 2021 on sn-devel-184 > >(cherry picked from commit ec95b3042bf2649c0600cafb12818c27242b5098) >--- > python/samba/tests/krb5/raw_testcase.py | 45 +++++++++++++++++++++++-- > 1 file changed, 42 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index be49f16b1f7..e213b5eef9b 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -263,6 +263,45 @@ class Krb5EncryptionKey: > return EncryptionKey_obj > > >+class RodcPacEncryptionKey(Krb5EncryptionKey): >+ def __init__(self, key, kvno, rodc_id=None): >+ super().__init__(key, kvno) >+ >+ if rodc_id is None: >+ kvno = self.kvno >+ if kvno is not None: >+ kvno >>= 16 >+ kvno &= (1 << 16) - 1 >+ >+ rodc_id = kvno or None >+ >+ if rodc_id is not None: >+ self.rodc_id = rodc_id.to_bytes(2, byteorder='little') >+ else: >+ self.rodc_id = b'' >+ >+ def make_zeroed_checksum(self, ctype=None): >+ checksum = super().make_zeroed_checksum(ctype) >+ return checksum + bytes(len(self.rodc_id)) >+ >+ def make_checksum(self, usage, plaintext, ctype=None): >+ checksum = super().make_checksum(usage, plaintext, ctype) >+ return checksum + self.rodc_id >+ >+ def verify_checksum(self, usage, plaintext, ctype, cksum): >+ if self.rodc_id: >+ cksum, cksum_rodc_id = cksum[:-2], cksum[-2:] >+ >+ if self.rodc_id != cksum_rodc_id: >+ raise AssertionError(f'{self.rodc_id.hex()} != ' >+ f'{cksum_rodc_id.hex()}') >+ >+ super().verify_checksum(usage, >+ plaintext, >+ ctype, >+ cksum) >+ >+ > class KerberosCredentials(Credentials): > def __init__(self): > super(KerberosCredentials, self).__init__() >@@ -325,7 +364,7 @@ class KerberosCredentials(Credentials): > etype = int(etype) > contents = binascii.a2b_hex(hexkey) > key = kcrypto.Key(etype, contents) >- self.forced_keys[etype] = Krb5EncryptionKey(key, self.kvno) >+ self.forced_keys[etype] = RodcPacEncryptionKey(key, self.kvno) > > def get_forced_key(self, etype): > etype = int(etype) >@@ -982,13 +1021,13 @@ class RawKerberosTest(TestCaseInTempDir): > > def SessionKey_create(self, etype, contents, kvno=None): > key = kcrypto.Key(etype, contents) >- return Krb5EncryptionKey(key, kvno) >+ return RodcPacEncryptionKey(key, kvno) > > def PasswordKey_create(self, etype=None, pwd=None, salt=None, kvno=None): > self.assertIsNotNone(pwd) > self.assertIsNotNone(salt) > key = kcrypto.string_to_key(etype, pwd, salt) >- return Krb5EncryptionKey(key, kvno) >+ return RodcPacEncryptionKey(key, kvno) > > def PasswordKey_from_etype_info2(self, creds, etype_info2, kvno=None): > e = etype_info2['etype'] >-- >2.25.1 > > >From d0c9c8e45559c2c9ff09b52173dce5dd3e84cb95 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 17 Sep 2021 14:56:51 +1200 >Subject: [PATCH 279/686] tests/krb5: Add method to verify ticket PAC checksums > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 12b5e72a35d632516980f6c051a5d83f913079e7) >--- > python/samba/tests/krb5/raw_testcase.py | 118 +++++++++++++++++++++++- > 1 file changed, 117 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e213b5eef9b..265789cdb26 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -34,8 +34,9 @@ from pyasn1.codec.native.encoder import encode as pyasn1_native_encode > from pyasn1.codec.ber.encoder import BitStringEncoder > > from samba.credentials import Credentials >-from samba.dcerpc import security >+from samba.dcerpc import krb5pac, security > from samba.gensec import FEATURE_SEAL >+from samba.ndr import ndr_pack, ndr_unpack > > import samba.tests > from samba.tests import TestCaseInTempDir >@@ -418,6 +419,10 @@ class KerberosTicketCreds: > class RawKerberosTest(TestCaseInTempDir): > """A raw Kerberos Test case.""" > >+ pac_checksum_types = {krb5pac.PAC_TYPE_SRV_CHECKSUM, >+ krb5pac.PAC_TYPE_KDC_CHECKSUM, >+ krb5pac.PAC_TYPE_TICKET_CHECKSUM} >+ > etypes_to_test = ( > {"value": -1111, "name": "dummy", }, > {"value": kcrypto.Enctype.AES256, "name": "aes128", }, >@@ -2900,6 +2905,114 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_blob) > self.assertEqual(expected_checksum, checksum) > >+ def verify_ticket(self, ticket, krbtgt_key, expect_pac=True): >+ # Check if the ticket is a TGT. >+ sname = ticket.ticket['sname'] >+ is_tgt = sname['name-string'][0] == b'krbtgt' >+ >+ # Decrypt the ticket. >+ >+ key = ticket.decryption_key >+ enc_part = ticket.ticket['enc-part'] >+ >+ self.assertElementEqual(enc_part, 'etype', key.etype) >+ self.assertElementKVNO(enc_part, 'kvno', key.kvno) >+ >+ enc_part = key.decrypt(KU_TICKET, enc_part['cipher']) >+ enc_part = self.der_decode( >+ enc_part, asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ # Fetch the authorization data from the ticket. >+ auth_data = enc_part.get('authorization-data') >+ if expect_pac: >+ self.assertIsNotNone(auth_data) >+ elif auth_data is None: >+ return >+ >+ # Get a copy of the authdata with an empty PAC, and the existing PAC >+ # (if present). >+ empty_pac = self.get_empty_pac() >+ auth_data, pac_data = self.replace_pac(auth_data, >+ empty_pac, >+ expect_pac=expect_pac) >+ if not expect_pac: >+ return >+ >+ # Unpack the PAC as both PAC_DATA and PAC_DATA_RAW types. We use the >+ # raw type to create a new PAC with zeroed signatures for >+ # verification. This is because on Windows, the resource_groups field >+ # is added to PAC_LOGON_INFO after the info3 field has been created, >+ # which results in a different ordering of pointer values than Samba >+ # (see commit 0e201ecdc53). Using the raw type avoids changing >+ # PAC_LOGON_INFO, so verification against Windows can work. We still >+ # need the PAC_DATA type to retrieve the actual checksums, because the >+ # signatures in the raw type may contain padding bytes. >+ pac = ndr_unpack(krb5pac.PAC_DATA, >+ pac_data) >+ raw_pac = ndr_unpack(krb5pac.PAC_DATA_RAW, >+ pac_data) >+ >+ checksums = {} >+ >+ for pac_buffer, raw_pac_buffer in zip(pac.buffers, raw_pac.buffers): >+ buffer_type = pac_buffer.type >+ if buffer_type in self.pac_checksum_types: >+ self.assertNotIn(buffer_type, checksums, >+ f'Duplicate checksum type {buffer_type}') >+ >+ # Fetch the checksum and the checksum type from the PAC buffer. >+ checksum = pac_buffer.info.signature >+ ctype = pac_buffer.info.type >+ if ctype & 1 << 31: >+ ctype |= -1 << 31 >+ >+ checksums[buffer_type] = checksum, ctype >+ >+ if buffer_type != krb5pac.PAC_TYPE_TICKET_CHECKSUM: >+ # Zero the checksum field so that we can later verify the >+ # checksums. The ticket checksum field is not zeroed. >+ >+ signature = ndr_unpack( >+ krb5pac.PAC_SIGNATURE_DATA, >+ raw_pac_buffer.info.remaining) >+ signature.signature = bytes(len(checksum)) >+ raw_pac_buffer.info.remaining = ndr_pack( >+ signature) >+ >+ # Re-encode the PAC. >+ pac_data = ndr_pack(raw_pac) >+ >+ # Verify the signatures. >+ >+ server_checksum, server_ctype = checksums[ >+ krb5pac.PAC_TYPE_SRV_CHECKSUM] >+ Krb5EncryptionKey.verify_checksum(key, >+ KU_NON_KERB_CKSUM_SALT, >+ pac_data, >+ server_ctype, >+ server_checksum) >+ >+ kdc_checksum, kdc_ctype = checksums[ >+ krb5pac.PAC_TYPE_KDC_CHECKSUM] >+ krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >+ server_checksum, >+ kdc_ctype, >+ kdc_checksum) >+ >+ if is_tgt: >+ self.assertNotIn(krb5pac.PAC_TYPE_TICKET_CHECKSUM, checksums) >+ else: >+ ticket_checksum, ticket_ctype = checksums[ >+ krb5pac.PAC_TYPE_TICKET_CHECKSUM] >+ enc_part['authorization-data'] = auth_data >+ enc_part = self.der_encode(enc_part, >+ asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >+ enc_part, >+ ticket_ctype, >+ ticket_checksum) >+ > def replace_pac(self, auth_data, new_pac, expect_pac=True): > if new_pac is not None: > self.assertElementEqual(new_pac, 'ad-type', AD_WIN2K_PAC) >@@ -2943,6 +3056,9 @@ class RawKerberosTest(TestCaseInTempDir): > > return new_auth_data, old_pac > >+ def get_empty_pac(self): >+ return self.AuthorizationData_create(AD_WIN2K_PAC, bytes(1)) >+ > def get_outer_pa_dict(self, kdc_exchange_dict): > return self.get_pa_dict(kdc_exchange_dict['req_padata']) > >-- >2.25.1 > > >From 952e801be4177df1bb46b584a828d34fd00fdc35 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 17 Sep 2021 15:26:12 +1200 >Subject: [PATCH 280/686] tests/krb5: Add method for modifying a ticket and > creating PAC checksums > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1fcde7cb6ce50e0a08097841e92476f320560664) >--- > python/samba/tests/krb5/raw_testcase.py | 234 ++++++++++++++++++++++++ > 1 file changed, 234 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 265789cdb26..4ac7698ffab 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3013,6 +3013,240 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_ctype, > ticket_checksum) > >+ def modified_ticket(self, >+ ticket, *, >+ new_ticket_key=None, >+ modify_fn=None, >+ modify_pac_fn=None, >+ exclude_pac=False, >+ update_pac_checksums=True, >+ checksum_keys=None, >+ include_checksums=None): >+ if checksum_keys is None: >+ # A dict containing a key for each checksum type to be created in >+ # the PAC. >+ checksum_keys = {} >+ >+ if include_checksums is None: >+ # A dict containing a value for each checksum type; True if the >+ # checksum type is to be included in the PAC, False if it is to be >+ # excluded, or None/not present if the checksum is to be included >+ # based on its presence in the original PAC. >+ include_checksums = {} >+ >+ # Check that the values passed in by the caller make sense. >+ >+ self.assertLessEqual(checksum_keys.keys(), self.pac_checksum_types) >+ self.assertLessEqual(include_checksums.keys(), self.pac_checksum_types) >+ >+ if exclude_pac: >+ self.assertIsNone(modify_pac_fn) >+ >+ update_pac_checksums = False >+ >+ if not update_pac_checksums: >+ self.assertFalse(checksum_keys) >+ self.assertFalse(include_checksums) >+ >+ expect_pac = update_pac_checksums or modify_pac_fn is not None >+ >+ key = ticket.decryption_key >+ >+ if new_ticket_key is None: >+ # Use the same key to re-encrypt the ticket. >+ new_ticket_key = key >+ >+ if krb5pac.PAC_TYPE_SRV_CHECKSUM not in checksum_keys: >+ # If the server signature key is not present, fall back to the key >+ # used to encrypt the ticket. >+ checksum_keys[krb5pac.PAC_TYPE_SRV_CHECKSUM] = new_ticket_key >+ >+ if krb5pac.PAC_TYPE_TICKET_CHECKSUM not in checksum_keys: >+ # If the ticket signature key is not present, fall back to the key >+ # used for the KDC signature. >+ kdc_checksum_key = checksum_keys.get(krb5pac.PAC_TYPE_KDC_CHECKSUM) >+ if kdc_checksum_key is not None: >+ checksum_keys[krb5pac.PAC_TYPE_TICKET_CHECKSUM] = ( >+ kdc_checksum_key) >+ >+ # Decrypt the ticket. >+ >+ enc_part = ticket.ticket['enc-part'] >+ >+ self.assertElementEqual(enc_part, 'etype', key.etype) >+ self.assertElementKVNO(enc_part, 'kvno', key.kvno) >+ >+ enc_part = key.decrypt(KU_TICKET, enc_part['cipher']) >+ enc_part = self.der_decode( >+ enc_part, asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ # Modify the ticket here. >+ if modify_fn is not None: >+ enc_part = modify_fn(enc_part) >+ >+ auth_data = enc_part.get('authorization-data') >+ if expect_pac: >+ self.assertIsNotNone(auth_data) >+ if auth_data is not None: >+ new_pac = None >+ if not exclude_pac: >+ # Get a copy of the authdata with an empty PAC, and the >+ # existing PAC (if present). >+ empty_pac = self.get_empty_pac() >+ empty_pac_auth_data, pac_data = self.replace_pac(auth_data, >+ empty_pac) >+ >+ if expect_pac: >+ self.assertIsNotNone(pac_data) >+ if pac_data is not None: >+ pac = ndr_unpack(krb5pac.PAC_DATA, pac_data) >+ >+ # Modify the PAC here. >+ if modify_pac_fn is not None: >+ pac = modify_pac_fn(pac) >+ >+ if update_pac_checksums: >+ # Get the enc-part with an empty PAC, which is needed >+ # to create a ticket signature. >+ enc_part_to_sign = enc_part.copy() >+ enc_part_to_sign['authorization-data'] = ( >+ empty_pac_auth_data) >+ enc_part_to_sign = self.der_encode( >+ enc_part_to_sign, >+ asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ self.update_pac_checksums(pac, >+ checksum_keys, >+ include_checksums, >+ enc_part_to_sign) >+ >+ # Re-encode the PAC. >+ pac_data = ndr_pack(pac) >+ new_pac = self.AuthorizationData_create(AD_WIN2K_PAC, >+ pac_data) >+ >+ # Replace the PAC in the authorization data and re-add it to the >+ # ticket enc-part. >+ auth_data, _ = self.replace_pac(auth_data, new_pac) >+ enc_part['authorization-data'] = auth_data >+ >+ # Re-encrypt the ticket enc-part with the new key. >+ enc_part_new = self.der_encode(enc_part, >+ asn1Spec=krb5_asn1.EncTicketPart()) >+ enc_part_new = self.EncryptedData_create(new_ticket_key, >+ KU_TICKET, >+ enc_part_new) >+ >+ # Create a copy of the ticket with the new enc-part. >+ new_ticket = ticket.ticket.copy() >+ new_ticket['enc-part'] = enc_part_new >+ >+ new_ticket_creds = KerberosTicketCreds( >+ new_ticket, >+ session_key=ticket.session_key, >+ crealm=ticket.crealm, >+ cname=ticket.cname, >+ srealm=ticket.srealm, >+ sname=ticket.sname, >+ decryption_key=new_ticket_key, >+ ticket_private=enc_part, >+ encpart_private=ticket.encpart_private) >+ >+ return new_ticket_creds >+ >+ def update_pac_checksums(self, >+ pac, >+ checksum_keys, >+ include_checksums, >+ enc_part=None): >+ pac_buffers = pac.buffers >+ checksum_buffers = {} >+ >+ # Find the relevant PAC checksum buffers. >+ for pac_buffer in pac_buffers: >+ buffer_type = pac_buffer.type >+ if buffer_type in self.pac_checksum_types: >+ self.assertNotIn(buffer_type, checksum_buffers, >+ f'Duplicate checksum type {buffer_type}') >+ >+ checksum_buffers[buffer_type] = pac_buffer >+ >+ # Create any additional buffers that were requested but not >+ # present. Conversely, remove any buffers that were requested to be >+ # removed. >+ for buffer_type in self.pac_checksum_types: >+ if buffer_type in checksum_buffers: >+ if include_checksums.get(buffer_type) is False: >+ checksum_buffer = checksum_buffers.pop(buffer_type) >+ >+ pac.num_buffers -= 1 >+ pac_buffers.remove(checksum_buffer) >+ >+ elif include_checksums.get(buffer_type) is True: >+ info = krb5pac.PAC_SIGNATURE_DATA() >+ >+ checksum_buffer = krb5pac.PAC_BUFFER() >+ checksum_buffer.type = buffer_type >+ checksum_buffer.info = info >+ >+ pac_buffers.append(checksum_buffer) >+ pac.num_buffers += 1 >+ >+ checksum_buffers[buffer_type] = checksum_buffer >+ >+ # Fill the relevant checksum buffers. >+ for buffer_type, checksum_buffer in checksum_buffers.items(): >+ checksum_key = checksum_keys[buffer_type] >+ ctype = checksum_key.ctype & ((1 << 32) - 1) >+ >+ if buffer_type == krb5pac.PAC_TYPE_TICKET_CHECKSUM: >+ self.assertIsNotNone(enc_part) >+ >+ signature = checksum_key.make_checksum( >+ KU_NON_KERB_CKSUM_SALT, >+ enc_part) >+ >+ elif buffer_type == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ signature = Krb5EncryptionKey.make_zeroed_checksum( >+ checksum_key) >+ >+ else: >+ signature = checksum_key.make_zeroed_checksum() >+ >+ checksum_buffer.info.signature = signature >+ checksum_buffer.info.type = ctype >+ >+ # Add the new checksum buffers to the PAC. >+ pac.buffers = pac_buffers >+ >+ # Calculate the server and KDC checksums and insert them into the PAC. >+ >+ server_checksum_buffer = checksum_buffers.get( >+ krb5pac.PAC_TYPE_SRV_CHECKSUM) >+ if server_checksum_buffer is not None: >+ server_checksum_key = checksum_keys[krb5pac.PAC_TYPE_SRV_CHECKSUM] >+ >+ pac_data = ndr_pack(pac) >+ server_checksum = Krb5EncryptionKey.make_checksum( >+ server_checksum_key, >+ KU_NON_KERB_CKSUM_SALT, >+ pac_data) >+ >+ server_checksum_buffer.info.signature = server_checksum >+ >+ kdc_checksum_buffer = checksum_buffers.get( >+ krb5pac.PAC_TYPE_KDC_CHECKSUM) >+ if kdc_checksum_buffer is not None: >+ self.assertIsNotNone(server_checksum_buffer) >+ >+ kdc_checksum_key = checksum_keys[krb5pac.PAC_TYPE_KDC_CHECKSUM] >+ >+ kdc_checksum = kdc_checksum_key.make_checksum( >+ KU_NON_KERB_CKSUM_SALT, >+ server_checksum) >+ >+ kdc_checksum_buffer.info.signature = kdc_checksum >+ > def replace_pac(self, auth_data, new_pac, expect_pac=True): > if new_pac is not None: > self.assertElementEqual(new_pac, 'ad-type', AD_WIN2K_PAC) >-- >2.25.1 > > >From 5d725516c0e6a993eef2627f661be61498b569b5 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 13:33:16 +1200 >Subject: [PATCH 281/686] tests/krb5: Simplify adding authdata to ticket by > using modified_ticket() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 4c67a53cdca206a118e82b356db0faf0ddc011ab) >--- > python/samba/tests/krb5/fast_tests.py | 49 +++++-------------------- > python/samba/tests/krb5/raw_testcase.py | 8 ++++ > 2 files changed, 18 insertions(+), 39 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 42e75e7513c..d8ccfaee325 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -25,10 +25,7 @@ import collections > import ldb > > from samba.dcerpc import security >-from samba.tests.krb5.raw_testcase import ( >- KerberosTicketCreds, >- Krb5EncryptionKey >-) >+from samba.tests.krb5.raw_testcase import Krb5EncryptionKey > from samba.tests.krb5.kdc_base_test import KDCBaseTest > from samba.tests.krb5.rfc4120_constants import ( > AD_FX_FAST_ARMOR, >@@ -45,7 +42,6 @@ from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, > KRB_AS_REP, > KRB_TGS_REP, >- KU_TICKET, > NT_PRINCIPAL, > NT_SRV_INST, > PADATA_FX_COOKIE, >@@ -1428,44 +1424,19 @@ class FAST_Tests(KDCBaseTest): > def gen_tgt_fast_armor_auth_data(self): > user_tgt = self.get_user_tgt() > >- ticket_decryption_key = user_tgt.decryption_key >+ auth_data = self.generate_fast_armor_auth_data() >+ >+ def modify_fn(enc_part): >+ enc_part['authorization-data'].append(auth_data) > >- tgt_encpart = self.getElementValue(user_tgt.ticket, 'enc-part') >- self.assertElementEqual(tgt_encpart, 'etype', >- ticket_decryption_key.etype) >- self.assertElementKVNO(tgt_encpart, 'kvno', >- ticket_decryption_key.kvno) >- tgt_cipher = self.getElementValue(tgt_encpart, 'cipher') >- tgt_decpart = ticket_decryption_key.decrypt(KU_TICKET, tgt_cipher) >- tgt_private = self.der_decode(tgt_decpart, >- asn1Spec=krb5_asn1.EncTicketPart()) >+ return enc_part > >- auth_data = self.generate_fast_armor_auth_data() >- tgt_private['authorization-data'].append(auth_data) >- >- # Re-encrypt the user TGT. >- tgt_private_new = self.der_encode( >- tgt_private, >- asn1Spec=krb5_asn1.EncTicketPart()) >- tgt_encpart = self.EncryptedData_create(ticket_decryption_key, >- KU_TICKET, >- tgt_private_new) >- user_ticket = user_tgt.ticket.copy() >- user_ticket['enc-part'] = tgt_encpart >- >- user_tgt = KerberosTicketCreds( >- user_ticket, >- session_key=user_tgt.session_key, >- crealm=user_tgt.crealm, >- cname=user_tgt.cname, >- srealm=user_tgt.srealm, >- sname=user_tgt.sname, >- decryption_key=user_tgt.decryption_key, >- ticket_private=tgt_private, >- encpart_private=user_tgt.encpart_private) >+ checksum_keys = self.get_krbtgt_checksum_key() > > # Use our modifed TGT to replace the one in the request. >- return user_tgt >+ return self.modified_ticket(user_tgt, >+ modify_fn=modify_fn, >+ checksum_keys=checksum_keys) > > def create_fast_cookie(self, cookie): > self.assertIsNotNone(cookie) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 4ac7698ffab..57013caafb1 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3290,6 +3290,14 @@ class RawKerberosTest(TestCaseInTempDir): > > return new_auth_data, old_pac > >+ def get_krbtgt_checksum_key(self): >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ return { >+ krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key >+ } >+ > def get_empty_pac(self): > return self.AuthorizationData_create(AD_WIN2K_PAC, bytes(1)) > >-- >2.25.1 > > >From 65adb3b59da1c32ea236042b96b4a18468ec2e0a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 17:01:12 +1200 >Subject: [PATCH 282/686] tests/krb5: Make get_default_enctypes() return a set > of enctype constants > >This is often more convenient than a bitfield. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7cedd383bcc1b5652ea65817b464d6e0485c7b8b) >--- > python/samba/tests/krb5/kdc_base_test.py | 13 ++++--------- > 1 file changed, 4 insertions(+), 9 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 59175c7bb2f..3d2d20cb65b 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -222,11 +222,11 @@ class KDCBaseTest(RawKerberosTest): > functional_level = self.get_domain_functional_level(samdb) > > # RC4 should always be supported >- default_enctypes = security.KERB_ENCTYPE_RC4_HMAC_MD5 >+ default_enctypes = {kcrypto.Enctype.RC4} > if functional_level >= DS_DOMAIN_FUNCTION_2008: > # AES is only supported at functional level 2008 or higher >- default_enctypes |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 >- default_enctypes |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 >+ default_enctypes.add(kcrypto.Enctype.AES256) >+ default_enctypes.add(kcrypto.Enctype.AES128) > > return default_enctypes > >@@ -513,12 +513,7 @@ class KDCBaseTest(RawKerberosTest): > > default_enctypes = self.get_default_enctypes() > >- if default_enctypes & security.KERB_ENCTYPE_RC4_HMAC_MD5: >- self.assertIn(kcrypto.Enctype.RC4, keys) >- if default_enctypes & security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96: >- self.assertIn(kcrypto.Enctype.AES256, keys) >- if default_enctypes & security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96: >- self.assertIn(kcrypto.Enctype.AES128, keys) >+ self.assertCountEqual(default_enctypes, keys) > > return keys > >-- >2.25.1 > > >From 65d96b8374a38091413d6b33b74320f5f271bebd Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 21:01:46 +1200 >Subject: [PATCH 283/686] tests/krb5: Add methods to convert between enctypes > and bitfields > >These methods are useful for converting a collection of encryption types >into msDS-SupportedEncryptionTypes bit flags, and vice versa. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 432eba9e09849e74f4c0f2d7826d45cbd2b7ce42) >--- > python/samba/tests/krb5/kdc_base_test.py | 6 +-- > python/samba/tests/krb5/raw_testcase.py | 51 +++++++++++++++++++----- > 2 files changed, 43 insertions(+), 14 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 3d2d20cb65b..10ad9e6961f 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -633,10 +633,8 @@ class KDCBaseTest(RawKerberosTest): > > enctypes = supported_enctypes > if fast_support: >- fast_bits = (security.KERB_ENCTYPE_FAST_SUPPORTED | >- security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >- security.KERB_ENCTYPE_CLAIMS_SUPPORTED) >- enctypes = (enctypes or 0) | fast_bits >+ enctypes = enctypes or 0 >+ enctypes |= KerberosCredentials.fast_supported_bits > > if enctypes is not None: > details['msDS-SupportedEncryptionTypes'] = str(enctypes) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 57013caafb1..57579126f8a 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -304,6 +304,11 @@ class RodcPacEncryptionKey(Krb5EncryptionKey): > > > class KerberosCredentials(Credentials): >+ >+ fast_supported_bits = (security.KERB_ENCTYPE_FAST_SUPPORTED | >+ security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >+ security.KERB_ENCTYPE_CLAIMS_SUPPORTED) >+ > def __init__(self): > super(KerberosCredentials, self).__init__() > all_enc_types = 0 >@@ -331,26 +336,52 @@ class KerberosCredentials(Credentials): > def set_ap_supported_enctypes(self, value): > self.ap_supported_enctypes = int(value) > >- def _get_krb5_etypes(self, supported_enctypes): >+ etype_map = collections.OrderedDict([ >+ (kcrypto.Enctype.AES256, >+ security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96), >+ (kcrypto.Enctype.AES128, >+ security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96), >+ (kcrypto.Enctype.RC4, >+ security.KERB_ENCTYPE_RC4_HMAC_MD5), >+ (kcrypto.Enctype.DES_MD5, >+ security.KERB_ENCTYPE_DES_CBC_MD5), >+ (kcrypto.Enctype.DES_CRC, >+ security.KERB_ENCTYPE_DES_CBC_CRC) >+ ]) >+ >+ @classmethod >+ def etypes_to_bits(self, etypes): >+ bits = 0 >+ for etype in etypes: >+ bit = self.etype_map[etype] >+ if bits & bit: >+ raise ValueError(f'Got duplicate etype: {etype}') >+ bits |= bit >+ >+ return bits >+ >+ @classmethod >+ def bits_to_etypes(self, bits): > etypes = () >+ for etype, bit in self.etype_map.items(): >+ if bit & bits: >+ bits &= ~bit >+ etypes += (etype,) > >- if supported_enctypes & security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96: >- etypes += (kcrypto.Enctype.AES256,) >- if supported_enctypes & security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96: >- etypes += (kcrypto.Enctype.AES128,) >- if supported_enctypes & security.KERB_ENCTYPE_RC4_HMAC_MD5: >- etypes += (kcrypto.Enctype.RC4,) >+ bits &= ~self.fast_supported_bits >+ if bits != 0: >+ raise ValueError(f'Unsupported etype bits: {bits}') > > return etypes > > def get_as_krb5_etypes(self): >- return self._get_krb5_etypes(self.as_supported_enctypes) >+ return self.bits_to_etypes(self.as_supported_enctypes) > > def get_tgs_krb5_etypes(self): >- return self._get_krb5_etypes(self.tgs_supported_enctypes) >+ return self.bits_to_etypes(self.tgs_supported_enctypes) > > def get_ap_krb5_etypes(self): >- return self._get_krb5_etypes(self.ap_supported_enctypes) >+ return self.bits_to_etypes(self.ap_supported_enctypes) > > def set_kvno(self, kvno): > # Sign-extend from 32 bits. >-- >2.25.1 > > >From fcc01a0d6c78ecf3e0d14e0f8c51271e3e5005f8 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 17:10:49 +1200 >Subject: [PATCH 284/686] tests/krb5: Get supported enctypes for credentials > from database > >Look up the account's msDS-SupportedEncryptionTypes attribute to get the >encryption types that it supports. Move the fallback to RC4 to when the >ticket decryption key is obtained. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit b6eaf2cf44fb66d8f302d4cab050827a67de3ea4) >--- > python/samba/tests/krb5/as_req_tests.py | 4 +- > python/samba/tests/krb5/kdc_base_test.py | 52 +++++++++++++++++------- > python/samba/tests/krb5/raw_testcase.py | 5 ++- > 3 files changed, 43 insertions(+), 18 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 35f88a0c920..8d9b90fee69 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -60,7 +60,7 @@ class AsReqKerberosTests(KDCBaseTest): > initial_kdc_options=None): > client_creds = self.get_client_creds() > client_account = client_creds.get_username() >- client_as_etypes = client_creds.get_as_krb5_etypes() >+ client_as_etypes = self.get_default_enctypes() > krbtgt_creds = self.get_krbtgt_creds(require_keys=False) > krbtgt_account = krbtgt_creds.get_username() > realm = krbtgt_creds.get_realm() >@@ -114,7 +114,7 @@ class AsReqKerberosTests(KDCBaseTest): > def test_as_req_enc_timestamp(self): > client_creds = self.get_client_creds() > client_account = client_creds.get_username() >- client_as_etypes = client_creds.get_as_krb5_etypes() >+ client_as_etypes = self.get_default_enctypes() > client_kvno = client_creds.get_kvno() > krbtgt_creds = self.get_krbtgt_creds(require_strongest_key=True) > krbtgt_account = krbtgt_creds.get_username() >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 10ad9e6961f..cdaeaf9f3e1 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -289,6 +289,8 @@ class KDCBaseTest(RawKerberosTest): > # Save the account name so it can be deleted in tearDownClass > self.accounts.add(dn) > >+ self.creds_set_enctypes(creds) >+ > return (creds, dn) > > def create_rodc(self, ctx): >@@ -522,13 +524,28 @@ class KDCBaseTest(RawKerberosTest): > for enctype, key in keys.items(): > creds.set_forced_key(enctype, key) > >- supported_enctypes = 0 >- if kcrypto.Enctype.AES256 in keys: >- supported_enctypes |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 >- if kcrypto.Enctype.AES128 in keys: >- supported_enctypes |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 >- if kcrypto.Enctype.RC4 in keys: >- supported_enctypes |= security.KERB_ENCTYPE_RC4_HMAC_MD5 >+ def creds_set_enctypes(self, creds): >+ samdb = self.get_samdb() >+ >+ res = samdb.search(creds.get_dn(), >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-SupportedEncryptionTypes']) >+ supported_enctypes = res[0].get('msDS-SupportedEncryptionTypes', idx=0) >+ >+ if supported_enctypes is None: >+ supported_enctypes = 0 >+ >+ creds.set_as_supported_enctypes(supported_enctypes) >+ creds.set_tgs_supported_enctypes(supported_enctypes) >+ creds.set_ap_supported_enctypes(supported_enctypes) >+ >+ def creds_set_default_enctypes(self, creds, fast_support=False): >+ default_enctypes = self.get_default_enctypes() >+ supported_enctypes = KerberosCredentials.etypes_to_bits( >+ default_enctypes) >+ >+ if fast_support: >+ supported_enctypes |= KerberosCredentials.fast_supported_bits > > creds.set_as_supported_enctypes(supported_enctypes) > creds.set_tgs_supported_enctypes(supported_enctypes) >@@ -662,14 +679,6 @@ class KDCBaseTest(RawKerberosTest): > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) > >- if machine_account: >- if supported_enctypes is not None: >- tgs_enctypes = supported_enctypes >- else: >- tgs_enctypes = security.KERB_ENCTYPE_RC4_HMAC_MD5 >- >- creds.set_tgs_supported_enctypes(tgs_enctypes) >- > # Handle secret replication to the RODC. > > if allowed_replication or revealed_to_rodc: >@@ -814,6 +823,11 @@ class KDCBaseTest(RawKerberosTest): > keys = self.get_keys(samdb, krbtgt_dn) > self.creds_set_keys(creds, keys) > >+ # The RODC krbtgt account should support the default enctypes, >+ # although it might not have the msDS-SupportedEncryptionTypes >+ # attribute. >+ self.creds_set_default_enctypes(creds) >+ > return creds > > c = self._get_krb5_creds(prefix='RODC_KRBTGT', >@@ -858,6 +872,8 @@ class KDCBaseTest(RawKerberosTest): > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) > >+ self.creds_set_enctypes(creds) >+ > return creds > > c = self._get_krb5_creds(prefix='MOCK_RODC_KRBTGT', >@@ -898,6 +914,12 @@ class KDCBaseTest(RawKerberosTest): > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) > >+ # The krbtgt account should support the default enctypes, although >+ # it might not (on Samba) have the msDS-SupportedEncryptionTypes >+ # attribute. >+ self.creds_set_default_enctypes(creds, >+ fast_support=self.kdc_fast_support) >+ > return creds > > c = self._get_krb5_creds(prefix='KRBTGT', >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 57579126f8a..8d7778602f5 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1082,7 +1082,10 @@ class RawKerberosTest(TestCaseInTempDir): > > if etype is None: > etypes = creds.get_tgs_krb5_etypes() >- etype = etypes[0] >+ if etypes: >+ etype = etypes[0] >+ else: >+ etype = kcrypto.Enctype.RC4 > > forced_key = creds.get_forced_key(etype) > if forced_key is not None: >-- >2.25.1 > > >From 6de9b44acfc25c210e0da864c3d19a5ada6f4714 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 17:11:28 +1200 >Subject: [PATCH 285/686] tests/krb5: Correctly check PA-SUPPORTED-ENCTYPES > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 14cd933a9d6af08deb680c9f688b166138d45ed9) >--- > python/samba/tests/krb5/fast_tests.py | 4 ++++ > python/samba/tests/krb5/kdc_base_test.py | 3 +++ > python/samba/tests/krb5/raw_testcase.py | 24 +++++++++++++++--------- > 3 files changed, 22 insertions(+), 9 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index d8ccfaee325..431b48f00d6 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1126,6 +1126,7 @@ class FAST_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) > krbtgt_decryption_key = self.TicketDecryptionKey_from_creds( > krbtgt_creds) >+ krbtgt_etypes = krbtgt_creds.tgs_supported_enctypes > > target_username = target_creds.get_username()[:-1] > target_realm = target_creds.get_realm() >@@ -1134,6 +1135,7 @@ class FAST_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=[target_service, target_username]) > target_decryption_key = self.TicketDecryptionKey_from_creds( > target_creds) >+ target_etypes = target_creds.tgs_supported_enctypes > > fast_cookie = None > preauth_etype_info2 = None >@@ -1322,6 +1324,7 @@ class FAST_Tests(KDCBaseTest): > expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_supported_etypes=krbtgt_etypes, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, > ticket_decryption_key=krbtgt_decryption_key, >@@ -1355,6 +1358,7 @@ class FAST_Tests(KDCBaseTest): > expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_supported_etypes=target_etypes, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, > ticket_decryption_key=target_decryption_key, >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index cdaeaf9f3e1..646859e85b3 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1267,6 +1267,8 @@ class KDCBaseTest(RawKerberosTest): > expected_sname = self.PrincipalName_create( > name_type=NT_SRV_INST, names=['krbtgt', realm.upper()]) > >+ expected_etypes = krbtgt_creds.tgs_supported_enctypes >+ > rep, kdc_exchange_dict = self._test_as_exchange( > cname=cname, > realm=realm, >@@ -1279,6 +1281,7 @@ class KDCBaseTest(RawKerberosTest): > expected_srealm=expected_realm, > expected_sname=expected_sname, > expected_salt=salt, >+ expected_supported_etypes=expected_etypes, > etypes=etype, > padata=padata, > kdc_options=kdc_options, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 8d7778602f5..c6bc3e553ad 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1879,6 +1879,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_anon=False, > expected_srealm=None, > expected_sname=None, >+ expected_supported_etypes=None, > expected_flags=None, > unexpected_flags=None, > ticket_decryption_key=None, >@@ -1923,6 +1924,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, >+ 'expected_supported_etypes': expected_supported_etypes, > 'expected_flags': expected_flags, > 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, >@@ -1963,6 +1965,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_anon=False, > expected_srealm=None, > expected_sname=None, >+ expected_supported_etypes=None, > expected_flags=None, > unexpected_flags=None, > ticket_decryption_key=None, >@@ -2006,6 +2009,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, >+ 'expected_supported_etypes': expected_supported_etypes, > 'expected_flags': expected_flags, > 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, >@@ -2312,19 +2316,19 @@ class RawKerberosTest(TestCaseInTempDir): > if canonicalize: > self.assertIn(PADATA_SUPPORTED_ETYPES, enc_pa_dict) > >+ expected_supported_etypes = kdc_exchange_dict[ >+ 'expected_supported_etypes'] >+ expected_supported_etypes |= ( >+ security.KERB_ENCTYPE_DES_CBC_CRC | >+ security.KERB_ENCTYPE_DES_CBC_MD5 | >+ security.KERB_ENCTYPE_RC4_HMAC_MD5) >+ > (supported_etypes,) = struct.unpack( > '<L', > enc_pa_dict[PADATA_SUPPORTED_ETYPES]) > >- self.assertTrue( >- security.KERB_ENCTYPE_FAST_SUPPORTED >- & supported_etypes) >- self.assertTrue( >- security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED >- & supported_etypes) >- self.assertTrue( >- security.KERB_ENCTYPE_CLAIMS_SUPPORTED >- & supported_etypes) >+ self.assertEqual(supported_etypes, >+ expected_supported_etypes) > else: > self.assertNotIn(PADATA_SUPPORTED_ETYPES, enc_pa_dict) > >@@ -3396,6 +3400,7 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_options, > expected_flags=None, > unexpected_flags=None, >+ expected_supported_etypes=None, > preauth_key=None, > ticket_decryption_key=None, > pac_request=None, >@@ -3424,6 +3429,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_cname=expected_cname, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_supported_etypes=expected_supported_etypes, > ticket_decryption_key=ticket_decryption_key, > generate_padata_fn=generate_padata_fn, > check_error_fn=check_error_fn, >-- >2.25.1 > > >From fb7a60f5aef992fe90d3430ea8dbf9f699677085 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 13:54:39 +1200 >Subject: [PATCH 286/686] tests/krb5: Set key version number for all accounts > created with create_account() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 054ec1a8cc4ae42918c7c06ef9c66c8a81242655) >--- > python/samba/tests/krb5/kdc_base_test.py | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 646859e85b3..91034a10e15 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -291,6 +291,12 @@ class KDCBaseTest(RawKerberosTest): > > self.creds_set_enctypes(creds) > >+ res = samdb.search(base=dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KeyVersionNumber']) >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ creds.set_kvno(kvno) >+ > return (creds, dn) > > def create_rodc(self, ctx): >@@ -670,12 +676,6 @@ class KDCBaseTest(RawKerberosTest): > additional_details=details, > account_control=user_account_control) > >- res = samdb.search(base=dn, >- scope=ldb.SCOPE_BASE, >- attrs=['msDS-KeyVersionNumber']) >- kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >- creds.set_kvno(kvno) >- > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) > >-- >2.25.1 > > >From d1f8690529cb918aae6ae08b3b04504f1b239a12 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 13:59:24 +1200 >Subject: [PATCH 287/686] tests/krb5: Allow tgs_req() to check the returned > ticket enc-part > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 38b4b334caf1b32f1479db3ada48b2028946f5e6) >--- > python/samba/tests/krb5/kdc_base_test.py | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 91034a10e15..914112fdfc7 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1084,7 +1084,7 @@ class KDCBaseTest(RawKerberosTest): > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, > expected_error_mode=0, padata=None, kdc_options=0, >- to_rodc=False): >+ to_rodc=False, service_creds=None): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1098,6 +1098,12 @@ class KDCBaseTest(RawKerberosTest): > crealm=realm, > cname=cname) > >+ if service_creds is not None: >+ decryption_key = self.TicketDecryptionKey_from_creds( >+ service_creds) >+ else: >+ decryption_key = None >+ > if not expected_error_mode: > check_error_fn = None > check_rep_fn = self.generic_check_kdc_rep >@@ -1120,6 +1126,7 @@ class KDCBaseTest(RawKerberosTest): > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, > check_kdc_private_fn=self.generic_check_kdc_private, >+ ticket_decryption_key=decryption_key, > generate_padata_fn=generate_padata if padata is not None else None, > tgt=tgt, > authenticator_subkey=subkey, >-- >2.25.1 > > >From ed275ff056d511bdd6dcb4f92d6c58196aaf794e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 13:58:09 +1200 >Subject: [PATCH 288/686] tests/krb5: Add method to get DC credentials > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 9d01043042f1caac98a23cf4d9aa9a02a31a9239) >--- > python/samba/tests/krb5/kdc_base_test.py | 42 ++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 914112fdfc7..5de9907d02b 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -930,6 +930,48 @@ class KDCBaseTest(RawKerberosTest): > fallback_creds_fn=download_krbtgt_creds) > return c > >+ def get_dc_creds(self, >+ require_keys=True, >+ require_strongest_key=False): >+ if require_strongest_key: >+ self.assertTrue(require_keys) >+ >+ def download_dc_creds(): >+ samdb = self.get_samdb() >+ >+ dc_rid = 1000 >+ dc_sid = '%s-%d' % (samdb.get_domain_sid(), dc_rid) >+ >+ res = samdb.search(base='<SID=%s>' % dc_sid, >+ scope=ldb.SCOPE_BASE, >+ attrs=['sAMAccountName', >+ 'msDS-KeyVersionNumber']) >+ dn = res[0].dn >+ username = str(res[0]['sAMAccountName']) >+ >+ creds = KerberosCredentials() >+ creds.set_domain(self.env_get_var('DOMAIN', 'DC')) >+ creds.set_realm(self.env_get_var('REALM', 'DC')) >+ creds.set_username(username) >+ >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ creds.set_kvno(kvno) >+ creds.set_dn(dn) >+ >+ keys = self.get_keys(samdb, dn) >+ self.creds_set_keys(creds, keys) >+ >+ self.creds_set_enctypes(creds) >+ >+ return creds >+ >+ c = self._get_krb5_creds(prefix='DC', >+ allow_missing_password=True, >+ allow_missing_keys=not require_keys, >+ require_strongest_key=require_strongest_key, >+ fallback_creds_fn=download_dc_creds) >+ return c >+ > def as_req(self, cname, sname, realm, etypes, padata=None, kdc_options=0): > '''Send a Kerberos AS_REQ, returns the undecoded response > ''' >-- >2.25.1 > > >From 2137d25440eb953d19eae90e84bff81e9471a275 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 14:08:16 +1200 >Subject: [PATCH 289/686] tests/krb5: Fix checking for presence of > authorization data > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit f9284d8517edd9ffd96f0c24166a16366f97de8f) >--- > python/samba/tests/krb5/kdc_base_test.py | 3 ++- > .../ms_kile_client_principal_lookup_tests.py | 6 ++++-- > python/samba/tests/krb5/raw_testcase.py | 16 +++++++++++++--- > 3 files changed, 19 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 5de9907d02b..b4d3739aa11 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1126,7 +1126,7 @@ class KDCBaseTest(RawKerberosTest): > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, > expected_error_mode=0, padata=None, kdc_options=0, >- to_rodc=False, service_creds=None): >+ to_rodc=False, service_creds=None, expect_pac=True): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1173,6 +1173,7 @@ class KDCBaseTest(RawKerberosTest): > tgt=tgt, > authenticator_subkey=subkey, > kdc_options=str(kdc_options), >+ expect_pac=expect_pac, > to_rodc=to_rodc) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index 99c842701ea..64ebe15ad70 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -321,7 +321,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ expect_pac=False) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >@@ -695,7 +696,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ expect_pac=False) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index c6bc3e553ad..b531e33041d 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -944,12 +944,15 @@ class RawKerberosTest(TestCaseInTempDir): > v = self.getElementValue(obj, elem) > self.assertIsNone(v) > >- def assertElementPresent(self, obj, elem): >+ def assertElementPresent(self, obj, elem, expect_empty=False): > v = self.getElementValue(obj, elem) > self.assertIsNotNone(v) > if self.strict_checking: > if isinstance(v, collections.abc.Container): >- self.assertNotEqual(0, len(v)) >+ if expect_empty: >+ self.assertEqual(0, len(v)) >+ else: >+ self.assertNotEqual(0, len(v)) > > def assertElementEqual(self, obj, elem, value): > v = self.getElementValue(obj, elem) >@@ -1907,6 +1910,7 @@ class RawKerberosTest(TestCaseInTempDir): > outer_req=None, > pac_request=None, > pac_options=None, >+ expect_pac=True, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -1952,6 +1956,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'outer_req': outer_req, > 'pac_request': pac_request, > 'pac_options': pac_options, >+ 'expect_pac': expect_pac, > 'to_rodc': to_rodc > } > if callback_dict is None: >@@ -1992,6 +1997,7 @@ class RawKerberosTest(TestCaseInTempDir): > outer_req=None, > pac_request=None, > pac_options=None, >+ expect_pac=True, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -2036,6 +2042,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'outer_req': outer_req, > 'pac_request': pac_request, > 'pac_options': pac_options, >+ 'expect_pac': expect_pac, > 'to_rodc': to_rodc > } > if callback_dict is None: >@@ -2236,6 +2243,8 @@ class RawKerberosTest(TestCaseInTempDir): > armor_key = kdc_exchange_dict['armor_key'] > self.verify_ticket_checksum(ticket, ticket_checksum, armor_key) > >+ expect_pac = kdc_exchange_dict['expect_pac'] >+ > ticket_session_key = None > if ticket_private is not None: > self.assertElementFlags(ticket_private, 'flags', >@@ -2265,7 +2274,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementMissing(ticket_private, 'renew-till') > if self.strict_checking: > self.assertElementEqual(ticket_private, 'caddr', []) >- self.assertElementPresent(ticket_private, 'authorization-data') >+ self.assertElementPresent(ticket_private, 'authorization-data', >+ expect_empty=not expect_pac) > > encpart_session_key = None > if encpart_private is not None: >-- >2.25.1 > > >From 50117583f454d2f54af31442b2852692b7c88731 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 22 Sep 2021 11:41:45 +1200 >Subject: [PATCH 290/686] tests/krb5: Provide ticket enc-part key to tgs_req() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit f2f1f3a1e9269f0e7b93006bba2368a6ffbecc7c) >--- > python/samba/tests/krb5/kdc_base_test.py | 3 +- > python/samba/tests/krb5/kdc_tgs_tests.py | 6 ++-- > .../ms_kile_client_principal_lookup_tests.py | 28 ++++++++++++------- > 3 files changed, 24 insertions(+), 13 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index b4d3739aa11..b71ae66bf54 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1215,7 +1215,8 @@ class KDCBaseTest(RawKerberosTest): > names=[service, target_name]) > > rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype, >- to_rodc=to_rodc) >+ to_rodc=to_rodc, >+ service_creds=target_creds) > > service_ticket = rep['ticket'] > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index dad9e6b88df..0904233b01f 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -132,7 +132,8 @@ class KdcTgsTests(KDCBaseTest): > names=["ldap", samdb.host_dns_name()]) > > (rep, _) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=self.get_dc_creds()) > > self.check_tgs_reply(rep) > >@@ -175,7 +176,8 @@ class KdcTgsTests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index 64ebe15ad70..ce796f63ac2 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -126,7 +126,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -185,7 +186,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, mc.get_realm(), ticket, key, etype) >+ cname, sname, mc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -247,7 +249,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >@@ -322,7 +325,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > (rep, enc_part) = self.tgs_req( > cname, sname, uc.get_realm(), ticket, key, etype, >- expect_pac=False) >+ service_creds=mc, expect_pac=False) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >@@ -390,7 +393,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -492,7 +496,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -555,7 +560,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -619,7 +625,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -697,7 +704,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > (rep, enc_part) = self.tgs_req( > cname, sname, uc.get_realm(), ticket, key, etype, >- expect_pac=False) >+ service_creds=mc, expect_pac=False) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >@@ -767,7 +774,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >-- >2.25.1 > > >From f5e2a63f7e776245c32b42c270cf6789d8ab6ba9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 14:05:58 +1200 >Subject: [PATCH 291/686] tests/krb5: Simplify account creation > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 394e8db261b10d130c5e5730989bf68f9bf4f85f) >--- > .../ms_kile_client_principal_lookup_tests.py | 16 ++++------------ > 1 file changed, 4 insertions(+), 12 deletions(-) > >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index ce796f63ac2..501bc4892f4 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -282,15 +282,11 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > samdb = self.get_samdb() > user_name = "mskileusr" > alt_name = "mskilealtsec" >- (uc, dn) = self.create_account(samdb, user_name) >+ (uc, dn) = self.create_account(samdb, user_name, >+ account_control=UF_DONT_REQUIRE_PREAUTH) > realm = uc.get_realm().lower() > alt_sec = "Kerberos:%s@%s" % (alt_name, realm) > self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) >- self.modify_attribute( >- samdb, >- dn, >- "userAccountControl", >- str(UF_NORMAL_ACCOUNT | UF_DONT_REQUIRE_PREAUTH)) > > mach_name = "mskilemac" > (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >@@ -660,15 +656,11 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > samdb = self.get_samdb() > user_name = "mskileusr" > alt_name = "mskilealtsec" >- (uc, dn) = self.create_account(samdb, user_name) >+ (uc, dn) = self.create_account(samdb, user_name, >+ account_control=UF_DONT_REQUIRE_PREAUTH) > realm = uc.get_realm().lower() > alt_sec = "Kerberos:%s@%s" % (alt_name, realm) > self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) >- self.modify_attribute( >- samdb, >- dn, >- "userAccountControl", >- str(UF_NORMAL_ACCOUNT | UF_DONT_REQUIRE_PREAUTH)) > ename = alt_name + "@" + realm > > mach_name = "mskilemac" >-- >2.25.1 > > >From 212b5d0cb88ec25e8cd5995e6a94e5c63cd195fb Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 13:54:47 +1200 >Subject: [PATCH 292/686] tests/krb5: Add get_rodc_krbtgt_creds() to > RawKerberosTest > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1458cd9065de34c42bd5ec63feb2f66c25103982) >--- > python/samba/tests/krb5/raw_testcase.py | 11 +++++++++++ > 1 file changed, 11 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b531e33041d..59882e44173 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -750,6 +750,17 @@ class RawKerberosTest(TestCaseInTempDir): > c.set_gensec_features(c.get_gensec_features() | FEATURE_SEAL) > return c > >+ def get_rodc_krbtgt_creds(self, >+ require_keys=True, >+ require_strongest_key=False): >+ if require_strongest_key: >+ self.assertTrue(require_keys) >+ c = self._get_krb5_creds(prefix='RODC_KRBTGT', >+ allow_missing_password=True, >+ allow_missing_keys=not require_keys, >+ require_strongest_key=require_strongest_key) >+ return c >+ > def get_krbtgt_creds(self, > require_keys=True, > require_strongest_key=False): >-- >2.25.1 > > >From 319bddfa0684ab9551f5343e7589c2cca943f209 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 14:10:07 +1200 >Subject: [PATCH 293/686] tests/krb5: Verify checksums of tickets obtained from > the KDC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ea7b550a500d9e458498d37688b67dafd3d9509d) >--- > python/samba/tests/krb5/raw_testcase.py | 34 +++++++++++++++++-------- > 1 file changed, 24 insertions(+), 10 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 59882e44173..985792887ca 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2254,6 +2254,13 @@ class RawKerberosTest(TestCaseInTempDir): > armor_key = kdc_exchange_dict['armor_key'] > self.verify_ticket_checksum(ticket, ticket_checksum, armor_key) > >+ to_rodc = kdc_exchange_dict['to_rodc'] >+ if to_rodc: >+ krbtgt_creds = self.get_rodc_krbtgt_creds() >+ else: >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ > expect_pac = kdc_exchange_dict['expect_pac'] > > ticket_session_key = None >@@ -2386,6 +2393,9 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_private=ticket_private, > encpart_private=encpart_private) > >+ if ticket_decryption_key is not None: >+ self.verify_ticket(ticket_creds, krbtgt_key, expect_pac=expect_pac) >+ > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > > def check_pac_options_claims_support(self, pac_options): >@@ -3061,16 +3071,20 @@ class RawKerberosTest(TestCaseInTempDir): > if is_tgt: > self.assertNotIn(krb5pac.PAC_TYPE_TICKET_CHECKSUM, checksums) > else: >- ticket_checksum, ticket_ctype = checksums[ >- krb5pac.PAC_TYPE_TICKET_CHECKSUM] >- enc_part['authorization-data'] = auth_data >- enc_part = self.der_encode(enc_part, >- asn1Spec=krb5_asn1.EncTicketPart()) >- >- krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >- enc_part, >- ticket_ctype, >- ticket_checksum) >+ ticket_checksum, ticket_ctype = checksums.get( >+ krb5pac.PAC_TYPE_TICKET_CHECKSUM, >+ (None, None)) >+ if self.strict_checking: >+ self.assertIsNotNone(ticket_checksum) >+ if ticket_checksum is not None: >+ enc_part['authorization-data'] = auth_data >+ enc_part = self.der_encode(enc_part, >+ asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >+ enc_part, >+ ticket_ctype, >+ ticket_checksum) > > def modified_ticket(self, > ticket, *, >-- >2.25.1 > > >From 7b667d0cc1358b1f14ed0c7d4a6411aa3589c7d9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 15:06:18 +1200 >Subject: [PATCH 294/686] tests/krb5: Add method to determine if principal is > krbtgt > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit c0b81f0dd54d0d71b5d0f5a870b505e82d0e85b8) >--- > python/samba/tests/krb5/raw_testcase.py | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 985792887ca..cadf2b50dc9 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2977,7 +2977,7 @@ class RawKerberosTest(TestCaseInTempDir): > def verify_ticket(self, ticket, krbtgt_key, expect_pac=True): > # Check if the ticket is a TGT. > sname = ticket.ticket['sname'] >- is_tgt = sname['name-string'][0] == b'krbtgt' >+ is_tgt = self.is_tgs(sname) > > # Decrypt the ticket. > >@@ -3371,6 +3371,10 @@ class RawKerberosTest(TestCaseInTempDir): > krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key > } > >+ def is_tgs(self, principal): >+ name = principal['name-string'][0] >+ return name in ('krbtgt', b'krbtgt') >+ > def get_empty_pac(self): > return self.AuthorizationData_create(AD_WIN2K_PAC, bytes(1)) > >-- >2.25.1 > > >From 4cf2d632a85b18771e6699bdd640ea797f08fae6 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 15:10:35 +1200 >Subject: [PATCH 295/686] tests/krb5: Add classes for testing invalid checksums > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Thu Sep 23 19:28:44 UTC 2021 on sn-devel-184 > >(cherry picked from commit 5b331443d0698256ee7fcc040a1ab8137efe925d) >--- > python/samba/tests/krb5/raw_testcase.py | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index cadf2b50dc9..579d52b3e92 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -303,6 +303,29 @@ class RodcPacEncryptionKey(Krb5EncryptionKey): > cksum) > > >+class ZeroedChecksumKey(Krb5EncryptionKey): >+ def make_checksum(self, usage, plaintext, ctype=None): >+ return self.make_zeroed_checksum(ctype) >+ >+ >+class WrongLengthChecksumKey(Krb5EncryptionKey): >+ def __init__(self, key, kvno, length): >+ super().__init__(key, kvno) >+ >+ self._length = length >+ >+ def make_checksum(self, usage, plaintext, ctype=None): >+ checksum = super().make_checksum(usage, plaintext, ctype) >+ >+ diff = self._length - len(checksum) >+ if diff > 0: >+ checksum += bytes(diff) >+ elif diff < 0: >+ checksum = checksum[:self._length] >+ >+ return checksum >+ >+ > class KerberosCredentials(Credentials): > > fast_supported_bits = (security.KERB_ENCTYPE_FAST_SUPPORTED | >-- >2.25.1 > > >From dc2695d8ddf0e5ae764b0667b8ab9c3985cc8087 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:16:24 +1300 >Subject: [PATCH 296/686] tests/krb5: Rename method parameter > >For class methods, the name given to the first parameter is generally 'cls' >rather than 'self'. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit d501ddca3b7b9c39c0b3eccf19176e3122cf5b9d) >--- > python/samba/tests/krb5/raw_testcase.py | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 579d52b3e92..11c0e308e3d 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -373,10 +373,10 @@ class KerberosCredentials(Credentials): > ]) > > @classmethod >- def etypes_to_bits(self, etypes): >+ def etypes_to_bits(cls, etypes): > bits = 0 > for etype in etypes: >- bit = self.etype_map[etype] >+ bit = cls.etype_map[etype] > if bits & bit: > raise ValueError(f'Got duplicate etype: {etype}') > bits |= bit >@@ -384,14 +384,14 @@ class KerberosCredentials(Credentials): > return bits > > @classmethod >- def bits_to_etypes(self, bits): >+ def bits_to_etypes(cls, bits): > etypes = () >- for etype, bit in self.etype_map.items(): >+ for etype, bit in cls.etype_map.items(): > if bit & bits: > bits &= ~bit > etypes += (etype,) > >- bits &= ~self.fast_supported_bits >+ bits &= ~cls.fast_supported_bits > if bits != 0: > raise ValueError(f'Unsupported etype bits: {bits}') > >-- >2.25.1 > > >From f90f857b570e4e3774305634c677e1dfdeea3ef1 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:16:51 +1300 >Subject: [PATCH 297/686] tests/krb5: Remove unused parameter > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 8e4b21590836dab02c1864f6ac12b3879c4bd69c) >--- > python/samba/tests/krb5/raw_testcase.py | 3 --- > 1 file changed, 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 11c0e308e3d..1119c9926d7 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2169,7 +2169,6 @@ class RawKerberosTest(TestCaseInTempDir): > > self.check_rep_padata(kdc_exchange_dict, > callback_dict, >- rep, > fast_response['padata'], > error_code=0) > >@@ -2509,7 +2508,6 @@ class RawKerberosTest(TestCaseInTempDir): > > etype_info2 = self.check_rep_padata(kdc_exchange_dict, > callback_dict, >- rep, > rep_padata, > error_code) > >@@ -2520,7 +2518,6 @@ class RawKerberosTest(TestCaseInTempDir): > def check_rep_padata(self, > kdc_exchange_dict, > callback_dict, >- rep, > rep_padata, > error_code): > rep_msg_type = kdc_exchange_dict['rep_msg_type'] >-- >2.25.1 > > >From eae3f191efc68932fcf75cb36ed6c0b346a8c9c1 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:23:17 +1300 >Subject: [PATCH 298/686] tests/krb5: Allow for missing msDS-KeyVersionNumber > attribute > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ce433ff868d3cdf8e8a6e4995d89d6e036335fb6) >--- > python/samba/tests/krb5/kdc_base_test.py | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index b71ae66bf54..bb92bbd65e5 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -294,8 +294,10 @@ class KDCBaseTest(RawKerberosTest): > res = samdb.search(base=dn, > scope=ldb.SCOPE_BASE, > attrs=['msDS-KeyVersionNumber']) >- kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >- creds.set_kvno(kvno) >+ kvno = res[0].get('msDS-KeyVersionNumber', idx=0) >+ if kvno is not None: >+ self.assertEqual(int(kvno), 1) >+ creds.set_kvno(1) > > return (creds, dn) > >-- >2.25.1 > > >From a100ca06c6951414adde6a0fae31e0f17c8dfeed Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 30 Sep 2021 10:51:01 +1300 >Subject: [PATCH 299/686] tests/krb5: Fix sending PA-PAC-OPTIONS and > PA-PAC-REQUEST > >These padata were not being sent if other FAST padata was not specified. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 >(cherry picked from commit 6f1282e8d34073d8499ce919908b39645b017cb8) >--- > python/samba/tests/krb5/raw_testcase.py | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 1119c9926d7..ceff1b6220e 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1801,8 +1801,6 @@ class RawKerberosTest(TestCaseInTempDir): > fast_padata, req_body = generate_fast_padata_fn(kdc_exchange_dict, > callback_dict, > req_body) >- >- fast_padata += additional_padata > else: > fast_padata = [] > >@@ -1847,6 +1845,7 @@ class RawKerberosTest(TestCaseInTempDir): > KU_FAST_REQ_CHKSUM, > checksum_blob) > >+ fast_padata += additional_padata > fast = generate_fast_fn(kdc_exchange_dict, > callback_dict, > inner_req_body, >-- >2.25.1 > > >From 25d0d76d5c6032cde0c25359b091268717e202b9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 30 Sep 2021 10:54:33 +1300 >Subject: [PATCH 300/686] tests/krb5: Fix PA-PAC-OPTIONS checking > >Make the check work correctly if bits other than the claims bit are >specified. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1fd00135fa4dff4331d86b228ccc01f834476997) >--- > python/samba/tests/krb5/raw_testcase.py | 44 +++++++++++++------------ > 1 file changed, 23 insertions(+), 21 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index ceff1b6220e..0217674ed2d 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2354,10 +2354,10 @@ class RawKerberosTest(TestCaseInTempDir): > if self.strict_checking: > self.assertElementEqual(encpart_private, 'caddr', []) > >- sent_claims = self.sent_claims(kdc_exchange_dict) >+ sent_pac_options = self.get_sent_pac_options(kdc_exchange_dict) > > if self.strict_checking: >- if sent_claims or canonicalize: >+ if canonicalize or '1' in sent_pac_options: > self.assertElementPresent(encpart_private, > 'encrypted-pa-data') > enc_pa_dict = self.get_pa_dict( >@@ -2381,12 +2381,15 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertNotIn(PADATA_SUPPORTED_ETYPES, enc_pa_dict) > >- # ClaimsCompIdFASTSupported registry key >- if sent_claims: >+ if '1' in sent_pac_options: > self.assertIn(PADATA_PAC_OPTIONS, enc_pa_dict) > >- self.check_pac_options_claims_support( >- enc_pa_dict[PADATA_PAC_OPTIONS]) >+ pac_options = self.der_decode( >+ enc_pa_dict[PADATA_PAC_OPTIONS], >+ asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >+ >+ self.assertElementEqual(pac_options, 'options', >+ sent_pac_options) > else: > self.assertNotIn(PADATA_PAC_OPTIONS, enc_pa_dict) > else: >@@ -2419,11 +2422,6 @@ class RawKerberosTest(TestCaseInTempDir): > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > >- def check_pac_options_claims_support(self, pac_options): >- pac_options = self.der_decode(pac_options, >- asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >- self.assertEqual('1', pac_options['options'][0]) # claims bit >- > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >@@ -2565,8 +2563,9 @@ class RawKerberosTest(TestCaseInTempDir): > if not sent_fast and error_code != 0: > expected_patypes += (PADATA_PW_SALT,) > else: >- sent_claims = self.sent_claims(kdc_exchange_dict) >- if sent_claims and error_code not in (0, KDC_ERR_GENERIC): >+ sent_pac_options = self.get_sent_pac_options(kdc_exchange_dict) >+ if ('1' in sent_pac_options >+ and error_code not in (0, KDC_ERR_GENERIC)): > expected_patypes += (PADATA_PAC_OPTIONS,) > elif error_code != KDC_ERR_GENERIC: > if expect_etype_info: >@@ -2656,8 +2655,9 @@ class RawKerberosTest(TestCaseInTempDir): > continue > if patype == PADATA_PAC_OPTIONS: > self.assertIsNone(pac_options) >- pac_options = pavalue >- self.assertIsNotNone(pac_options) >+ pac_options = self.der_decode( >+ pavalue, >+ asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) > continue > if patype == PADATA_PW_SALT: > self.assertIsNone(pw_salt) >@@ -2677,7 +2677,7 @@ class RawKerberosTest(TestCaseInTempDir): > inner=True) > > if pac_options is not None: >- self.check_pac_options_claims_support(pac_options) >+ self.assertElementEqual(pac_options, 'options', sent_pac_options) > > if pw_salt is not None: > self.assertEqual(12, len(pw_salt)) >@@ -3418,19 +3418,21 @@ class RawKerberosTest(TestCaseInTempDir): > > return PADATA_ENCRYPTED_CHALLENGE in fast_pa_dict > >- def sent_claims(self, kdc_exchange_dict): >+ def get_sent_pac_options(self, kdc_exchange_dict): > fast_pa_dict = self.get_fast_pa_dict(kdc_exchange_dict) > > if PADATA_PAC_OPTIONS not in fast_pa_dict: >- return False >+ return '' > > pac_options = self.der_decode(fast_pa_dict[PADATA_PAC_OPTIONS], > asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) > pac_options = pac_options['options'] >- claims_pos = len(tuple(krb5_asn1.PACOptionFlags('claims'))) - 1 > >- return (claims_pos < len(pac_options) >- and pac_options[claims_pos] == '1') >+ # Mask out unsupported bits. >+ pac_options, remaining = pac_options[:4], pac_options[4:] >+ pac_options += '0' * len(remaining) >+ >+ return pac_options > > def get_krbtgt_sname(self): > krbtgt_creds = self.get_krbtgt_creds() >-- >2.25.1 > > >From 2e7e64ac0c850f15b3a8bdc3959a4f98f1e07538 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:47:39 +1300 >Subject: [PATCH 301/686] tests/krb5: Rename allowed_to_delegate_to parameter > for clarity > >This helps to distinguish resourced-based and non-resource-based >constrained delegation. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 31817c383c2014224b1397fde610624663313246) >--- > python/samba/tests/krb5/kdc_base_test.py | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index bb92bbd65e5..e6639270f69 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -598,7 +598,7 @@ class KDCBaseTest(RawKerberosTest): > 'no_auth_data_required': False, > 'supported_enctypes': None, > 'not_delegated': False, >- 'allowed_to_delegate_to': None, >+ 'delegation_to_spn': None, > 'trusted_to_auth_for_delegation': False, > 'fast_support': False > } >@@ -629,13 +629,13 @@ class KDCBaseTest(RawKerberosTest): > no_auth_data_required, > supported_enctypes, > not_delegated, >- allowed_to_delegate_to, >+ delegation_to_spn, > trusted_to_auth_for_delegation, > fast_support): > if machine_account: > self.assertFalse(not_delegated) > else: >- self.assertIsNone(allowed_to_delegate_to) >+ self.assertIsNone(delegation_to_spn) > self.assertFalse(trusted_to_auth_for_delegation) > > samdb = self.get_samdb() >@@ -664,8 +664,8 @@ class KDCBaseTest(RawKerberosTest): > if enctypes is not None: > details['msDS-SupportedEncryptionTypes'] = str(enctypes) > >- if allowed_to_delegate_to: >- details['msDS-AllowedToDelegateTo'] = allowed_to_delegate_to >+ if delegation_to_spn: >+ details['msDS-AllowedToDelegateTo'] = delegation_to_spn > > if machine_account: > spn = 'host/' + user_name >-- >2.25.1 > > >From 211d69964107fd6e0ff8c1cd04a3afc81e9ae866 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:50:36 +1300 >Subject: [PATCH 302/686] tests/krb5: Allow created accounts to use > resource-based constrained delegation > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit bba8cb8dce19e47a7b813efd9a7527e38856435e) >--- > python/samba/tests/krb5/kdc_base_test.py | 33 ++++++++++++++++++++++++ > 1 file changed, 33 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index e6639270f69..918e04a1dbe 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -301,6 +301,30 @@ class KDCBaseTest(RawKerberosTest): > > return (creds, dn) > >+ def get_security_descriptor(self, dn): >+ samdb = self.get_samdb() >+ >+ sid = self.get_objectSid(samdb, dn) >+ >+ owner_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) >+ >+ ace = security.ace() >+ ace.access_mask = security.SEC_ADS_GENERIC_ALL >+ >+ ace.trustee = security.dom_sid(sid) >+ >+ dacl = security.acl() >+ dacl.revision = security.SECURITY_ACL_REVISION_ADS >+ dacl.aces = [ace] >+ dacl.num_aces = 1 >+ >+ security_desc = security.descriptor() >+ security_desc.type |= security.SEC_DESC_DACL_PRESENT >+ security_desc.owner_sid = owner_sid >+ security_desc.dacl = dacl >+ >+ return ndr_pack(security_desc) >+ > def create_rodc(self, ctx): > ctx.nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn] > ctx.full_nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn] >@@ -599,6 +623,7 @@ class KDCBaseTest(RawKerberosTest): > 'supported_enctypes': None, > 'not_delegated': False, > 'delegation_to_spn': None, >+ 'delegation_from_dn': None, > 'trusted_to_auth_for_delegation': False, > 'fast_support': False > } >@@ -630,12 +655,14 @@ class KDCBaseTest(RawKerberosTest): > supported_enctypes, > not_delegated, > delegation_to_spn, >+ delegation_from_dn, > trusted_to_auth_for_delegation, > fast_support): > if machine_account: > self.assertFalse(not_delegated) > else: > self.assertIsNone(delegation_to_spn) >+ self.assertIsNone(delegation_from_dn) > self.assertFalse(trusted_to_auth_for_delegation) > > samdb = self.get_samdb() >@@ -667,6 +694,12 @@ class KDCBaseTest(RawKerberosTest): > if delegation_to_spn: > details['msDS-AllowedToDelegateTo'] = delegation_to_spn > >+ if delegation_from_dn: >+ security_descriptor = self.get_security_descriptor( >+ delegation_from_dn) >+ details['msDS-AllowedToActOnBehalfOfOtherIdentity'] = ( >+ security_descriptor) >+ > if machine_account: > spn = 'host/' + user_name > else: >-- >2.25.1 > > >From 5f54f5f3bdfd44918a9e05f876d454febb8d00b6 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:52:17 +1300 >Subject: [PATCH 303/686] tests/krb5: Add assertion to make failures clearer > >These failures may occur if tests are not run against an RODC. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit cda50b5c505072989abf84c209e16ff4efe2e628) >--- > python/samba/tests/krb5/kdc_base_test.py | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 918e04a1dbe..25433ba1069 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -590,6 +590,7 @@ class KDCBaseTest(RawKerberosTest): > scope=ldb.SCOPE_BASE, > attrs=[group_attr]) > orig_msg = res[0] >+ self.assertIn(group_attr, orig_msg) > > members = list(orig_msg[group_attr]) > members.append(account_dn) >-- >2.25.1 > > >From 417b49d5517f7c61a073d3c902803324dd2a011b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:54:49 +1300 >Subject: [PATCH 304/686] tests/krb5: Introduce helper method for creating > invalid length checksums > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 9d142dc3a452b0f06efc66f422402ee6e553ee7c) >--- > python/samba/tests/krb5/raw_testcase.py | 13 ++++++++----- > 1 file changed, 8 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 0217674ed2d..6107442409f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -314,17 +314,20 @@ class WrongLengthChecksumKey(Krb5EncryptionKey): > > self._length = length > >- def make_checksum(self, usage, plaintext, ctype=None): >- checksum = super().make_checksum(usage, plaintext, ctype) >- >- diff = self._length - len(checksum) >+ @classmethod >+ def _adjust_to_length(cls, checksum, length): >+ diff = length - len(checksum) > if diff > 0: > checksum += bytes(diff) > elif diff < 0: >- checksum = checksum[:self._length] >+ checksum = checksum[:length] > > return checksum > >+ def make_checksum(self, usage, plaintext, ctype=None): >+ checksum = super().make_checksum(usage, plaintext, ctype) >+ return self._adjust_to_length(checksum, self._length) >+ > > class KerberosCredentials(Credentials): > >-- >2.25.1 > > >From 568ad85b0715ab268b6473f36f0f7f516d6d2510 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:56:21 +1300 >Subject: [PATCH 305/686] tests/krb5: Fix method for creating invalid length > zeroed checksum > >Previously the base class method was being used. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ae09219c3a1c6d47817f51baf3784e8986c7478d) >--- > python/samba/tests/krb5/raw_testcase.py | 3 +++ > 1 file changed, 3 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 6107442409f..a3f17e4dc4a 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -324,6 +324,9 @@ class WrongLengthChecksumKey(Krb5EncryptionKey): > > return checksum > >+ def make_zeroed_checksum(self, ctype=None): >+ return bytes(self._length) >+ > def make_checksum(self, usage, plaintext, ctype=None): > checksum = super().make_checksum(usage, plaintext, ctype) > return self._adjust_to_length(checksum, self._length) >-- >2.25.1 > > >From 160e30347729142ed8e9b6c77b8d40cad5cd4164 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:59:42 +1300 >Subject: [PATCH 306/686] tests/krb5: Fix checksum generation and verification > >The KDC and server checksums may be generated using the same key, but >only the KDC checksum should have an RODCIdentifier. To fix this, >instead of overriding the existing methods, add additional ones for >RODC-specific signatures, so that both types of signatures can be >generated or verified. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a927cecafdd5ad6dc5189fa98cb42684c9c3b033) >--- > python/samba/tests/krb5/raw_testcase.py | 57 ++++++++++++++----------- > 1 file changed, 32 insertions(+), 25 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index a3f17e4dc4a..aefbdd6d761 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -281,15 +281,15 @@ class RodcPacEncryptionKey(Krb5EncryptionKey): > else: > self.rodc_id = b'' > >- def make_zeroed_checksum(self, ctype=None): >+ def make_rodc_zeroed_checksum(self, ctype=None): > checksum = super().make_zeroed_checksum(ctype) > return checksum + bytes(len(self.rodc_id)) > >- def make_checksum(self, usage, plaintext, ctype=None): >+ def make_rodc_checksum(self, usage, plaintext, ctype=None): > checksum = super().make_checksum(usage, plaintext, ctype) > return checksum + self.rodc_id > >- def verify_checksum(self, usage, plaintext, ctype, cksum): >+ def verify_rodc_checksum(self, usage, plaintext, ctype, cksum): > if self.rodc_id: > cksum, cksum_rodc_id = cksum[:-2], cksum[-2:] > >@@ -303,12 +303,15 @@ class RodcPacEncryptionKey(Krb5EncryptionKey): > cksum) > > >-class ZeroedChecksumKey(Krb5EncryptionKey): >+class ZeroedChecksumKey(RodcPacEncryptionKey): > def make_checksum(self, usage, plaintext, ctype=None): > return self.make_zeroed_checksum(ctype) > >+ def make_rodc_checksum(self, usage, plaintext, ctype=None): >+ return self.make_rodc_zeroed_checksum(ctype) > >-class WrongLengthChecksumKey(Krb5EncryptionKey): >+ >+class WrongLengthChecksumKey(RodcPacEncryptionKey): > def __init__(self, key, kvno, length): > super().__init__(key, kvno) > >@@ -331,6 +334,13 @@ class WrongLengthChecksumKey(Krb5EncryptionKey): > checksum = super().make_checksum(usage, plaintext, ctype) > return self._adjust_to_length(checksum, self._length) > >+ def make_rodc_zeroed_checksum(self, ctype=None): >+ return bytes(self._length) >+ >+ def make_rodc_checksum(self, usage, plaintext, ctype=None): >+ checksum = super().make_rodc_checksum(usage, plaintext, ctype) >+ return self._adjust_to_length(checksum, self._length) >+ > > class KerberosCredentials(Credentials): > >@@ -3080,18 +3090,17 @@ class RawKerberosTest(TestCaseInTempDir): > > server_checksum, server_ctype = checksums[ > krb5pac.PAC_TYPE_SRV_CHECKSUM] >- Krb5EncryptionKey.verify_checksum(key, >- KU_NON_KERB_CKSUM_SALT, >- pac_data, >- server_ctype, >- server_checksum) >+ key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >+ pac_data, >+ server_ctype, >+ server_checksum) > > kdc_checksum, kdc_ctype = checksums[ > krb5pac.PAC_TYPE_KDC_CHECKSUM] >- krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >- server_checksum, >- kdc_ctype, >- kdc_checksum) >+ krbtgt_key.verify_rodc_checksum(KU_NON_KERB_CKSUM_SALT, >+ server_checksum, >+ kdc_ctype, >+ kdc_checksum) > > if is_tgt: > self.assertNotIn(krb5pac.PAC_TYPE_TICKET_CHECKSUM, checksums) >@@ -3106,10 +3115,10 @@ class RawKerberosTest(TestCaseInTempDir): > enc_part = self.der_encode(enc_part, > asn1Spec=krb5_asn1.EncTicketPart()) > >- krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >- enc_part, >- ticket_ctype, >- ticket_checksum) >+ krbtgt_key.verify_rodc_checksum(KU_NON_KERB_CKSUM_SALT, >+ enc_part, >+ ticket_ctype, >+ ticket_checksum) > > def modified_ticket(self, > ticket, *, >@@ -3300,16 +3309,15 @@ class RawKerberosTest(TestCaseInTempDir): > if buffer_type == krb5pac.PAC_TYPE_TICKET_CHECKSUM: > self.assertIsNotNone(enc_part) > >- signature = checksum_key.make_checksum( >+ signature = checksum_key.make_rodc_checksum( > KU_NON_KERB_CKSUM_SALT, > enc_part) > > elif buffer_type == krb5pac.PAC_TYPE_SRV_CHECKSUM: >- signature = Krb5EncryptionKey.make_zeroed_checksum( >- checksum_key) >+ signature = checksum_key.make_zeroed_checksum() > > else: >- signature = checksum_key.make_zeroed_checksum() >+ signature = checksum_key.make_rodc_zeroed_checksum() > > checksum_buffer.info.signature = signature > checksum_buffer.info.type = ctype >@@ -3325,8 +3333,7 @@ class RawKerberosTest(TestCaseInTempDir): > server_checksum_key = checksum_keys[krb5pac.PAC_TYPE_SRV_CHECKSUM] > > pac_data = ndr_pack(pac) >- server_checksum = Krb5EncryptionKey.make_checksum( >- server_checksum_key, >+ server_checksum = server_checksum_key.make_checksum( > KU_NON_KERB_CKSUM_SALT, > pac_data) > >@@ -3339,7 +3346,7 @@ class RawKerberosTest(TestCaseInTempDir): > > kdc_checksum_key = checksum_keys[krb5pac.PAC_TYPE_KDC_CHECKSUM] > >- kdc_checksum = kdc_checksum_key.make_checksum( >+ kdc_checksum = kdc_checksum_key.make_rodc_checksum( > KU_NON_KERB_CKSUM_SALT, > server_checksum) > >-- >2.25.1 > > >From 30a5762c491a27dc4be138d1d586a9deb8e58e42 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 12:03:33 +1300 >Subject: [PATCH 307/686] tests/krb5: Allow excluding the PAC server checksum > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit dcf45a151a198f7165cd332a26db78a5d8e8f8c5) >--- > python/samba/tests/krb5/raw_testcase.py | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index aefbdd6d761..4c1aedbca0f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3342,7 +3342,10 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_checksum_buffer = checksum_buffers.get( > krb5pac.PAC_TYPE_KDC_CHECKSUM) > if kdc_checksum_buffer is not None: >- self.assertIsNotNone(server_checksum_buffer) >+ if server_checksum_buffer is None: >+ # There's no server signature to make the checksum over, so >+ # just make the checksum over an empty bytes object. >+ server_checksum = bytes() > > kdc_checksum_key = checksum_keys[krb5pac.PAC_TYPE_KDC_CHECKSUM] > >-- >2.25.1 > > >From 31199a768e61126a32754d3c626cdb24b85c261e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 12:06:03 +1300 >Subject: [PATCH 308/686] tests/krb5: Fix handling authdata with missing PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a4bc712ee02f32c2d04dfc2d99d58931344e5ceb) >--- > python/samba/tests/krb5/raw_testcase.py | 11 ++++++----- > 1 file changed, 6 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 4c1aedbca0f..b9895e547c4 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3200,11 +3200,11 @@ class RawKerberosTest(TestCaseInTempDir): > # Get a copy of the authdata with an empty PAC, and the > # existing PAC (if present). > empty_pac = self.get_empty_pac() >- empty_pac_auth_data, pac_data = self.replace_pac(auth_data, >- empty_pac) >+ empty_pac_auth_data, pac_data = self.replace_pac( >+ auth_data, >+ empty_pac, >+ expect_pac=expect_pac) > >- if expect_pac: >- self.assertIsNotNone(pac_data) > if pac_data is not None: > pac = ndr_unpack(krb5pac.PAC_DATA, pac_data) > >@@ -3234,7 +3234,8 @@ class RawKerberosTest(TestCaseInTempDir): > > # Replace the PAC in the authorization data and re-add it to the > # ticket enc-part. >- auth_data, _ = self.replace_pac(auth_data, new_pac) >+ auth_data, _ = self.replace_pac(auth_data, new_pac, >+ expect_pac=expect_pac) > enc_part['authorization-data'] = auth_data > > # Re-encrypt the ticket enc-part with the new key. >-- >2.25.1 > > >From 4858db6d8db90024b72c15bf4c91b9e167146db7 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 12:16:58 +1300 >Subject: [PATCH 309/686] tests/krb5: Fix status code checking > >The type used to encode the status code is actually KERB-ERROR-DATA, >rather than PA-DATA. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 012b6fcd1976c6570e9b92c133d8c21e543e5a4f) >--- > python/samba/tests/krb5/raw_testcase.py | 89 +++++++++----------- > python/samba/tests/krb5/rfc4120_constants.py | 6 ++ > 2 files changed, 48 insertions(+), 47 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b9895e547c4..db7db28cac5 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -49,6 +49,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_GENERIC, > KDC_ERR_PREAUTH_FAILED, > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, >+ KERB_ERR_TYPE_EXTENDED, > KRB_AP_REQ, > KRB_AS_REP, > KRB_AS_REQ, >@@ -85,7 +86,6 @@ from samba.tests.krb5.rfc4120_constants import ( > PADATA_PAC_REQUEST, > PADATA_PK_AS_REQ, > PADATA_PK_AS_REP_19, >- PADATA_PW_SALT, > PADATA_SUPPORTED_ETYPES > ) > import samba.tests.krb5.kcrypto as kcrypto >@@ -2497,34 +2497,51 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(edata) > if edata is not None: > if rep_msg_type == KRB_TGS_REP and not sent_fast: >- rep_padata = [self.der_decode(edata, >- asn1Spec=krb5_asn1.PA_DATA())] >+ error_data = self.der_decode( >+ edata, >+ asn1Spec=krb5_asn1.KERB_ERROR_DATA()) >+ self.assertEqual(KERB_ERR_TYPE_EXTENDED, >+ error_data['data-type']) >+ >+ extended_error = error_data['data-value'] >+ >+ self.assertEqual(12, len(extended_error)) >+ >+ status = int.from_bytes(extended_error[:4], 'little') >+ flags = int.from_bytes(extended_error[8:], 'little') >+ >+ expected_status = kdc_exchange_dict['expected_status'] >+ self.assertEqual(expected_status, status) >+ >+ self.assertEqual(3, flags) > else: >+ self.assertIsNone(kdc_exchange_dict['expected_status']) >+ > rep_padata = self.der_decode(edata, > asn1Spec=krb5_asn1.METHOD_DATA()) >- self.assertGreater(len(rep_padata), 0) >+ self.assertGreater(len(rep_padata), 0) > >- if sent_fast: >- self.assertEqual(1, len(rep_padata)) >- rep_pa_dict = self.get_pa_dict(rep_padata) >- self.assertIn(PADATA_FX_FAST, rep_pa_dict) >+ if sent_fast: >+ self.assertEqual(1, len(rep_padata)) >+ rep_pa_dict = self.get_pa_dict(rep_padata) >+ self.assertIn(PADATA_FX_FAST, rep_pa_dict) > >- armor_key = kdc_exchange_dict['armor_key'] >- self.assertIsNotNone(armor_key) >- fast_response = self.check_fx_fast_data( >- kdc_exchange_dict, >- rep_pa_dict[PADATA_FX_FAST], >- armor_key, >- expect_strengthen_key=False) >+ armor_key = kdc_exchange_dict['armor_key'] >+ self.assertIsNotNone(armor_key) >+ fast_response = self.check_fx_fast_data( >+ kdc_exchange_dict, >+ rep_pa_dict[PADATA_FX_FAST], >+ armor_key, >+ expect_strengthen_key=False) > >- rep_padata = fast_response['padata'] >+ rep_padata = fast_response['padata'] > >- etype_info2 = self.check_rep_padata(kdc_exchange_dict, >- callback_dict, >- rep_padata, >- error_code) >+ etype_info2 = self.check_rep_padata(kdc_exchange_dict, >+ callback_dict, >+ rep_padata, >+ error_code) > >- kdc_exchange_dict['preauth_etype_info2'] = etype_info2 >+ kdc_exchange_dict['preauth_etype_info2'] = etype_info2 > > return rep > >@@ -2576,13 +2593,10 @@ class RawKerberosTest(TestCaseInTempDir): > expected_patypes += (PADATA_FX_COOKIE,) > > if rep_msg_type == KRB_TGS_REP: >- if not sent_fast and error_code != 0: >- expected_patypes += (PADATA_PW_SALT,) >- else: >- sent_pac_options = self.get_sent_pac_options(kdc_exchange_dict) >- if ('1' in sent_pac_options >- and error_code not in (0, KDC_ERR_GENERIC)): >- expected_patypes += (PADATA_PAC_OPTIONS,) >+ sent_pac_options = self.get_sent_pac_options(kdc_exchange_dict) >+ if ('1' in sent_pac_options >+ and error_code not in (0, KDC_ERR_GENERIC)): >+ expected_patypes += (PADATA_PAC_OPTIONS,) > elif error_code != KDC_ERR_GENERIC: > if expect_etype_info: > self.assertGreater(len(expect_etype_info2), 0) >@@ -2621,7 +2635,6 @@ class RawKerberosTest(TestCaseInTempDir): > fast_error = None > fx_fast = None > pac_options = None >- pw_salt = None > for pa in rep_padata: > patype = self.getElementValue(pa, 'padata-type') > pavalue = self.getElementValue(pa, 'padata-value') >@@ -2675,11 +2688,6 @@ class RawKerberosTest(TestCaseInTempDir): > pavalue, > asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) > continue >- if patype == PADATA_PW_SALT: >- self.assertIsNone(pw_salt) >- pw_salt = pavalue >- self.assertIsNotNone(pw_salt) >- continue > > if fast_cookie is not None: > kdc_exchange_dict['fast_cookie'] = fast_cookie >@@ -2695,19 +2703,6 @@ class RawKerberosTest(TestCaseInTempDir): > if pac_options is not None: > self.assertElementEqual(pac_options, 'options', sent_pac_options) > >- if pw_salt is not None: >- self.assertEqual(12, len(pw_salt)) >- >- status = int.from_bytes(pw_salt[:4], 'little') >- flags = int.from_bytes(pw_salt[8:], 'little') >- >- expected_status = kdc_exchange_dict['expected_status'] >- self.assertEqual(expected_status, status) >- >- self.assertEqual(3, flags) >- else: >- self.assertIsNone(kdc_exchange_dict.get('expected_status')) >- > if enc_challenge is not None: > if not sent_enc_challenge: > self.assertEqual(len(enc_challenge), 0) >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index ac2bac4d91e..76f2b75d94e 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -78,6 +78,12 @@ KDC_ERR_SKEW = 37 > KDC_ERR_GENERIC = 60 > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS = 93 > >+# Extended error types >+KERB_AP_ERR_TYPE_SKEW_RECOVERY = int( >+ krb5_asn1.KerbErrorDataTypeValues('kERB-AP-ERR-TYPE-SKEW-RECOVERY')) >+KERB_ERR_TYPE_EXTENDED = int( >+ krb5_asn1.KerbErrorDataTypeValues('kERB-ERR-TYPE-EXTENDED')) >+ > # Name types > NT_UNKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-UNKNOWN')) > NT_PRINCIPAL = int(krb5_asn1.NameTypeValues('kRB5-NT-PRINCIPAL')) >-- >2.25.1 > > >From ce2f18cc23fb370f940f8eb3db4ac775321de2c3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 13:01:30 +1300 >Subject: [PATCH 310/686] tests/krb5: Make expected_sname checking more > explicit > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >[abartlet@samba.org backported from commit 8f6d369d709614e2f5c0684882c62f0476bcafa2 > as Samba 4.14 as the test which crashes older MIT KDC versions is > omitted] >--- > python/samba/tests/krb5/fast_tests.py | 39 ++++++++++--------------- > python/samba/tests/krb5/raw_testcase.py | 6 +--- > 2 files changed, 17 insertions(+), 28 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 431b48f00d6..5180eb57563 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -99,11 +99,7 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_simple_no_sname(self): >- krbtgt_creds = self.get_krbtgt_creds() >- krbtgt_username = krbtgt_creds.get_username() >- krbtgt_realm = krbtgt_creds.get_realm() >- expected_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ expected_sname = self.get_krbtgt_sname() > > self._run_test_sequence([ > { >@@ -116,11 +112,7 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_simple_tgs_no_sname(self): >- krbtgt_creds = self.get_krbtgt_creds() >- krbtgt_username = krbtgt_creds.get_username() >- krbtgt_realm = krbtgt_creds.get_realm() >- expected_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ expected_sname = self.get_krbtgt_sname() > > self._run_test_sequence([ > { >@@ -134,11 +126,7 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_no_sname(self): >- krbtgt_creds = self.get_krbtgt_creds() >- krbtgt_username = krbtgt_creds.get_username() >- krbtgt_realm = krbtgt_creds.get_realm() >- expected_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ expected_sname = self.get_krbtgt_sname() > > self._run_test_sequence([ > { >@@ -153,11 +141,7 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_tgs_no_sname(self): >- krbtgt_creds = self.get_krbtgt_creds() >- krbtgt_username = krbtgt_creds.get_username() >- krbtgt_realm = krbtgt_creds.get_realm() >- expected_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ expected_sname = self.get_krbtgt_sname() > > self._run_test_sequence([ > { >@@ -830,6 +814,8 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_ad_fx_fast_armor(self): >+ expected_sname = self.get_krbtgt_sname() >+ > # If the authenticator or TGT authentication data contains the > # AD-fx-fast-armor authdata type, the KDC must reject the request > # (RFC6113 5.4.1.1). >@@ -849,7 +835,8 @@ class FAST_Tests(KDCBaseTest): > 'use_fast': True, > 'gen_authdata_fn': self.generate_fast_armor_auth_data, > 'gen_tgt_fn': self.get_user_tgt, >- 'fast_armor': None >+ 'fast_armor': None, >+ 'expected_sname': expected_sname > } > ]) > >@@ -877,6 +864,8 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_ad_fx_fast_armor_ticket(self): >+ expected_sname = self.get_krbtgt_sname() >+ > # If the authenticator or TGT authentication data contains the > # AD-fx-fast-armor authdata type, the KDC must reject the request > # (RFC6113 5.4.2). >@@ -896,7 +885,8 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': KDC_ERR_GENERIC, > 'use_fast': True, > 'gen_tgt_fn': self.gen_tgt_fast_armor_auth_data, >- 'fast_armor': None >+ 'fast_armor': None, >+ 'expected_sname': expected_sname > } > ]) > >@@ -956,6 +946,8 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_tgs_no_subkey(self): >+ expected_sname = self.get_krbtgt_sname() >+ > # Show that omitting the subkey in the TGS-REQ authenticator fails > # (RFC6113 5.4.2). > self._run_test_sequence([ >@@ -965,7 +957,8 @@ class FAST_Tests(KDCBaseTest): > 'use_fast': True, > 'gen_tgt_fn': self.get_user_tgt, > 'fast_armor': None, >- 'include_subkey': False >+ 'include_subkey': False, >+ 'expected_sname': expected_sname > } > ]) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index db7db28cac5..f6aeb00dc8f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2475,11 +2475,7 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertElementMissing(rep, 'cname') > self.assertElementEqualUTF8(rep, 'realm', expected_srealm) >- if sent_fast and error_code == KDC_ERR_GENERIC: >- self.assertElementEqualPrincipal(rep, 'sname', >- self.get_krbtgt_sname()) >- else: >- self.assertElementEqualPrincipal(rep, 'sname', expected_sname) >+ self.assertElementEqualPrincipal(rep, 'sname', expected_sname) > self.assertElementMissing(rep, 'e-text') > if (error_code == KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS > or (rep_msg_type == KRB_TGS_REP >-- >2.25.1 > > >From 9f60f4b687d3af301e9c67279b78d931b8289194 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 13:03:49 +1300 >Subject: [PATCH 311/686] tests/krb5: Fix assertElementFlags() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 788b3a29eea62f9f38ca8865c7cb7860bdc94bec) >--- > python/samba/tests/krb5/fast_tests.py | 4 ++-- > python/samba/tests/krb5/raw_testcase.py | 4 ++-- > 2 files changed, 4 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 5180eb57563..cf9b9d718bb 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1305,10 +1305,10 @@ class FAST_Tests(KDCBaseTest): > > expected_flags = kdc_dict.pop('expected_flags', None) > if expected_flags is not None: >- expected_flags = krb5_asn1.KDCOptions(expected_flags) >+ expected_flags = krb5_asn1.TicketFlags(expected_flags) > unexpected_flags = kdc_dict.pop('unexpected_flags', None) > if unexpected_flags is not None: >- unexpected_flags = krb5_asn1.KDCOptions(unexpected_flags) >+ unexpected_flags = krb5_asn1.TicketFlags(unexpected_flags) > > if rep_type == KRB_AS_REP: > kdc_exchange_dict = self.as_exchange_dict( >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index f6aeb00dc8f..a24faf1d060 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1053,14 +1053,14 @@ class RawKerberosTest(TestCaseInTempDir): > v = self.getElementValue(obj, elem) > self.assertIsNotNone(v) > if expected is not None: >- self.assertIsInstance(expected, krb5_asn1.KDCOptions) >+ self.assertIsInstance(expected, krb5_asn1.TicketFlags) > for i, flag in enumerate(expected): > if flag == 1: > self.assertEqual('1', v[i], > f"'{expected.namedValues[i]}' " > f"expected in {v}") > if unexpected is not None: >- self.assertIsInstance(unexpected, krb5_asn1.KDCOptions) >+ self.assertIsInstance(unexpected, krb5_asn1.TicketFlags) > for i, flag in enumerate(unexpected): > if flag == 1: > self.assertEqual('0', v[i], >-- >2.25.1 > > >From fdc8ce031ca4ea78089661bfd5e6e434f7debc9d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 14:02:37 +1300 >Subject: [PATCH 312/686] tests/krb5: Remove unneeded parameters from ticket > cache key > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7fba83c6c6309a525742c38e904d3e473db99ef1) >--- > python/samba/tests/krb5/kdc_base_test.py | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 25433ba1069..7ddaa53b541 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1278,8 +1278,7 @@ class KDCBaseTest(RawKerberosTest): > expected_flags=None, unexpected_flags=None, > fresh=False): > user_name = creds.get_username() >- cache_key = (user_name, to_rodc, kdc_options, >- expected_flags, unexpected_flags) >+ cache_key = (user_name, to_rodc, kdc_options) > > if not fresh: > tgt = self.tkt_cache.get(cache_key) >-- >2.25.1 > > >From de347be0788b59dbdcae4f9433e04e52020bd3d1 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 15:48:58 +1300 >Subject: [PATCH 313/686] tests/krb5: Fix checking for presence of error data > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ab92dc16d20b0996b8c46714652c15019c795095) >--- > python/samba/tests/krb5/fast_tests.py | 39 +++++++++++++++++------- > python/samba/tests/krb5/kdc_base_test.py | 4 ++- > python/samba/tests/krb5/kdc_tgs_tests.py | 3 +- > python/samba/tests/krb5/raw_testcase.py | 27 ++++++++-------- > 4 files changed, 48 insertions(+), 25 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index cf9b9d718bb..28fe0686335 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -107,7 +107,8 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': (KDC_ERR_GENERIC, KDC_ERR_S_PRINCIPAL_UNKNOWN), > 'use_fast': False, > 'sname': None, >- 'expected_sname': expected_sname >+ 'expected_sname': expected_sname, >+ 'expect_edata': False > } > ]) > >@@ -121,7 +122,8 @@ class FAST_Tests(KDCBaseTest): > 'use_fast': False, > 'gen_tgt_fn': self.get_user_tgt, > 'sname': None, >- 'expected_sname': expected_sname >+ 'expected_sname': expected_sname, >+ 'expect_edata': False > } > ]) > >@@ -172,6 +174,7 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': KDC_ERR_NOT_US, > 'use_fast': False, > 'gen_tgt_fn': self.get_user_service_ticket, >+ 'expect_edata': False > } > ]) > >@@ -182,6 +185,7 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': KDC_ERR_NOT_US, > 'use_fast': False, > 'gen_tgt_fn': self.get_mach_service_ticket, >+ 'expect_edata': False > } > ]) > >@@ -294,7 +298,8 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': KDC_ERR_ETYPE_NOSUPP, > 'use_fast': False, > 'gen_tgt_fn': self.get_mach_tgt, >- 'etypes': () >+ 'etypes': (), >+ 'expect_edata': False > } > ]) > >@@ -342,7 +347,8 @@ class FAST_Tests(KDCBaseTest): > 'use_fast': True, > 'gen_fast_fn': self.generate_empty_fast, > 'fast_armor': None, >- 'gen_armor_tgt_fn': self.get_mach_tgt >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'expect_edata': False > } > ]) > >@@ -365,7 +371,8 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': KDC_ERR_GENERIC, > 'use_fast': True, > 'fast_armor': None, # no armor, >- 'gen_armor_tgt_fn': self.get_mach_tgt >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'expect_edata': False > } > ]) > >@@ -809,7 +816,8 @@ class FAST_Tests(KDCBaseTest): > # should be KRB_APP_ERR_MODIFIED > 'use_fast': False, > 'gen_authdata_fn': self.generate_fast_used_auth_data, >- 'gen_tgt_fn': self.get_user_tgt >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'expect_edata': False > } > ]) > >@@ -836,7 +844,8 @@ class FAST_Tests(KDCBaseTest): > 'gen_authdata_fn': self.generate_fast_armor_auth_data, > 'gen_tgt_fn': self.get_user_tgt, > 'fast_armor': None, >- 'expected_sname': expected_sname >+ 'expected_sname': expected_sname, >+ 'expect_edata': False > } > ]) > >@@ -886,7 +895,8 @@ class FAST_Tests(KDCBaseTest): > 'use_fast': True, > 'gen_tgt_fn': self.gen_tgt_fast_armor_auth_data, > 'fast_armor': None, >- 'expected_sname': expected_sname >+ 'expected_sname': expected_sname, >+ 'expect_edata': False > } > ]) > >@@ -958,7 +968,8 @@ class FAST_Tests(KDCBaseTest): > 'gen_tgt_fn': self.get_user_tgt, > 'fast_armor': None, > 'include_subkey': False, >- 'expected_sname': expected_sname >+ 'expected_sname': expected_sname, >+ 'expect_edata': False > } > ]) > >@@ -1209,6 +1220,10 @@ class FAST_Tests(KDCBaseTest): > else: > tgt_cname = client_cname > >+ expect_edata = kdc_dict.pop('expect_edata', None) >+ if expect_edata is not None: >+ self.assertTrue(expected_error_mode) >+ > expected_cname = kdc_dict.pop('expected_cname', tgt_cname) > expected_anon = kdc_dict.pop('expected_anon', > False) >@@ -1343,7 +1358,8 @@ class FAST_Tests(KDCBaseTest): > inner_req=inner_req, > outer_req=outer_req, > pac_request=True, >- pac_options=pac_options) >+ pac_options=pac_options, >+ expect_edata=expect_edata) > else: # KRB_TGS_REP > kdc_exchange_dict = self.tgs_exchange_dict( > expected_crealm=expected_crealm, >@@ -1376,7 +1392,8 @@ class FAST_Tests(KDCBaseTest): > inner_req=inner_req, > outer_req=outer_req, > pac_request=None, >- pac_options=pac_options) >+ pac_options=pac_options, >+ expect_edata=expect_edata) > > repeat = kdc_dict.pop('repeat', 1) > for _ in range(repeat): >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 7ddaa53b541..d25fc0b42b2 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1162,7 +1162,8 @@ class KDCBaseTest(RawKerberosTest): > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, > expected_error_mode=0, padata=None, kdc_options=0, >- to_rodc=False, service_creds=None, expect_pac=True): >+ to_rodc=False, service_creds=None, expect_pac=True, >+ expect_edata=None): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1209,6 +1210,7 @@ class KDCBaseTest(RawKerberosTest): > tgt=tgt, > authenticator_subkey=subkey, > kdc_options=str(kdc_options), >+ expect_edata=expect_edata, > expect_pac=expect_pac, > to_rodc=to_rodc) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 0904233b01f..2b55ba8a376 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -85,7 +85,8 @@ class KdcTgsTests(KDCBaseTest): > names=["host", samdb.host_dns_name()]) > > (rep, enc_part) = self.tgs_req(cname, sname, realm, ticket, key, etype, >- expected_error_mode=KDC_ERR_BADMATCH) >+ expected_error_mode=KDC_ERR_BADMATCH, >+ expect_edata=False) > > self.assertIsNone( > enc_part, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index a24faf1d060..1a3aedbd436 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1959,6 +1959,7 @@ class RawKerberosTest(TestCaseInTempDir): > outer_req=None, > pac_request=None, > pac_options=None, >+ expect_edata=None, > expect_pac=True, > to_rodc=False): > if expected_error_mode == 0: >@@ -2005,6 +2006,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'outer_req': outer_req, > 'pac_request': pac_request, > 'pac_options': pac_options, >+ 'expect_edata': expect_edata, > 'expect_pac': expect_pac, > 'to_rodc': to_rodc > } >@@ -2046,6 +2048,7 @@ class RawKerberosTest(TestCaseInTempDir): > outer_req=None, > pac_request=None, > pac_options=None, >+ expect_edata=None, > expect_pac=True, > to_rodc=False): > if expected_error_mode == 0: >@@ -2091,6 +2094,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'outer_req': outer_req, > 'pac_request': pac_request, > 'pac_options': pac_options, >+ 'expect_edata': expect_edata, > 'expect_pac': expect_pac, > 'to_rodc': to_rodc > } >@@ -2477,20 +2481,20 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementEqualUTF8(rep, 'realm', expected_srealm) > self.assertElementEqualPrincipal(rep, 'sname', expected_sname) > self.assertElementMissing(rep, 'e-text') >- if (error_code == KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS >- or (rep_msg_type == KRB_TGS_REP >- and not sent_fast) >- or (sent_fast and fast_armor_type is not None >- and fast_armor_type != FX_FAST_ARMOR_AP_REQUEST) >- or inner): >+ expected_status = kdc_exchange_dict['expected_status'] >+ expect_edata = kdc_exchange_dict['expect_edata'] >+ if expect_edata is None: >+ expect_edata = (error_code != KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS >+ and (not sent_fast or fast_armor_type is None >+ or fast_armor_type == FX_FAST_ARMOR_AP_REQUEST) >+ and not inner) >+ if not expect_edata: >+ self.assertIsNone(expected_status) > self.assertElementMissing(rep, 'e-data') > return rep > edata = self.getElementValue(rep, 'e-data') > if self.strict_checking: >- if error_code != KDC_ERR_GENERIC: >- # Predicting whether an ERR_GENERIC error contains e-data is >- # more complicated. >- self.assertIsNotNone(edata) >+ self.assertIsNotNone(edata) > if edata is not None: > if rep_msg_type == KRB_TGS_REP and not sent_fast: > error_data = self.der_decode( >@@ -2506,12 +2510,11 @@ class RawKerberosTest(TestCaseInTempDir): > status = int.from_bytes(extended_error[:4], 'little') > flags = int.from_bytes(extended_error[8:], 'little') > >- expected_status = kdc_exchange_dict['expected_status'] > self.assertEqual(expected_status, status) > > self.assertEqual(3, flags) > else: >- self.assertIsNone(kdc_exchange_dict['expected_status']) >+ self.assertIsNone(expected_status) > > rep_padata = self.der_decode(edata, > asn1Spec=krb5_asn1.METHOD_DATA()) >-- >2.25.1 > > >From d1617a525d3cc776a468348814f9f7c2e674d91e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:10:07 +1300 >Subject: [PATCH 314/686] tests/krb5: Add expect_claims parameter to > kdc_exchange_dict > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7cfc225b549108739bd86e222f2f35eb96af4ea3) >--- > python/samba/tests/krb5/raw_testcase.py | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 1a3aedbd436..0415f1ff6e6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1961,6 +1961,7 @@ class RawKerberosTest(TestCaseInTempDir): > pac_options=None, > expect_edata=None, > expect_pac=True, >+ expect_claims=True, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -2008,6 +2009,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'pac_options': pac_options, > 'expect_edata': expect_edata, > 'expect_pac': expect_pac, >+ 'expect_claims': expect_claims, > 'to_rodc': to_rodc > } > if callback_dict is None: >@@ -2050,6 +2052,7 @@ class RawKerberosTest(TestCaseInTempDir): > pac_options=None, > expect_edata=None, > expect_pac=True, >+ expect_claims=True, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -2096,6 +2099,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'pac_options': pac_options, > 'expect_edata': expect_edata, > 'expect_pac': expect_pac, >+ 'expect_claims': expect_claims, > 'to_rodc': to_rodc > } > if callback_dict is None: >-- >2.25.1 > > >From 0f97d65c0b3283900a393e3336f896e6a4b5537b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:15:26 +1300 >Subject: [PATCH 315/686] tests/krb5: Check buffer types in PAC with > STRICT_CHECKING=1 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit aa2e583fdea4fd93e4e71c54630e32a1035d1e2a) >--- > librpc/idl/krb5pac.idl | 3 ++ > python/samba/tests/krb5/raw_testcase.py | 52 +++++++++++++++++++++++++ > 2 files changed, 55 insertions(+) > >diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl >index 711b7f94b6c..141894ec5f1 100644 >--- a/librpc/idl/krb5pac.idl >+++ b/librpc/idl/krb5pac.idl >@@ -113,6 +113,9 @@ interface krb5pac > PAC_TYPE_LOGON_NAME = 10, > PAC_TYPE_CONSTRAINED_DELEGATION = 11, > PAC_TYPE_UPN_DNS_INFO = 12, >+ PAC_TYPE_CLIENT_CLAIMS_INFO = 13, >+ PAC_TYPE_DEVICE_INFO = 14, >+ PAC_TYPE_DEVICE_CLAIMS_INFO = 15, > PAC_TYPE_TICKET_CHECKSUM = 16 > } PAC_TYPE; > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 0415f1ff6e6..320de0a4dbe 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2340,6 +2340,13 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(ticket_private, 'authorization-data', > expect_empty=not expect_pac) > >+ if expect_pac: >+ authorization_data = self.getElementValue(ticket_private, >+ 'authorization-data') >+ pac_data = self.get_pac(authorization_data) >+ >+ self.check_pac_buffers(pac_data, kdc_exchange_dict) >+ > encpart_session_key = None > if encpart_private is not None: > self.assertElementPresent(encpart_private, 'key') >@@ -2446,6 +2453,47 @@ class RawKerberosTest(TestCaseInTempDir): > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > >+ def check_pac_buffers(self, pac_data, kdc_exchange_dict): >+ pac = ndr_unpack(krb5pac.PAC_DATA, pac_data) >+ >+ rep_msg_type = kdc_exchange_dict['rep_msg_type'] >+ armor_tgt = kdc_exchange_dict['armor_tgt'] >+ >+ expected_sname = kdc_exchange_dict['expected_sname'] >+ expect_claims = kdc_exchange_dict['expect_claims'] >+ >+ expected_types = [krb5pac.PAC_TYPE_LOGON_INFO, >+ krb5pac.PAC_TYPE_SRV_CHECKSUM, >+ krb5pac.PAC_TYPE_KDC_CHECKSUM, >+ krb5pac.PAC_TYPE_LOGON_NAME, >+ krb5pac.PAC_TYPE_UPN_DNS_INFO] >+ >+ kdc_options = kdc_exchange_dict['kdc_options'] >+ pos = len(tuple(krb5_asn1.KDCOptions('cname-in-addl-tkt'))) - 1 >+ constrained_delegation = (pos < len(kdc_options) >+ and kdc_options[pos] == '1') >+ if constrained_delegation: >+ expected_types.append(krb5pac.PAC_TYPE_CONSTRAINED_DELEGATION) >+ >+ if self.kdc_fast_support: >+ if expect_claims: >+ expected_types.append(krb5pac.PAC_TYPE_CLIENT_CLAIMS_INFO) >+ >+ if (rep_msg_type == KRB_TGS_REP >+ and armor_tgt is not None): >+ expected_types.append(krb5pac.PAC_TYPE_DEVICE_INFO) >+ expected_types.append(krb5pac.PAC_TYPE_DEVICE_CLAIMS_INFO) >+ >+ if not self.is_tgs(expected_sname): >+ expected_types.append(krb5pac.PAC_TYPE_TICKET_CHECKSUM) >+ >+ if self.strict_checking: >+ buffer_types = [pac_buffer.type >+ for pac_buffer in pac.buffers] >+ self.assertCountEqual(expected_types, buffer_types, >+ f'expected: {expected_types} ' >+ f'got: {buffer_types}') >+ > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >@@ -3397,6 +3445,10 @@ class RawKerberosTest(TestCaseInTempDir): > > return new_auth_data, old_pac > >+ def get_pac(self, auth_data, expect_pac=True): >+ _, pac = self.replace_pac(auth_data, None, expect_pac) >+ return pac >+ > def get_krbtgt_checksum_key(self): > krbtgt_creds = self.get_krbtgt_creds() > krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >-- >2.25.1 > > >From 4e012d8aaef0a7aff2211e3592f729492bfd8f58 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:26:54 +1300 >Subject: [PATCH 316/686] tests/krb5: Check constrained delegation PAC buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 0e232fa1c9e5760ae6b9a99b5e7aa5513b84aa8b) >--- > python/samba/tests/krb5/raw_testcase.py | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 320de0a4dbe..8144bd37b2f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2053,6 +2053,8 @@ class RawKerberosTest(TestCaseInTempDir): > expect_edata=None, > expect_pac=True, > expect_claims=True, >+ expected_proxy_target=None, >+ expected_transited_services=None, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -2100,6 +2102,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'expect_edata': expect_edata, > 'expect_pac': expect_pac, > 'expect_claims': expect_claims, >+ 'expected_proxy_target': expected_proxy_target, >+ 'expected_transited_services': expected_transited_services, > 'to_rodc': to_rodc > } > if callback_dict is None: >@@ -2494,6 +2498,23 @@ class RawKerberosTest(TestCaseInTempDir): > f'expected: {expected_types} ' > f'got: {buffer_types}') > >+ for pac_buffer in pac.buffers: >+ if pac_buffer.type == krb5pac.PAC_TYPE_CONSTRAINED_DELEGATION: >+ expected_proxy_target = kdc_exchange_dict[ >+ 'expected_proxy_target'] >+ expected_transited_services = kdc_exchange_dict[ >+ 'expected_transited_services'] >+ >+ delegation_info = pac_buffer.info.info >+ >+ self.assertEqual(expected_proxy_target, >+ str(delegation_info.proxy_target)) >+ >+ transited_services = list(map( >+ str, delegation_info.transited_services)) >+ self.assertEqual(expected_transited_services, >+ transited_services) >+ > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >-- >2.25.1 > > >From ddd9135cb19843020288fdf92326221ea627042d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:41:23 +1300 >Subject: [PATCH 317/686] tests/krb5: Save account SPN > >This is useful for testing delegation. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit bb58b4b58c66a6ada79e886dd0c44401e1c5878c) >--- > python/samba/tests/krb5/kdc_base_test.py | 1 + > python/samba/tests/krb5/raw_testcase.py | 7 +++++++ > 2 files changed, 8 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index d25fc0b42b2..70ab14786da 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -285,6 +285,7 @@ class KDCBaseTest(RawKerberosTest): > else: > creds.set_workstation('') > creds.set_dn(ldb.Dn(samdb, dn)) >+ creds.set_spn(spn) > # > # Save the account name so it can be deleted in tearDownClass > self.accounts.add(dn) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 8144bd37b2f..c34ffb848e1 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -365,6 +365,7 @@ class KerberosCredentials(Credentials): > self.forced_salt = None > > self.dn = None >+ self.spn = None > > def set_as_supported_enctypes(self, value): > self.as_supported_enctypes = int(value) >@@ -467,6 +468,12 @@ class KerberosCredentials(Credentials): > def get_dn(self): > return self.dn > >+ def set_spn(self, spn): >+ self.spn = spn >+ >+ def get_spn(self): >+ return self.spn >+ > > class KerberosTicketCreds: > def __init__(self, ticket, session_key, >-- >2.25.1 > > >From 86436c576684033d9af984b149774468dc24e4eb Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:48:50 +1300 >Subject: [PATCH 318/686] tests/krb5: Allow specifying options and expected > flags when obtaining a ticket > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 34020766bb7094d1ab5d4fc4c0ee89ccb81f39f1) >--- > python/samba/tests/krb5/kdc_base_test.py | 31 +++++++++++++++++------- > 1 file changed, 22 insertions(+), 9 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 70ab14786da..34a23b3b876 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1164,7 +1164,7 @@ class KDCBaseTest(RawKerberosTest): > def tgs_req(self, cname, sname, realm, ticket, key, etypes, > expected_error_mode=0, padata=None, kdc_options=0, > to_rodc=False, service_creds=None, expect_pac=True, >- expect_edata=None): >+ expect_edata=None, expected_flags=None, unexpected_flags=None): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1203,6 +1203,8 @@ class KDCBaseTest(RawKerberosTest): > expected_srealm=realm, > expected_sname=sname, > expected_error_mode=expected_error_mode, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, > check_kdc_private_fn=self.generic_check_kdc_private, >@@ -1230,10 +1232,12 @@ class KDCBaseTest(RawKerberosTest): > return rep, enc_part > > def get_service_ticket(self, tgt, target_creds, service='host', >- to_rodc=False, fresh=False): >+ to_rodc=False, kdc_options=None, >+ expected_flags=None, unexpected_flags=None, >+ fresh=False): > user_name = tgt.cname['name-string'][0] > target_name = target_creds.get_username() >- cache_key = (user_name, target_name, service, to_rodc) >+ cache_key = (user_name, target_name, service, to_rodc, kdc_options) > > if not fresh: > ticket = self.tkt_cache.get(cache_key) >@@ -1243,6 +1247,10 @@ class KDCBaseTest(RawKerberosTest): > > etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) > >+ if kdc_options is None: >+ kdc_options = '0' >+ kdc_options = krb5_asn1.KDCOptions(kdc_options) >+ > key = tgt.session_key > ticket = tgt.ticket > >@@ -1255,7 +1263,10 @@ class KDCBaseTest(RawKerberosTest): > > rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype, > to_rodc=to_rodc, >- service_creds=target_creds) >+ service_creds=target_creds, >+ kdc_options=kdc_options, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags) > > service_ticket = rep['ticket'] > >@@ -1309,11 +1320,11 @@ class KDCBaseTest(RawKerberosTest): > self.TicketDecryptionKey_from_creds(krbtgt_creds)) > > if kdc_options is None: >- kdc_options = krb5_asn1.KDCOptions('forwardable,' >- 'renewable,' >- 'canonicalize,' >- 'renewable-ok') >- kdc_options = str(kdc_options) >+ kdc_options = ('forwardable,' >+ 'renewable,' >+ 'canonicalize,' >+ 'renewable-ok') >+ kdc_options = krb5_asn1.KDCOptions(kdc_options) > > pac_options = '1' # supports claims > >@@ -1370,6 +1381,8 @@ class KDCBaseTest(RawKerberosTest): > expected_srealm=expected_realm, > expected_sname=expected_sname, > expected_salt=salt, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > expected_supported_etypes=expected_etypes, > etypes=etype, > padata=padata, >-- >2.25.1 > > >From 04d87cd0ee9e2b7eaa919b09ed47c861099a7c0d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:52:01 +1300 >Subject: [PATCH 319/686] tests/krb5: Supply supported account enctypes in > tgs_req() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 248249dc0acac89d1495c3572cbd2cbe8bdca362) >--- > python/samba/tests/krb5/kdc_base_test.py | 3 +++ > 1 file changed, 3 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 34a23b3b876..93951586cc7 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1181,8 +1181,10 @@ class KDCBaseTest(RawKerberosTest): > if service_creds is not None: > decryption_key = self.TicketDecryptionKey_from_creds( > service_creds) >+ expected_supported_etypes = service_creds.tgs_supported_enctypes > else: > decryption_key = None >+ expected_supported_etypes = None > > if not expected_error_mode: > check_error_fn = None >@@ -1205,6 +1207,7 @@ class KDCBaseTest(RawKerberosTest): > expected_error_mode=expected_error_mode, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, >+ expected_supported_etypes=expected_supported_etypes, > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, > check_kdc_private_fn=self.generic_check_kdc_private, >-- >2.25.1 > > >From 1cc4986df0956c449c70bd74797e0789d0ead9e9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 30 Sep 2021 16:53:35 +1300 >Subject: [PATCH 320/686] tests/krb5: Add parameter to enforce presence of > ticket checksums > >This allows existing tests to pass before this functionality is >implemented. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ef24fe982d750a42be81808379b0254d8488c559) >--- > python/samba/tests/krb5/raw_testcase.py | 20 +++++++++++++++++--- > 1 file changed, 17 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index c34ffb848e1..72a39b23b0e 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1942,6 +1942,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_flags=None, > unexpected_flags=None, > ticket_decryption_key=None, >+ expect_ticket_checksum=None, > generate_fast_fn=None, > generate_fast_armor_fn=None, > generate_fast_padata_fn=None, >@@ -1990,6 +1991,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_flags': expected_flags, > 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, >+ 'expect_ticket_checksum': expect_ticket_checksum, > 'generate_fast_fn': generate_fast_fn, > 'generate_fast_armor_fn': generate_fast_armor_fn, > 'generate_fast_padata_fn': generate_fast_padata_fn, >@@ -2034,6 +2036,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_flags=None, > unexpected_flags=None, > ticket_decryption_key=None, >+ expect_ticket_checksum=None, > generate_fast_fn=None, > generate_fast_armor_fn=None, > generate_fast_padata_fn=None, >@@ -2083,6 +2086,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_flags': expected_flags, > 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, >+ 'expect_ticket_checksum': expect_ticket_checksum, > 'generate_fast_fn': generate_fast_fn, > 'generate_fast_armor_fn': generate_fast_armor_fn, > 'generate_fast_padata_fn': generate_fast_padata_fn, >@@ -2459,8 +2463,15 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_private=ticket_private, > encpart_private=encpart_private) > >+ # TODO: This parameter should be removed when all service tickets are >+ # issued with ticket checksums. >+ expect_ticket_checksum = kdc_exchange_dict['expect_ticket_checksum'] >+ if expect_ticket_checksum: >+ self.assertIsNotNone(ticket_decryption_key) >+ > if ticket_decryption_key is not None: >- self.verify_ticket(ticket_creds, krbtgt_key, expect_pac=expect_pac) >+ self.verify_ticket(ticket_creds, krbtgt_key, expect_pac=expect_pac, >+ expect_ticket_checksum=expect_ticket_checksum) > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > >@@ -3083,7 +3094,8 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_blob) > self.assertEqual(expected_checksum, checksum) > >- def verify_ticket(self, ticket, krbtgt_key, expect_pac=True): >+ def verify_ticket(self, ticket, krbtgt_key, expect_pac=True, >+ expect_ticket_checksum=True): > # Check if the ticket is a TGT. > sname = ticket.ticket['sname'] > is_tgt = self.is_tgs(sname) >@@ -3182,8 +3194,10 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_checksum, ticket_ctype = checksums.get( > krb5pac.PAC_TYPE_TICKET_CHECKSUM, > (None, None)) >- if self.strict_checking: >+ if expect_ticket_checksum: > self.assertIsNotNone(ticket_checksum) >+ elif expect_ticket_checksum is False: >+ self.assertIsNone(ticket_checksum) > if ticket_checksum is not None: > enc_part['authorization-data'] = auth_data > enc_part = self.der_encode(enc_part, >-- >2.25.1 > > >From 07deb6e959d8aec0dace72ee5363e28c40051976 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 14 Oct 2021 16:43:05 +1300 >Subject: [PATCH 321/686] tests/krb5: Add compatability tests for ticket > checksums > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >[abartlet@samba.org: Backported from ec4b264bdf9ab64a728212580b344fbf35c3c673 > to Samba 4.14 due to conflicts in > knownfail as the test which crashes older MIT KDC versions is > omitted] >--- > .../samba/tests/krb5/compatability_tests.py | 44 ++++++++++++++++++- > selftest/knownfail_heimdal_kdc | 6 ++- > source4/selftest/tests.py | 7 ++- > 3 files changed, 53 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py >index cd67549212a..0da72796894 100755 >--- a/python/samba/tests/krb5/compatability_tests.py >+++ b/python/samba/tests/krb5/compatability_tests.py >@@ -23,7 +23,7 @@ import os > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > >-from samba.tests.krb5.raw_testcase import RawKerberosTest >+from samba.tests.krb5.kdc_base_test import KDCBaseTest > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > AES128_CTS_HMAC_SHA1_96, >@@ -50,7 +50,7 @@ MIT_ENC_AS_REP_PART_TYPE_TAG = 0x7A > ENC_PA_REP_FLAG = 0x00010000 > > >-class SimpleKerberosTests(RawKerberosTest): >+class SimpleKerberosTests(KDCBaseTest): > > def setUp(self): > super(SimpleKerberosTests, self).setUp() >@@ -120,6 +120,46 @@ class SimpleKerberosTests(RawKerberosTest): > self.fail( > "(Heimdal) Salt populated for ARCFOUR_HMAC_MD5 encryption") > >+ def test_heimdal_ticket_signature(self): >+ # Ensure that a DC correctly issues tickets signed with its krbtgt key. >+ user_creds = self.get_client_creds() >+ target_creds = self.get_service_creds() >+ >+ krbtgt_creds = self.get_krbtgt_creds() >+ key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ # Get a TGT from the DC. >+ tgt = self.get_tgt(user_creds) >+ >+ # Ensure the PAC contains the expected checksums. >+ self.verify_ticket(tgt, key) >+ >+ # Get a service ticket from the DC. >+ service_ticket = self.get_service_ticket(tgt, target_creds) >+ >+ # Ensure the PAC contains the expected checksums. >+ self.verify_ticket(service_ticket, key, expect_ticket_checksum=True) >+ >+ def test_mit_ticket_signature(self): >+ # Ensure that a DC does not issue tickets signed with its krbtgt key. >+ user_creds = self.get_client_creds() >+ target_creds = self.get_service_creds() >+ >+ krbtgt_creds = self.get_krbtgt_creds() >+ key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ # Get a TGT from the DC. >+ tgt = self.get_tgt(user_creds) >+ >+ # Ensure the PAC contains the expected checksums. >+ self.verify_ticket(tgt, key) >+ >+ # Get a service ticket from the DC. >+ service_ticket = self.get_service_ticket(tgt, target_creds) >+ >+ # Ensure the PAC does not contain the expected checksums. >+ self.verify_ticket(service_ticket, key, expect_ticket_checksum=False) >+ > def as_pre_auth_req(self, creds, etypes): > user = creds.get_username() > realm = creds.get_realm() >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 80b8224f015..6eb667f8969 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -1,7 +1,7 @@ > # > # We expect all the MIT specific compatability tests to fail on heimdal > # kerberos >-^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_mit_ >+^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_mit_(?!ticket_signature) > # > # Heimdal currently fails the following MS-KILE client principal lookup > # tests >@@ -121,3 +121,7 @@ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_sname.ad_dc >+# >+# Heimdal currently does not generate ticket signatures >+# >+^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_heimdal_ticket_signature >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 979dd5124b2..0fd77868bd6 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1265,7 +1265,12 @@ planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests", > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD' > }) >-planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests") >+planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0', >+ }) > planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests") > planpythontestsuite( > "ad_dc", >-- >2.25.1 > > >From 3c1268de2fbab7981e9c3b1081e3b12074abc917 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 14:37:03 +1300 >Subject: [PATCH 322/686] tests/krb5: Use correct principal name type > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 687c8f94c68af9f1e44771dfd7219eeb41382bba) >--- > python/samba/tests/krb5/fast_tests.py | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 28fe0686335..1cdfd5e20c4 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -43,6 +43,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_AS_REP, > KRB_TGS_REP, > NT_PRINCIPAL, >+ NT_SRV_HST, > NT_SRV_INST, > PADATA_FX_COOKIE, > PADATA_FX_FAST, >@@ -1136,7 +1137,7 @@ class FAST_Tests(KDCBaseTest): > target_realm = target_creds.get_realm() > target_service = 'host' > target_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=[target_service, target_username]) >+ name_type=NT_SRV_HST, names=[target_service, target_username]) > target_decryption_key = self.TicketDecryptionKey_from_creds( > target_creds) > target_etypes = target_creds.tgs_supported_enctypes >-- >2.25.1 > > >From 7f606d594c936af6e29c182f1d693f307495d48e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 14:39:26 +1300 >Subject: [PATCH 323/686] tests/krb5: Clarify checksum type assertion message > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ee2b7e2c77f021984ec583fa0c4c756979197b0f) >--- > python/samba/tests/krb5/raw_testcase.py | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 72a39b23b0e..e52eb5ae5b9 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -248,7 +248,8 @@ class Krb5EncryptionKey: > > def verify_checksum(self, usage, plaintext, ctype, cksum): > if self.ctype != ctype: >- raise AssertionError(f'{self.ctype} != {ctype}') >+ raise AssertionError(f'key checksum type ({self.ctype}) != ' >+ f'checksum type ({ctype})') > > kcrypto.verify_checksum(ctype, > self.key, >-- >2.25.1 > > >From 16af8b758a64dc4d6042a72986034af0071158eb Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 16:15:43 +1300 >Subject: [PATCH 324/686] tests/krb5: Fix padata checking at functional level > 2003 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 72265227e9c2037b63cdfb01a456a86ac8932f59) >--- > python/samba/tests/krb5/raw_testcase.py | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e52eb5ae5b9..bb9d414da5b 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2661,11 +2661,10 @@ class RawKerberosTest(TestCaseInTempDir): > if kcrypto.Enctype.RC4 in proposed_etypes: > expect_etype_info = True > for etype in proposed_etypes: >- if etype in (kcrypto.Enctype.AES256, kcrypto.Enctype.AES128): >- expect_etype_info = False > if etype not in client_as_etypes: > continue > if etype in (kcrypto.Enctype.AES256, kcrypto.Enctype.AES128): >+ expect_etype_info = False > if etype > expected_aes_type: > expected_aes_type = etype > if etype in (kcrypto.Enctype.RC4,) and error_code != 0: >@@ -2865,7 +2864,8 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertIsNone(etype_info2) > if expect_etype_info: >- self.assertIsNotNone(etype_info) >+ if self.strict_checking: >+ self.assertIsNotNone(etype_info) > else: > if self.strict_checking: > self.assertIsNone(etype_info) >-- >2.25.1 > > >From 89ad2924edd22b2f105add1869f5a6bbbc4b06e9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 12 Oct 2021 11:34:59 +1300 >Subject: [PATCH 325/686] tests/krb5: Add environment variable to specify KDC > FAST support > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >[abartlet@samba.org backportd from commit 238f52bad811688624e9fd4b1595266e2149094a > because tests.py changed in more recent releases with new tests nearby] >--- > python/samba/tests/krb5/raw_testcase.py | 6 +++- > source4/selftest/tests.py | 37 +++++++++++++++++-------- > 2 files changed, 31 insertions(+), 12 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index bb9d414da5b..fbddb7f83b1 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -568,7 +568,11 @@ class RawKerberosTest(TestCaseInTempDir): > # obtained. > cls.creds_dict = {} > >- cls.kdc_fast_support = False >+ kdc_fast_support = samba.tests.env_get_var_value('FAST_SUPPORT', >+ allow_missing=True) >+ if kdc_fast_support is None: >+ kdc_fast_support = '0' >+ cls.kdc_fast_support = bool(int(kdc_fast_support)) > > def setUp(self): > super().setUp() >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 0fd77868bd6..2179c377d1f 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -713,39 +713,47 @@ planoldpythontestsuite("nt4_dc", "samba.tests.netbios", extra_args=['-U"$USERNAM > planoldpythontestsuite("ad_dc:local", "samba.tests.gpo", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) > planoldpythontestsuite("ad_dc:local", "samba.tests.dckeytab", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) > >+have_fast_support = int('SAMBA_USES_MITKDC' in config_hash) > planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", >- environ={'SERVICE_USERNAME':'$SERVER'}) >+ environ={'SERVICE_USERNAME':'$SERVER', >+ 'FAST_SUPPORT': have_fast_support}) > planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", > environ={'SERVICE_USERNAME':'srv_account', > 'SERVICE_PASSWORD':'$PASSWORD', >- 'FOR_USER':'$USERNAME'}) >+ 'FOR_USER':'$USERNAME', >+ 'FAST_SUPPORT': have_fast_support}) > >-planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests") >+planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests", >+ environ={'FAST_SUPPORT': have_fast_support}) > > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_rpc", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > > for env in ["ad_dc", smbv1_disabled_testenv]: >@@ -1243,6 +1251,7 @@ for env in ["fl2008r2dc", "fl2003dc"]: > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > > >@@ -1263,22 +1272,26 @@ for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: > planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'FAST_SUPPORT': have_fast_support > }) > planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support, > }) >-planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests") >+planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests", >+ environ={'FAST_SUPPORT': have_fast_support}) > planpythontestsuite( > "ad_dc", > "samba.tests.krb5.kdc_tgs_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > planpythontestsuite( > "ad_dc", >@@ -1287,6 +1300,7 @@ planpythontestsuite( > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > planpythontestsuite( > "ad_dc", >@@ -1294,7 +1308,8 @@ planpythontestsuite( > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > > for env in [ >-- >2.25.1 > > >From 3ff34dedc905247f1011f55e6382af21b77b3f9e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 14:45:45 +1300 >Subject: [PATCH 326/686] tests/krb5: Check padata types when STRICT_CHECKING=0 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >[abartlet@samba.org backported from commit bd22dcd9cc4dfda827f892224eb2da4a16564176 > to Samba 4.14 due to conflicts in > knownfail as the test which crashes older MIT KDC versions is > omitted] >--- > python/samba/tests/krb5/raw_testcase.py | 25 +++++++++++++++++++++---- > selftest/knownfail_mit_kdc | 9 +++++++++ > 2 files changed, 30 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index fbddb7f83b1..dbcff787f70 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1079,6 +1079,20 @@ class RawKerberosTest(TestCaseInTempDir): > f"'{unexpected.namedValues[i]}' " > f"unexpected in {v}") > >+ def assertSequenceElementsEqual(self, expected, got, *, >+ require_strict=None): >+ if self.strict_checking: >+ self.assertEqual(expected, got) >+ else: >+ fail_msg = f'expected: {expected} got: {got}' >+ >+ if require_strict is not None: >+ fail_msg += f' (ignoring: {require_strict})' >+ expected = (x for x in expected if x not in require_strict) >+ got = (x for x in got if x not in require_strict) >+ >+ self.assertCountEqual(expected, got, fail_msg) >+ > def get_KerberosTimeWithUsec(self, epoch=None, offset=None): > if epoch is None: > epoch = time.time() >@@ -2714,10 +2728,13 @@ class RawKerberosTest(TestCaseInTempDir): > expected_patypes += (PADATA_FX_FAST,) > expected_patypes += (PADATA_FX_COOKIE,) > >- if self.strict_checking: >- for i, patype in enumerate(expected_patypes): >- self.assertElementEqual(rep_padata[i], 'padata-type', patype) >- self.assertEqual(len(rep_padata), len(expected_patypes)) >+ got_patypes = tuple(pa['padata-type'] for pa in rep_padata) >+ self.assertSequenceElementsEqual(expected_patypes, got_patypes, >+ require_strict={PADATA_FX_COOKIE, >+ PADATA_FX_FAST, >+ PADATA_PAC_OPTIONS, >+ PADATA_PK_AS_REP_19, >+ PADATA_PK_AS_REQ}) > > etype_info2 = None > etype_info = None >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index f167c2bf856..4e0b20c5c80 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -290,6 +290,11 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_b > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c >+# >+# MIT currently fails some as_req_no_preauth tests. >+# >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth.*aes.*rc4.*fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth.*rc4.*aes.*fl2003dc > # Differences in our KDC compared to windows > # > ^samba4.krb5.kdc .*.as-req-pac-request # We should reply to a request for a PAC over UDP with KRB5KRB_ERR_RESPONSE_TOO_BIG unconditionally >@@ -304,6 +309,9 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_authdata_fast_not_used.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_enc_timestamp.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_clock_skew.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_no_fast.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_wrong_key.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_wrong_key_kdc.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_tgt.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_tgt_mach.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_armor.ad_dc >@@ -318,5 +326,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_fast_no_etypes.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_sname.ad_dc >-- >2.25.1 > > >From 6e173b136d4ab02edb490ffc5ca9e9a4bb856579 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 14:48:03 +1300 >Subject: [PATCH 327/686] tests/krb5: Check logon name in PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit e7c39cc44f2e16aecb01c0afc195911a474ef0b9) >--- > python/samba/tests/krb5/raw_testcase.py | 6 ++++++ > 1 file changed, 6 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index dbcff787f70..b0cd2bfdf0f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2552,6 +2552,12 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertEqual(expected_transited_services, > transited_services) > >+ elif pac_buffer.type == krb5pac.PAC_TYPE_LOGON_NAME: >+ expected_cname = kdc_exchange_dict['expected_cname'] >+ account_name = expected_cname['name-string'][0] >+ >+ self.assertEqual(account_name, pac_buffer.info.account_name) >+ > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >-- >2.25.1 > > >From e647541584a96359f3de2611897831b1b83035c3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 14:49:34 +1300 >Subject: [PATCH 328/686] tests/krb5: Simplify padata checking > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit cf3ca6ac4567d7c7954ea4ecc8cc9dd5effcc094) >--- > python/samba/tests/krb5/raw_testcase.py | 169 ++++++------------------ > 1 file changed, 41 insertions(+), 128 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b0cd2bfdf0f..b51ad499192 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2742,73 +2742,32 @@ class RawKerberosTest(TestCaseInTempDir): > PADATA_PK_AS_REP_19, > PADATA_PK_AS_REQ}) > >- etype_info2 = None >- etype_info = None >- enc_timestamp = None >- enc_challenge = None >- pk_as_req = None >- pk_as_rep19 = None >- fast_cookie = None >- fast_error = None >- fx_fast = None >- pac_options = None >- for pa in rep_padata: >- patype = self.getElementValue(pa, 'padata-type') >- pavalue = self.getElementValue(pa, 'padata-value') >- if patype == PADATA_ETYPE_INFO2: >- self.assertIsNone(etype_info2) >- etype_info2 = self.der_decode(pavalue, >- asn1Spec=krb5_asn1.ETYPE_INFO2()) >- continue >- if patype == PADATA_ETYPE_INFO: >- self.assertIsNone(etype_info) >- etype_info = self.der_decode(pavalue, >- asn1Spec=krb5_asn1.ETYPE_INFO()) >- continue >- if patype == PADATA_ENC_TIMESTAMP: >- self.assertIsNone(enc_timestamp) >- enc_timestamp = pavalue >- self.assertEqual(len(enc_timestamp), 0) >- continue >- if patype == PADATA_ENCRYPTED_CHALLENGE: >- self.assertIsNone(enc_challenge) >- enc_challenge = pavalue >- continue >- if patype == PADATA_PK_AS_REQ: >- self.assertIsNone(pk_as_req) >- pk_as_req = pavalue >- self.assertEqual(len(pk_as_req), 0) >- continue >- if patype == PADATA_PK_AS_REP_19: >- self.assertIsNone(pk_as_rep19) >- pk_as_rep19 = pavalue >- self.assertEqual(len(pk_as_rep19), 0) >- continue >- if patype == PADATA_FX_COOKIE: >- self.assertIsNone(fast_cookie) >- fast_cookie = pavalue >- self.assertIsNotNone(fast_cookie) >- continue >- if patype == PADATA_FX_ERROR: >- self.assertIsNone(fast_error) >- fast_error = pavalue >- self.assertIsNotNone(fast_error) >- continue >- if patype == PADATA_FX_FAST: >- self.assertIsNone(fx_fast) >- fx_fast = pavalue >- self.assertEqual(len(fx_fast), 0) >- continue >- if patype == PADATA_PAC_OPTIONS: >- self.assertIsNone(pac_options) >- pac_options = self.der_decode( >- pavalue, >- asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >- continue >+ if not expected_patypes: >+ return None >+ >+ pa_dict = self.get_pa_dict(rep_padata) >+ >+ enc_timestamp = pa_dict.get(PADATA_ENC_TIMESTAMP) >+ if enc_timestamp is not None: >+ self.assertEqual(len(enc_timestamp), 0) >+ >+ pk_as_req = pa_dict.get(PADATA_PK_AS_REQ) >+ if pk_as_req is not None: >+ self.assertEqual(len(pk_as_req), 0) >+ >+ pk_as_rep19 = pa_dict.get(PADATA_PK_AS_REP_19) >+ if pk_as_rep19 is not None: >+ self.assertEqual(len(pk_as_rep19), 0) > >+ fx_fast = pa_dict.get(PADATA_FX_FAST) >+ if fx_fast is not None: >+ self.assertEqual(len(fx_fast), 0) >+ >+ fast_cookie = pa_dict.get(PADATA_FX_COOKIE) > if fast_cookie is not None: > kdc_exchange_dict['fast_cookie'] = fast_cookie > >+ fast_error = pa_dict.get(PADATA_FX_ERROR) > if fast_error is not None: > fast_error = self.der_decode(fast_error, > asn1Spec=krb5_asn1.KRB_ERROR()) >@@ -2817,9 +2776,14 @@ class RawKerberosTest(TestCaseInTempDir): > fast_error, > inner=True) > >+ pac_options = pa_dict.get(PADATA_PAC_OPTIONS) > if pac_options is not None: >+ pac_options = self.der_decode( >+ pac_options, >+ asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) > self.assertElementEqual(pac_options, 'options', sent_pac_options) > >+ enc_challenge = pa_dict.get(PADATA_ENCRYPTED_CHALLENGE) > if enc_challenge is not None: > if not sent_enc_challenge: > self.assertEqual(len(enc_challenge), 0) >@@ -2862,52 +2826,21 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertLess(current_time - 300, rep_time) > self.assertLess(rep_time, current_time + 300) > >- if all(etype not in client_as_etypes or etype not in proposed_etypes >- for etype in (kcrypto.Enctype.AES256, >- kcrypto.Enctype.AES128, >- kcrypto.Enctype.RC4)): >- self.assertIsNone(etype_info2) >- self.assertIsNone(etype_info) >- if rep_msg_type == KRB_AS_REP: >- if self.strict_checking: >- if sent_fast: >- self.assertIsNotNone(enc_challenge) >- self.assertIsNone(enc_timestamp) >- else: >- self.assertIsNotNone(enc_timestamp) >- self.assertIsNone(enc_challenge) >- self.assertIsNotNone(pk_as_req) >- self.assertIsNotNone(pk_as_rep19) >- else: >- self.assertIsNone(enc_timestamp) >- self.assertIsNone(enc_challenge) >- self.assertIsNone(pk_as_req) >- self.assertIsNone(pk_as_rep19) >- return None >- >- if error_code != KDC_ERR_GENERIC: >- if self.strict_checking: >- self.assertIsNotNone(etype_info2) >- else: >- self.assertIsNone(etype_info2) >- if expect_etype_info: >- if self.strict_checking: >- self.assertIsNotNone(etype_info) >- else: >- if self.strict_checking: >- self.assertIsNone(etype_info) >- if unexpect_etype_info: >- self.assertIsNone(etype_info) >- >- if error_code != KDC_ERR_GENERIC and self.strict_checking: >+ etype_info2 = pa_dict.get(PADATA_ETYPE_INFO2) >+ if etype_info2 is not None: >+ etype_info2 = self.der_decode(etype_info2, >+ asn1Spec=krb5_asn1.ETYPE_INFO2()) > self.assertGreaterEqual(len(etype_info2), 1) >- self.assertEqual(len(etype_info2), len(expect_etype_info2)) >+ if self.strict_checking: >+ self.assertEqual(len(etype_info2), len(expect_etype_info2)) > for i in range(0, len(etype_info2)): > e = self.getElementValue(etype_info2[i], 'etype') >- self.assertEqual(e, expect_etype_info2[i]) >+ if self.strict_checking: >+ self.assertEqual(e, expect_etype_info2[i]) > salt = self.getElementValue(etype_info2[i], 'salt') > if e == kcrypto.Enctype.RC4: >- self.assertIsNone(salt) >+ if self.strict_checking: >+ self.assertIsNone(salt) > else: > self.assertIsNotNone(salt) > expected_salt = kdc_exchange_dict['expected_salt'] >@@ -2916,7 +2849,11 @@ class RawKerberosTest(TestCaseInTempDir): > s2kparams = self.getElementValue(etype_info2[i], 's2kparams') > if self.strict_checking: > self.assertIsNone(s2kparams) >+ >+ etype_info = pa_dict.get(PADATA_ETYPE_INFO) > if etype_info is not None: >+ etype_info = self.der_decode(etype_info, >+ asn1Spec=krb5_asn1.ETYPE_INFO()) > self.assertEqual(len(etype_info), 1) > e = self.getElementValue(etype_info[0], 'etype') > self.assertEqual(e, kcrypto.Enctype.RC4) >@@ -2926,30 +2863,6 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(salt) > self.assertEqual(len(salt), 0) > >- if error_code not in (KDC_ERR_PREAUTH_FAILED, >- KDC_ERR_GENERIC): >- if sent_fast: >- self.assertIsNotNone(enc_challenge) >- if self.strict_checking: >- self.assertIsNone(enc_timestamp) >- else: >- self.assertIsNotNone(enc_timestamp) >- if self.strict_checking: >- self.assertIsNone(enc_challenge) >- if not sent_enc_challenge: >- if self.strict_checking: >- self.assertIsNotNone(pk_as_req) >- self.assertIsNotNone(pk_as_rep19) >- else: >- self.assertIsNone(pk_as_req) >- self.assertIsNone(pk_as_rep19) >- else: >- if self.strict_checking: >- self.assertIsNone(enc_timestamp) >- self.assertIsNone(enc_challenge) >- self.assertIsNone(pk_as_req) >- self.assertIsNone(pk_as_rep19) >- > return etype_info2 > > def generate_simple_fast(self, >-- >2.25.1 > > >From e9db3f3297d86904bae7dfbc48501efc1fd373a0 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 11:48:41 +1300 >Subject: [PATCH 329/686] tests/krb5: Disable debugging output for tests > >This reduces the time spent running the tests in a testenv. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit dfd613661eec4b81e162f2d86a8fa9266c2fdc03) >--- > python/samba/tests/krb5/as_canonicalization_tests.py | 4 ++-- > python/samba/tests/krb5/as_req_tests.py | 4 ++-- > python/samba/tests/krb5/compatability_tests.py | 4 ++-- > python/samba/tests/krb5/kdc_tests.py | 4 ++-- > python/samba/tests/krb5/kdc_tgs_tests.py | 4 ++-- > python/samba/tests/krb5/s4u_tests.py | 4 ++-- > python/samba/tests/krb5/simple_tests.py | 4 ++-- > python/samba/tests/krb5/test_ccache.py | 4 ++-- > python/samba/tests/krb5/test_ldap.py | 4 ++-- > python/samba/tests/krb5/test_rpc.py | 4 ++-- > python/samba/tests/krb5/test_smb.py | 4 ++-- > python/samba/tests/krb5/xrealm_tests.py | 4 ++-- > 12 files changed, 24 insertions(+), 24 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index 29d8cf418f5..9538d0ae3cf 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -427,8 +427,8 @@ class KerberosASCanonicalizationTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > > unittest.main() >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 8d9b90fee69..7d7baaebf24 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -198,8 +198,8 @@ class AsReqKerberosTests(KDCBaseTest): > self.assertIsNotNone(as_rep) > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() > >diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py >index 0da72796894..ed2dc565b6d 100755 >--- a/python/samba/tests/krb5/compatability_tests.py >+++ b/python/samba/tests/krb5/compatability_tests.py >@@ -261,7 +261,7 @@ class SimpleKerberosTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/kdc_tests.py b/python/samba/tests/krb5/kdc_tests.py >index 928f3c25c0f..b7c8566a1ec 100755 >--- a/python/samba/tests/krb5/kdc_tests.py >+++ b/python/samba/tests/krb5/kdc_tests.py >@@ -222,7 +222,7 @@ class KdcTests(RawKerberosTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 2b55ba8a376..3075cc6b0a9 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -211,7 +211,7 @@ class KdcTgsTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index 57575f0595d..bbddef4d6e0 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -197,7 +197,7 @@ class S4UKerberosTests(RawKerberosTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/simple_tests.py b/python/samba/tests/krb5/simple_tests.py >index 795d753b4f7..3cd3b17bb31 100755 >--- a/python/samba/tests/krb5/simple_tests.py >+++ b/python/samba/tests/krb5/simple_tests.py >@@ -179,7 +179,7 @@ class SimpleKerberosTests(RawKerberosTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >index feb7a7bd9be..c44ea02d504 100755 >--- a/python/samba/tests/krb5/test_ccache.py >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -129,7 +129,7 @@ class CcacheTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/test_ldap.py b/python/samba/tests/krb5/test_ldap.py >index d304fb9d71e..95b2d24221a 100755 >--- a/python/samba/tests/krb5/test_ldap.py >+++ b/python/samba/tests/krb5/test_ldap.py >@@ -90,7 +90,7 @@ class LdapTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/test_rpc.py b/python/samba/tests/krb5/test_rpc.py >index 324b57f2847..40ac6df7a35 100755 >--- a/python/samba/tests/krb5/test_rpc.py >+++ b/python/samba/tests/krb5/test_rpc.py >@@ -73,7 +73,7 @@ class RpcTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/test_smb.py b/python/samba/tests/krb5/test_smb.py >index 45d4fe5e0c1..eebc9a9d4fe 100755 >--- a/python/samba/tests/krb5/test_smb.py >+++ b/python/samba/tests/krb5/test_smb.py >@@ -104,7 +104,7 @@ class SmbTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/xrealm_tests.py b/python/samba/tests/krb5/xrealm_tests.py >index 073cb755b46..73a6b3cf52d 100755 >--- a/python/samba/tests/krb5/xrealm_tests.py >+++ b/python/samba/tests/krb5/xrealm_tests.py >@@ -181,7 +181,7 @@ class XrealmKerberosTests(RawKerberosTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >-- >2.25.1 > > >From 34a5ae5bcca63af9bed9e4f6ad6be42eddc1e520 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 5 Oct 2021 19:47:22 +1300 >Subject: [PATCH 330/686] tests/krb5: Provide clearer assertion messages for > test failures > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 5233f002000f196875af488b4f4d1df26fca90de) >--- > python/samba/tests/krb5/raw_testcase.py | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b51ad499192..188a54451d3 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1942,7 +1942,12 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNone(check_error_fn) > self.assertEqual(0, len(expected_error_mode)) > self.assertIsNotNone(expected_msg_type) >- self.assertEqual(msg_type, expected_msg_type) >+ if msg_type == KRB_ERROR: >+ error_code = self.getElementValue(rep, 'error-code') >+ fail_msg = f'Got unexpected error: {error_code}' >+ else: >+ fail_msg = f'Expected to fail with error: {expected_error_mode}' >+ self.assertEqual(msg_type, expected_msg_type, fail_msg) > > if msg_type == KRB_ERROR: > return check_error_fn(kdc_exchange_dict, >-- >2.25.1 > > >From 7a8c7cd7b40dfda374da2a9c82a07abe9b17be3b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 5 Oct 2021 16:32:01 +1300 >Subject: [PATCH 331/686] tests/krb5: Fix sha1 checksum type > >Previously, sha1 signatures were being designated as rsa-md5-des3 >signatures. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ebe729786806c69e95b26ffc410e887e203accb8) >--- > python/samba/tests/krb5/kcrypto.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kcrypto.py b/python/samba/tests/krb5/kcrypto.py >index 2a72969de00..a919b785ad1 100755 >--- a/python/samba/tests/krb5/kcrypto.py >+++ b/python/samba/tests/krb5/kcrypto.py >@@ -81,8 +81,8 @@ class Cksumtype(object): > MD4_DES = 3 > MD5 = 7 > MD5_DES = 8 >- SHA1 = 9 > SHA1_DES3 = 12 >+ SHA1 = 14 > SHA1_AES128 = 15 > SHA1_AES256 = 16 > HMAC_MD5 = -138 >-- >2.25.1 > > >From fd734d336969441d41bd0019277dd0e2ef168664 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 13 Oct 2021 12:26:22 +1300 >Subject: [PATCH 332/686] selftest/dbcheck: Fix up RODC one-way links > >Test accounts were replicated to the RODC and then deleted, causing >state links to remain in the database. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 40e5db4aabcd32834ee524857b77d36921f6bdfe) > >[jsutton@samba.org Adapted to fix conflict] >--- > testprogs/blackbox/dbcheck.sh | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/testprogs/blackbox/dbcheck.sh b/testprogs/blackbox/dbcheck.sh >index 5691426d01b..60e85d2c409 100755 >--- a/testprogs/blackbox/dbcheck.sh >+++ b/testprogs/blackbox/dbcheck.sh >@@ -19,7 +19,7 @@ dbcheck() { > > # This list of attributes can be freely extended > dbcheck_fix_one_way_links() { >- $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes fix_all_string_dn_component_mismatch --attrs="lastKnownParent defaultObjectCategory fromServer rIDSetReferences" --cross-ncs $ARGS >+ $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes fix_all_string_dn_component_mismatch --attrs="lastKnownParent defaultObjectCategory fromServer rIDSetReferences msDS-RevealOnDemandGroup msDS-NeverRevealGroup" --cross-ncs $ARGS > } > > # This list of attributes can be freely extended >-- >2.25.1 > > >From a2fd562f96b4e4cbde9a759f28013d3b8efe7a05 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 14 Oct 2021 16:58:15 +1300 >Subject: [PATCH 333/686] tests/krb5: Add TKT_SIG_SUPPORT environment variable > >This lets us indicate that service tickets should be issued with ticket >checksums in the PAC. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >[abartlet@samba.org backported from commit ae2c57fb0332f94ac44d0886c5edbed707ef52fe > due to changes in other tests nearby in tests.py] >--- > python/samba/tests/krb5/raw_testcase.py | 6 ++++ > source4/selftest/tests.py | 41 +++++++++++++++++-------- > 2 files changed, 34 insertions(+), 13 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 188a54451d3..1f7c51c07a5 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -574,6 +574,12 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_fast_support = '0' > cls.kdc_fast_support = bool(int(kdc_fast_support)) > >+ tkt_sig_support = samba.tests.env_get_var_value('TKT_SIG_SUPPORT', >+ allow_missing=True) >+ if tkt_sig_support is None: >+ tkt_sig_support = '0' >+ cls.tkt_sig_support = bool(int(tkt_sig_support)) >+ > def setUp(self): > super().setUp() > self.do_asn1_print = False >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 2179c377d1f..eca24554246 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -714,46 +714,54 @@ planoldpythontestsuite("ad_dc:local", "samba.tests.gpo", extra_args=['-U"$USERNA > planoldpythontestsuite("ad_dc:local", "samba.tests.dckeytab", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) > > have_fast_support = int('SAMBA_USES_MITKDC' in config_hash) >+tkt_sig_support = 0 > planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", > environ={'SERVICE_USERNAME':'$SERVER', >- 'FAST_SUPPORT': have_fast_support}) >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support}) > planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", > environ={'SERVICE_USERNAME':'srv_account', > 'SERVICE_PASSWORD':'$PASSWORD', > 'FOR_USER':'$USERNAME', >- 'FAST_SUPPORT': have_fast_support}) >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support}) > > planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests", >- environ={'FAST_SUPPORT': have_fast_support}) >+ environ={'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support}) > > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_rpc", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > > for env in ["ad_dc", smbv1_disabled_testenv]: >@@ -1251,7 +1259,8 @@ for env in ["fl2008r2dc", "fl2003dc"]: > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > > >@@ -1273,7 +1282,8 @@ planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", > environ={ >@@ -1281,9 +1291,11 @@ planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests", >- environ={'FAST_SUPPORT': have_fast_support}) >+ environ={'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support}) > planpythontestsuite( > "ad_dc", > "samba.tests.krb5.kdc_tgs_tests", >@@ -1291,7 +1303,8 @@ planpythontestsuite( > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planpythontestsuite( > "ad_dc", >@@ -1300,7 +1313,8 @@ planpythontestsuite( > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planpythontestsuite( > "ad_dc", >@@ -1309,7 +1323,8 @@ planpythontestsuite( > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > > for env in [ >-- >2.25.1 > > >From d35a2f9dd3230b113e0b3b6e8c25881cea86f005 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 5 Oct 2021 15:39:11 +1300 >Subject: [PATCH 334/686] tests/krb5: Require ticket checksums if decryption > key is available > >We perform this check conditionally, because MIT doesn't currently add >ticket checksums. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit bf63221722903665e7b20991021fb5cdf4e4327e) >--- > python/samba/tests/krb5/raw_testcase.py | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 1f7c51c07a5..2e289c90ce7 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2493,15 +2493,14 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_private=ticket_private, > encpart_private=encpart_private) > >- # TODO: This parameter should be removed when all service tickets are >- # issued with ticket checksums. > expect_ticket_checksum = kdc_exchange_dict['expect_ticket_checksum'] > if expect_ticket_checksum: > self.assertIsNotNone(ticket_decryption_key) > > if ticket_decryption_key is not None: > self.verify_ticket(ticket_creds, krbtgt_key, expect_pac=expect_pac, >- expect_ticket_checksum=expect_ticket_checksum) >+ expect_ticket_checksum=expect_ticket_checksum >+ or self.tkt_sig_support) > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > >-- >2.25.1 > > >From 157df93e83946e40930eaa6f4180983c08d0aebe Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 6 Oct 2021 16:35:47 +1300 >Subject: [PATCH 335/686] tests/krb5: Verify tickets obtained with > get_service_ticket() > >We only require the ticket checksum with Heimdal, because MIT currently >doesn't add it. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit d86eee2fd0fb72e52d878ceba0c476ca58abe6cf) >--- > python/samba/tests/krb5/kdc_base_test.py | 8 ++++++++ > 1 file changed, 8 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 93951586cc7..8a5e12bbed4 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1287,6 +1287,14 @@ class KDCBaseTest(RawKerberosTest): > sname=sname, > decryption_key=target_key) > >+ if to_rodc: >+ krbtgt_creds = self.get_rodc_krbtgt_creds() >+ else: >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ self.verify_ticket(service_ticket_creds, krbtgt_key, >+ expect_ticket_checksum=self.tkt_sig_support) >+ > self.tkt_cache[cache_key] = service_ticket_creds > > return service_ticket_creds >-- >2.25.1 > > >From a08f8562c9c44dbf3915f9b7d5cb02651ddf736b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 30 Sep 2021 15:03:04 +1300 >Subject: [PATCH 336/686] tests/krb5: Add constrained delegation tests > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 56ccdba54e0c7cf3409d8430ea1012e5d3d9b092) >--- > python/samba/tests/krb5/rfc4120_constants.py | 5 + > python/samba/tests/krb5/rodc_tests.py | 73 ++ > python/samba/tests/krb5/s4u_tests.py | 958 ++++++++++++++++++- > python/samba/tests/usage.py | 1 + > selftest/knownfail_heimdal_kdc | 29 + > source4/selftest/tests.py | 11 +- > 6 files changed, 1070 insertions(+), 7 deletions(-) > create mode 100755 python/samba/tests/krb5/rodc_tests.py > >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index 76f2b75d94e..39bb2db8e32 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -69,12 +69,17 @@ PADATA_SUPPORTED_ETYPES = int( > KDC_ERR_C_PRINCIPAL_UNKNOWN = 6 > KDC_ERR_S_PRINCIPAL_UNKNOWN = 7 > KDC_ERR_POLICY = 12 >+KDC_ERR_BADOPTION = 13 > KDC_ERR_ETYPE_NOSUPP = 14 >+KDC_ERR_SUMTYPE_NOSUPP = 15 > KDC_ERR_PREAUTH_FAILED = 24 > KDC_ERR_PREAUTH_REQUIRED = 25 >+KDC_ERR_BAD_INTEGRITY = 31 > KDC_ERR_NOT_US = 35 > KDC_ERR_BADMATCH = 36 > KDC_ERR_SKEW = 37 >+KDC_ERR_MODIFIED = 41 >+KDC_ERR_INAPP_CKSUM = 50 > KDC_ERR_GENERIC = 60 > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS = 93 > >diff --git a/python/samba/tests/krb5/rodc_tests.py b/python/samba/tests/krb5/rodc_tests.py >new file mode 100755 >index 00000000000..4579f9eb552 >--- /dev/null >+++ b/python/samba/tests/krb5/rodc_tests.py >@@ -0,0 +1,73 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class RodcKerberosTests(KDCBaseTest): >+ >+ def setUp(self): >+ super().setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ # Ensure that an RODC correctly issues tickets signed with its krbtgt key >+ # and including the RODCIdentifier. >+ def test_rodc_ticket_signature(self): >+ user_creds = self.get_cached_creds( >+ machine_account=False, >+ opts={ >+ 'revealed_to_rodc': True >+ }) >+ target_creds = self.get_cached_creds( >+ machine_account=True, >+ opts={ >+ 'revealed_to_rodc': True >+ }) >+ >+ krbtgt_creds = self.get_rodc_krbtgt_creds() >+ rodc_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ # Get a TGT from the RODC. >+ tgt = self.get_tgt(user_creds, to_rodc=True) >+ >+ # Ensure the PAC contains the expected checksums. >+ self.verify_ticket(tgt, rodc_key) >+ >+ # Get a service ticket from the RODC. >+ service_ticket = self.get_service_ticket(tgt, target_creds, >+ to_rodc=True) >+ >+ # Ensure the PAC contains the expected checksums. >+ self.verify_ticket(service_ticket, rodc_key) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = False >+ global_hexdump = False >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index bbddef4d6e0..9a25256081a 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -18,17 +18,34 @@ > > import sys > import os >+import functools > > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > >+from samba import ntstatus >+from samba.dcerpc import krb5pac, lsa >+ > from samba.tests import env_get_var_value >-from samba.tests.krb5.kcrypto import Cksumtype >-from samba.tests.krb5.raw_testcase import RawKerberosTest >+from samba.tests.krb5.kcrypto import Cksumtype, Enctype >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+from samba.tests.krb5.raw_testcase import ( >+ RodcPacEncryptionKey, >+ ZeroedChecksumKey >+) > from samba.tests.krb5.rfc4120_constants import ( >+ AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5, >+ KDC_ERR_BADOPTION, >+ KDC_ERR_BAD_INTEGRITY, >+ KDC_ERR_GENERIC, >+ KDC_ERR_INAPP_CKSUM, >+ KDC_ERR_MODIFIED, >+ KDC_ERR_SUMTYPE_NOSUPP, > KU_PA_ENC_TIMESTAMP, > KU_AS_REP_ENC_PART, > KU_TGS_REP_ENC_PART_SUB_KEY, >+ NT_PRINCIPAL > ) > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > >@@ -36,7 +53,7 @@ global_asn1_print = False > global_hexdump = False > > >-class S4UKerberosTests(RawKerberosTest): >+class S4UKerberosTests(KDCBaseTest): > > def setUp(self): > super(S4UKerberosTests, self).setUp() >@@ -119,8 +136,14 @@ class S4UKerberosTests(RawKerberosTest): > self.assertEqual(msg_type, 11) > > enc_part2 = key.decrypt(KU_AS_REP_ENC_PART, rep['enc-part']['cipher']) >- enc_part2 = self.der_decode( >- enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ # MIT KDC encodes both EncASRepPart and EncTGSRepPart with >+ # application tag 26 >+ try: >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ except Exception: >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) > > # S4U2Self Request > sname = cname >@@ -195,6 +218,931 @@ class S4UKerberosTests(RawKerberosTest): > msg_type = self._test_s4u2self(pa_s4u2self_ctype=Cksumtype.CRC32) > self.assertEqual(msg_type, 30) > >+ def _run_s4u2self_test(self, kdc_dict): >+ client_opts = kdc_dict.pop('client_opts', None) >+ client_creds = self.get_cached_creds(machine_account=False, >+ opts=client_opts) >+ >+ service_opts = kdc_dict.pop('service_opts', None) >+ service_creds = self.get_cached_creds(machine_account=True, >+ opts=service_opts) >+ >+ service_tgt = self.get_tgt(service_creds) >+ modify_service_tgt_fn = kdc_dict.pop('modify_service_tgt_fn', None) >+ if modify_service_tgt_fn is not None: >+ service_tgt = modify_service_tgt_fn(service_tgt) >+ >+ client_name = client_creds.get_username() >+ client_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[client_name]) >+ >+ service_name = service_creds.get_username()[:-1] >+ service_sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=['host', service_name]) >+ >+ realm = client_creds.get_realm() >+ >+ expected_flags = kdc_dict.pop('expected_flags', None) >+ if expected_flags is not None: >+ expected_flags = krb5_asn1.TicketFlags(expected_flags) >+ >+ unexpected_flags = kdc_dict.pop('unexpected_flags', None) >+ if unexpected_flags is not None: >+ unexpected_flags = krb5_asn1.TicketFlags(unexpected_flags) >+ >+ kdc_options = kdc_dict.pop('kdc_options', '0') >+ kdc_options = krb5_asn1.KDCOptions(kdc_options) >+ >+ service_decryption_key = self.TicketDecryptionKey_from_creds( >+ service_creds) >+ >+ authenticator_subkey = self.RandomKey(Enctype.AES256) >+ >+ etypes = kdc_dict.pop('etypes', (AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5)) >+ >+ def generate_s4u2self_padata(_kdc_exchange_dict, >+ _callback_dict, >+ req_body): >+ pa_s4u = self.PA_S4U2Self_create( >+ name=client_cname, >+ realm=realm, >+ tgt_session_key=service_tgt.session_key, >+ ctype=None) >+ >+ return [pa_s4u], req_body >+ >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=realm, >+ expected_cname=client_cname, >+ expected_srealm=realm, >+ expected_sname=service_sname, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, >+ ticket_decryption_key=service_decryption_key, >+ expect_ticket_checksum=True, >+ generate_padata_fn=generate_s4u2self_padata, >+ check_rep_fn=self.generic_check_kdc_rep, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ expected_error_mode=0, >+ tgt=service_tgt, >+ authenticator_subkey=authenticator_subkey, >+ kdc_options=str(kdc_options), >+ expect_claims=False) >+ >+ self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=None, >+ realm=realm, >+ sname=service_sname, >+ etypes=etypes) >+ >+ # Ensure we used all the parameters given to us. >+ self.assertEqual({}, kdc_dict) >+ >+ # Test performing an S4U2Self operation with a forwardable ticket. The >+ # resulting ticket should have the 'forwardable' flag set. >+ def test_s4u2self_forwardable(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'expected_flags': 'forwardable' >+ }) >+ >+ # Test performing an S4U2Self operation without requesting a forwardable >+ # ticket. The resulting ticket should not have the 'forwardable' flag set. >+ def test_s4u2self_without_forwardable(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'unexpected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with a non-forwardable TGT. The 'forwardable' flag should >+ # not be set on the ticket. >+ def test_s4u2self_not_forwardable(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=False), >+ 'unexpected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with the not_delegated flag set on the client. The >+ # 'forwardable' flag should not be set on the ticket. >+ def test_s4u2self_client_not_delegated(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': True >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'unexpected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with a service not trusted to authenticate for delegation, >+ # but having an empty msDS-AllowedToDelegateTo attribute. The 'forwardable' >+ # flag should be set on the ticket. >+ def test_s4u2self_not_trusted_empty_allowed(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'service_opts': { >+ 'trusted_to_auth_for_delegation': False, >+ 'delegation_to_spn': () >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'expected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with a service not trusted to authenticate for delegation >+ # and having a non-empty msDS-AllowedToDelegateTo attribute. The >+ # 'forwardable' flag should not be set on the ticket. >+ def test_s4u2self_not_trusted_nonempty_allowed(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'service_opts': { >+ 'trusted_to_auth_for_delegation': False, >+ 'delegation_to_spn': ('test',) >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'unexpected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with a service trusted to authenticate for delegation and >+ # having an empty msDS-AllowedToDelegateTo attribute. The 'forwardable' >+ # flag should be set on the ticket. >+ def test_s4u2self_trusted_empty_allowed(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'service_opts': { >+ 'trusted_to_auth_for_delegation': True, >+ 'delegation_to_spn': () >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'expected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with a service trusted to authenticate for delegation and >+ # having a non-empty msDS-AllowedToDelegateTo attribute. The 'forwardable' >+ # flag should be set on the ticket. >+ def test_s4u2self_trusted_nonempty_allowed(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'service_opts': { >+ 'trusted_to_auth_for_delegation': True, >+ 'delegation_to_spn': ('test',) >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'expected_flags': 'forwardable' >+ }) >+ >+ def _run_delegation_test(self, kdc_dict): >+ client_opts = kdc_dict.pop('client_opts', None) >+ client_creds = self.get_cached_creds(machine_account=False, >+ opts=client_opts) >+ >+ service1_opts = kdc_dict.pop('service1_opts', {}) >+ service2_opts = kdc_dict.pop('service2_opts', {}) >+ >+ allow_delegation = kdc_dict.pop('allow_delegation', False) >+ allow_rbcd = kdc_dict.pop('allow_rbcd', False) >+ self.assertFalse(allow_delegation and allow_rbcd) >+ >+ if allow_rbcd: >+ service1_creds = self.get_cached_creds(machine_account=True, >+ opts=service1_opts) >+ >+ self.assertNotIn('delegation_from_dn', service2_opts) >+ service2_opts['delegation_from_dn'] = str(service1_creds.get_dn()) >+ >+ service2_creds = self.get_cached_creds(machine_account=True, >+ opts=service2_opts) >+ else: >+ service2_creds = self.get_cached_creds(machine_account=True, >+ opts=service2_opts) >+ >+ if allow_delegation: >+ self.assertNotIn('delegation_to_spn', service1_opts) >+ service1_opts['delegation_to_spn'] = service2_creds.get_spn() >+ >+ service1_creds = self.get_cached_creds(machine_account=True, >+ opts=service1_opts) >+ >+ client_tkt_options = kdc_dict.pop('client_tkt_options', 'forwardable') >+ expected_flags = krb5_asn1.TicketFlags(client_tkt_options) >+ >+ client_tgt = self.get_tgt(client_creds, >+ kdc_options=client_tkt_options, >+ expected_flags=expected_flags) >+ client_service_tkt = self.get_service_ticket( >+ client_tgt, >+ service1_creds, >+ kdc_options=client_tkt_options, >+ expected_flags=expected_flags) >+ >+ service1_tgt = self.get_tgt(service1_creds) >+ >+ modify_client_tkt_fn = kdc_dict.pop('modify_client_tkt_fn', None) >+ if modify_client_tkt_fn is not None: >+ client_service_tkt = modify_client_tkt_fn(client_service_tkt) >+ >+ additional_tickets = [client_service_tkt.ticket] >+ >+ modify_service_tgt_fn = kdc_dict.pop('modify_service_tgt_fn', None) >+ if modify_service_tgt_fn is not None: >+ service1_tgt = modify_service_tgt_fn(service1_tgt) >+ >+ kdc_options = kdc_dict.pop('kdc_options', None) >+ if kdc_options is None: >+ kdc_options = str(krb5_asn1.KDCOptions('cname-in-addl-tkt')) >+ >+ client_username = client_creds.get_username() >+ client_realm = client_creds.get_realm() >+ client_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[client_username]) >+ >+ service1_name = service1_creds.get_username()[:-1] >+ service1_realm = service1_creds.get_realm() >+ >+ service2_name = service2_creds.get_username()[:-1] >+ service2_realm = service2_creds.get_realm() >+ service2_service = 'host' >+ service2_sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[service2_service, >+ service2_name]) >+ service2_decryption_key = self.TicketDecryptionKey_from_creds( >+ service2_creds) >+ service2_etypes = service2_creds.tgs_supported_enctypes >+ >+ expected_error_mode = kdc_dict.pop('expected_error_mode') >+ expected_status = kdc_dict.pop('expected_status', None) >+ if expected_error_mode: >+ check_error_fn = self.generic_check_kdc_error >+ check_rep_fn = None >+ else: >+ check_error_fn = None >+ check_rep_fn = self.generic_check_kdc_rep >+ >+ self.assertIsNone(expected_status) >+ >+ expect_edata = kdc_dict.pop('expect_edata', None) >+ if expect_edata is not None: >+ self.assertTrue(expected_error_mode) >+ >+ pac_options = kdc_dict.pop('pac_options', None) >+ >+ authenticator_subkey = self.RandomKey(Enctype.AES256) >+ >+ etypes = kdc_dict.pop('etypes', (AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5)) >+ >+ expected_proxy_target = service2_creds.get_spn() >+ >+ expected_transited_services = kdc_dict.pop( >+ 'expected_transited_services', []) >+ >+ transited_service = f'host/{service1_name}@{service1_realm}' >+ expected_transited_services.append(transited_service) >+ >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=client_realm, >+ expected_cname=client_cname, >+ expected_srealm=service2_realm, >+ expected_sname=service2_sname, >+ expected_supported_etypes=service2_etypes, >+ ticket_decryption_key=service2_decryption_key, >+ check_error_fn=check_error_fn, >+ check_rep_fn=check_rep_fn, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ expected_error_mode=expected_error_mode, >+ expected_status=expected_status, >+ callback_dict={}, >+ tgt=service1_tgt, >+ authenticator_subkey=authenticator_subkey, >+ kdc_options=kdc_options, >+ pac_options=pac_options, >+ expect_edata=expect_edata, >+ expected_proxy_target=expected_proxy_target, >+ expected_transited_services=expected_transited_services) >+ >+ self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=None, >+ realm=service2_realm, >+ sname=service2_sname, >+ etypes=etypes, >+ additional_tickets=additional_tickets) >+ >+ # Ensure we used all the parameters given to us. >+ self.assertEqual({}, kdc_dict) >+ >+ def test_constrained_delegation(self): >+ # Test constrained delegation. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_delegation': True >+ }) >+ >+ def test_constrained_delegation_existing_delegation_info(self): >+ # Test constrained delegation with an existing S4U_DELEGATION_INFO >+ # structure in the PAC. >+ >+ services = ['service1', 'service2', 'service3'] >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': functools.partial( >+ self.add_delegation_info, services=services), >+ 'expected_transited_services': services >+ }) >+ >+ def test_constrained_delegation_not_allowed(self): >+ # Test constrained delegation when the delegating service does not >+ # allow it. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_delegation': False >+ }) >+ >+ def test_constrained_delegation_no_client_pac(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': (KDC_ERR_BADOPTION, >+ KDC_ERR_MODIFIED), >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': self.remove_ticket_pac, >+ 'expect_edata': False >+ }) >+ >+ def test_constrained_delegation_no_service_pac(self): >+ # Test constrained delegation when the service TGT does not contain a >+ # PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_delegation': True, >+ 'modify_service_tgt_fn': self.remove_ticket_pac >+ }) >+ >+ def test_constrained_delegation_non_forwardable(self): >+ # Test constrained delegation with a non-forwardable ticket. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_ACCOUNT_RESTRICTION, >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=False) >+ }) >+ >+ def test_constrained_delegation_pac_options_rbcd(self): >+ # Test constrained delegation, but with the RBCD bit set in the PAC >+ # options. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'pac_options': '0001', # supports RBCD >+ 'allow_delegation': True >+ }) >+ >+ def test_rbcd_existing_delegation_info(self): >+ # Test constrained delegation with an existing S4U_DELEGATION_INFO >+ # structure in the PAC. >+ >+ services = ['service1', 'service2', 'service3'] >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': functools.partial( >+ self.add_delegation_info, services=services), >+ 'expected_transited_services': services >+ }) >+ >+ def test_rbcd_not_allowed(self): >+ # Test resource-based constrained delegation when the target service >+ # does not allow it. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_NOT_FOUND, >+ 'allow_rbcd': False, >+ 'pac_options': '0001' # supports RBCD >+ }) >+ >+ def test_rbcd_no_client_pac_a(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC, and an empty msDS-AllowedToDelegateTo attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': self.remove_ticket_pac >+ }) >+ >+ def test_rbcd_no_client_pac_b(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC, and a non-empty msDS-AllowedToDelegateTo attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': ntstatus.NT_STATUS_NO_MATCH, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': self.remove_ticket_pac, >+ 'service1_opts': { >+ 'delegation_to_spn': ('host/test') >+ } >+ }) >+ >+ def test_rbcd_no_service_pac(self): >+ # Test constrained delegation when the service TGT does not contain a >+ # PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': >+ ntstatus.NT_STATUS_NOT_FOUND, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_service_tgt_fn': self.remove_ticket_pac >+ }) >+ >+ def test_rbcd_non_forwardable(self): >+ # Test resource-based constrained delegation with a non-forwardable >+ # ticket. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_ACCOUNT_RESTRICTION, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=False) >+ }) >+ >+ def test_rbcd_no_pac_options_a(self): >+ # Test resource-based constrained delegation without the RBCD bit set >+ # in the PAC options, and an empty msDS-AllowedToDelegateTo attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '1' # does not support RBCD >+ }) >+ >+ def test_rbcd_no_pac_options_b(self): >+ # Test resource-based constrained delegation without the RBCD bit set >+ # in the PAC options, and a non-empty msDS-AllowedToDelegateTo >+ # attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_NO_MATCH, >+ 'allow_rbcd': True, >+ 'pac_options': '1', # does not support RBCD >+ 'service1_opts': { >+ 'delegation_to_spn': ('host/test') >+ } >+ }) >+ >+ def test_bronze_bit_constrained_delegation_old_checksum(self): >+ # Attempt to modify the ticket without updating the PAC checksums. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': (KDC_ERR_MODIFIED, >+ KDC_ERR_BAD_INTEGRITY), >+ 'allow_delegation': True, >+ 'client_tkt_options': '0', # non-forwardable ticket >+ 'modify_client_tkt_fn': functools.partial( >+ self.set_ticket_forwardable, >+ flag=True, update_pac_checksums=False), >+ 'expect_edata': False >+ }) >+ >+ def test_bronze_bit_rbcd_old_checksum(self): >+ # Attempt to modify the ticket without updating the PAC checksums. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'client_tkt_options': '0', # non-forwardable ticket >+ 'modify_client_tkt_fn': functools.partial( >+ self.set_ticket_forwardable, >+ flag=True, update_pac_checksums=False) >+ }) >+ >+ def test_constrained_delegation_missing_client_checksum(self): >+ # Present a user ticket without the required checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ if checksum == krb5pac.PAC_TYPE_TICKET_CHECKSUM: >+ expected_error_mode = (KDC_ERR_BADOPTION, >+ KDC_ERR_MODIFIED) >+ else: >+ expected_error_mode = KDC_ERR_GENERIC >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': functools.partial( >+ self.remove_pac_checksum, checksum=checksum), >+ 'expect_edata': False >+ }) >+ >+ def test_constrained_delegation_missing_service_checksum(self): >+ # Present the service's ticket without the required checksums. >+ for checksum in filter(lambda x: x != krb5pac.PAC_TYPE_TICKET_CHECKSUM, >+ self.pac_checksum_types): >+ with self.subTest(checksum=checksum): >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'expected_status': >+ ntstatus.NT_STATUS_INSUFFICIENT_RESOURCES, >+ 'allow_delegation': True, >+ 'modify_service_tgt_fn': functools.partial( >+ self.remove_pac_checksum, checksum=checksum) >+ }) >+ >+ def test_rbcd_missing_client_checksum(self): >+ # Present a user ticket without the required checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ if checksum == krb5pac.PAC_TYPE_TICKET_CHECKSUM: >+ expected_error_mode = KDC_ERR_MODIFIED >+ else: >+ expected_error_mode = KDC_ERR_GENERIC >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': >+ ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': functools.partial( >+ self.remove_pac_checksum, checksum=checksum) >+ }) >+ >+ def test_rbcd_missing_service_checksum(self): >+ # Present the service's ticket without the required checksums. >+ for checksum in filter(lambda x: x != krb5pac.PAC_TYPE_TICKET_CHECKSUM, >+ self.pac_checksum_types): >+ with self.subTest(checksum=checksum): >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'expected_status': >+ ntstatus.NT_STATUS_INSUFFICIENT_RESOURCES, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_service_tgt_fn': functools.partial( >+ self.remove_pac_checksum, checksum=checksum) >+ }) >+ >+ def test_constrained_delegation_zeroed_client_checksum(self): >+ # Present a user ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': (KDC_ERR_MODIFIED, >+ KDC_ERR_BAD_INTEGRITY), >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': functools.partial( >+ self.zeroed_pac_checksum, checksum=checksum), >+ 'expect_edata': False >+ }) >+ >+ def test_constrained_delegation_zeroed_service_checksum(self): >+ # Present the service's ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ expected_error_mode = (KDC_ERR_MODIFIED, >+ KDC_ERR_BAD_INTEGRITY) >+ expected_status = ntstatus.NT_STATUS_WRONG_PASSWORD >+ else: >+ expected_error_mode = 0 >+ expected_status = None >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, >+ 'allow_delegation': True, >+ 'modify_service_tgt_fn': functools.partial( >+ self.zeroed_pac_checksum, checksum=checksum) >+ }) >+ >+ def test_rbcd_zeroed_client_checksum(self): >+ # Present a user ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': >+ ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': functools.partial( >+ self.zeroed_pac_checksum, checksum=checksum) >+ }) >+ >+ def test_rbcd_zeroed_service_checksum(self): >+ # Present the service's ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ expected_error_mode = (KDC_ERR_MODIFIED, >+ KDC_ERR_BAD_INTEGRITY) >+ expected_status = ntstatus.NT_STATUS_WRONG_PASSWORD >+ else: >+ expected_error_mode = 0 >+ expected_status = None >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_service_tgt_fn': functools.partial( >+ self.zeroed_pac_checksum, checksum=checksum) >+ }) >+ >+ unkeyed_ctypes = {Cksumtype.MD5, Cksumtype.SHA1, Cksumtype.CRC32} >+ >+ def test_constrained_delegation_unkeyed_client_checksum(self): >+ # Present a user ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ for ctype in self.unkeyed_ctypes: >+ with self.subTest(checksum=checksum, ctype=ctype): >+ if (checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM >+ and ctype == Cksumtype.SHA1): >+ expected_error_mode = (KDC_ERR_SUMTYPE_NOSUPP, >+ KDC_ERR_INAPP_CKSUM) >+ else: >+ expected_error_mode = (KDC_ERR_GENERIC, >+ KDC_ERR_INAPP_CKSUM) >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': functools.partial( >+ self.unkeyed_pac_checksum, >+ checksum=checksum, ctype=ctype), >+ 'expect_edata': False >+ }) >+ >+ def test_constrained_delegation_unkeyed_service_checksum(self): >+ # Present the service's ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ for ctype in self.unkeyed_ctypes: >+ with self.subTest(checksum=checksum, ctype=ctype): >+ if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ if ctype == Cksumtype.SHA1: >+ expected_error_mode = (KDC_ERR_SUMTYPE_NOSUPP, >+ KDC_ERR_INAPP_CKSUM) >+ expected_status = ntstatus.NT_STATUS_LOGON_FAILURE >+ else: >+ expected_error_mode = (KDC_ERR_GENERIC, >+ KDC_ERR_INAPP_CKSUM) >+ expected_status = ( >+ ntstatus.NT_STATUS_INSUFFICIENT_RESOURCES) >+ else: >+ expected_error_mode = 0 >+ expected_status = None >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, >+ 'allow_delegation': True, >+ 'modify_service_tgt_fn': functools.partial( >+ self.unkeyed_pac_checksum, >+ checksum=checksum, ctype=ctype) >+ }) >+ >+ def test_rbcd_unkeyed_client_checksum(self): >+ # Present a user ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ for ctype in self.unkeyed_ctypes: >+ with self.subTest(checksum=checksum, ctype=ctype): >+ if (checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM >+ and ctype == Cksumtype.SHA1): >+ expected_error_mode = KDC_ERR_SUMTYPE_NOSUPP >+ else: >+ expected_error_mode = KDC_ERR_GENERIC >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': >+ ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': functools.partial( >+ self.unkeyed_pac_checksum, >+ checksum=checksum, ctype=ctype) >+ }) >+ >+ def test_rbcd_unkeyed_service_checksum(self): >+ # Present the service's ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ for ctype in self.unkeyed_ctypes: >+ with self.subTest(checksum=checksum, ctype=ctype): >+ if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ if ctype == Cksumtype.SHA1: >+ expected_error_mode = (KDC_ERR_SUMTYPE_NOSUPP, >+ KDC_ERR_BAD_INTEGRITY) >+ expected_status = ntstatus.NT_STATUS_LOGON_FAILURE >+ else: >+ expected_error_mode = KDC_ERR_GENERIC >+ expected_status = ( >+ ntstatus.NT_STATUS_INSUFFICIENT_RESOURCES) >+ else: >+ expected_error_mode = 0 >+ expected_status = None >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_service_tgt_fn': functools.partial( >+ self.unkeyed_pac_checksum, >+ checksum=checksum, ctype=ctype) >+ }) >+ >+ def remove_pac_checksum(self, ticket, checksum): >+ checksum_keys = self.get_krbtgt_checksum_key() >+ >+ return self.modified_ticket(ticket, >+ checksum_keys=checksum_keys, >+ include_checksums={checksum: False}) >+ >+ def zeroed_pac_checksum(self, ticket, checksum): >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ server_key = ticket.decryption_key >+ >+ checksum_keys = { >+ krb5pac.PAC_TYPE_SRV_CHECKSUM: server_key, >+ krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key, >+ krb5pac.PAC_TYPE_TICKET_CHECKSUM: krbtgt_key, >+ } >+ >+ if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ zeroed_key = server_key >+ else: >+ zeroed_key = krbtgt_key >+ >+ checksum_keys[checksum] = ZeroedChecksumKey(zeroed_key.key, >+ zeroed_key.kvno) >+ >+ return self.modified_ticket(ticket, >+ checksum_keys=checksum_keys, >+ include_checksums={checksum: True}) >+ >+ def unkeyed_pac_checksum(self, ticket, checksum, ctype): >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ server_key = ticket.decryption_key >+ >+ checksum_keys = { >+ krb5pac.PAC_TYPE_SRV_CHECKSUM: server_key, >+ krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key, >+ krb5pac.PAC_TYPE_TICKET_CHECKSUM: krbtgt_key, >+ } >+ >+ # Make a copy of the existing key and change the ctype. >+ key = checksum_keys[checksum] >+ new_key = RodcPacEncryptionKey(key.key, key.kvno) >+ new_key.ctype = ctype >+ checksum_keys[checksum] = new_key >+ >+ return self.modified_ticket(ticket, >+ checksum_keys=checksum_keys, >+ include_checksums={checksum: True}) >+ >+ def add_delegation_info(self, ticket, services=None): >+ def modify_pac_fn(pac): >+ pac_buffers = pac.buffers >+ self.assertNotIn(krb5pac.PAC_TYPE_CONSTRAINED_DELEGATION, >+ (buffer.type for buffer in pac_buffers)) >+ >+ transited_services = list(map(lsa.String, services)) >+ >+ delegation = krb5pac.PAC_CONSTRAINED_DELEGATION() >+ delegation.proxy_target = lsa.String('test_proxy_target') >+ delegation.transited_services = transited_services >+ delegation.num_transited_services = len(transited_services) >+ >+ info = krb5pac.PAC_CONSTRAINED_DELEGATION_CTR() >+ info.info = delegation >+ >+ pac_buffer = krb5pac.PAC_BUFFER() >+ pac_buffer.type = krb5pac.PAC_TYPE_CONSTRAINED_DELEGATION >+ pac_buffer.info = info >+ >+ pac_buffers.append(pac_buffer) >+ >+ pac.buffers = pac_buffers >+ pac.num_buffers += 1 >+ >+ return pac >+ >+ checksum_keys = self.get_krbtgt_checksum_key() >+ >+ return self.modified_ticket(ticket, >+ checksum_keys=checksum_keys, >+ modify_pac_fn=modify_pac_fn) >+ >+ def set_ticket_forwardable(self, ticket, flag, update_pac_checksums=True): >+ flag = '1' if flag else '0' >+ >+ def modify_fn(enc_part): >+ # Reset the forwardable flag >+ forwardable_pos = (len(tuple(krb5_asn1.TicketFlags('forwardable'))) >+ - 1) >+ >+ flags = enc_part['flags'] >+ self.assertLessEqual(forwardable_pos, len(flags)) >+ enc_part['flags'] = (flags[:forwardable_pos] + >+ flag + >+ flags[forwardable_pos+1:]) >+ >+ return enc_part >+ >+ if update_pac_checksums: >+ checksum_keys = self.get_krbtgt_checksum_key() >+ else: >+ checksum_keys = None >+ >+ return self.modified_ticket(ticket, >+ modify_fn=modify_fn, >+ checksum_keys=checksum_keys, >+ update_pac_checksums=update_pac_checksums) >+ >+ def remove_ticket_pac(self, ticket): >+ return self.modified_ticket(ticket, >+ exclude_pac=True) >+ > > if __name__ == "__main__": > global_asn1_print = False >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 1795846d7bc..81d78119d51 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -100,6 +100,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py', > 'python/samba/tests/krb5/as_req_tests.py', > 'python/samba/tests/krb5/fast_tests.py', >+ 'python/samba/tests/krb5/rodc_tests.py', > } > > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 6eb667f8969..0b8e83f1f3f 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -125,3 +125,32 @@ > # Heimdal currently does not generate ticket signatures > # > ^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_heimdal_ticket_signature >+# >+# S4U tests >+# >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_missing_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_service_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_zeroed_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_zeroed_service_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_existing_delegation_info >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_missing_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_a >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_b >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_unkeyed_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_unkeyed_service_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_service_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_client_not_delegated >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_forwardable >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_forwardable >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_empty_allowed >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_nonempty_allowed >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_trusted_empty_allowed >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_trusted_nonempty_allowed >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_without_forwardable >+# >+# RODC tests >+# >+^samba.tests.krb5.rodc_tests.samba.tests.krb5.rodc_tests.RodcKerberosTests.test_rodc_ticket_signature >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index eca24554246..f0ae3433091 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -721,9 +721,16 @@ planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", > 'FAST_SUPPORT': have_fast_support, > 'TKT_SIG_SUPPORT': tkt_sig_support}) > planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", >- environ={'SERVICE_USERNAME':'srv_account', >- 'SERVICE_PASSWORD':'$PASSWORD', >+ environ={'ADMIN_USERNAME':'$USERNAME', >+ 'ADMIN_PASSWORD':'$PASSWORD', > 'FOR_USER':'$USERNAME', >+ 'STRICT_CHECKING':'0', >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support}) >+planoldpythontestsuite("rodc:local", "samba.tests.krb5.rodc_tests", >+ environ={'ADMIN_USERNAME':'$USERNAME', >+ 'ADMIN_PASSWORD':'$PASSWORD', >+ 'STRICT_CHECKING':'0', > 'FAST_SUPPORT': have_fast_support, > 'TKT_SIG_SUPPORT': tkt_sig_support}) > >-- >2.25.1 > > >From d65cf87fe5674f041db605d02df48484f39524ae Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 12:07:40 +1300 >Subject: [PATCH 337/686] tests/krb5: Don't include empty AD-IF-RELEVANT > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1a08399cd8169a525cc9e7aed99da84ef20e5b9c) >--- > python/samba/tests/krb5/raw_testcase.py | 19 ++++++++++++------- > 1 file changed, 12 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 2e289c90ce7..e008223eb23 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3424,14 +3424,19 @@ class RawKerberosTest(TestCaseInTempDir): > if expect_pac: > self.assertIsNotNone(old_pac, 'Expected PAC') > >- ad_relevant = self.der_encode( >- relevant_elems, >- asn1Spec=krb5_asn1.AD_IF_RELEVANT()) >- >- authdata_elem = self.AuthorizationData_create(AD_IF_RELEVANT, >- ad_relevant) >+ if relevant_elems: >+ ad_relevant = self.der_encode( >+ relevant_elems, >+ asn1Spec=krb5_asn1.AD_IF_RELEVANT()) >+ >+ authdata_elem = self.AuthorizationData_create( >+ AD_IF_RELEVANT, >+ ad_relevant) >+ else: >+ authdata_elem = None > >- new_auth_data.append(authdata_elem) >+ if authdata_elem is not None: >+ new_auth_data.append(authdata_elem) > > if expect_pac: > self.assertIsNotNone(ad_relevant, 'Expected AD-RELEVANT') >-- >2.25.1 > > >From 49851becc748701de676bc7fa7517fd00508f5e4 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:41:35 +1300 >Subject: [PATCH 338/686] tests/krb5: Allow bypassing cache when creating > accounts > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 3948701f1d0f3ccd06f6dad56ca72833d66b1d84) >--- > python/samba/tests/krb5/kdc_base_test.py | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 8a5e12bbed4..87160f675ae 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -610,7 +610,8 @@ class KDCBaseTest(RawKerberosTest): > > def get_cached_creds(self, *, > machine_account, >- opts=None): >+ opts=None, >+ use_cache=True): > if opts is None: > opts = {} > >@@ -638,9 +639,13 @@ class KDCBaseTest(RawKerberosTest): > > cache_key = tuple(sorted(account_opts.items())) > >- creds = self.account_cache.get(cache_key) >- if creds is None: >- creds = self.create_account_opts(**account_opts) >+ if use_cache: >+ creds = self.account_cache.get(cache_key) >+ if creds is not None: >+ return creds >+ >+ creds = self.create_account_opts(**account_opts) >+ if use_cache: > self.account_cache[cache_key] = creds > > return creds >-- >2.25.1 > > >From ed7ee40b772e57e90f1dfbd75258f0028e8fed57 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:40:39 +1300 >Subject: [PATCH 339/686] tests/krb5: Fix duplicate account creation > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 3dede18c5a1801023a60cc55b99022b033428350) >--- > .../krb5/ms_kile_client_principal_lookup_tests.py | 13 +++++-------- > 1 file changed, 5 insertions(+), 8 deletions(-) > >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index 501bc4892f4..2ee3d4a2a83 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -150,18 +150,15 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # Create a machine account for the test. > # > samdb = self.get_samdb() >- user_name = "mskilemac" >- (mc, dn) = self.create_account(samdb, user_name, machine_account=True) >- realm = mc.get_realm().lower() >- > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, dn) = self.create_account(samdb, mach_name, machine_account=True) >+ realm = mc.get_realm().lower() > > # Do the initial AS-REQ, should get a pre-authentication required > # response > etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) > cname = self.PrincipalName_create( >- name_type=NT_PRINCIPAL, names=[user_name]) >+ name_type=NT_PRINCIPAL, names=[mach_name]) > sname = self.PrincipalName_create( > name_type=NT_SRV_INST, names=["krbtgt", realm]) > >@@ -180,7 +177,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > key = self.EncryptionKey_import(enc_part2['key']) > cname = self.PrincipalName_create( > name_type=NT_PRINCIPAL, >- names=[user_name]) >+ names=[mach_name]) > sname = self.PrincipalName_create( > name_type=NT_PRINCIPAL, > names=[mc.get_username()]) >@@ -197,7 +194,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # check the crealm and cname > cname = enc_part['cname'] > self.assertEqual(NT_PRINCIPAL, cname['name-type']) >- self.assertEqual(user_name.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(mach_name.encode('UTF8'), cname['name-string'][0]) > self.assertEqual(realm.upper().encode('UTF8'), enc_part['crealm']) > > def test_nt_principal_step_3(self): >-- >2.25.1 > > >From 5afda2910fc40d2790bb31dfe6c6cfb563b6e986 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 16:06:58 +1300 >Subject: [PATCH 340/686] s4:kdc: Simplify samba_kdc_update_pac_blob() to take > ldb_context as parameter > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7149eeaceb426470b1b8181749d2d081c2fb83a4) >--- > source4/kdc/mit_samba.c | 7 +------ > source4/kdc/pac-glue.c | 5 ++--- > source4/kdc/pac-glue.h | 3 +-- > source4/kdc/wdc-samba4.c | 2 +- > 4 files changed, 5 insertions(+), 12 deletions(-) > >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index 54dcd545ea1..2936fe2d18a 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -482,7 +482,6 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > DATA_BLOB *deleg_blob = NULL; > struct samba_kdc_entry *client_skdc_entry = NULL; > struct samba_kdc_entry *krbtgt_skdc_entry = NULL; >- struct samba_kdc_entry *server_skdc_entry = NULL; > bool is_in_db = false; > bool is_untrusted = false; > size_t num_types = 0; >@@ -513,9 +512,6 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > if (server == NULL) { > return EINVAL; > } >- server_skdc_entry = >- talloc_get_type_abort(server->e_data, >- struct samba_kdc_entry); > > if (krbtgt == NULL) { > return EINVAL; >@@ -575,8 +571,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > > nt_status = samba_kdc_update_pac_blob(tmp_ctx, > context, >- krbtgt_skdc_entry, >- server_skdc_entry, >+ krbtgt_skdc_entry->kdc_db_ctx->samdb, > *pac, > pac_blob, > pac_srv_sig, >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index 126001cb718..b4eeeb65243 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -747,8 +747,7 @@ NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx, > > NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > krb5_context context, >- struct samba_kdc_entry *krbtgt, >- struct samba_kdc_entry *server, >+ struct ldb_context *samdb, > const krb5_pac pac, DATA_BLOB *pac_blob, > struct PAC_SIGNATURE_DATA *pac_srv_sig, > struct PAC_SIGNATURE_DATA *pac_kdc_sig) >@@ -768,7 +767,7 @@ NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > * as the token might be generated by a trusted domain. > */ > nt_status = authsam_update_user_info_dc(mem_ctx, >- krbtgt->kdc_db_ctx->samdb, >+ samdb, > user_info_dc); > if (!NT_STATUS_IS_OK(nt_status)) { > return nt_status; >diff --git a/source4/kdc/pac-glue.h b/source4/kdc/pac-glue.h >index 2eb7fd3b755..7b51b0389f5 100644 >--- a/source4/kdc/pac-glue.h >+++ b/source4/kdc/pac-glue.h >@@ -51,8 +51,7 @@ NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx, > > NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > krb5_context context, >- struct samba_kdc_entry *krbtgt, >- struct samba_kdc_entry *server, >+ struct ldb_context *samdb, > const krb5_pac pac, DATA_BLOB *pac_blob, > struct PAC_SIGNATURE_DATA *pac_srv_sig, > struct PAC_SIGNATURE_DATA *pac_kdc_sig); >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index a7d8de1f417..68c8a8aa572 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -186,7 +186,7 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > } > > nt_status = samba_kdc_update_pac_blob(mem_ctx, context, >- krbtgt_skdc_entry, p, >+ krbtgt_skdc_entry->kdc_db_ctx->samdb, > *pac, pac_blob, > pac_srv_sig, pac_kdc_sig); > if (!NT_STATUS_IS_OK(nt_status)) { >-- >2.25.1 > > >From 33318759723434f3044674975fe337029eb1760e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 6 Oct 2021 16:40:21 +1300 >Subject: [PATCH 341/686] s4:kdc: Fix debugging messages > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit c14c61748b5a2d2a4f4de00615c476fcf381309e) >--- > source4/kdc/wdc-samba4.c | 48 ++++++++++++++++++++-------------------- > 1 file changed, 24 insertions(+), 24 deletions(-) > >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index 68c8a8aa572..037db40ce46 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -238,10 +238,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > switch (types[i]) { > case PAC_TYPE_LOGON_INFO: > if (logon_info_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("logon info type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ logon_info_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >@@ -250,10 +250,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > break; > case PAC_TYPE_CONSTRAINED_DELEGATION: > if (delegation_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("constrained delegation type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ delegation_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >@@ -262,10 +262,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > break; > case PAC_TYPE_LOGON_NAME: > if (logon_name_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("logon name type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ logon_name_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >@@ -274,10 +274,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > break; > case PAC_TYPE_UPN_DNS_INFO: > if (upn_dns_info_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("upn dns info type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ upn_dns_info_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >@@ -286,10 +286,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > break; > case PAC_TYPE_SRV_CHECKSUM: > if (srv_checksum_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("server checksum type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ srv_checksum_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >@@ -298,10 +298,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > break; > case PAC_TYPE_KDC_CHECKSUM: > if (kdc_checksum_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("kdc checksum type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ kdc_checksum_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >-- >2.25.1 > > >From 99b1e7b419bc7ab1430f90587b70b3ac529ada1b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:42:29 +1300 >Subject: [PATCH 342/686] s4/torture: Expect ticket checksum PAC buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org backported from commit d5002c34ce1ffef795dc83af3175ca0e04d17dfd > due to missing tests in Samba 4.14 that crashed the MIT KDC] > >[jsutton@samba.org Backported to adapt to missing netlogon_validate_pac > from d6a4eea5fd284755d181426dba84ddd5c1ba9769 and test_S4U2Proxy from > 90bdaaf09d9c5595170272bd0bfebaac0a90ae01] >--- > selftest/knownfail_heimdal_kdc | 41 ++++++++++++++++++++++++++++++++ > selftest/knownfail_mit_kdc | 41 ++++++++++++++++++++++++++++++++ > source4/torture/rpc/remote_pac.c | 8 ++++++- > 3 files changed, 89 insertions(+), 1 deletion(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 0b8e83f1f3f..31572067ad4 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -154,3 +154,44 @@ > # RODC tests > # > ^samba.tests.krb5.rodc_tests.samba.tests.krb5.rodc_tests.RodcKerberosTests.test_rodc_ticket_signature >+# >+# PAC tests >+# >+^netr-bdc-arcfour.verify-sig-arcfour >+^netr-bdc-arcfour.verify-sig-arcfour >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc:local >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc_ntvfs:local >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 4e0b20c5c80..09efbc7b590 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -329,3 +329,44 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_fast_no_etypes.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_sname.ad_dc >+# >+# PAC tests >+# >+^netr-bdc-arcfour.verify-sig-arcfour >+^netr-bdc-arcfour.verify-sig-arcfour >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc:local >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc_ntvfs:local >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c >index 3ada0704612..3e02245d7ba 100644 >--- a/source4/torture/rpc/remote_pac.c >+++ b/source4/torture/rpc/remote_pac.c >@@ -280,7 +280,7 @@ static bool test_PACVerify(struct torture_context *tctx, > (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); > torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_pull_struct_blob of PAC_DATA structure failed"); > >- num_pac_buffers = 4; >+ num_pac_buffers = 5; > if (expect_pac_upn_dns_info) { > num_pac_buffers += 1; > } >@@ -331,6 +331,12 @@ static bool test_PACVerify(struct torture_context *tctx, > pac_buf->info != NULL, > "PAC_TYPE_KDC_CHECKSUM info"); > >+ pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_TICKET_CHECKSUM); >+ torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_TICKET_CHECKSUM"); >+ torture_assert(tctx, >+ pac_buf->info != NULL, >+ "PAC_TYPE_TICKET_CHECKSUM info"); >+ > pac_wrapped_struct.ChecksumLength = pac_data->pac_srv_sig->signature.length; > pac_wrapped_struct.SignatureType = pac_data->pac_kdc_sig->type; > pac_wrapped_struct.SignatureLength = pac_data->pac_kdc_sig->signature.length; >-- >2.25.1 > > >From 204c2cfa4b9993e375ce40b0775a26828a8f901a Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Mon, 28 Dec 2020 22:07:10 +0200 >Subject: [PATCH 343/686] kdc: remove KRB5SignedPath, to be replaced with PAC > >KRB5SignedPath was a Heimdal-specific authorization data element used to >protect the authenticity of evidence tickets when used in constrained >delegation (without a Windows PAC). > >Remove this, to be replaced with the Windows PAC which itself now supports >signing the entire ticket in the TGS key. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >[jsutton@samba.org Backported from Heimdal commit > bb1d8f2a8c2545bccdf2c9179ce9259bf1050086 > - Removed tests > - Removed auditing hook (only present in Heimdal master) > - Added knownfails >] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ccabc7f16cca5b0dcb46233e934e708167f1071b) >--- > selftest/knownfail_heimdal_kdc | 6 + > source4/heimdal/kdc/kerberos5.c | 12 -- > source4/heimdal/kdc/krb5tgs.c | 297 ----------------------------- > source4/heimdal/lib/asn1/krb5.asn1 | 21 -- > 4 files changed, 6 insertions(+), 330 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 31572067ad4..f0263133eee 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -130,6 +130,7 @@ > # > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_missing_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_service_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_zeroed_client_checksum >@@ -195,3 +196,8 @@ > ^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc > ^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc > ^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >+# >+# The lack of KRB5SignedPath means we no longer return >+# KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case >+# >+^samba4.krb5.kdc with machine account.as-req-pac-request.fl2000dc:local >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index 0fa336e871c..a400b21a652 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -1744,18 +1744,6 @@ _kdc_as_rep(krb5_context context, > _kdc_log_timestamp(context, config, "AS-REQ", et.authtime, et.starttime, > et.endtime, et.renew_till); > >- /* do this as the last thing since this signs the EncTicketPart */ >- ret = _kdc_add_KRB5SignedPath(context, >- config, >- server, >- setype, >- client->entry.principal, >- NULL, >- NULL, >- &et); >- if (ret) >- goto out; >- > log_as_req(context, config, reply_key->keytype, setype, b); > > ret = _kdc_encode_reply(context, config, >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index ef337ea4faf..fcdebede3a9 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -47,230 +47,6 @@ get_krbtgt_realm(const PrincipalName *p) > return NULL; > } > >-/* >- * The KDC might add a signed path to the ticket authorization data >- * field. This is to avoid server impersonating clients and the >- * request constrained delegation. >- * >- * This is done by storing a KRB5_AUTHDATA_IF_RELEVANT with a single >- * entry of type KRB5SignedPath. >- */ >- >-static krb5_error_code >-find_KRB5SignedPath(krb5_context context, >- const AuthorizationData *ad, >- krb5_data *data) >-{ >- AuthorizationData child; >- krb5_error_code ret; >- int pos; >- >- if (ad == NULL || ad->len == 0) >- return KRB5KDC_ERR_PADATA_TYPE_NOSUPP; >- >- pos = ad->len - 1; >- >- if (ad->val[pos].ad_type != KRB5_AUTHDATA_IF_RELEVANT) >- return KRB5KDC_ERR_PADATA_TYPE_NOSUPP; >- >- ret = decode_AuthorizationData(ad->val[pos].ad_data.data, >- ad->val[pos].ad_data.length, >- &child, >- NULL); >- if (ret) { >- krb5_set_error_message(context, ret, "Failed to decode " >- "IF_RELEVANT with %d", ret); >- return ret; >- } >- >- if (child.len != 1) { >- free_AuthorizationData(&child); >- return KRB5KDC_ERR_PADATA_TYPE_NOSUPP; >- } >- >- if (child.val[0].ad_type != KRB5_AUTHDATA_SIGNTICKET) { >- free_AuthorizationData(&child); >- return KRB5KDC_ERR_PADATA_TYPE_NOSUPP; >- } >- >- if (data) >- ret = der_copy_octet_string(&child.val[0].ad_data, data); >- free_AuthorizationData(&child); >- return ret; >-} >- >-krb5_error_code >-_kdc_add_KRB5SignedPath(krb5_context context, >- krb5_kdc_configuration *config, >- hdb_entry_ex *krbtgt, >- krb5_enctype enctype, >- krb5_principal client, >- krb5_const_principal server, >- krb5_principals principals, >- EncTicketPart *tkt) >-{ >- krb5_error_code ret; >- KRB5SignedPath sp; >- krb5_data data; >- krb5_crypto crypto = NULL; >- size_t size = 0; >- >- if (server && principals) { >- ret = add_Principals(principals, server); >- if (ret) >- return ret; >- } >- >- { >- KRB5SignedPathData spd; >- >- spd.client = client; >- spd.authtime = tkt->authtime; >- spd.delegated = principals; >- spd.method_data = NULL; >- >- ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length, >- &spd, &size, ret); >- if (ret) >- return ret; >- if (data.length != size) >- krb5_abortx(context, "internal asn.1 encoder error"); >- } >- >- { >- Key *key; >- ret = hdb_enctype2key(context, &krbtgt->entry, enctype, &key); >- if (ret == 0) >- ret = krb5_crypto_init(context, &key->key, 0, &crypto); >- if (ret) { >- free(data.data); >- return ret; >- } >- } >- >- /* >- * Fill in KRB5SignedPath >- */ >- >- sp.etype = enctype; >- sp.delegated = principals; >- sp.method_data = NULL; >- >- ret = krb5_create_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 0, >- data.data, data.length, &sp.cksum); >- krb5_crypto_destroy(context, crypto); >- free(data.data); >- if (ret) >- return ret; >- >- ASN1_MALLOC_ENCODE(KRB5SignedPath, data.data, data.length, &sp, &size, ret); >- free_Checksum(&sp.cksum); >- if (ret) >- return ret; >- if (data.length != size) >- krb5_abortx(context, "internal asn.1 encoder error"); >- >- >- /* >- * Add IF-RELEVANT(KRB5SignedPath) to the last slot in >- * authorization data field. >- */ >- >- ret = _kdc_tkt_add_if_relevant_ad(context, tkt, >- KRB5_AUTHDATA_SIGNTICKET, &data); >- krb5_data_free(&data); >- >- return ret; >-} >- >-static krb5_error_code >-check_KRB5SignedPath(krb5_context context, >- krb5_kdc_configuration *config, >- hdb_entry_ex *krbtgt, >- krb5_principal cp, >- EncTicketPart *tkt, >- krb5_principals *delegated, >- int *signedpath) >-{ >- krb5_error_code ret; >- krb5_data data; >- krb5_crypto crypto = NULL; >- >- if (delegated) >- *delegated = NULL; >- >- ret = find_KRB5SignedPath(context, tkt->authorization_data, &data); >- if (ret == 0) { >- KRB5SignedPathData spd; >- KRB5SignedPath sp; >- size_t size = 0; >- >- ret = decode_KRB5SignedPath(data.data, data.length, &sp, NULL); >- krb5_data_free(&data); >- if (ret) >- return ret; >- >- spd.client = cp; >- spd.authtime = tkt->authtime; >- spd.delegated = sp.delegated; >- spd.method_data = sp.method_data; >- >- ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length, >- &spd, &size, ret); >- if (ret) { >- free_KRB5SignedPath(&sp); >- return ret; >- } >- if (data.length != size) >- krb5_abortx(context, "internal asn.1 encoder error"); >- >- { >- Key *key; >- ret = hdb_enctype2key(context, &krbtgt->entry, sp.etype, &key); >- if (ret == 0) >- ret = krb5_crypto_init(context, &key->key, 0, &crypto); >- if (ret) { >- free(data.data); >- free_KRB5SignedPath(&sp); >- return ret; >- } >- } >- ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, >- data.data, data.length, >- &sp.cksum); >- krb5_crypto_destroy(context, crypto); >- free(data.data); >- if (ret) { >- free_KRB5SignedPath(&sp); >- kdc_log(context, config, 5, >- "KRB5SignedPath not signed correctly, not marking as signed"); >- return 0; >- } >- >- if (delegated && sp.delegated) { >- >- *delegated = malloc(sizeof(*sp.delegated)); >- if (*delegated == NULL) { >- free_KRB5SignedPath(&sp); >- return ENOMEM; >- } >- >- ret = copy_Principals(*delegated, sp.delegated); >- if (ret) { >- free_KRB5SignedPath(&sp); >- free(*delegated); >- *delegated = NULL; >- return ret; >- } >- } >- free_KRB5SignedPath(&sp); >- >- *signedpath = 1; >- } >- >- return 0; >-} >- > /* > * > */ >@@ -738,7 +514,6 @@ tgs_make_reply(krb5_context context, > krb5_principal client_principal, > hdb_entry_ex *krbtgt, > krb5_enctype krbtgt_etype, >- krb5_principals spp, > const krb5_data *rspac, > const METHOD_DATA *enc_pa_data, > const char **e_text, >@@ -903,20 +678,6 @@ tgs_make_reply(krb5_context context, > goto out; > } > } >- >- /* Filter out type KRB5SignedPath */ >- ret = find_KRB5SignedPath(context, et.authorization_data, NULL); >- if (ret == 0) { >- if (et.authorization_data->len == 1) { >- free_AuthorizationData(et.authorization_data); >- free(et.authorization_data); >- et.authorization_data = NULL; >- } else { >- AuthorizationData *ad = et.authorization_data; >- free_AuthorizationDataElement(&ad->val[ad->len - 1]); >- ad->len--; >- } >- } > } > > ret = krb5_copy_keyblock_contents(context, sessionkey, &et.key); >@@ -945,24 +706,6 @@ tgs_make_reply(krb5_context context, > _kdc_log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime, > et.endtime, et.renew_till); > >- /* Don't sign cross realm tickets, they can't be checked anyway */ >- { >- char *r = get_krbtgt_realm(&ek.sname); >- >- if (r == NULL || strcmp(r, ek.srealm) == 0) { >- ret = _kdc_add_KRB5SignedPath(context, >- config, >- krbtgt, >- krbtgt_etype, >- client_principal, >- NULL, >- spp, >- &et); >- if (ret) >- goto out; >- } >- } >- > if (enc_pa_data->len) { > rep.padata = calloc(1, sizeof(*rep.padata)); > if (rep.padata == NULL) { >@@ -1517,7 +1260,6 @@ tgs_build_reply(krb5_context context, > HDB *clientdb, *s4u2self_impersonated_clientdb; > krb5_realm ref_realm = NULL; > EncTicketPart *tgt = &ticket->ticket; >- krb5_principals spp = NULL; > const EncryptionKey *ekey; > krb5_keyblock sessionkey; > krb5_kvno kvno; >@@ -1891,23 +1633,6 @@ server_lookup: > goto out; > } > >- /* also check the krbtgt for signature */ >- ret = check_KRB5SignedPath(context, >- config, >- krbtgt, >- cp, >- tgt, >- &spp, >- &signedpath); >- if (ret) { >- const char *msg = krb5_get_error_message(context, ret); >- kdc_log(context, config, 0, >- "KRB5SignedPath check failed for %s (%s) from %s with %s", >- spn, cpn, from, msg); >- krb5_free_error_message(context, msg); >- goto out; >- } >- > /* > * Process request > */ >@@ -2183,27 +1908,6 @@ server_lookup: > goto out; > } > >- /* >- * Check that the KDC issued the user's ticket. >- */ >- ret = check_KRB5SignedPath(context, >- config, >- krbtgt, >- cp, >- &adtkt, >- NULL, >- &ad_signedpath); >- if (ret) { >- const char *msg = krb5_get_error_message(context, ret); >- kdc_log(context, config, 0, >- "KRB5SignedPath check from service %s failed " >- "for delegation to %s for client %s (%s)" >- "from %s failed with %s", >- spn, tpn, dpn, cpn, from, msg); >- krb5_free_error_message(context, msg); >- goto out; >- } >- > if (!ad_signedpath) { > ret = KRB5KDC_ERR_BADOPTION; > kdc_log(context, config, 0, >@@ -2301,7 +2005,6 @@ server_lookup: > cp, > krbtgt_out, > krbtgt_etype, >- spp, > &rspac, > &enc_pa_data, > e_text, >diff --git a/source4/heimdal/lib/asn1/krb5.asn1 b/source4/heimdal/lib/asn1/krb5.asn1 >index c2f40c0ecd6..155d51d4ac8 100644 >--- a/source4/heimdal/lib/asn1/krb5.asn1 >+++ b/source4/heimdal/lib/asn1/krb5.asn1 >@@ -43,9 +43,6 @@ EXPORTS > KRB-PRIV, > KRB-SAFE, > KRB-SAFE-BODY, >- KRB5SignedPath, >- KRB5SignedPathData, >- KRB5SignedPathPrincipals, > KerberosString, > KerberosTime, > KrbCredInfo, >@@ -713,24 +710,6 @@ PA-S4U2Self ::= SEQUENCE { > auth[3] GeneralString > } > >--- never encoded on the wire, just used to checksum over >-KRB5SignedPathData ::= SEQUENCE { >- client[0] Principal OPTIONAL, >- authtime[1] KerberosTime, >- delegated[2] Principals OPTIONAL, >- method_data[3] METHOD-DATA OPTIONAL >-} >- >-KRB5SignedPath ::= SEQUENCE { >- -- DERcoded KRB5SignedPathData >- -- krbtgt key (etype), KeyUsage = XXX >- etype[0] ENCTYPE, >- cksum[1] Checksum, >- -- srvs delegated though >- delegated[2] Principals OPTIONAL, >- method_data[3] METHOD-DATA OPTIONAL >-} >- > AD-LoginAlias ::= SEQUENCE { -- ad-type number TBD -- > login-alias [0] PrincipalName, > checksum [1] Checksum >-- >2.25.1 > > >From 66a63301460afee62f5eec4b719bc5dbb2422494 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Fri, 13 Aug 2021 12:44:37 +0300 >Subject: [PATCH 344/686] kdc: sign ticket using Windows PAC > >Split Windows PAC signing and verification logic, as the signing has to be when >the ticket is ready. > >Create sign and verify the PAC KDC signature if the plugin did not, allowing >for S4U2Proxy to work, instead of KRB5SignedPath. > >Use the header key to verify PAC server signature, as the same key used to >encrypt/decrypt the ticket should be used for PAC server signature, like U2U >tickets are signed witht the tgt session-key and not with the longterm key, >and so krbtgt should be no different and the header key should be used. > >Lookup the delegated client in DB instead of passing the delegator DB entry. > >Add PAC ticket-signatures and related functions. > >Note: due to the change from KRB5SignedPath to PAC, S4U2Proxy requests >against new KDC will not work if the evidence ticket was acquired from >an old KDC, and vide versa. > >Closes: #767 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >[jsutton@samba.org Backported from Heimdal commit > 2ffaba9401d19c718764d4bd24180960290238e9 > - Removed tests > - Adapted to Samba's version of Heimdal > - Addressed build failures with -O3 > - Added knownfails >] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org backported from commit d7b03394a9012960d71489e775d40d10fd6f5232 > due to conflicts in knownfail due to missing tests that crash the > MIT KDC] >--- > selftest/knownfail_heimdal_kdc | 54 +-- > source4/heimdal/kdc/kerberos5.c | 69 +--- > source4/heimdal/kdc/krb5tgs.c | 354 +++++++++--------- > source4/heimdal/kdc/windc.c | 15 +- > source4/heimdal/kdc/windc_plugin.h | 5 +- > source4/heimdal/lib/krb5/authdata.c | 124 +++++++ > source4/heimdal/lib/krb5/pac.c | 376 ++++++++++++++++++-- > source4/heimdal/lib/krb5/version-script.map | 5 + > source4/heimdal_build/wscript_build | 2 +- > source4/selftest/tests.py | 2 +- > 10 files changed, 687 insertions(+), 319 deletions(-) > create mode 100644 source4/heimdal/lib/krb5/authdata.c > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index f0263133eee..4ec682c01d0 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -1,7 +1,7 @@ > # > # We expect all the MIT specific compatability tests to fail on heimdal > # kerberos >-^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_mit_(?!ticket_signature) >+^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_mit_ > # > # Heimdal currently fails the following MS-KILE client principal lookup > # tests >@@ -122,14 +122,9 @@ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_sname.ad_dc > # >-# Heimdal currently does not generate ticket signatures >-# >-^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_heimdal_ticket_signature >-# > # S4U tests > # > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_missing_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_service_checksum >@@ -143,60 +138,13 @@ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_unkeyed_service_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_service_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_client_not_delegated > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_forwardable >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_forwardable > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_empty_allowed >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_nonempty_allowed >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_trusted_empty_allowed >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_trusted_nonempty_allowed >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_without_forwardable > # > # RODC tests > # > ^samba.tests.krb5.rodc_tests.samba.tests.krb5.rodc_tests.RodcKerberosTests.test_rodc_ticket_signature > # >-# PAC tests >-# >-^netr-bdc-arcfour.verify-sig-arcfour >-^netr-bdc-arcfour.verify-sig-arcfour >-^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc:local >-^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc_ntvfs:local >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >-# > # The lack of KRB5SignedPath means we no longer return > # KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case > # >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index a400b21a652..7b17d2539ce 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -1712,6 +1712,7 @@ _kdc_as_rep(krb5_context context, > if (send_pac_p(context, req)) { > krb5_pac p = NULL; > krb5_data data; >+ uint16_t rodc_id; > > ret = _kdc_pac_generate(context, client, pk_reply_key, &p); > if (ret) { >@@ -1720,10 +1721,13 @@ _kdc_as_rep(krb5_context context, > goto out; > } > if (p != NULL) { >+ rodc_id = server->entry.kvno >> 16; >+ > ret = _krb5_pac_sign(context, p, et.authtime, > client->entry.principal, > &skey->key, /* Server key */ > &skey->key, /* FIXME: should be krbtgt key */ >+ rodc_id, > &data); > krb5_pac_free(context, p); > if (ret) { >@@ -1732,9 +1736,7 @@ _kdc_as_rep(krb5_context context, > goto out; > } > >- ret = _kdc_tkt_add_if_relevant_ad(context, &et, >- KRB5_AUTHDATA_WIN2K_PAC, >- &data); >+ ret = _kdc_tkt_insert_pac(context, &et, &data); > krb5_data_free(&data); > if (ret) > goto out; >@@ -1888,64 +1890,3 @@ prepare_enc_data(krb5_context context, > > return TRUE; > } >- >-/* >- * Add the AuthorizationData `data´ of `type´ to the last element in >- * the sequence of authorization_data in `tkt´ wrapped in an IF_RELEVANT >- */ >- >-krb5_error_code >-_kdc_tkt_add_if_relevant_ad(krb5_context context, >- EncTicketPart *tkt, >- int type, >- const krb5_data *data) >-{ >- krb5_error_code ret; >- size_t size = 0; >- >- if (tkt->authorization_data == NULL) { >- tkt->authorization_data = calloc(1, sizeof(*tkt->authorization_data)); >- if (tkt->authorization_data == NULL) { >- krb5_set_error_message(context, ENOMEM, "out of memory"); >- return ENOMEM; >- } >- } >- >- /* add the entry to the last element */ >- { >- AuthorizationData ad = { 0, NULL }; >- AuthorizationDataElement ade; >- >- ade.ad_type = type; >- ade.ad_data = *data; >- >- ret = add_AuthorizationData(&ad, &ade); >- if (ret) { >- krb5_set_error_message(context, ret, "add AuthorizationData failed"); >- return ret; >- } >- >- ade.ad_type = KRB5_AUTHDATA_IF_RELEVANT; >- >- ASN1_MALLOC_ENCODE(AuthorizationData, >- ade.ad_data.data, ade.ad_data.length, >- &ad, &size, ret); >- free_AuthorizationData(&ad); >- if (ret) { >- krb5_set_error_message(context, ret, "ASN.1 encode of " >- "AuthorizationData failed"); >- return ret; >- } >- if (ade.ad_data.length != size) >- krb5_abortx(context, "internal asn.1 encoder error"); >- >- ret = add_AuthorizationData(tkt->authorization_data, &ade); >- der_free_octet_string(&ade.ad_data); >- if (ret) { >- krb5_set_error_message(context, ret, "add AuthorizationData failed"); >- return ret; >- } >- } >- >- return 0; >-} >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index fcdebede3a9..e8bbb42465f 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -59,85 +59,64 @@ check_PAC(krb5_context context, > hdb_entry_ex *client, > hdb_entry_ex *server, > hdb_entry_ex *krbtgt, >+ hdb_entry_ex *ticket_server, > const EncryptionKey *server_check_key, >- const EncryptionKey *server_sign_key, >- const EncryptionKey *krbtgt_sign_key, >+ const EncryptionKey *krbtgt_check_key, > EncTicketPart *tkt, >- krb5_data *rspac, >- int *signedpath) >+ krb5_boolean *kdc_issued, >+ krb5_pac *ppac) > { >- AuthorizationData *ad = tkt->authorization_data; >- unsigned i, j; >+ krb5_pac pac = NULL; > krb5_error_code ret; >+ krb5_boolean signedticket; > >- if (ad == NULL || ad->len == 0) >- return 0; >- >- for (i = 0; i < ad->len; i++) { >- AuthorizationData child; >- >- if (ad->val[i].ad_type != KRB5_AUTHDATA_IF_RELEVANT) >- continue; >- >- ret = decode_AuthorizationData(ad->val[i].ad_data.data, >- ad->val[i].ad_data.length, >- &child, >- NULL); >- if (ret) { >- krb5_set_error_message(context, ret, "Failed to decode " >- "IF_RELEVANT with %d", ret); >- return ret; >- } >- for (j = 0; j < child.len; j++) { >- >- if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) { >- int signed_pac = 0; >- krb5_pac pac; >- >- /* Found PAC */ >- ret = krb5_pac_parse(context, >- child.val[j].ad_data.data, >- child.val[j].ad_data.length, >- &pac); >- free_AuthorizationData(&child); >- if (ret) >- return ret; >+ *kdc_issued = FALSE; >+ *ppac = NULL; > >- ret = krb5_pac_verify(context, pac, tkt->authtime, >- client_principal, >- server_check_key, NULL); >- if (ret) { >- krb5_pac_free(context, pac); >- return ret; >- } >+ ret = _krb5_kdc_pac_ticket_parse(context, tkt, &signedticket, &pac); >+ if (ret || pac == NULL) >+ return ret; > >- ret = _kdc_pac_verify(context, client_principal, >- delegated_proxy_principal, >- client, server, krbtgt, &pac, &signed_pac); >- if (ret) { >- krb5_pac_free(context, pac); >- return ret; >- } >+ /* Verify the server signature. */ >+ ret = krb5_pac_verify(context, pac, tkt->authtime, client_principal, >+ server_check_key, NULL); >+ if (ret) { >+ krb5_pac_free(context, pac); >+ return ret; >+ } > >- /* >- * Only re-sign PAC if we could verify it with the PAC >- * function. The no-verify case happens when we get in >- * a PAC from cross realm from a Windows domain and >- * that there is no PAC verification function. >- */ >- if (signed_pac) { >- *signedpath = 1; >- ret = _krb5_pac_sign(context, pac, tkt->authtime, >- client_principal, >- server_sign_key, krbtgt_sign_key, rspac); >- } >+ /* Verify the KDC signatures. */ >+ ret = _kdc_pac_verify(context, client_principal, delegated_proxy_principal, >+ client, server, krbtgt, &pac); >+ if (ret == KRB5_PLUGIN_NO_HANDLE) { >+ /* >+ * We can't verify the KDC signatures if the ticket was issued by >+ * another realm's KDC. >+ */ >+ if (krb5_realm_compare(context, server->entry.principal, >+ ticket_server->entry.principal)) { >+ ret = krb5_pac_verify(context, pac, 0, NULL, NULL, >+ krbtgt_check_key); >+ if (ret) { > krb5_pac_free(context, pac); >- > return ret; > } > } >- free_AuthorizationData(&child); >+ /* Discard the PAC if the plugin didn't handle it */ >+ krb5_pac_free(context, pac); >+ ret = krb5_pac_init(context, &pac); >+ if (ret) >+ return ret; >+ } else if (ret) { >+ krb5_pac_free(context, pac); >+ return ret; > } >+ >+ *kdc_issued = signedticket || >+ krb5_principal_is_krbtgt(context, >+ ticket_server->entry.principal); >+ *ppac = pac; >+ > return 0; > } > >@@ -499,11 +478,12 @@ static krb5_error_code > tgs_make_reply(krb5_context context, > krb5_kdc_configuration *config, > KDC_REQ_BODY *b, >- krb5_const_principal tgt_name, >+ krb5_principal tgt_name, > const EncTicketPart *tgt, > const krb5_keyblock *replykey, > int rk_is_subkey, > const EncryptionKey *serverkey, >+ const EncryptionKey *krbtgtkey, > const krb5_keyblock *sessionkey, > krb5_kvno kvno, > AuthorizationData *auth_data, >@@ -513,8 +493,9 @@ tgs_make_reply(krb5_context context, > hdb_entry_ex *client, > krb5_principal client_principal, > hdb_entry_ex *krbtgt, >- krb5_enctype krbtgt_etype, >- const krb5_data *rspac, >+ krb5_pac mspac, >+ uint16_t rodc_id, >+ krb5_boolean add_ticket_sig, > const METHOD_DATA *enc_pa_data, > const char **e_text, > krb5_data *reply) >@@ -647,17 +628,6 @@ tgs_make_reply(krb5_context context, > if (!server->entry.flags.proxiable) > et.flags.proxiable = 0; > >- if(rspac->length) { >- /* >- * No not need to filter out the any PAC from the >- * auth_data since it's signed by the KDC. >- */ >- ret = _kdc_tkt_add_if_relevant_ad(context, &et, >- KRB5_AUTHDATA_WIN2K_PAC, rspac); >- if (ret) >- goto out; >- } >- > if (auth_data) { > unsigned int i = 0; > >@@ -724,6 +694,11 @@ tgs_make_reply(krb5_context context, > is_weak = 1; > } > >+ /* The PAC should be the last change to the ticket. */ >+ ret = _krb5_kdc_pac_sign_ticket(context, mspac, tgt_name, serverkey, >+ krbtgtkey, rodc_id, add_ticket_sig, &et); >+ if (ret) >+ goto out; > > /* It is somewhat unclear where the etype in the following > encryption should come from. What we have is a session >@@ -910,6 +885,7 @@ tgs_parse_request(krb5_context context, > int **cusec, > AuthorizationData **auth_data, > krb5_keyblock **replykey, >+ Key **header_key, > int *rk_is_subkey) > { > static char failed[] = "<unparse_name failed>"; >@@ -1047,6 +1023,8 @@ tgs_parse_request(krb5_context context, > goto out; > } > >+ *header_key = tkey; >+ > { > krb5_authenticator auth; > >@@ -1236,6 +1214,57 @@ eout: > return ENOMEM; > } > >+static krb5_error_code >+db_fetch_client(krb5_context context, >+ krb5_kdc_configuration *config, >+ int flags, >+ krb5_principal cp, >+ const char *cpn, >+ const char *krbtgt_realm, >+ HDB **clientdb, >+ hdb_entry_ex **client_out) >+{ >+ krb5_error_code ret; >+ hdb_entry_ex *client = NULL; >+ >+ *client_out = NULL; >+ >+ ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | flags, >+ NULL, clientdb, &client); >+ if (ret == HDB_ERR_NOT_FOUND_HERE) { >+ /* >+ * This is OK, we are just trying to find out if they have >+ * been disabled or deleted in the meantime; missing secrets >+ * are OK. >+ */ >+ } else if (ret) { >+ /* >+ * If the client belongs to the same realm as our TGS, it >+ * should exist in the local database. >+ */ >+ const char *msg; >+ >+ if (strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) { >+ if (ret == HDB_ERR_NOENTRY) >+ ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; >+ kdc_log(context, config, 4, "Client no longer in database: %s", cpn); >+ return ret; >+ } >+ >+ msg = krb5_get_error_message(context, ret); >+ kdc_log(context, config, 4, "Client not found in database: %s", msg); >+ krb5_free_error_message(context, msg); >+ } else if (client->entry.flags.invalid || !client->entry.flags.client) { >+ kdc_log(context, config, 4, "Client has invalid bit set"); >+ _kdc_free_ent(context, client); >+ return KRB5KDC_ERR_POLICY; >+ } >+ >+ *client_out = client; >+ >+ return 0; >+} >+ > static krb5_error_code > tgs_build_reply(krb5_context context, > krb5_kdc_configuration *config, >@@ -1243,6 +1272,7 @@ tgs_build_reply(krb5_context context, > KDC_REQ_BODY *b, > hdb_entry_ex *krbtgt, > krb5_enctype krbtgt_etype, >+ Key *tkey_check, > const krb5_keyblock *replykey, > int rk_is_subkey, > krb5_ticket *ticket, >@@ -1263,7 +1293,9 @@ tgs_build_reply(krb5_context context, > const EncryptionKey *ekey; > krb5_keyblock sessionkey; > krb5_kvno kvno; >- krb5_data rspac; >+ krb5_pac mspac = NULL; >+ uint16_t rodc_id; >+ krb5_boolean add_ticket_sig = FALSE; > > hdb_entry_ex *krbtgt_out = NULL; > >@@ -1274,15 +1306,13 @@ tgs_build_reply(krb5_context context, > int nloop = 0; > EncTicketPart adtkt; > char opt_str[128]; >- int signedpath = 0; >+ krb5_boolean kdc_issued = FALSE; > >- Key *tkey_check; > Key *tkey_sign; > int flags = HDB_F_FOR_TGS_REQ; > > memset(&sessionkey, 0, sizeof(sessionkey)); > memset(&adtkt, 0, sizeof(adtkt)); >- krb5_data_zero(&rspac); > memset(&enc_pa_data, 0, sizeof(enc_pa_data)); > > s = b->sname; >@@ -1517,18 +1547,6 @@ server_lookup: > * backward. > */ > >- /* >- * Validate authoriation data >- */ >- >- ret = hdb_enctype2key(context, &krbtgt->entry, >- krbtgt_etype, &tkey_check); >- if(ret) { >- kdc_log(context, config, 0, >- "Failed to find key for krbtgt PAC check"); >- goto out; >- } >- > /* Now refetch the primary krbtgt, and get the current kvno (the > * sign check may have been on an old kvno, and the server may > * have been an incoming trust) */ >@@ -1589,41 +1607,14 @@ server_lookup: > goto out; > } > >- ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | flags, >- NULL, &clientdb, &client); >- if(ret == HDB_ERR_NOT_FOUND_HERE) { >- /* This is OK, we are just trying to find out if they have >- * been disabled or deleted in the meantime, missing secrets >- * is OK */ >- } else if(ret){ >- const char *krbtgt_realm, *msg; >- >- /* >- * If the client belongs to the same realm as our krbtgt, it >- * should exist in the local database. >- * >- */ >- >- krbtgt_realm = krb5_principal_get_realm(context, krbtgt_out->entry.principal); >- >- if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) { >- if (ret == HDB_ERR_NOENTRY) >- ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; >- kdc_log(context, config, 1, "Client no longer in database: %s", >- cpn); >- goto out; >- } >- >- msg = krb5_get_error_message(context, ret); >- kdc_log(context, config, 1, "Client not found in database: %s", msg); >- krb5_free_error_message(context, msg); >- } >+ ret = db_fetch_client(context, config, flags, cp, cpn, >+ krb5_principal_get_realm(context, krbtgt_out->entry.principal), >+ &clientdb, &client); >+ if (ret) >+ goto out; > >- ret = check_PAC(context, config, cp, NULL, >- client, server, krbtgt, >- &tkey_check->key, >- ekey, &tkey_sign->key, >- tgt, &rspac, &signedpath); >+ ret = check_PAC(context, config, cp, NULL, client, server, krbtgt, krbtgt, >+ &tkey_check->key, &tkey_check->key, tgt, &kdc_issued, &mspac); > if (ret) { > const char *msg = krb5_get_error_message(context, ret); > kdc_log(context, config, 0, >@@ -1743,27 +1734,15 @@ server_lookup: > goto out; > > /* If we were about to put a PAC into the ticket, we better fix it to be the right PAC */ >- if(rspac.data) { >- krb5_pac p = NULL; >- krb5_data_free(&rspac); >- ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, &p); >+ if (mspac) { >+ krb5_pac_free(context, mspac); >+ mspac = NULL; >+ ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, &mspac); > if (ret) { > kdc_log(context, config, 0, "PAC generation failed for -- %s", > tpn); > goto out; > } >- if (p != NULL) { >- ret = _krb5_pac_sign(context, p, ticket->ticket.authtime, >- s4u2self_impersonated_client->entry.principal, >- ekey, &tkey_sign->key, >- &rspac); >- krb5_pac_free(context, p); >- if (ret) { >- kdc_log(context, config, 0, "PAC signing failed for -- %s", >- tpn); >- goto out; >- } >- } > } > > /* >@@ -1806,22 +1785,25 @@ server_lookup: > && b->additional_tickets->len != 0 > && b->kdc_options.enc_tkt_in_skey == 0) > { >- int ad_signedpath = 0; >+ hdb_entry_ex *adclient = NULL; >+ krb5_boolean ad_kdc_issued = FALSE; > Key *clientkey; > Ticket *t; > > /* >- * Require that the KDC have issued the service's krbtgt (not >- * self-issued ticket with kimpersonate(1). >+ * We require that the service's krbtgt has a PAC. > */ >- if (!signedpath) { >+ if (mspac == NULL) { > ret = KRB5KDC_ERR_BADOPTION; > kdc_log(context, config, 0, >- "Constrained delegation done on service ticket %s/%s", >+ "Constrained delegation without PAC %s/%s", > cpn, spn); > goto out; > } > >+ krb5_pac_free(context, mspac); >+ mspac = NULL; >+ > t = &b->additional_tickets->val[0]; > > ret = hdb_enctype2key(context, &client->entry, >@@ -1885,19 +1867,32 @@ server_lookup: > goto out; > } > >- krb5_data_free(&rspac); >+ /* Try lookup the delegated client in DB */ >+ ret = db_fetch_client(context, config, flags, tp, tpn, >+ krb5_principal_get_realm(context, krbtgt_out->entry.principal), >+ NULL, &adclient); >+ if (ret) >+ goto out; >+ >+ if (adclient != NULL) { >+ ret = kdc_check_flags(context, config, >+ adclient, tpn, >+ server, spn, >+ FALSE); >+ if (ret) { >+ _kdc_free_ent(context, adclient); >+ goto out; >+ } >+ } > > /* >- * generate the PAC for the user. >- * > * TODO: pass in t->sname and t->realm and build > * a S4U_DELEGATION_INFO blob to the PAC. > */ >- ret = check_PAC(context, config, tp, dp, >- client, server, krbtgt, >- &clientkey->key, >- ekey, &tkey_sign->key, >- &adtkt, &rspac, &ad_signedpath); >+ ret = check_PAC(context, config, tp, dp, adclient, server, krbtgt, client, >+ &clientkey->key, &tkey_check->key, &adtkt, &ad_kdc_issued, &mspac); >+ if (adclient) >+ _kdc_free_ent(context, adclient); > if (ret) { > const char *msg = krb5_get_error_message(context, ret); > kdc_log(context, config, 0, >@@ -1908,13 +1903,12 @@ server_lookup: > goto out; > } > >- if (!ad_signedpath) { >+ if (mspac == NULL || !ad_kdc_issued) { > ret = KRB5KDC_ERR_BADOPTION; > kdc_log(context, config, 0, >- "Ticket not signed with PAC nor SignedPath service %s failed " >- "for delegation to %s for client %s (%s)" >- "from %s", >- spn, tpn, dpn, cpn, from); >+ "Ticket not signed with PAC; service %s failed for " >+ "for delegation to %s for client %s (%s) from %s; (%s).", >+ spn, tpn, dpn, cpn, from, mspac ? "Ticket unsigned" : "No PAC"); > goto out; > } > >@@ -1983,6 +1977,25 @@ server_lookup: > } > } > >+ /* >+ * Only add ticket signature if the requested server is not krbtgt, and >+ * either the header server is krbtgt or, in the case of renewal/validation >+ * if it was signed with PAC ticket signature and we verified it. >+ * Currently Heimdal only allows renewal of krbtgt anyway but that might >+ * change one day (see issue #763) so make sure to check for it. >+ */ >+ >+ if (kdc_issued && >+ !krb5_principal_is_krbtgt(context, server->entry.principal)) >+ add_ticket_sig = TRUE; >+ >+ /* >+ * Active-Directory implementations use the high part of the kvno as the >+ * read-only-dc identifier, we need to embed it in the PAC KDC signatures. >+ */ >+ >+ rodc_id = krbtgt_out->entry.kvno >> 16; >+ > /* > * > */ >@@ -1995,6 +2008,7 @@ server_lookup: > replykey, > rk_is_subkey, > ekey, >+ &tkey_sign->key, > &sessionkey, > kvno, > *auth_data, >@@ -2004,8 +2018,9 @@ server_lookup: > client, > cp, > krbtgt_out, >- krbtgt_etype, >- &rspac, >+ mspac, >+ rodc_id, >+ add_ticket_sig, > &enc_pa_data, > e_text, > reply); >@@ -2018,7 +2033,6 @@ out: > if (dpn) > free(dpn); > >- krb5_data_free(&rspac); > krb5_free_keyblock_contents(context, &sessionkey); > if(krbtgt_out) > _kdc_free_ent(context, krbtgt_out); >@@ -2043,6 +2057,9 @@ out: > > free_EncTicketPart(&adtkt); > >+ if (mspac) >+ krb5_pac_free(context, mspac); >+ > return ret; > } > >@@ -2063,6 +2080,7 @@ _kdc_tgs_rep(krb5_context context, > krb5_error_code ret; > int i = 0; > const PA_DATA *tgs_req; >+ Key *header_key = NULL; > > hdb_entry_ex *krbtgt = NULL; > krb5_ticket *ticket = NULL; >@@ -2100,6 +2118,7 @@ _kdc_tgs_rep(krb5_context context, > &csec, &cusec, > &auth_data, > &replykey, >+ &header_key, > &rk_is_subkey); > if (ret == HDB_ERR_NOT_FOUND_HERE) { > /* kdc_log() is called in tgs_parse_request() */ >@@ -2117,6 +2136,7 @@ _kdc_tgs_rep(krb5_context context, > &req->req_body, > krbtgt, > krbtgt_etype, >+ header_key, > replykey, > rk_is_subkey, > ticket, >diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c >index fb1c8a6a993..43dc89e2bc0 100644 >--- a/source4/heimdal/kdc/windc.c >+++ b/source4/heimdal/kdc/windc.c >@@ -77,8 +77,14 @@ _kdc_pac_generate(krb5_context context, > krb5_pac *pac) > { > *pac = NULL; >- if (windcft == NULL) >+ if (krb5_config_get_bool_default(context, NULL, FALSE, "realms", >+ client->entry.principal->realm, >+ "disable_pac", NULL)) > return 0; >+ if (windcft == NULL) { >+ return krb5_pac_init(context, pac); >+ } >+ > if (windcft->pac_pk_generate != NULL && pk_reply_key != NULL) > return (windcft->pac_pk_generate)(windcctx, context, > client, pk_reply_key, pac); >@@ -92,20 +98,17 @@ _kdc_pac_verify(krb5_context context, > hdb_entry_ex *client, > hdb_entry_ex *server, > hdb_entry_ex *krbtgt, >- krb5_pac *pac, >- int *verified) >+ krb5_pac *pac) > { > krb5_error_code ret; > > if (windcft == NULL) >- return 0; >+ return KRB5_PLUGIN_NO_HANDLE; > > ret = windcft->pac_verify(windcctx, context, > client_principal, > delegated_proxy_principal, > client, server, krbtgt, pac); >- if (ret == 0) >- *verified = 1; > return ret; > } > >diff --git a/source4/heimdal/kdc/windc_plugin.h b/source4/heimdal/kdc/windc_plugin.h >index bf90826cb06..dda258da3d1 100644 >--- a/source4/heimdal/kdc/windc_plugin.h >+++ b/source4/heimdal/kdc/windc_plugin.h >@@ -43,8 +43,9 @@ > * krb5_pac_init and fill in the PAC structure for the principal using > * krb5_pac_add_buffer. > * >- * The PAC verify function should verify all components in the PAC >- * using krb5_pac_get_types and krb5_pac_get_buffer for all types. >+ * The PAC verify function should verify the PAC KDC signatures by fetching >+ * the right KDC key and calling krb5_pac_verify() with that KDC key. >+ * Optionally, update the PAC buffers upon success. > * > * Check client access function check if the client is authorized. > */ >diff --git a/source4/heimdal/lib/krb5/authdata.c b/source4/heimdal/lib/krb5/authdata.c >new file mode 100644 >index 00000000000..ac426618f6e >--- /dev/null >+++ b/source4/heimdal/lib/krb5/authdata.c >@@ -0,0 +1,124 @@ >+/* >+ * Copyright (c) 1997-2021 Kungliga Tekniska Högskolan >+ * (Royal Institute of Technology, Stockholm, Sweden). >+ * Copyright (c) 2021 Isaac Boukris >+ * All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * 3. Neither the name of the Institute nor the names of its contributors >+ * may be used to endorse or promote products derived from this software >+ * without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND >+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE >+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >+ * SUCH DAMAGE. >+ */ >+ >+#include "krb5_locl.h" >+ >+/* >+ * Add the AuthorizationData `data´ of `type´ to the last element in >+ * the sequence of authorization_data in `tkt´ wrapped in an IF_RELEVANT >+ */ >+ >+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >+_kdc_tkt_add_if_relevant_ad(krb5_context context, >+ EncTicketPart *tkt, >+ int type, >+ const krb5_data *data) >+{ >+ krb5_error_code ret; >+ size_t size = 0; >+ >+ if (tkt->authorization_data == NULL) { >+ tkt->authorization_data = calloc(1, sizeof(*tkt->authorization_data)); >+ if (tkt->authorization_data == NULL) { >+ return krb5_enomem(context); >+ } >+ } >+ >+ /* add the entry to the last element */ >+ { >+ AuthorizationData ad = { 0, NULL }; >+ AuthorizationDataElement ade; >+ >+ ade.ad_type = type; >+ ade.ad_data = *data; >+ >+ ret = add_AuthorizationData(&ad, &ade); >+ if (ret) { >+ krb5_set_error_message(context, ret, "add AuthorizationData failed"); >+ return ret; >+ } >+ >+ ade.ad_type = KRB5_AUTHDATA_IF_RELEVANT; >+ >+ ASN1_MALLOC_ENCODE(AuthorizationData, >+ ade.ad_data.data, ade.ad_data.length, >+ &ad, &size, ret); >+ free_AuthorizationData(&ad); >+ if (ret) { >+ krb5_set_error_message(context, ret, "ASN.1 encode of " >+ "AuthorizationData failed"); >+ return ret; >+ } >+ if (ade.ad_data.length != size) >+ krb5_abortx(context, "internal asn.1 encoder error"); >+ >+ ret = add_AuthorizationData(tkt->authorization_data, &ade); >+ der_free_octet_string(&ade.ad_data); >+ if (ret) { >+ krb5_set_error_message(context, ret, "add AuthorizationData failed"); >+ return ret; >+ } >+ } >+ >+ return 0; >+} >+ >+/* >+ * Insert a PAC wrapped in AD-IF-RELEVANT container as the first AD element, >+ * as some clients such as Windows may fail to parse it otherwise. >+ */ >+ >+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >+_kdc_tkt_insert_pac(krb5_context context, >+ EncTicketPart *tkt, >+ const krb5_data *data) >+{ >+ AuthorizationDataElement ade; >+ unsigned int i; >+ krb5_error_code ret; >+ >+ ret = _kdc_tkt_add_if_relevant_ad(context, tkt, KRB5_AUTHDATA_WIN2K_PAC, >+ data); >+ if (ret) >+ return ret; >+ >+ heim_assert(tkt->authorization_data->len != 0, "No authorization_data!"); >+ ade = tkt->authorization_data->val[tkt->authorization_data->len - 1]; >+ for (i = 0; i < tkt->authorization_data->len - 1; i++) { >+ tkt->authorization_data->val[i + 1] = tkt->authorization_data->val[i]; >+ } >+ tkt->authorization_data->val[0] = ade; >+ >+ return 0; >+} >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 26aae107b32..eec1e84c7bd 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -53,6 +53,8 @@ struct krb5_pac_data { > struct PAC_INFO_BUFFER *server_checksum; > struct PAC_INFO_BUFFER *privsvr_checksum; > struct PAC_INFO_BUFFER *logon_name; >+ struct PAC_INFO_BUFFER *ticket_checksum; >+ krb5_data ticket_sign_data; > }; > > #define PAC_ALIGNMENT 8 >@@ -64,6 +66,7 @@ struct krb5_pac_data { > #define PAC_PRIVSVR_CHECKSUM 7 > #define PAC_LOGON_NAME 10 > #define PAC_CONSTRAINED_DELEGATION 11 >+#define PAC_TICKET_CHECKSUM 16 > > #define CHECK(r,f,l) \ > do { \ >@@ -142,13 +145,13 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > CHECK(ret, krb5_ret_uint32(sp, &tmp2), out); > if (tmp < 1) { > ret = EINVAL; /* Too few buffers */ >- krb5_set_error_message(context, ret, N_("PAC have too few buffer", "")); >+ krb5_set_error_message(context, ret, N_("PAC has too few buffers", "")); > goto out; > } > if (tmp2 != 0) { > ret = EINVAL; /* Wrong version */ > krb5_set_error_message(context, ret, >- N_("PAC have wrong version %d", ""), >+ N_("PAC has wrong version %d", ""), > (int)tmp2); > goto out; > } >@@ -191,7 +194,7 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > if (p->pac->buffers[i].offset_lo > len) { > ret = EINVAL; > krb5_set_error_message(context, ret, >- N_("PAC offset off end", "")); >+ N_("PAC offset overflow", "")); > goto out; > } > if (p->pac->buffers[i].offset_lo < header_end) { >@@ -204,7 +207,7 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > } > if (p->pac->buffers[i].buffersize > len - p->pac->buffers[i].offset_lo){ > ret = EINVAL; >- krb5_set_error_message(context, ret, N_("PAC length off end", "")); >+ krb5_set_error_message(context, ret, N_("PAC length overflow", "")); > goto out; > } > >@@ -213,7 +216,7 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > if (p->server_checksum) { > ret = EINVAL; > krb5_set_error_message(context, ret, >- N_("PAC have two server checksums", "")); >+ N_("PAC has multiple server checksums", "")); > goto out; > } > p->server_checksum = &p->pac->buffers[i]; >@@ -221,7 +224,7 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > if (p->privsvr_checksum) { > ret = EINVAL; > krb5_set_error_message(context, ret, >- N_("PAC have two KDC checksums", "")); >+ N_("PAC has multiple KDC checksums", "")); > goto out; > } > p->privsvr_checksum = &p->pac->buffers[i]; >@@ -229,10 +232,18 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > if (p->logon_name) { > ret = EINVAL; > krb5_set_error_message(context, ret, >- N_("PAC have two logon names", "")); >+ N_("PAC has multiple logon names", "")); > goto out; > } > p->logon_name = &p->pac->buffers[i]; >+ } else if (p->pac->buffers[i].type == PAC_TICKET_CHECKSUM) { >+ if (p->ticket_checksum) { >+ ret = EINVAL; >+ krb5_set_error_message(context, ret, >+ N_("PAC has multiple ticket checksums", "")); >+ goto out; >+ } >+ p->ticket_checksum = &p->pac->buffers[i]; > } > } > >@@ -425,6 +436,7 @@ KRB5_LIB_FUNCTION void KRB5_LIB_CALL > krb5_pac_free(krb5_context context, krb5_pac pac) > { > krb5_data_free(&pac->data); >+ krb5_data_free(&pac->ticket_sign_data); > free(pac->pac); > free(pac); > } >@@ -444,6 +456,7 @@ verify_checksum(krb5_context context, > uint32_t type; > krb5_error_code ret; > Checksum cksum; >+ size_t cksumsize; > > memset(&cksum, 0, sizeof(cksum)); > >@@ -456,8 +469,17 @@ verify_checksum(krb5_context context, > > CHECK(ret, krb5_ret_uint32(sp, &type), out); > cksum.cksumtype = type; >- cksum.checksum.length = >- sig->buffersize - krb5_storage_seek(sp, 0, SEEK_CUR); >+ >+ ret = krb5_checksumsize(context, type, &cksumsize); >+ if (ret) >+ goto out; >+ >+ /* Allow for RODCIdentifier trailer, see MS-PAC 2.8 */ >+ if (cksumsize > (sig->buffersize - krb5_storage_seek(sp, 0, SEEK_CUR))) { >+ ret = EINVAL; >+ goto out; >+ } >+ cksum.checksum.length = cksumsize; > cksum.checksum.data = malloc(cksum.checksum.length); > if (cksum.checksum.data == NULL) { > ret = krb5_enomem(context); >@@ -804,7 +826,6 @@ out: > return ret; > } > >- > /** > * Verify the PAC. > * >@@ -844,18 +865,22 @@ krb5_pac_verify(krb5_context context, > return EINVAL; > } > >- ret = verify_logonname(context, >- pac->logon_name, >- &pac->data, >- authtime, >- principal); >- if (ret) >- return ret; >+ if (principal != NULL) { >+ ret = verify_logonname(context, pac->logon_name, &pac->data, authtime, >+ principal); >+ if (ret) >+ return ret; >+ } >+ >+ if (pac->server_checksum->buffersize < 4 || >+ pac->privsvr_checksum->buffersize < 4) >+ return EINVAL; > > /* > * in the service case, clean out data option of the privsvr and > * server checksum before checking the checksum. > */ >+ if (server != NULL) > { > krb5_data *copy; > >@@ -897,6 +922,20 @@ krb5_pac_verify(krb5_context context, > privsvr); > if (ret) > return ret; >+ >+ if (pac->ticket_sign_data.length != 0) { >+ if (pac->ticket_checksum == NULL) { >+ krb5_set_error_message(context, EINVAL, >+ "PAC missing ticket checksum"); >+ return EINVAL; >+ } >+ >+ ret = verify_checksum(context, pac->ticket_checksum, &pac->data, >+ pac->ticket_sign_data.data, >+ pac->ticket_sign_data.length, privsvr); >+ if (ret) >+ return ret; >+ } > } > > return 0; >@@ -965,13 +1004,14 @@ _krb5_pac_sign(krb5_context context, > krb5_principal principal, > const krb5_keyblock *server_key, > const krb5_keyblock *priv_key, >+ uint16_t rodc_id, > krb5_data *data) > { > krb5_error_code ret; > krb5_storage *sp = NULL, *spdata = NULL; > uint32_t end; > size_t server_size, priv_size; >- uint32_t server_offset = 0, priv_offset = 0; >+ uint32_t server_offset = 0, priv_offset = 0, ticket_offset = 0; > uint32_t server_cksumtype = 0, priv_cksumtype = 0; > int num = 0; > size_t i; >@@ -985,9 +1025,9 @@ _krb5_pac_sign(krb5_context context, > p->server_checksum = &p->pac->buffers[i]; > } > if (p->server_checksum != &p->pac->buffers[i]) { >- ret = EINVAL; >+ ret = KRB5KDC_ERR_BADOPTION; > krb5_set_error_message(context, ret, >- N_("PAC have two server checksums", "")); >+ N_("PAC has multiple server checksums", "")); > goto out; > } > } else if (p->pac->buffers[i].type == PAC_PRIVSVR_CHECKSUM) { >@@ -995,9 +1035,9 @@ _krb5_pac_sign(krb5_context context, > p->privsvr_checksum = &p->pac->buffers[i]; > } > if (p->privsvr_checksum != &p->pac->buffers[i]) { >- ret = EINVAL; >+ ret = KRB5KDC_ERR_BADOPTION; > krb5_set_error_message(context, ret, >- N_("PAC have two KDC checksums", "")); >+ N_("PAC has multiple KDC checksums", "")); > goto out; > } > } else if (p->pac->buffers[i].type == PAC_LOGON_NAME) { >@@ -1005,9 +1045,19 @@ _krb5_pac_sign(krb5_context context, > p->logon_name = &p->pac->buffers[i]; > } > if (p->logon_name != &p->pac->buffers[i]) { >- ret = EINVAL; >+ ret = KRB5KDC_ERR_BADOPTION; >+ krb5_set_error_message(context, ret, >+ N_("PAC has multiple logon names", "")); >+ goto out; >+ } >+ } else if (p->pac->buffers[i].type == PAC_TICKET_CHECKSUM) { >+ if (p->ticket_checksum == NULL) { >+ p->ticket_checksum = &p->pac->buffers[i]; >+ } >+ if (p->ticket_checksum != &p->pac->buffers[i]) { >+ ret = KRB5KDC_ERR_BADOPTION; > krb5_set_error_message(context, ret, >- N_("PAC have two logon names", "")); >+ N_("PAC has multiple ticket checksums", "")); > goto out; > } > } >@@ -1019,6 +1069,8 @@ _krb5_pac_sign(krb5_context context, > num++; > if (p->privsvr_checksum == NULL) > num++; >+ if (p->ticket_sign_data.length != 0 && p->ticket_checksum == NULL) >+ num++; > > if (num) { > void *ptr; >@@ -1044,6 +1096,11 @@ _krb5_pac_sign(krb5_context context, > memset(p->privsvr_checksum, 0, sizeof(*p->privsvr_checksum)); > p->privsvr_checksum->type = PAC_PRIVSVR_CHECKSUM; > } >+ if (p->ticket_sign_data.length != 0 && p->ticket_checksum == NULL) { >+ p->ticket_checksum = &p->pac->buffers[p->pac->numbuffers++]; >+ memset(p->ticket_checksum, 0, sizeof(*p->privsvr_checksum)); >+ p->ticket_checksum->type = PAC_TICKET_CHECKSUM; >+ } > } > > /* Calculate LOGON NAME */ >@@ -1055,6 +1112,7 @@ _krb5_pac_sign(krb5_context context, > ret = pac_checksum(context, server_key, &server_cksumtype, &server_size); > if (ret) > goto out; >+ > ret = pac_checksum(context, priv_key, &priv_cksumtype, &priv_size); > if (ret) > goto out; >@@ -1095,10 +1153,24 @@ _krb5_pac_sign(krb5_context context, > priv_offset = end + 4; > CHECK(ret, krb5_store_uint32(spdata, priv_cksumtype), out); > CHECK(ret, fill_zeros(context, spdata, priv_size), out); >+ if (rodc_id != 0) { >+ len += sizeof(rodc_id); >+ CHECK(ret, fill_zeros(context, spdata, sizeof(rodc_id)), out); >+ } >+ } else if (p->ticket_sign_data.length != 0 && >+ p->pac->buffers[i].type == PAC_TICKET_CHECKSUM) { >+ len = priv_size + 4; >+ ticket_offset = end + 4; >+ CHECK(ret, krb5_store_uint32(spdata, priv_cksumtype), out); >+ CHECK(ret, fill_zeros(context, spdata, priv_size), out); >+ if (rodc_id != 0) { >+ len += sizeof(rodc_id); >+ CHECK(ret, krb5_store_uint16(spdata, rodc_id), out); >+ } > } else if (p->pac->buffers[i].type == PAC_LOGON_NAME) { > len = krb5_storage_write(spdata, logon.data, logon.length); > if (logon.length != len) { >- ret = EINVAL; >+ ret = KRB5KDC_ERR_BADOPTION; > goto out; > } > } else { >@@ -1156,6 +1228,16 @@ _krb5_pac_sign(krb5_context context, > } > > /* sign */ >+ if (p->ticket_sign_data.length) { >+ ret = create_checksum(context, priv_key, priv_cksumtype, >+ p->ticket_sign_data.data, >+ p->ticket_sign_data.length, >+ (char *)d.data + ticket_offset, priv_size); >+ if (ret) { >+ krb5_data_free(&d); >+ goto out; >+ } >+ } > ret = create_checksum(context, server_key, server_cksumtype, > d.data, d.length, > (char *)d.data + server_offset, server_size); >@@ -1171,6 +1253,32 @@ _krb5_pac_sign(krb5_context context, > goto out; > } > >+ if (rodc_id != 0) { >+ krb5_data rd; >+ krb5_storage *rs = krb5_storage_emem(); >+ if (rs == NULL) { >+ krb5_data_free(&d); >+ ret = krb5_enomem(context); >+ goto out; >+ } >+ krb5_storage_set_flags(rs, KRB5_STORAGE_BYTEORDER_LE); >+ ret = krb5_store_uint16(rs, rodc_id); >+ if (ret) { >+ krb5_storage_free(rs); >+ krb5_data_free(&d); >+ goto out; >+ } >+ ret = krb5_storage_to_data(rs, &rd); >+ krb5_storage_free(rs); >+ if (ret) { >+ krb5_data_free(&d); >+ goto out; >+ } >+ heim_assert(rd.length == sizeof(rodc_id), "invalid length"); >+ memcpy((char *)d.data + priv_offset + priv_size, rd.data, rd.length); >+ krb5_data_free(&rd); >+ } >+ > /* done */ > *data = d; > >@@ -1187,3 +1295,221 @@ out: > krb5_storage_free(spdata); > return ret; > } >+ >+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >+_krb5_pac_get_kdc_checksum_info(krb5_context context, >+ krb5_pac pac, >+ krb5_cksumtype *cstype, >+ uint16_t *rodc_id) >+{ >+ krb5_error_code ret; >+ krb5_storage *sp = NULL; >+ const struct PAC_INFO_BUFFER *sig; >+ size_t cksumsize, prefix; >+ uint32_t type = 0; >+ >+ *cstype = 0; >+ *rodc_id = 0; >+ >+ sig = pac->privsvr_checksum; >+ if (sig == NULL) { >+ krb5_set_error_message(context, KRB5KDC_ERR_BADOPTION, >+ "PAC missing kdc checksum"); >+ return KRB5KDC_ERR_BADOPTION; >+ } >+ >+ sp = krb5_storage_from_mem((char *)pac->data.data + sig->offset_lo, >+ sig->buffersize); >+ if (sp == NULL) >+ return krb5_enomem(context); >+ >+ krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); >+ >+ ret = krb5_ret_uint32(sp, &type); >+ if (ret) >+ goto out; >+ >+ ret = krb5_checksumsize(context, type, &cksumsize); >+ if (ret) >+ goto out; >+ >+ prefix = krb5_storage_seek(sp, 0, SEEK_CUR); >+ >+ if ((sig->buffersize - prefix) >= cksumsize + 2) { >+ krb5_storage_seek(sp, cksumsize, SEEK_CUR); >+ ret = krb5_ret_uint16(sp, rodc_id); >+ if (ret) >+ goto out; >+ } >+ >+ *cstype = type; >+ >+out: >+ krb5_storage_free(sp); >+ >+ return ret; >+} >+ >+static unsigned char single_zero = '\0'; >+static krb5_data single_zero_pac = { 1, &single_zero }; >+ >+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >+_krb5_kdc_pac_ticket_parse(krb5_context context, >+ EncTicketPart *tkt, >+ krb5_boolean *signedticket, >+ krb5_pac *ppac) >+{ >+ AuthorizationData *ad = tkt->authorization_data; >+ krb5_boolean pac_found = FALSE; >+ krb5_pac pac = NULL; >+ unsigned i, j; >+ size_t len = 0; >+ krb5_error_code ret; >+ >+ *signedticket = FALSE; >+ *ppac = NULL; >+ >+ if (ad == NULL || ad->len == 0) >+ return 0; >+ >+ for (i = 0; i < ad->len; i++) { >+ AuthorizationData child; >+ >+ if (ad->val[i].ad_type == KRB5_AUTHDATA_WIN2K_PAC) >+ return KRB5KDC_ERR_BADOPTION; >+ >+ if (ad->val[i].ad_type != KRB5_AUTHDATA_IF_RELEVANT) >+ continue; >+ >+ ret = decode_AuthorizationData(ad->val[i].ad_data.data, >+ ad->val[i].ad_data.length, >+ &child, >+ NULL); >+ if (ret) { >+ krb5_set_error_message(context, ret, "Failed to decode " >+ "AD-IF-RELEVANT with %d", ret); >+ return ret; >+ } >+ >+ for (j = 0; j < child.len; j++) { >+ if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) { >+ krb5_data adifr_data = ad->val[i].ad_data; >+ krb5_data pac_data = child.val[j].ad_data; >+ krb5_data recoded_adifr; >+ >+ if (pac_found) { >+ free_AuthorizationData(&child); >+ return KRB5KDC_ERR_BADOPTION; >+ } >+ pac_found = TRUE; >+ >+ ret = krb5_pac_parse(context, >+ pac_data.data, >+ pac_data.length, >+ &pac); >+ if (ret) { >+ free_AuthorizationData(&child); >+ return ret; >+ } >+ >+ if (pac->ticket_checksum == NULL) { >+ free_AuthorizationData(&child); >+ *ppac = pac; >+ continue; >+ } >+ >+ /* >+ * Encode the ticket with the PAC replaced with a single zero >+ * byte, to be used as input data to the ticket signature. >+ */ >+ >+ child.val[j].ad_data = single_zero_pac; >+ >+ ASN1_MALLOC_ENCODE(AuthorizationData, recoded_adifr.data, >+ recoded_adifr.length, &child, &len, ret); >+ if (recoded_adifr.length != len) >+ krb5_abortx(context, "Internal error in ASN.1 encoder"); >+ >+ child.val[j].ad_data = pac_data; >+ free_AuthorizationData(&child); >+ >+ if (ret) { >+ krb5_pac_free(context, pac); >+ return ret; >+ } >+ >+ ad->val[i].ad_data = recoded_adifr; >+ >+ ASN1_MALLOC_ENCODE(EncTicketPart, >+ pac->ticket_sign_data.data, >+ pac->ticket_sign_data.length, tkt, &len, >+ ret); >+ if(pac->ticket_sign_data.length != len) >+ krb5_abortx(context, "Internal error in ASN.1 encoder"); >+ >+ ad->val[i].ad_data = adifr_data; >+ krb5_data_free(&recoded_adifr); >+ >+ if (ret) { >+ krb5_pac_free(context, pac); >+ return ret; >+ } >+ >+ *signedticket = TRUE; >+ *ppac = pac; >+ } >+ } >+ free_AuthorizationData(&child); >+ } >+ return 0; >+} >+ >+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >+_krb5_kdc_pac_sign_ticket(krb5_context context, >+ const krb5_pac pac, >+ krb5_principal client, >+ const krb5_keyblock *server_key, >+ const krb5_keyblock *kdc_key, >+ uint16_t rodc_id, >+ krb5_boolean add_ticket_sig, >+ EncTicketPart *tkt) >+{ >+ krb5_error_code ret; >+ krb5_data tkt_data; >+ krb5_data rspac; >+ >+ krb5_data_zero(&rspac); >+ krb5_data_zero(&tkt_data); >+ >+ krb5_data_free(&pac->ticket_sign_data); >+ >+ if (add_ticket_sig) { >+ size_t len = 0; >+ >+ ret = _kdc_tkt_insert_pac(context, tkt, &single_zero_pac); >+ if (ret) >+ return ret; >+ >+ ASN1_MALLOC_ENCODE(EncTicketPart, tkt_data.data, tkt_data.length, >+ tkt, &len, ret); >+ if(tkt_data.length != len) >+ krb5_abortx(context, "Internal error in ASN.1 encoder"); >+ if (ret) >+ return ret; >+ >+ ret = remove_AuthorizationData(tkt->authorization_data, 0); >+ if (ret) { >+ krb5_data_free(&tkt_data); >+ return ret; >+ } >+ >+ pac->ticket_sign_data = tkt_data; >+ } >+ >+ ret = _krb5_pac_sign(context, pac, tkt->authtime, client, server_key, >+ kdc_key, rodc_id, &rspac); >+ if (ret) >+ return ret; >+ >+ return _kdc_tkt_insert_pac(context, tkt, &rspac); >+} >diff --git a/source4/heimdal/lib/krb5/version-script.map b/source4/heimdal/lib/krb5/version-script.map >index ddae2a06764..91eb3543003 100644 >--- a/source4/heimdal/lib/krb5/version-script.map >+++ b/source4/heimdal/lib/krb5/version-script.map >@@ -751,6 +751,11 @@ HEIMDAL_KRB5_2.0 { > _krb5_get_host_realm_int; > _krb5_get_int; > _krb5_pac_sign; >+ _krb5_kdc_pac_sign_ticket; >+ _krb5_kdc_pac_ticket_parse; >+ _krb5_pac_get_kdc_checksum_info; >+ _kdc_tkt_insert_pac; >+ _kdc_tkt_add_if_relevant_ad; > _krb5_parse_moduli; > _krb5_pk_kdf; > _krb5_pk_load_id; >diff --git a/source4/heimdal_build/wscript_build b/source4/heimdal_build/wscript_build >index e896c3e9454..5f50f3c2ae6 100644 >--- a/source4/heimdal_build/wscript_build >+++ b/source4/heimdal_build/wscript_build >@@ -628,7 +628,7 @@ if not bld.CONFIG_SET("USING_SYSTEM_KRB5"): > KRB5_SOURCE = [os.path.join('lib/krb5/', x) for x in to_list( > '''acache.c add_et_list.c > addr_families.c appdefault.c >- asn1_glue.c auth_context.c >+ asn1_glue.c auth_context.c authdata.c > build_ap_req.c build_auth.c cache.c > changepw.c codec.c config_file.c > constants.c convert_creds.c >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index f0ae3433091..4bf4243cb59 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -714,7 +714,7 @@ planoldpythontestsuite("ad_dc:local", "samba.tests.gpo", extra_args=['-U"$USERNA > planoldpythontestsuite("ad_dc:local", "samba.tests.dckeytab", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) > > have_fast_support = int('SAMBA_USES_MITKDC' in config_hash) >-tkt_sig_support = 0 >+tkt_sig_support = int('SAMBA4_USES_HEIMDAL' in config_hash) > planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", > environ={'SERVICE_USERNAME':'$SERVER', >-- >2.25.1 > > >From fac873944e21e7e2bba65b33adcab32dc8e88b48 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Sun, 19 Sep 2021 15:04:14 +0300 >Subject: [PATCH 345/686] krb5: allow NULL parameter to krb5_pac_free() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >[jsutton@samba.org Cherry-picked from Heimdal commit >b295167208a96e68515902138f6ce93972892ec5] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 2d09de5c41e729bccc2d7949d8a3568a95e80e76) >--- > source4/heimdal/kdc/krb5tgs.c | 3 +-- > source4/heimdal/lib/krb5/pac.c | 2 ++ > 2 files changed, 3 insertions(+), 2 deletions(-) > >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index e8bbb42465f..24a4f261766 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -2057,8 +2057,7 @@ out: > > free_EncTicketPart(&adtkt); > >- if (mspac) >- krb5_pac_free(context, mspac); >+ krb5_pac_free(context, mspac); > > return ret; > } >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index eec1e84c7bd..18f385fac1f 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -435,6 +435,8 @@ krb5_pac_get_types(krb5_context context, > KRB5_LIB_FUNCTION void KRB5_LIB_CALL > krb5_pac_free(krb5_context context, krb5_pac pac) > { >+ if (pac == NULL) >+ return; > krb5_data_free(&pac->data); > krb5_data_free(&pac->ticket_sign_data); > free(pac->pac); >-- >2.25.1 > > >From 979c7576fe082489bbcfb76e2ed841ecf79bd0e3 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Sun, 19 Sep 2021 15:16:58 +0300 >Subject: [PATCH 346/686] krb5: rework PAC validation loop > >Avoid allocating the PAC on error. > >Closes: #836 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >[jsutton@samba.org Cherry-picked from Heimdal commit >6df8be5091363a1c9a9165465ab8292f817bec81] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 2773379603a5a625c5d1c6e62f29c442942ff570) >--- > source4/heimdal/lib/krb5/pac.c | 132 +++++++++++++++++---------------- > 1 file changed, 69 insertions(+), 63 deletions(-) > >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 18f385fac1f..922a8710eda 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -1362,11 +1362,10 @@ _krb5_kdc_pac_ticket_parse(krb5_context context, > krb5_pac *ppac) > { > AuthorizationData *ad = tkt->authorization_data; >- krb5_boolean pac_found = FALSE; > krb5_pac pac = NULL; > unsigned i, j; > size_t len = 0; >- krb5_error_code ret; >+ krb5_error_code ret = 0; > > *signedticket = FALSE; > *ppac = NULL; >@@ -1377,8 +1376,10 @@ _krb5_kdc_pac_ticket_parse(krb5_context context, > for (i = 0; i < ad->len; i++) { > AuthorizationData child; > >- if (ad->val[i].ad_type == KRB5_AUTHDATA_WIN2K_PAC) >- return KRB5KDC_ERR_BADOPTION; >+ if (ad->val[i].ad_type == KRB5_AUTHDATA_WIN2K_PAC) { >+ ret = KRB5KDC_ERR_BADOPTION; >+ goto out; >+ } > > if (ad->val[i].ad_type != KRB5_AUTHDATA_IF_RELEVANT) > continue; >@@ -1390,79 +1391,84 @@ _krb5_kdc_pac_ticket_parse(krb5_context context, > if (ret) { > krb5_set_error_message(context, ret, "Failed to decode " > "AD-IF-RELEVANT with %d", ret); >- return ret; >+ goto out; > } > > for (j = 0; j < child.len; j++) { >- if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) { >- krb5_data adifr_data = ad->val[i].ad_data; >- krb5_data pac_data = child.val[j].ad_data; >- krb5_data recoded_adifr; >- >- if (pac_found) { >- free_AuthorizationData(&child); >- return KRB5KDC_ERR_BADOPTION; >- } >- pac_found = TRUE; >- >- ret = krb5_pac_parse(context, >- pac_data.data, >- pac_data.length, >- &pac); >- if (ret) { >- free_AuthorizationData(&child); >- return ret; >- } >- >- if (pac->ticket_checksum == NULL) { >- free_AuthorizationData(&child); >- *ppac = pac; >- continue; >- } >- >- /* >- * Encode the ticket with the PAC replaced with a single zero >- * byte, to be used as input data to the ticket signature. >- */ >- >- child.val[j].ad_data = single_zero_pac; >- >- ASN1_MALLOC_ENCODE(AuthorizationData, recoded_adifr.data, >- recoded_adifr.length, &child, &len, ret); >- if (recoded_adifr.length != len) >- krb5_abortx(context, "Internal error in ASN.1 encoder"); >- >- child.val[j].ad_data = pac_data; >+ krb5_data adifr_data = ad->val[i].ad_data; >+ krb5_data pac_data = child.val[j].ad_data; >+ krb5_data recoded_adifr; >+ >+ if (child.val[j].ad_type != KRB5_AUTHDATA_WIN2K_PAC) >+ continue; >+ >+ if (pac != NULL) { >+ free_AuthorizationData(&child); >+ ret = KRB5KDC_ERR_BADOPTION; >+ goto out; >+ } >+ >+ ret = krb5_pac_parse(context, >+ pac_data.data, >+ pac_data.length, >+ &pac); >+ if (ret) { > free_AuthorizationData(&child); >+ goto out; >+ } > >- if (ret) { >- krb5_pac_free(context, pac); >- return ret; >- } >+ if (pac->ticket_checksum == NULL) >+ continue; > >- ad->val[i].ad_data = recoded_adifr; >+ /* >+ * Encode the ticket with the PAC replaced with a single zero >+ * byte, to be used as input data to the ticket signature. >+ */ > >- ASN1_MALLOC_ENCODE(EncTicketPart, >- pac->ticket_sign_data.data, >- pac->ticket_sign_data.length, tkt, &len, >- ret); >- if(pac->ticket_sign_data.length != len) >- krb5_abortx(context, "Internal error in ASN.1 encoder"); >+ child.val[j].ad_data = single_zero_pac; > >- ad->val[i].ad_data = adifr_data; >- krb5_data_free(&recoded_adifr); >+ ASN1_MALLOC_ENCODE(AuthorizationData, recoded_adifr.data, >+ recoded_adifr.length, &child, &len, ret); >+ if (recoded_adifr.length != len) >+ krb5_abortx(context, "Internal error in ASN.1 encoder"); > >- if (ret) { >- krb5_pac_free(context, pac); >- return ret; >- } >+ child.val[j].ad_data = pac_data; > >- *signedticket = TRUE; >- *ppac = pac; >+ if (ret) { >+ free_AuthorizationData(&child); >+ goto out; > } >+ >+ ad->val[i].ad_data = recoded_adifr; >+ >+ ASN1_MALLOC_ENCODE(EncTicketPart, >+ pac->ticket_sign_data.data, >+ pac->ticket_sign_data.length, tkt, &len, >+ ret); >+ if (pac->ticket_sign_data.length != len) >+ krb5_abortx(context, "Internal error in ASN.1 encoder"); >+ >+ ad->val[i].ad_data = adifr_data; >+ krb5_data_free(&recoded_adifr); >+ >+ if (ret) { >+ free_AuthorizationData(&child); >+ goto out; >+ } >+ >+ *signedticket = TRUE; > } > free_AuthorizationData(&child); > } >+ >+out: >+ if (ret) { >+ krb5_pac_free(context, pac); >+ return ret; >+ } >+ >+ *ppac = pac; >+ > return 0; > } > >-- >2.25.1 > > >From 7205c43559d5acdfd311bb04673f1bf6199d57f2 Mon Sep 17 00:00:00 2001 >From: Luke Howard <lukeh@padl.com> >Date: Fri, 17 Sep 2021 13:57:57 +1000 >Subject: [PATCH 347/686] krb5: return KRB5KRB_AP_ERR_INAPP_CKSUM if PAC > checksum fails > >Return KRB5KRB_AP_ERR_INAPP_CKSUM instead of EINVAL when verifying a PAC, if >the checksum is absent or unkeyed. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >[jsutton@samba.org Cherry-picked from Heimdal commit >c4b99b48c4b18f30d504b427bc1961d7a71f631e] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit d6a472e953545ec3858ca969c1a4191e4f27ba63) >--- > source4/heimdal/lib/krb5/pac.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 922a8710eda..3e45125d35e 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -489,13 +489,13 @@ verify_checksum(krb5_context context, > } > ret = krb5_storage_read(sp, cksum.checksum.data, cksum.checksum.length); > if (ret != (int)cksum.checksum.length) { >- ret = EINVAL; >+ ret = KRB5KRB_AP_ERR_INAPP_CKSUM; > krb5_set_error_message(context, ret, "PAC checksum missing checksum"); > goto out; > } > > if (!krb5_checksum_is_keyed(context, cksum.cksumtype)) { >- ret = EINVAL; >+ ret = KRB5KRB_AP_ERR_INAPP_CKSUM; > krb5_set_error_message(context, ret, "Checksum type %d not keyed", > cksum.cksumtype); > goto out; >-- >2.25.1 > > >From e5f09169c206a99059d9daf53537381356df8fb5 Mon Sep 17 00:00:00 2001 >From: Luke Howard <lukeh@padl.com> >Date: Sun, 6 Jan 2019 17:54:58 +1100 >Subject: [PATCH 348/686] kdc: only set HDB_F_GET_KRBTGT when requesting TGS > principal > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >[jsutton@samba.org Backported from Heimdal commit > f1dd2b818aa0866960945edea02a6bc782ed697c > - Removed change to _kdc_find_etype() use_strongest_session_key > parameter since Samba's Heimdal version uses different logic >] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit db30b71f79864a20b38a1f812a5df833f3a92de8) >--- > source4/heimdal/kdc/kerberos5.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index 7b17d2539ce..d1fd201113b 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -983,6 +983,7 @@ _kdc_as_rep(krb5_context context, > pk_client_params *pkp = NULL; > #endif > const EncryptionKey *pk_reply_key = NULL; >+ krb5_boolean is_tgs; > > memset(&rep, 0, sizeof(rep)); > memset(&session_key, 0, sizeof(session_key)); >@@ -1033,6 +1034,8 @@ _kdc_as_rep(krb5_context context, > kdc_log(context, config, 0, "AS-REQ %s from %s for %s", > client_name, from, server_name); > >+ is_tgs = krb5_principal_is_krbtgt(context, server_princ); >+ > /* > * > */ >@@ -1101,7 +1104,7 @@ _kdc_as_rep(krb5_context context, > goto out; > } > ret = _kdc_db_fetch(context, config, server_princ, >- HDB_F_GET_SERVER|HDB_F_GET_KRBTGT | flags, >+ HDB_F_GET_SERVER | flags | (is_tgs ? HDB_F_GET_KRBTGT : 0), > NULL, NULL, &server); > if(ret == HDB_ERR_NOT_FOUND_HERE) { > kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", server_name); >-- >2.25.1 > > >From 2083ee80d5a33324f70d9b0d57f3b1ce3754c24a Mon Sep 17 00:00:00 2001 >From: Luke Howard <lukeh@padl.com> >Date: Thu, 23 Sep 2021 14:39:35 +1000 >Subject: [PATCH 349/686] kdc: use ticket client name when signing PAC > >The principal in the PAC_LOGON_NAME buffer is expected to match the client name >in the ticket. Previously we were setting this to the canonical client name, >which would have broken PAC validation if the client did not request name >canonicalization > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >[jsutton@samba.org Backported from Heimdal commit > 3b0856cab2b25624deb1f6e0e67637ba96a647ac > - Renamed variable to avoid shadowing existing variable >] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 75d1a7cd14b134506061ed64ddb9b99856231d2c) >--- > source4/heimdal/kdc/kerberos5.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index d1fd201113b..6dc945b134a 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -1716,6 +1716,7 @@ _kdc_as_rep(krb5_context context, > krb5_pac p = NULL; > krb5_data data; > uint16_t rodc_id; >+ krb5_principal client_pac; > > ret = _kdc_pac_generate(context, client, pk_reply_key, &p); > if (ret) { >@@ -1726,12 +1727,21 @@ _kdc_as_rep(krb5_context context, > if (p != NULL) { > rodc_id = server->entry.kvno >> 16; > >+ /* libkrb5 expects ticket and PAC client names to match */ >+ ret = _krb5_principalname2krb5_principal(context, &client_pac, >+ et.cname, et.crealm); >+ if (ret) { >+ krb5_pac_free(context, p); >+ goto out; >+ } >+ > ret = _krb5_pac_sign(context, p, et.authtime, >- client->entry.principal, >+ client_pac, > &skey->key, /* Server key */ > &skey->key, /* FIXME: should be krbtgt key */ > rodc_id, > &data); >+ krb5_free_principal(context, client_pac); > krb5_pac_free(context, p); > if (ret) { > kdc_log(context, config, 0, "PAC signing failed for -- %s", >-- >2.25.1 > > >From 2b49fd4d81bb34a122c1cf269f06fb20160897dd Mon Sep 17 00:00:00 2001 >From: Luke Howard <lukeh@padl.com> >Date: Thu, 23 Sep 2021 17:51:51 +1000 >Subject: [PATCH 350/686] kdc: correctly generate PAC TGS signature > >When generating an AS-REQ, the TGS signature was incorrectly generated using >the server key, which would fail to validate if the server was not also the >TGS. Fix this. > >Patch from Isaac Bourkis <iboukris@gmail.com>. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >[jsutton@samba.org Backported from Heimdal commit > e7863e2af922809dad25a2e948e98c408944d551 > - Samba's Heimdal version does not have the generate_pac() helper > function. > - Samba's Heimdal version does not use the 'r' context variable. >] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 91e684f5dcb48b76e6a322c15acb53cbce5c275a) >--- > source4/heimdal/kdc/kerberos5.c | 49 ++++++++++++++++++++++++++++++++- > 1 file changed, 48 insertions(+), 1 deletion(-) > >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index 6dc945b134a..a131f1af08e 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -948,6 +948,33 @@ _kdc_is_anonymous(krb5_context context, krb5_principal principal) > return 1; > } > >+static krb5_error_code >+get_local_tgs(krb5_context context, >+ krb5_kdc_configuration *config, >+ krb5_const_realm realm, >+ hdb_entry_ex **krbtgt) >+{ >+ krb5_error_code ret; >+ krb5_principal tgs_name; >+ >+ *krbtgt = NULL; >+ >+ ret = krb5_make_principal(context, >+ &tgs_name, >+ realm, >+ KRB5_TGS_NAME, >+ realm, >+ NULL); >+ if (ret) >+ return ret; >+ >+ ret = _kdc_db_fetch(context, config, tgs_name, >+ HDB_F_GET_KRBTGT, NULL, NULL, krbtgt); >+ krb5_free_principal(context, tgs_name); >+ >+ return ret; >+} >+ > /* > * > */ >@@ -984,6 +1011,8 @@ _kdc_as_rep(krb5_context context, > #endif > const EncryptionKey *pk_reply_key = NULL; > krb5_boolean is_tgs; >+ hdb_entry_ex *krbtgt = NULL; >+ Key *krbtgt_key = NULL; > > memset(&rep, 0, sizeof(rep)); > memset(&session_key, 0, sizeof(session_key)); >@@ -1466,6 +1495,22 @@ _kdc_as_rep(krb5_context context, > if(ret) > goto out; > >+ /* If server is not krbtgt, fetch local krbtgt key for signing authdata */ >+ if (is_tgs) { >+ krbtgt_key = skey; >+ } else { >+ ret = get_local_tgs(context, config, server_princ->realm, >+ &krbtgt); >+ if (ret) >+ goto out; >+ >+ ret = _kdc_get_preferred_key(context, config, krbtgt, >+ server_princ->realm, >+ NULL, &krbtgt_key); >+ if (ret) >+ goto out; >+ } >+ > if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey > || (f.request_anonymous && !config->allow_anonymous)) { > ret = KRB5KDC_ERR_BADOPTION; >@@ -1738,7 +1783,7 @@ _kdc_as_rep(krb5_context context, > ret = _krb5_pac_sign(context, p, et.authtime, > client_pac, > &skey->key, /* Server key */ >- &skey->key, /* FIXME: should be krbtgt key */ >+ &krbtgt_key->key, /* TGS key */ > rodc_id, > &data); > krb5_free_principal(context, client_pac); >@@ -1807,6 +1852,8 @@ out: > _kdc_free_ent(context, client); > if(server) > _kdc_free_ent(context, server); >+ if (krbtgt) >+ _kdc_free_ent(context, krbtgt); > return ret; > } > >-- >2.25.1 > > >From f93dfce0678a8fe3f60f3c434f31948c5c925b6b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 11 Aug 2021 13:27:11 +1200 >Subject: [PATCH 351/686] s4/heimdal/lib/krb5/pac.c: Align PAC buffers to match > Windows > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 28a5a586c8e9cd155d676dcfcb81a2587ace99d1) >--- > selftest/knownfail_heimdal_kdc | 1 + > source4/heimdal/lib/krb5/pac.c | 14 +++++++++++++- > 2 files changed, 14 insertions(+), 1 deletion(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 4ec682c01d0..20eea7f2d7e 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -124,6 +124,7 @@ > # > # S4U tests > # >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_constrained_delegation_old_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_client_checksum >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 3e45125d35e..6535a9bdcc4 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -62,10 +62,12 @@ struct krb5_pac_data { > #define PACTYPE_SIZE 8 > #define PAC_INFO_BUFFER_SIZE 16 > >+#define PAC_LOGON_INFO 1 > #define PAC_SERVER_CHECKSUM 6 > #define PAC_PRIVSVR_CHECKSUM 7 > #define PAC_LOGON_NAME 10 > #define PAC_CONSTRAINED_DELEGATION 11 >+#define PAC_UPN_DNS_INFO 12 > #define PAC_TICKET_CHECKSUM 16 > > #define CHECK(r,f,l) \ >@@ -1184,7 +1186,17 @@ _krb5_pac_sign(krb5_context context, > ret = krb5_enomem(context); > goto out; > } >- /* XXX if not aligned, fill_zeros */ >+ >+ if (p->pac->buffers[i].type == PAC_LOGON_INFO >+ || p->pac->buffers[i].type == PAC_UPN_DNS_INFO) >+ { >+ uint32_t rounded = (len + PAC_ALIGNMENT - 1) / PAC_ALIGNMENT >+ * PAC_ALIGNMENT; >+ uint32_t remaining = rounded - len; >+ CHECK(ret, fill_zeros(context, spdata, remaining), out); >+ >+ len = rounded; >+ } > } > > /* write header */ >-- >2.25.1 > > >From 697ad62c9b88202f4044a325bcd733fa8a3d88ad Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:43:41 +1300 >Subject: [PATCH 352/686] heimdal: Make _krb5_pac_get_kdc_checksum_info() into > a global function > >This lets us call it from Samba. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 3bdce12789af1e7a7aba56691f184625a432410d) >--- > source4/heimdal/lib/krb5/pac.c | 8 ++++---- > source4/heimdal/lib/krb5/version-script.map | 2 +- > 2 files changed, 5 insertions(+), 5 deletions(-) > >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 6535a9bdcc4..f6d38178a88 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -1311,10 +1311,10 @@ out: > } > > KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >-_krb5_pac_get_kdc_checksum_info(krb5_context context, >- krb5_pac pac, >- krb5_cksumtype *cstype, >- uint16_t *rodc_id) >+krb5_pac_get_kdc_checksum_info(krb5_context context, >+ krb5_pac pac, >+ krb5_cksumtype *cstype, >+ uint16_t *rodc_id) > { > krb5_error_code ret; > krb5_storage *sp = NULL; >diff --git a/source4/heimdal/lib/krb5/version-script.map b/source4/heimdal/lib/krb5/version-script.map >index 91eb3543003..9ba00cd04f6 100644 >--- a/source4/heimdal/lib/krb5/version-script.map >+++ b/source4/heimdal/lib/krb5/version-script.map >@@ -470,6 +470,7 @@ HEIMDAL_KRB5_2.0 { > krb5_pac_add_buffer; > krb5_pac_free; > krb5_pac_get_buffer; >+ krb5_pac_get_kdc_checksum_info; > krb5_pac_get_types; > krb5_pac_init; > krb5_pac_parse; >@@ -753,7 +754,6 @@ HEIMDAL_KRB5_2.0 { > _krb5_pac_sign; > _krb5_kdc_pac_sign_ticket; > _krb5_kdc_pac_ticket_parse; >- _krb5_pac_get_kdc_checksum_info; > _kdc_tkt_insert_pac; > _kdc_tkt_add_if_relevant_ad; > _krb5_parse_moduli; >-- >2.25.1 > > >From 6777daced07fe1f84f26eb2fac3a07ef69bbc55e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 16:08:39 +1300 >Subject: [PATCH 353/686] s4:kdc: Check ticket signature > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 02fa69c6c73c01d82807be4370e838f3e7c66f35) >--- > selftest/knownfail_heimdal_kdc | 9 -- > source4/kdc/wdc-samba4.c | 270 ++++++++++++++++++++++++++------- > 2 files changed, 215 insertions(+), 64 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 20eea7f2d7e..683dbacb979 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -124,13 +124,8 @@ > # > # S4U tests > # >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_constrained_delegation_old_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_client_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_service_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_zeroed_client_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_zeroed_service_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_existing_delegation_info > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_missing_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_a >@@ -142,10 +137,6 @@ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_forwardable > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_empty_allowed > # >-# RODC tests >-# >-^samba.tests.krb5.rodc_tests.samba.tests.krb5.rodc_tests.RodcKerberosTests.test_rodc_ticket_signature >-# > # The lack of KRB5SignedPath means we no longer return > # KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case > # >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index 037db40ce46..589df8a651d 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -23,7 +23,10 @@ > > #include "includes.h" > #include "kdc/kdc-glue.h" >+#include "kdc/db-glue.h" > #include "kdc/pac-glue.h" >+#include "sdb.h" >+#include "sdb_hdb.h" > > /* > * Given the right private pointer from hdb_samba4, >@@ -94,15 +97,13 @@ static krb5_error_code samba_wdc_get_pac_compat(void *priv, krb5_context context > return samba_wdc_get_pac(priv, context, client, NULL, pac); > } > >-/* Resign (and reform, including possibly new groups) a PAC */ >- >-static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, >- const krb5_principal client_principal, >- const krb5_principal delegated_proxy_principal, >- struct hdb_entry_ex *client, >- struct hdb_entry_ex *server, >- struct hdb_entry_ex *krbtgt, >- krb5_pac *pac) >+static krb5_error_code samba_wdc_reget_pac2(krb5_context context, >+ const krb5_principal delegated_proxy_principal, >+ struct hdb_entry_ex *client, >+ struct hdb_entry_ex *server, >+ struct hdb_entry_ex *krbtgt, >+ krb5_pac *pac, >+ krb5_cksumtype ctype) > { > struct samba_kdc_entry *p = > talloc_get_type_abort(server->ctx, >@@ -110,15 +111,13 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > struct samba_kdc_entry *krbtgt_skdc_entry = > talloc_get_type_abort(krbtgt->ctx, > struct samba_kdc_entry); >- TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac context"); >+ TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac2 context"); > krb5_pac new_pac = NULL; > DATA_BLOB *pac_blob = NULL; > DATA_BLOB *upn_blob = NULL; > DATA_BLOB *deleg_blob = NULL; > krb5_error_code ret; > NTSTATUS nt_status; >- struct PAC_SIGNATURE_DATA *pac_srv_sig; >- struct PAC_SIGNATURE_DATA *pac_kdc_sig; > bool is_in_db, is_untrusted; > size_t num_types = 0; > uint32_t *types = NULL; >@@ -130,6 +129,7 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > ssize_t upn_dns_info_idx = -1; > ssize_t srv_checksum_idx = -1; > ssize_t kdc_checksum_idx = -1; >+ ssize_t tkt_checksum_idx = -1; > > if (!mem_ctx) { > return ENOMEM; >@@ -150,6 +150,71 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > return ret; > } > >+ if (delegated_proxy_principal != NULL) { >+ krb5_enctype etype; >+ Key *key = NULL; >+ >+ if (!is_in_db) { >+ /* >+ * The RODC-issued PAC was signed by a KDC entry that we >+ * don't have a key for. The server signature is not >+ * trustworthy, since it could have been created by the >+ * server we got the ticket from. We must not proceed as >+ * otherwise the ticket signature is unchecked. >+ */ >+ talloc_free(mem_ctx); >+ return HDB_ERR_NOT_FOUND_HERE; >+ } >+ >+ /* Fetch the correct key depending on the checksum type. */ >+ if (ctype == CKSUMTYPE_HMAC_MD5) { >+ etype = ENCTYPE_ARCFOUR_HMAC; >+ } else { >+ ret = krb5_cksumtype_to_enctype(context, >+ ctype, >+ &etype); >+ if (ret != 0) { >+ talloc_free(mem_ctx); >+ return ret; >+ } >+ } >+ ret = hdb_enctype2key(context, &krbtgt->entry, etype, &key); >+ if (ret != 0) { >+ return ret; >+ } >+ >+ /* Check the KDC and ticket signatures. */ >+ ret = krb5_pac_verify(context, >+ *pac, >+ 0, >+ NULL, >+ NULL, >+ &key->key); >+ if (ret != 0) { >+ DEBUG(1, ("PAC KDC signature failed to verify\n")); >+ talloc_free(mem_ctx); >+ return ret; >+ } >+ >+ deleg_blob = talloc_zero(mem_ctx, DATA_BLOB); >+ if (!deleg_blob) { >+ talloc_free(mem_ctx); >+ return ENOMEM; >+ } >+ >+ nt_status = samba_kdc_update_delegation_info_blob(mem_ctx, >+ context, *pac, >+ server->entry.principal, >+ delegated_proxy_principal, >+ deleg_blob); >+ if (!NT_STATUS_IS_OK(nt_status)) { >+ DEBUG(0, ("Building PAC failed: %s\n", >+ nt_errstr(nt_status))); >+ talloc_free(mem_ctx); >+ return EINVAL; >+ } >+ } >+ > if (is_untrusted) { > struct samba_kdc_entry *client_skdc_entry = NULL; > >@@ -173,52 +238,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > return ENOMEM; > } > >- pac_srv_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA); >- if (!pac_srv_sig) { >- talloc_free(mem_ctx); >- return ENOMEM; >- } >- >- pac_kdc_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA); >- if (!pac_kdc_sig) { >- talloc_free(mem_ctx); >- return ENOMEM; >- } >- > nt_status = samba_kdc_update_pac_blob(mem_ctx, context, > krbtgt_skdc_entry->kdc_db_ctx->samdb, > *pac, pac_blob, >- pac_srv_sig, pac_kdc_sig); >- if (!NT_STATUS_IS_OK(nt_status)) { >- DEBUG(0, ("Building PAC failed: %s\n", >- nt_errstr(nt_status))); >- talloc_free(mem_ctx); >- return EINVAL; >- } >- >- if (is_in_db) { >- /* Now check the KDC signature, fetching the correct key based on the enc type */ >- ret = kdc_check_pac(context, pac_srv_sig->signature, pac_kdc_sig, krbtgt); >- if (ret != 0) { >- DEBUG(1, ("PAC KDC signature failed to verify\n")); >- talloc_free(mem_ctx); >- return ret; >- } >- } >- } >- >- if (delegated_proxy_principal) { >- deleg_blob = talloc_zero(mem_ctx, DATA_BLOB); >- if (!deleg_blob) { >- talloc_free(mem_ctx); >- return ENOMEM; >- } >- >- nt_status = samba_kdc_update_delegation_info_blob(mem_ctx, >- context, *pac, >- server->entry.principal, >- delegated_proxy_principal, >- deleg_blob); >+ NULL, NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > DEBUG(0, ("Building PAC failed: %s\n", > nt_errstr(nt_status))); >@@ -308,6 +331,18 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > } > kdc_checksum_idx = i; > break; >+ case PAC_TYPE_TICKET_CHECKSUM: >+ if (tkt_checksum_idx != -1) { >+ DEBUG(1, ("ticket checksum type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ tkt_checksum_idx, >+ i)); >+ SAFE_FREE(types); >+ talloc_free(mem_ctx); >+ return EINVAL; >+ } >+ tkt_checksum_idx = i; >+ break; > default: > continue; > } >@@ -471,6 +506,131 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > return ret; > } > >+/* Resign (and reform, including possibly new groups) a PAC */ >+ >+static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, >+ const krb5_principal client_principal, >+ const krb5_principal delegated_proxy_principal, >+ struct hdb_entry_ex *client, >+ struct hdb_entry_ex *server, >+ struct hdb_entry_ex *krbtgt, >+ krb5_pac *pac) >+{ >+ struct samba_kdc_entry *krbtgt_skdc_entry = >+ talloc_get_type_abort(krbtgt->ctx, >+ struct samba_kdc_entry); >+ krb5_error_code ret; >+ krb5_cksumtype ctype = CKSUMTYPE_NONE; >+ struct hdb_entry_ex signing_krbtgt_hdb; >+ >+ if (delegated_proxy_principal) { >+ uint16_t rodc_id; >+ unsigned int my_krbtgt_number; >+ >+ /* >+ * We're using delegated_proxy_principal for the moment to >+ * indicate cases where the ticket was encrypted with the server >+ * key, and not a krbtgt key. This cannot be trusted, so we need >+ * to find a krbtgt key that signs the PAC in order to trust the >+ * ticket. >+ * >+ * The krbtgt passed in to this function refers to the krbtgt >+ * used to decrypt the ticket of the server requesting >+ * S4U2Proxy. >+ * >+ * When we implement service ticket renewal, we need to check >+ * the PAC, and this will need to be updated. >+ */ >+ ret = krb5_pac_get_kdc_checksum_info(context, >+ *pac, >+ &ctype, >+ &rodc_id); >+ if (ret != 0) { >+ DEBUG(1, ("Failed to get PAC checksum info\n")); >+ return ret; >+ } >+ >+ /* >+ * We need to check the KDC and ticket signatures, fetching the >+ * correct key based on the enctype. >+ */ >+ >+ my_krbtgt_number = krbtgt_skdc_entry->kdc_db_ctx->my_krbtgt_number; >+ >+ if (my_krbtgt_number != 0) { >+ /* >+ * If we are an RODC, and we are not the KDC that signed >+ * the evidence ticket, then we need to proxy the >+ * request. >+ */ >+ if (rodc_id != my_krbtgt_number) { >+ return HDB_ERR_NOT_FOUND_HERE; >+ } >+ } else { >+ /* >+ * If we are a DC, the ticket may have been signed by a >+ * different KDC than the one that issued the header >+ * ticket. >+ */ >+ if (rodc_id != krbtgt->entry.kvno >> 16) { >+ struct sdb_entry_ex signing_krbtgt_sdb; >+ >+ /* >+ * If we didn't sign the ticket, then return an >+ * error. >+ */ >+ if (rodc_id != 0) { >+ return KRB5KRB_AP_ERR_MODIFIED; >+ } >+ >+ /* >+ * Fetch our key from the database. To support >+ * key rollover, we're going to need to try >+ * multiple keys by trial and error. For now, >+ * krbtgt keys aren't assumed to change. >+ */ >+ ret = samba_kdc_fetch(context, >+ krbtgt_skdc_entry->kdc_db_ctx, >+ krbtgt->entry.principal, >+ SDB_F_GET_KRBTGT | SDB_F_CANON, >+ 0, >+ &signing_krbtgt_sdb); >+ if (ret != 0) { >+ return ret; >+ } >+ >+ ret = sdb_entry_ex_to_hdb_entry_ex(context, >+ &signing_krbtgt_sdb, >+ &signing_krbtgt_hdb); >+ sdb_free_entry(&signing_krbtgt_sdb); >+ if (ret != 0) { >+ return ret; >+ } >+ >+ /* >+ * Replace the krbtgt entry with our own entry >+ * for further processing. >+ */ >+ krbtgt = &signing_krbtgt_hdb; >+ } >+ } >+ } >+ >+ ret = samba_wdc_reget_pac2(context, >+ delegated_proxy_principal, >+ client, >+ server, >+ krbtgt, >+ pac, >+ ctype); >+ >+ if (krbtgt == &signing_krbtgt_hdb) { >+ hdb_free_entry(context, &signing_krbtgt_hdb); >+ } >+ >+ return ret; >+} >+ > static char *get_netbios_name(TALLOC_CTX *mem_ctx, HostAddresses *addrs) > { > char *nb_name = NULL; >-- >2.25.1 > > >From 99352a3398f9f09f72bdc3885e1b0ac6a48d2152 Mon Sep 17 00:00:00 2001 >From: Nicolas Williams <nico@twosigma.com> >Date: Sun, 10 Oct 2021 21:55:59 -0500 >Subject: [PATCH 354/686] krb5: Fix PAC signature leak affecting KDC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >[jsutton@samba.org Cherry-picked from Heimdal commit > 54581d2d52443a9a07ed5980df331f660b397dcf] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit f6adfefbbb41b9100736134d0f975f1ec0c33c42) >--- > source4/heimdal/lib/krb5/pac.c | 136 +++++++++++++++------------------ > 1 file changed, 61 insertions(+), 75 deletions(-) > >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index f6d38178a88..05bcc523080 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -1018,9 +1018,10 @@ _krb5_pac_sign(krb5_context context, > uint32_t server_offset = 0, priv_offset = 0, ticket_offset = 0; > uint32_t server_cksumtype = 0, priv_cksumtype = 0; > int num = 0; >- size_t i; >+ size_t i, sz; > krb5_data logon, d; > >+ krb5_data_zero(&d); > krb5_data_zero(&logon); > > for (i = 0; i < p->pac->numbuffers; i++) { >@@ -1080,8 +1081,10 @@ _krb5_pac_sign(krb5_context context, > void *ptr; > > ptr = realloc(p->pac, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (p->pac->numbuffers + num - 1))); >- if (ptr == NULL) >- return krb5_enomem(context); >+ if (ptr == NULL) { >+ ret = krb5_enomem(context); >+ goto out; >+ } > > p->pac = ptr; > >@@ -1109,30 +1112,33 @@ _krb5_pac_sign(krb5_context context, > > /* Calculate LOGON NAME */ > ret = build_logon_name(context, authtime, principal, &logon); >- if (ret) >- goto out; > > /* Set lengths for checksum */ >- ret = pac_checksum(context, server_key, &server_cksumtype, &server_size); >- if (ret) >- goto out; >+ if (ret == 0) >+ ret = pac_checksum(context, server_key, &server_cksumtype, &server_size); > >- ret = pac_checksum(context, priv_key, &priv_cksumtype, &priv_size); >- if (ret) >- goto out; >+ if (ret == 0) >+ ret = pac_checksum(context, priv_key, &priv_cksumtype, &priv_size); > > /* Encode PAC */ >- sp = krb5_storage_emem(); >- if (sp == NULL) >- return krb5_enomem(context); >- >- krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); >+ if (ret == 0) { >+ sp = krb5_storage_emem(); >+ if (sp == NULL) >+ ret = krb5_enomem(context); >+ } > >- spdata = krb5_storage_emem(); >- if (spdata == NULL) { >- krb5_storage_free(sp); >- return krb5_enomem(context); >+ if (ret == 0) { >+ krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); >+ spdata = krb5_storage_emem(); >+ if (spdata == NULL) { >+ krb5_storage_free(sp); >+ ret = krb5_enomem(context); >+ } > } >+ >+ if (ret) >+ goto out; >+ > krb5_storage_set_flags(spdata, KRB5_STORAGE_BYTEORDER_LE); > > CHECK(ret, krb5_store_uint32(sp, p->pac->numbuffers), out); >@@ -1222,77 +1228,56 @@ _krb5_pac_sign(krb5_context context, > /* assert (server_offset != 0 && priv_offset != 0); */ > > /* export PAC */ >- ret = krb5_storage_to_data(spdata, &d); >- if (ret) { >- krb5_set_error_message(context, ret, N_("malloc: out of memory", "")); >- goto out; >- } >- ret = krb5_storage_write(sp, d.data, d.length); >- if (ret != (int)d.length) { >- krb5_data_free(&d); >- ret = krb5_enomem(context); >- goto out; >+ if (ret == 0) >+ ret = krb5_storage_to_data(spdata, &d); >+ if (ret == 0) { >+ sz = krb5_storage_write(sp, d.data, d.length); >+ if (sz != d.length) { >+ krb5_data_free(&d); >+ ret = krb5_enomem(context); >+ goto out; >+ } > } > krb5_data_free(&d); > >- ret = krb5_storage_to_data(sp, &d); >- if (ret) { >- ret = krb5_enomem(context); >- goto out; >- } >+ if (ret == 0) >+ ret = krb5_storage_to_data(sp, &d); > > /* sign */ >- if (p->ticket_sign_data.length) { >+ if (ret == 0 && p->ticket_sign_data.length) > ret = create_checksum(context, priv_key, priv_cksumtype, > p->ticket_sign_data.data, > p->ticket_sign_data.length, > (char *)d.data + ticket_offset, priv_size); >- if (ret) { >- krb5_data_free(&d); >- goto out; >- } >- } >- ret = create_checksum(context, server_key, server_cksumtype, >- d.data, d.length, >- (char *)d.data + server_offset, server_size); >- if (ret) { >- krb5_data_free(&d); >- goto out; >- } >- ret = create_checksum(context, priv_key, priv_cksumtype, >- (char *)d.data + server_offset, server_size, >- (char *)d.data + priv_offset, priv_size); >- if (ret) { >- krb5_data_free(&d); >- goto out; >- } >- >- if (rodc_id != 0) { >+ if (ret == 0) >+ ret = create_checksum(context, server_key, server_cksumtype, >+ d.data, d.length, >+ (char *)d.data + server_offset, server_size); >+ if (ret == 0) >+ ret = create_checksum(context, priv_key, priv_cksumtype, >+ (char *)d.data + server_offset, server_size, >+ (char *)d.data + priv_offset, priv_size); >+ if (ret == 0 && rodc_id != 0) { > krb5_data rd; > krb5_storage *rs = krb5_storage_emem(); >- if (rs == NULL) { >- krb5_data_free(&d); >+ if (rs == NULL) > ret = krb5_enomem(context); >- goto out; >- } > krb5_storage_set_flags(rs, KRB5_STORAGE_BYTEORDER_LE); >- ret = krb5_store_uint16(rs, rodc_id); >- if (ret) { >- krb5_storage_free(rs); >- krb5_data_free(&d); >- goto out; >- } >- ret = krb5_storage_to_data(rs, &rd); >+ if (ret == 0) >+ ret = krb5_store_uint16(rs, rodc_id); >+ if (ret == 0) >+ ret = krb5_storage_to_data(rs, &rd); > krb5_storage_free(rs); >- if (ret) { >- krb5_data_free(&d); >+ if (ret) > goto out; >- } > heim_assert(rd.length == sizeof(rodc_id), "invalid length"); > memcpy((char *)d.data + priv_offset + priv_size, rd.data, rd.length); > krb5_data_free(&rd); > } > >+ if (ret) >+ goto out; >+ > /* done */ > *data = d; > >@@ -1302,6 +1287,7 @@ _krb5_pac_sign(krb5_context context, > > return 0; > out: >+ krb5_data_free(&d); > krb5_data_free(&logon); > if (sp) > krb5_storage_free(sp); >@@ -1528,8 +1514,8 @@ _krb5_kdc_pac_sign_ticket(krb5_context context, > > ret = _krb5_pac_sign(context, pac, tkt->authtime, client, server_key, > kdc_key, rodc_id, &rspac); >- if (ret) >- return ret; >- >- return _kdc_tkt_insert_pac(context, tkt, &rspac); >+ if (ret == 0) >+ ret = _kdc_tkt_insert_pac(context, tkt, &rspac); >+ krb5_data_free(&rspac); >+ return ret; > } >-- >2.25.1 > > >From 52725576d3c896d6c875139682eaea1f869ece9d Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 15 Oct 2021 13:09:20 +1300 >Subject: [PATCH 355/686] selftest/dbcheck: Fix up RODC one-way links (use > correct dbcheck rule) > >The previous commit was correct on intention, but it was not noticed >as there is a race, that the incorrect rule was appended to. > >These links are removed by remove_plausible_deleted_DN_links not >fix_all_old_dn_string_component_mismatch > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Fri Oct 15 10:00:47 UTC 2021 on sn-devel-184 > >(cherry picked from commit a7ad665e65f0701eb75cac5bc10a366ccd9689f4) > >[jsutton@samba.org Adapted to fix conflict] >--- > testprogs/blackbox/dbcheck.sh | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/testprogs/blackbox/dbcheck.sh b/testprogs/blackbox/dbcheck.sh >index 60e85d2c409..1eb0367739d 100755 >--- a/testprogs/blackbox/dbcheck.sh >+++ b/testprogs/blackbox/dbcheck.sh >@@ -19,12 +19,12 @@ dbcheck() { > > # This list of attributes can be freely extended > dbcheck_fix_one_way_links() { >- $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes fix_all_string_dn_component_mismatch --attrs="lastKnownParent defaultObjectCategory fromServer rIDSetReferences msDS-RevealOnDemandGroup msDS-NeverRevealGroup" --cross-ncs $ARGS >+ $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes fix_all_string_dn_component_mismatch --attrs="lastKnownParent defaultObjectCategory fromServer rIDSetReferences" --cross-ncs $ARGS > } > > # This list of attributes can be freely extended > dbcheck_fix_stale_links() { >- $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes remove_plausible_deleted_DN_links --attrs="member msDS-NC-Replica-Locations msDS-NC-RO-Replica-Locations" --cross-ncs $ARGS >+ $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes remove_plausible_deleted_DN_links --attrs="member msDS-NC-Replica-Locations msDS-NC-RO-Replica-Locations msDS-RevealOnDemandGroup msDS-NeverRevealGroup" --cross-ncs $ARGS > } > > # This list of attributes can be freely extended >-- >2.25.1 > > >From c8b1619c62d9f7f997ab2225dd210cfbd3409ed3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 15 Oct 2021 12:12:30 +1300 >Subject: [PATCH 356/686] heimdal:kdc: Fix ticket signing without a PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit d23d8e859357b0fac4d1f4a49f1dce6cf60d6216) >--- > source4/heimdal/kdc/krb5tgs.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index 24a4f261766..b0c873a4ffb 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -695,10 +695,12 @@ tgs_make_reply(krb5_context context, > } > > /* The PAC should be the last change to the ticket. */ >- ret = _krb5_kdc_pac_sign_ticket(context, mspac, tgt_name, serverkey, >- krbtgtkey, rodc_id, add_ticket_sig, &et); >+ if (mspac != NULL) { >+ ret = _krb5_kdc_pac_sign_ticket(context, mspac, tgt_name, serverkey, >+ krbtgtkey, rodc_id, add_ticket_sig, &et); > if (ret) > goto out; >+ } > > /* It is somewhat unclear where the etype in the following > encryption should come from. What we have is a session >-- >2.25.1 > > >From 6723d8e50b1bc4d48bf9a9c07605e52fb36d5dfb Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 15 Oct 2021 14:26:40 +1300 >Subject: [PATCH 357/686] tests/krb5: Allow get_tgt() to request including or > omitting a PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit e086c6193f6da6fcb5d0bcada2199e9bc7ad25f5) >--- > python/samba/tests/krb5/kdc_base_test.py | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 87160f675ae..1fc15315b0b 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1306,9 +1306,9 @@ class KDCBaseTest(RawKerberosTest): > > def get_tgt(self, creds, to_rodc=False, kdc_options=None, > expected_flags=None, unexpected_flags=None, >- fresh=False): >+ pac_request=True, expect_pac=True, fresh=False): > user_name = creds.get_username() >- cache_key = (user_name, to_rodc, kdc_options) >+ cache_key = (user_name, to_rodc, kdc_options, pac_request) > > if not fresh: > tgt = self.tkt_cache.get(cache_key) >@@ -1363,7 +1363,7 @@ class KDCBaseTest(RawKerberosTest): > kdc_options=kdc_options, > preauth_key=None, > ticket_decryption_key=ticket_decryption_key, >- pac_request=True, >+ pac_request=pac_request, > pac_options=pac_options, > to_rodc=to_rodc) > self.check_pre_authentication(rep) >@@ -1405,8 +1405,9 @@ class KDCBaseTest(RawKerberosTest): > kdc_options=kdc_options, > preauth_key=preauth_key, > ticket_decryption_key=ticket_decryption_key, >- pac_request=True, >+ pac_request=pac_request, > pac_options=pac_options, >+ expect_pac=expect_pac, > to_rodc=to_rodc) > self.check_as_reply(rep) > >-- >2.25.1 > > >From eb4ee8cd9e626bc235a1912ebdcaf4c803375fa4 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 15 Oct 2021 14:27:15 +1300 >Subject: [PATCH 358/686] tests/krb5: Allow specifying whether to expect a PAC > with _test_as_exchange() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 0dc69c1327f72384628a869a00482f6528b8671b) >--- > python/samba/tests/krb5/raw_testcase.py | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e008223eb23..29dc5f397b6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3530,6 +3530,7 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_decryption_key=None, > pac_request=None, > pac_options=None, >+ expect_pac=True, > to_rodc=False): > > def _generate_padata_copy(_kdc_exchange_dict, >@@ -3569,6 +3570,7 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_options=str(kdc_options), > pac_request=pac_request, > pac_options=pac_options, >+ expect_pac=expect_pac, > to_rodc=to_rodc) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >-- >2.25.1 > > >From b22fce5be636abcf25f17e0dd969d5cbd8327c58 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 15 Oct 2021 14:27:25 +1300 >Subject: [PATCH 359/686] tests/krb5: Add method to get the PAC from a ticket > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 288355896a2b6f460c42559ec46ff980ab57782e) >--- > python/samba/tests/krb5/raw_testcase.py | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 29dc5f397b6..0790ac13f99 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3447,6 +3447,15 @@ class RawKerberosTest(TestCaseInTempDir): > _, pac = self.replace_pac(auth_data, None, expect_pac) > return pac > >+ def get_ticket_pac(self, ticket, expect_pac=True): >+ auth_data = ticket.ticket_private.get('authorization-data') >+ if expect_pac: >+ self.assertIsNotNone(auth_data) >+ elif auth_data is None: >+ return None >+ >+ return self.get_pac(auth_data, expect_pac=expect_pac) >+ > def get_krbtgt_checksum_key(self): > krbtgt_creds = self.get_krbtgt_creds() > krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >-- >2.25.1 > > >From a0847683a903d7925301f795bb8aba4f3017bc62 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 15 Oct 2021 14:29:26 +1300 >Subject: [PATCH 360/686] tests/krb5: Add tests for requesting a service ticket > without a PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Sun Oct 17 23:40:33 UTC 2021 on sn-devel-184 > >[abartlet@samba.org backported from commit 9d3a691920205f8a9dc05d0e173e25e6a335f139 > as the MIT KDC 1.16 seen on the reference Ubuntu 18.04 does not fail > test_remove_pac] >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 120 +++++++++++++++++++++++ > selftest/knownfail_heimdal_kdc | 5 + > selftest/knownfail_mit_kdc | 4 + > 3 files changed, 129 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 3075cc6b0a9..9d846a2c3ad 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -23,15 +23,18 @@ import os > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > >+import samba.tests.krb5.kcrypto as kcrypto > from samba.tests.krb5.kdc_base_test import KDCBaseTest > from samba.tests.krb5.rfc4120_constants import ( > AES256_CTS_HMAC_SHA1_96, > ARCFOUR_HMAC_MD5, > KRB_ERROR, >+ KRB_TGS_REP, > KDC_ERR_BADMATCH, > NT_PRINCIPAL, > NT_SRV_INST, > ) >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > > global_asn1_print = False > global_hexdump = False >@@ -209,6 +212,123 @@ class KdcTgsTests(KDCBaseTest): > pac_data.account_sid, > "rep = {%s},%s" % (rep, pac_data)) > >+ def _make_tgs_request(self, client_creds, service_creds, tgt, >+ expect_pac=True): >+ client_account = client_creds.get_username() >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[client_account]) >+ >+ service_account = service_creds.get_username() >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[service_account]) >+ >+ realm = service_creds.get_realm() >+ >+ expected_crealm = realm >+ expected_cname = cname >+ expected_srealm = realm >+ expected_sname = sname >+ >+ expected_supported_etypes = service_creds.tgs_supported_enctypes >+ >+ etypes = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ >+ kdc_options = str(krb5_asn1.KDCOptions('canonicalize')) >+ >+ target_decryption_key = self.TicketDecryptionKey_from_creds( >+ service_creds) >+ >+ authenticator_subkey = self.RandomKey(kcrypto.Enctype.AES256) >+ >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=expected_crealm, >+ expected_cname=expected_cname, >+ expected_srealm=expected_srealm, >+ expected_sname=expected_sname, >+ expected_supported_etypes=expected_supported_etypes, >+ ticket_decryption_key=target_decryption_key, >+ check_rep_fn=self.generic_check_kdc_rep, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ expected_error_mode=0, >+ tgt=tgt, >+ authenticator_subkey=authenticator_subkey, >+ kdc_options=kdc_options, >+ expect_pac=expect_pac) >+ >+ rep = self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ etypes=etypes) >+ self.check_reply(rep, KRB_TGS_REP) >+ >+ return kdc_exchange_dict['rep_ticket_creds'] >+ >+ def test_request_no_pac(self): >+ client_creds = self.get_client_creds() >+ service_creds = self.get_service_creds() >+ >+ tgt = self.get_tgt(client_creds, pac_request=False, >+ expect_pac=False) >+ >+ pac = self.get_ticket_pac(tgt, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ ticket = self._make_tgs_request(client_creds, service_creds, tgt, >+ expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ def test_client_no_auth_data_required(self): >+ client_creds = self.get_cached_creds( >+ machine_account=False, >+ opts={'no_auth_data_required': True}) >+ service_creds = self.get_service_creds() >+ >+ tgt = self.get_tgt(client_creds) >+ >+ pac = self.get_ticket_pac(tgt) >+ self.assertIsNotNone(pac) >+ >+ ticket = self._make_tgs_request(client_creds, service_creds, tgt) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_service_no_auth_data_required(self): >+ client_creds = self.get_client_creds() >+ service_creds = self.get_cached_creds( >+ machine_account=True, >+ opts={'no_auth_data_required': True}) >+ >+ tgt = self.get_tgt(client_creds) >+ >+ pac = self.get_ticket_pac(tgt) >+ self.assertIsNotNone(pac) >+ >+ ticket = self._make_tgs_request(client_creds, service_creds, tgt, >+ expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ def test_remove_pac(self): >+ client_creds = self.get_client_creds() >+ service_creds = self.get_service_creds() >+ >+ tgt = self.modified_ticket(self.get_tgt(client_creds), >+ exclude_pac=True) >+ >+ pac = self.get_ticket_pac(tgt, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ ticket = self._make_tgs_request(client_creds, service_creds, tgt, >+ expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ > > if __name__ == "__main__": > global_asn1_print = False >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 683dbacb979..32cfa2afa88 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -141,3 +141,8 @@ > # KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case > # > ^samba4.krb5.kdc with machine account.as-req-pac-request.fl2000dc:local >+# >+# TGS tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_client_no_auth_data_required >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 09efbc7b590..00f652db14a 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -276,6 +276,10 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_ldap_service_ticket\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_get_ticket_for_host_service_of_machine_account\(ad_dc\) > # >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_client_no_auth_data_required\(ad_dc\) >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_request_no_pac\(ad_dc\) >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required\(ad_dc\) >+# > # MIT currently fails the following MS-KILE tests. > # > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_1_3 >-- >2.25.1 > > >From 23a755bdf03600ddbf7169af0592f1efeb49fe3b Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 18 Oct 2021 15:21:50 +1300 >Subject: [PATCH 361/686] kdc: Remove UF_NO_AUTH_DATA_REQUIRED from client > principals > >Tests against Windows 2019 show that UF_NO_AUTH_DATA_REQUIRED >applies to services only, not to clients. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14871 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >[abartlet@samba.org backported from commit 92e8ce18a79e88c9b961dc20e39436c4cf653013 > as there was a knownfail conflict with the test_remove_pac case > which succeeds on this branch] >--- > selftest/knownfail_heimdal_kdc | 1 - > selftest/knownfail_mit_kdc | 1 - > source4/kdc/mit_samba.c | 7 ------- > source4/kdc/pac-glue.c | 5 ----- > 4 files changed, 14 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 32cfa2afa88..4d058bad3da 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -144,5 +144,4 @@ > # > # TGS tests > # >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_client_no_auth_data_required > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 00f652db14a..0f845fb9b1c 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -276,7 +276,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_ldap_service_ticket\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_get_ticket_for_host_service_of_machine_account\(ad_dc\) > # >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_client_no_auth_data_required\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_request_no_pac\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required\(ad_dc\) > # >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index 2936fe2d18a..689e14e1c38 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -495,18 +495,11 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > ssize_t srv_checksum_idx = -1; > ssize_t kdc_checksum_idx = -1; > krb5_pac new_pac = NULL; >- bool ok; > > if (client != NULL) { > client_skdc_entry = > talloc_get_type_abort(client->e_data, > struct samba_kdc_entry); >- >- /* The user account may be set not to want the PAC */ >- ok = samba_princ_needs_pac(client_skdc_entry); >- if (!ok) { >- return EINVAL; >- } > } > > if (server == NULL) { >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index b4eeeb65243..34518e14233 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -651,11 +651,6 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > } > *_upn_info_blob = NULL; > >- /* The user account may be set not to want the PAC */ >- if ( ! samba_princ_needs_pac(p)) { >- return NT_STATUS_OK; >- } >- > logon_blob = talloc_zero(mem_ctx, DATA_BLOB); > if (logon_blob == NULL) { > return NT_STATUS_NO_MEMORY; >-- >2.25.1 > > >From 861da0da07a01737867fa9ee3c467de10d0268a8 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 18 Oct 2021 16:00:45 +1300 >Subject: [PATCH 362/686] kdc: Correctly strip PAC, rather than error on > UF_NO_AUTH_DATA_REQUIRED for servers > >UF_NO_AUTH_DATA_REQUIRED on a server/service account should cause >the PAC to be stripped not to given an error if the PAC was still >present. > >Tested against Windows 2019 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14871 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 031a8287642e3c4b9d0b7c6b51f3b1d79b227542) >--- > selftest/knownfail_heimdal_kdc | 4 ---- > source4/kdc/wdc-samba4.c | 38 +++++++++++++++++++++++----------- > 2 files changed, 26 insertions(+), 16 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 4d058bad3da..683dbacb979 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -141,7 +141,3 @@ > # KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case > # > ^samba4.krb5.kdc with machine account.as-req-pac-request.fl2000dc:local >-# >-# TGS tests >-# >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index 589df8a651d..ac9d7d51733 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -105,13 +105,15 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > krb5_pac *pac, > krb5_cksumtype ctype) > { >- struct samba_kdc_entry *p = >+ struct samba_kdc_entry *server_skdc_entry = > talloc_get_type_abort(server->ctx, > struct samba_kdc_entry); > struct samba_kdc_entry *krbtgt_skdc_entry = > talloc_get_type_abort(krbtgt->ctx, > struct samba_kdc_entry); >- TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac2 context"); >+ TALLOC_CTX *mem_ctx = talloc_named(server_skdc_entry, >+ 0, >+ "samba_kdc_reget_pac2 context"); > krb5_pac new_pac = NULL; > DATA_BLOB *pac_blob = NULL; > DATA_BLOB *upn_blob = NULL; >@@ -135,12 +137,6 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > return ENOMEM; > } > >- /* The user account may be set not to want the PAC */ >- if (!samba_princ_needs_pac(p)) { >- talloc_free(mem_ctx); >- return EINVAL; >- } >- > /* If the krbtgt was generated by an RODC, and we are not that > * RODC, then we need to regenerate the PAC - we can't trust > * it */ >@@ -373,12 +369,28 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > return EINVAL; > } > >- /* Build an updated PAC */ >+ /* >+ * The server account may be set not to want the PAC. >+ * >+ * While this is wasteful if the above cacluations were done >+ * and now thrown away, this is cleaner as we do any ticket >+ * signature checking etc always. >+ * >+ * UF_NO_AUTH_DATA_REQUIRED is the rare case and most of the >+ * time (eg not accepting a ticket from the RODC) we do not >+ * need to re-generate anything anyway. >+ */ >+ if (!samba_princ_needs_pac(server_skdc_entry)) { >+ ret = 0; >+ new_pac = NULL; >+ goto out; >+ } >+ >+ /* Otherwise build an updated PAC */ > ret = krb5_pac_init(context, &new_pac); > if (ret != 0) { >- SAFE_FREE(types); >- talloc_free(mem_ctx); >- return ret; >+ new_pac = NULL; >+ goto out; > } > > for (i = 0;;) { >@@ -496,6 +508,8 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > } > } > >+out: >+ > SAFE_FREE(types); > > /* We now replace the pac */ >-- >2.25.1 > > >From b839f7ccd42f62836636823698342ed7ef280144 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 18 Oct 2021 16:05:19 +1300 >Subject: [PATCH 363/686] tests/krb5: Ensure PAC is not present if expect_pac > is false > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14871 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit cc3d27596b9e8a8a46e8ba9c3c1a445477d458cf) >--- > python/samba/tests/krb5/raw_testcase.py | 14 +++++++------- > 1 file changed, 7 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 0790ac13f99..0b9fe8e7a04 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2385,13 +2385,6 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(ticket_private, 'authorization-data', > expect_empty=not expect_pac) > >- if expect_pac: >- authorization_data = self.getElementValue(ticket_private, >- 'authorization-data') >- pac_data = self.get_pac(authorization_data) >- >- self.check_pac_buffers(pac_data, kdc_exchange_dict) >- > encpart_session_key = None > if encpart_private is not None: > self.assertElementPresent(encpart_private, 'key') >@@ -2493,6 +2486,13 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_private=ticket_private, > encpart_private=encpart_private) > >+ if ticket_private is not None: >+ pac_data = self.get_ticket_pac(ticket_creds, expect_pac=expect_pac) >+ if expect_pac: >+ self.check_pac_buffers(pac_data, kdc_exchange_dict) >+ else: >+ self.assertIsNone(pac_data) >+ > expect_ticket_checksum = kdc_exchange_dict['expect_ticket_checksum'] > if expect_ticket_checksum: > self.assertIsNotNone(ticket_decryption_key) >-- >2.25.1 > > >From c4c368a47a93b38fe30aa8eda74509646135ddea Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 18 Oct 2021 16:07:11 +1300 >Subject: [PATCH 364/686] tests/krb5: Add tests for constrained delegation to > NO_AUTH_DATA_REQUIRED service > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14871 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Wed Oct 20 09:22:43 UTC 2021 on sn-devel-184 > >(cherry picked from commit 83a654a4efd39a6e792a6d49e0ecf586e9bc53ef) >--- > python/samba/tests/krb5/s4u_tests.py | 107 ++++++++++++++++++++++++++- > selftest/knownfail_heimdal_kdc | 8 +- > 2 files changed, 113 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index 9a25256081a..bbb7135b55b 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -538,6 +538,8 @@ class S4UKerberosTests(KDCBaseTest): > transited_service = f'host/{service1_name}@{service1_realm}' > expected_transited_services.append(transited_service) > >+ expect_pac = kdc_dict.pop('expect_pac', True) >+ > kdc_exchange_dict = self.tgs_exchange_dict( > expected_crealm=client_realm, > expected_cname=client_cname, >@@ -557,7 +559,8 @@ class S4UKerberosTests(KDCBaseTest): > pac_options=pac_options, > expect_edata=expect_edata, > expected_proxy_target=expected_proxy_target, >- expected_transited_services=expected_transited_services) >+ expected_transited_services=expected_transited_services, >+ expect_pac=expect_pac) > > self._generic_kdc_exchange(kdc_exchange_dict, > cname=None, >@@ -577,6 +580,18 @@ class S4UKerberosTests(KDCBaseTest): > 'allow_delegation': True > }) > >+ def test_constrained_delegation_no_auth_data_required(self): >+ # Test constrained delegation. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_delegation': True, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ }, >+ 'expect_pac': False >+ }) >+ > def test_constrained_delegation_existing_delegation_info(self): > # Test constrained delegation with an existing S4U_DELEGATION_INFO > # structure in the PAC. >@@ -624,6 +639,35 @@ class S4UKerberosTests(KDCBaseTest): > 'modify_service_tgt_fn': self.remove_ticket_pac > }) > >+ def test_constrained_delegation_no_client_pac_no_auth_data_required(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': (KDC_ERR_BADOPTION, >+ KDC_ERR_MODIFIED), >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': self.remove_ticket_pac, >+ 'expect_edata': False, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ } >+ }) >+ >+ def test_constrained_delegation_no_service_pac_no_auth_data_required(self): >+ # Test constrained delegation when the service TGT does not contain a >+ # PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': (KDC_ERR_BADOPTION, >+ KDC_ERR_MODIFIED), >+ 'allow_delegation': True, >+ 'modify_service_tgt_fn': self.remove_ticket_pac, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ } >+ }) >+ > def test_constrained_delegation_non_forwardable(self): > # Test constrained delegation with a non-forwardable ticket. > self._run_delegation_test( >@@ -645,6 +689,18 @@ class S4UKerberosTests(KDCBaseTest): > 'allow_delegation': True > }) > >+ def test_rbcd_no_auth_data_required(self): >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ }, >+ 'expect_pac': False >+ }) >+ > def test_rbcd_existing_delegation_info(self): > # Test constrained delegation with an existing S4U_DELEGATION_INFO > # structure in the PAC. >@@ -712,6 +768,55 @@ class S4UKerberosTests(KDCBaseTest): > 'modify_service_tgt_fn': self.remove_ticket_pac > }) > >+ def test_rbcd_no_client_pac_no_auth_data_required_a(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC, and an empty msDS-AllowedToDelegateTo attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': self.remove_ticket_pac, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ } >+ }) >+ >+ def test_rbcd_no_client_pac_no_auth_data_required_b(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC, and a non-empty msDS-AllowedToDelegateTo attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': ntstatus.NT_STATUS_NO_MATCH, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': self.remove_ticket_pac, >+ 'service1_opts': { >+ 'delegation_to_spn': ('host/test') >+ }, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ } >+ }) >+ >+ def test_rbcd_no_service_pac_no_auth_data_required(self): >+ # Test constrained delegation when the service TGT does not contain a >+ # PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': >+ ntstatus.NT_STATUS_NOT_FOUND, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_service_tgt_fn': self.remove_ticket_pac, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ } >+ }) >+ > def test_rbcd_non_forwardable(self): > # Test resource-based constrained delegation with a non-forwardable > # ticket. >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 683dbacb979..b1d7a1ebe8f 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -125,7 +125,7 @@ > # S4U tests > # > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac\(.*\)$ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_existing_delegation_info > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_missing_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_a >@@ -141,3 +141,9 @@ > # KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case > # > ^samba4.krb5.kdc with machine account.as-req-pac-request.fl2000dc:local >+# >+# >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_auth_data_required >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_auth_data_required >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_a >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_b >-- >2.25.1 > > >From 0ed246bb56ad45207a1ea646a8cadc532abf8a34 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 8 Sep 2021 17:01:26 +1200 >Subject: [PATCH 365/686] pytest/rodc_rwdc: try to avoid race. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14868 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit a169e013e66bab15e594ce49b805edebfcd503cf) >--- > source4/dsdb/tests/python/rodc_rwdc.py | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/source4/dsdb/tests/python/rodc_rwdc.py b/source4/dsdb/tests/python/rodc_rwdc.py >index 3596c7d750a..30d6a3101c4 100644 >--- a/source4/dsdb/tests/python/rodc_rwdc.py >+++ b/source4/dsdb/tests/python/rodc_rwdc.py >@@ -251,6 +251,10 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > res = ldb_system.search(userdn, attrs=['unicodePwd']) > self.assertTrue('unicodePwd' in res[0]) > >+ # force replication here to flush any pending preloads (this >+ # was a racy test). >+ self.force_replication() >+ > newpass = userpass + '!' > > # Forcing replication should blank out password (when changed) >-- >2.25.1 > > >From 3319d3c3ed8194d76ed8e02f0c80b48aec19b801 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 16:27:40 +1200 >Subject: [PATCH 366/686] selftest: Increase account lockout windows to make > test more realiable > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14868 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 6292f0597f208d7953382341380921cf0fd0a8a8) >--- > source4/dsdb/tests/python/rodc_rwdc.py | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/tests/python/rodc_rwdc.py b/source4/dsdb/tests/python/rodc_rwdc.py >index 30d6a3101c4..b8501980c67 100644 >--- a/source4/dsdb/tests/python/rodc_rwdc.py >+++ b/source4/dsdb/tests/python/rodc_rwdc.py >@@ -289,14 +289,14 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > m = ldb.Message() > m.dn = ldb.Dn(self.ldb, self.base_dn) > >- self.account_lockout_duration = 10 >+ self.account_lockout_duration = 15 > account_lockout_duration_ticks = -int(self.account_lockout_duration * (1e7)) > > m["lockoutDuration"] = ldb.MessageElement(str(account_lockout_duration_ticks), > ldb.FLAG_MOD_REPLACE, > "lockoutDuration") > >- self.lockout_observation_window = 10 >+ self.lockout_observation_window = 15 > lockout_observation_window_ticks = -int(self.lockout_observation_window * (1e7)) > > m["lockOutObservationWindow"] = ldb.MessageElement(str(lockout_observation_window_ticks), >-- >2.25.1 > > >From 3853a77d6488accff3d8c14d674a52c4a356cc76 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 6 Aug 2021 11:08:10 +1200 >Subject: [PATCH 367/686] pytest: dynamic tests optionally add __doc__ > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit aacb18f920349e13b562c7c97901a0be7b273137) >--- > python/samba/tests/__init__.py | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py >index 13d42779262..b6d8a508d4c 100644 >--- a/python/samba/tests/__init__.py >+++ b/python/samba/tests/__init__.py >@@ -70,7 +70,7 @@ class TestCase(unittest.TestCase): > """A Samba test case.""" > > @classmethod >- def generate_dynamic_test(cls, fnname, suffix, *args): >+ def generate_dynamic_test(cls, fnname, suffix, *args, doc=None): > """ > fnname is something like "test_dynamic_sum" > suffix is something like "1plus2" >@@ -83,6 +83,7 @@ class TestCase(unittest.TestCase): > """ > def fn(self): > getattr(self, "_%s_with_args" % fnname)(*args) >+ fn.__doc__ = doc > setattr(cls, "%s_%s" % (fnname, suffix), fn) > > @classmethod >-- >2.25.1 > > >From db893795187eb99994ce70d64c8baaa7b993c3fd Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:40:09 +1300 >Subject: [PATCH 368/686] selftest: krb5 account creation: clarify account type > as an enum > >This makes the code clearer with a symbolic constant rather >than a True/False boolean. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 49306f74eb29a2192019fab9260f9d242f9d5fd9) >--- > .../tests/krb5/as_canonicalization_tests.py | 7 ++- > python/samba/tests/krb5/kdc_base_test.py | 63 ++++++++++++------- > python/samba/tests/krb5/kdc_tgs_tests.py | 7 ++- > .../ms_kile_client_principal_lookup_tests.py | 36 +++++++---- > python/samba/tests/krb5/rodc_tests.py | 4 +- > python/samba/tests/krb5/s4u_tests.py | 35 ++++++----- > python/samba/tests/krb5/test_ccache.py | 11 ++-- > 7 files changed, 100 insertions(+), 63 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index 9538d0ae3cf..674fcb37101 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -171,9 +171,10 @@ class KerberosASCanonicalizationTests(KDCBaseTest): > def machine_account_creds(self): > if self.machine_creds is None: > samdb = self.get_samdb() >- self.machine_creds, _ = self.create_account(samdb, >- MACHINE_NAME, >- machine_account=True) >+ self.machine_creds, _ = self.create_account( >+ samdb, >+ MACHINE_NAME, >+ account_type=self.AccountType.COMPUTER) > self.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) > self.machine_creds.set_kerberos_state(DONT_USE_KERBEROS) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 1fc15315b0b..7cd3c5255f2 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -23,6 +23,7 @@ import tempfile > import binascii > import collections > import secrets >+from enum import Enum, auto > > from collections import namedtuple > import ldb >@@ -90,6 +91,10 @@ class KDCBaseTest(RawKerberosTest): > """ Base class for KDC tests. > """ > >+ class AccountType(Enum): >+ USER = auto() >+ COMPUTER = auto() >+ > @classmethod > def setUpClass(cls): > super().setUpClass() >@@ -230,7 +235,7 @@ class KDCBaseTest(RawKerberosTest): > > return default_enctypes > >- def create_account(self, samdb, name, machine_account=False, >+ def create_account(self, samdb, name, account_type=AccountType.USER, > spn=None, upn=None, additional_details=None, > ou=None, account_control=0): > '''Create an account for testing. >@@ -238,8 +243,10 @@ class KDCBaseTest(RawKerberosTest): > which is used by tearDownClass to clean up the created accounts. > ''' > if ou is None: >- guid = (DS_GUID_COMPUTERS_CONTAINER if machine_account >- else DS_GUID_USERS_CONTAINER) >+ if account_type is account_type.COMPUTER: >+ guid = DS_GUID_COMPUTERS_CONTAINER >+ else: >+ guid = DS_GUID_USERS_CONTAINER > > ou = samdb.get_wellknown_dn(samdb.get_default_basedn(), guid) > >@@ -248,14 +255,17 @@ class KDCBaseTest(RawKerberosTest): > # remove the account if it exists, this will happen if a previous test > # run failed > delete_force(samdb, dn) >- if machine_account: >- object_class = "computer" >- account_name = "%s$" % name >- account_control |= UF_WORKSTATION_TRUST_ACCOUNT >- else: >+ if account_type is self.AccountType.USER: > object_class = "user" > account_name = name > account_control |= UF_NORMAL_ACCOUNT >+ else: >+ object_class = "computer" >+ account_name = "%s$" % name >+ if account_type is self.AccountType.COMPUTER: >+ account_control |= UF_WORKSTATION_TRUST_ACCOUNT >+ else: >+ self.fail() > > password = generate_random_password(32, 32) > utf16pw = ('"%s"' % password).encode('utf-16-le') >@@ -267,6 +277,10 @@ class KDCBaseTest(RawKerberosTest): > "userAccountControl": str(account_control), > "unicodePwd": utf16pw} > if spn is not None: >+ if isinstance(spn, str): >+ spn = spn.format(account=account_name) >+ else: >+ spn = tuple(s.format(account=account_name) for s in spn) > details["servicePrincipalName"] = spn > if upn is not None: > details["userPrincipalName"] = upn >@@ -280,10 +294,10 @@ class KDCBaseTest(RawKerberosTest): > creds.set_domain(samdb.domain_netbios_name().upper()) > creds.set_password(password) > creds.set_username(account_name) >- if machine_account: >- creds.set_workstation(name) >- else: >+ if account_type is self.AccountType.USER: > creds.set_workstation('') >+ else: >+ creds.set_workstation(name) > creds.set_dn(ldb.Dn(samdb, dn)) > creds.set_spn(spn) > # >@@ -609,13 +623,14 @@ class KDCBaseTest(RawKerberosTest): > return cleanup > > def get_cached_creds(self, *, >- machine_account, >+ account_type, > opts=None, > use_cache=True): > if opts is None: > opts = {} > > opts_default = { >+ 'spn': None, > 'allowed_replication': False, > 'allowed_replication_mock': False, > 'denied_replication': False, >@@ -632,7 +647,7 @@ class KDCBaseTest(RawKerberosTest): > } > > account_opts = { >- 'machine_account': machine_account, >+ 'account_type': account_type, > **opts_default, > **opts > } >@@ -651,7 +666,8 @@ class KDCBaseTest(RawKerberosTest): > return creds > > def create_account_opts(self, *, >- machine_account, >+ account_type, >+ spn, > allowed_replication, > allowed_replication_mock, > denied_replication, >@@ -665,12 +681,13 @@ class KDCBaseTest(RawKerberosTest): > delegation_from_dn, > trusted_to_auth_for_delegation, > fast_support): >- if machine_account: >- self.assertFalse(not_delegated) >- else: >+ if account_type is self.AccountType.USER: >+ self.assertIsNone(spn) > self.assertIsNone(delegation_to_spn) > self.assertIsNone(delegation_from_dn) > self.assertFalse(trusted_to_auth_for_delegation) >+ else: >+ self.assertFalse(not_delegated) > > samdb = self.get_samdb() > rodc_samdb = self.get_rodc_samdb() >@@ -707,13 +724,11 @@ class KDCBaseTest(RawKerberosTest): > details['msDS-AllowedToActOnBehalfOfOtherIdentity'] = ( > security_descriptor) > >- if machine_account: >+ if spn is None and account_type is not self.AccountType.USER: > spn = 'host/' + user_name >- else: >- spn = None > > creds, dn = self.create_account(samdb, user_name, >- machine_account=machine_account, >+ account_type=account_type, > spn=spn, > additional_details=details, > account_control=user_account_control) >@@ -787,7 +802,7 @@ class KDCBaseTest(RawKerberosTest): > allow_missing_password=False, > allow_missing_keys=True): > def create_client_account(): >- return self.get_cached_creds(machine_account=False) >+ return self.get_cached_creds(account_type=self.AccountType.USER) > > c = self._get_krb5_creds(prefix='CLIENT', > allow_missing_password=allow_missing_password, >@@ -799,7 +814,7 @@ class KDCBaseTest(RawKerberosTest): > allow_missing_password=False, > allow_missing_keys=True): > def create_mach_account(): >- return self.get_cached_creds(machine_account=True, >+ return self.get_cached_creds(account_type=self.AccountType.COMPUTER, > opts={'fast_support': True}) > > c = self._get_krb5_creds(prefix='MAC', >@@ -813,7 +828,7 @@ class KDCBaseTest(RawKerberosTest): > allow_missing_keys=True): > def create_service_account(): > return self.get_cached_creds( >- machine_account=True, >+ account_type=self.AccountType.COMPUTER, > opts={ > 'trusted_to_auth_for_delegation': True, > 'fast_support': True >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 9d846a2c3ad..f36704f998c 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -148,7 +148,8 @@ class KdcTgsTests(KDCBaseTest): > samdb = self.get_samdb() > user_name = "tsttktusr" > (uc, dn) = self.create_account(samdb, user_name) >- (mc, _) = self.create_account(samdb, "tsttktmac", machine_account=True) >+ (mc, _) = self.create_account(samdb, "tsttktmac", >+ account_type=self.AccountType.COMPUTER) > realm = uc.get_realm().lower() > > # Do the initial AS-REQ, should get a pre-authentication required >@@ -282,7 +283,7 @@ class KdcTgsTests(KDCBaseTest): > > def test_client_no_auth_data_required(self): > client_creds = self.get_cached_creds( >- machine_account=False, >+ account_type=self.AccountType.USER, > opts={'no_auth_data_required': True}) > service_creds = self.get_service_creds() > >@@ -299,7 +300,7 @@ class KdcTgsTests(KDCBaseTest): > def test_service_no_auth_data_required(self): > client_creds = self.get_client_creds() > service_creds = self.get_cached_creds( >- machine_account=True, >+ account_type=self.AccountType.COMPUTER, > opts={'no_auth_data_required': True}) > > tgt = self.get_tgt(client_creds) >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index 2ee3d4a2a83..0aa3309b814 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -95,7 +95,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -151,7 +152,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # > samdb = self.get_samdb() > mach_name = "mskilemac" >- (mc, dn) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, dn) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > realm = mc.get_realm().lower() > > # Do the initial AS-REQ, should get a pre-authentication required >@@ -215,7 +217,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -286,7 +289,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, as we've set UF_DONT_REQUIRE_PREAUTH > # we should get a valid AS-RESP >@@ -351,7 +355,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -420,7 +425,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -459,7 +465,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -523,7 +530,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > ename = user_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -586,7 +594,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, dn) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, dn) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > ename = mach_name + "@" + realm > uname = mach_name + "$@" + realm > >@@ -661,7 +670,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > ename = alt_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, as we've set UF_DONT_REQUIRE_PREAUTH > # we should get a valid AS-RESP >@@ -728,7 +738,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > uname = user_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -798,7 +809,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > ename = alt_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >diff --git a/python/samba/tests/krb5/rodc_tests.py b/python/samba/tests/krb5/rodc_tests.py >index 4579f9eb552..302ae865cf1 100755 >--- a/python/samba/tests/krb5/rodc_tests.py >+++ b/python/samba/tests/krb5/rodc_tests.py >@@ -39,12 +39,12 @@ class RodcKerberosTests(KDCBaseTest): > # and including the RODCIdentifier. > def test_rodc_ticket_signature(self): > user_creds = self.get_cached_creds( >- machine_account=False, >+ account_type=self.AccountType.USER, > opts={ > 'revealed_to_rodc': True > }) > target_creds = self.get_cached_creds( >- machine_account=True, >+ account_type=self.AccountType.COMPUTER, > opts={ > 'revealed_to_rodc': True > }) >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index bbb7135b55b..ea629d29706 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -220,12 +220,14 @@ class S4UKerberosTests(KDCBaseTest): > > def _run_s4u2self_test(self, kdc_dict): > client_opts = kdc_dict.pop('client_opts', None) >- client_creds = self.get_cached_creds(machine_account=False, >- opts=client_opts) >+ client_creds = self.get_cached_creds( >+ account_type=self.AccountType.USER, >+ opts=client_opts) > > service_opts = kdc_dict.pop('service_opts', None) >- service_creds = self.get_cached_creds(machine_account=True, >- opts=service_opts) >+ service_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service_opts) > > service_tgt = self.get_tgt(service_creds) > modify_service_tgt_fn = kdc_dict.pop('modify_service_tgt_fn', None) >@@ -432,8 +434,9 @@ class S4UKerberosTests(KDCBaseTest): > > def _run_delegation_test(self, kdc_dict): > client_opts = kdc_dict.pop('client_opts', None) >- client_creds = self.get_cached_creds(machine_account=False, >- opts=client_opts) >+ client_creds = self.get_cached_creds( >+ account_type=self.AccountType.USER, >+ opts=client_opts) > > service1_opts = kdc_dict.pop('service1_opts', {}) > service2_opts = kdc_dict.pop('service2_opts', {}) >@@ -443,24 +446,28 @@ class S4UKerberosTests(KDCBaseTest): > self.assertFalse(allow_delegation and allow_rbcd) > > if allow_rbcd: >- service1_creds = self.get_cached_creds(machine_account=True, >- opts=service1_opts) >+ service1_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service1_opts) > > self.assertNotIn('delegation_from_dn', service2_opts) > service2_opts['delegation_from_dn'] = str(service1_creds.get_dn()) > >- service2_creds = self.get_cached_creds(machine_account=True, >- opts=service2_opts) >+ service2_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service2_opts) > else: >- service2_creds = self.get_cached_creds(machine_account=True, >- opts=service2_opts) >+ service2_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service2_opts) > > if allow_delegation: > self.assertNotIn('delegation_to_spn', service1_opts) > service1_opts['delegation_to_spn'] = service2_creds.get_spn() > >- service1_creds = self.get_cached_creds(machine_account=True, >- opts=service1_opts) >+ service1_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service1_opts) > > client_tkt_options = kdc_dict.pop('client_tkt_options', 'forwardable') > expected_flags = krb5_asn1.TicketFlags(client_tkt_options) >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >index c44ea02d504..6a2b78398ac 100755 >--- a/python/samba/tests/krb5/test_ccache.py >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -55,11 +55,12 @@ class CcacheTests(KDCBaseTest): > (user_credentials, _) = self.create_account(samdb, user_name) > > # Create the machine account. >- (mach_credentials, _) = self.create_account(samdb, >- mach_name, >- machine_account=True, >- spn="%s/%s" % (service, >- mach_name)) >+ (mach_credentials, _) = self.create_account( >+ samdb, >+ mach_name, >+ account_type=self.AccountType.COMPUTER, >+ spn="%s/%s" % (service, >+ mach_name)) > > # Talk to the KDC to obtain the service ticket, which gets placed into > # the cache. The machine account name has to match the name in the >-- >2.25.1 > > >From 26486f7d62745539ed87f66f97802ab6ddc1d928 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:39:05 +1300 >Subject: [PATCH 369/686] tests/krb5: Decrease length of test account prefix > >This allows us more room to test with different account names. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit a5a6296e57cab2b53617d997c37b4e92d4124cc7) >--- > python/samba/tests/krb5/kdc_base_test.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 7cd3c5255f2..8f453b464fd 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -108,7 +108,7 @@ class KDCBaseTest(RawKerberosTest): > # An identifier to ensure created accounts have unique names. Windows > # caches accounts based on usernames, so account names being different > # across test runs avoids previous test runs affecting the results. >- cls.account_base = f'krb5_{secrets.token_hex(5)}_' >+ cls.account_base = f'{secrets.token_hex(4)}_' > cls.account_id = 0 > > # A set containing DNs of accounts created as part of testing. >-- >2.25.1 > > >From feb0283ec349eeb69fec9a1decd8ca9b32654982 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:41:39 +1300 >Subject: [PATCH 370/686] tests/krb5: Allow specifying prefix or suffix for > test account names > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 7e39994ed341883ac4c8c257220c19dbf70c7bc5) >--- > python/samba/tests/krb5/kdc_base_test.py | 8 ++++++++ > 1 file changed, 8 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 8f453b464fd..d8f3969d228 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -630,6 +630,8 @@ class KDCBaseTest(RawKerberosTest): > opts = {} > > opts_default = { >+ 'name_prefix': None, >+ 'name_suffix': None, > 'spn': None, > 'allowed_replication': False, > 'allowed_replication_mock': False, >@@ -667,6 +669,8 @@ class KDCBaseTest(RawKerberosTest): > > def create_account_opts(self, *, > account_type, >+ name_prefix, >+ name_suffix, > spn, > allowed_replication, > allowed_replication_mock, >@@ -696,6 +700,10 @@ class KDCBaseTest(RawKerberosTest): > > user_name = self.account_base + str(self.account_id) > type(self).account_id += 1 >+ if name_prefix is not None: >+ user_name = name_prefix + user_name >+ if name_suffix is not None: >+ user_name += name_suffix > > user_account_control = 0 > if trusted_to_auth_for_delegation: >-- >2.25.1 > > >From 77710701323cc180a8f15a12a047419c85210658 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:44:19 +1300 >Subject: [PATCH 371/686] tests/krb5: Allow creating machine accounts without a > trailing dollar > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit f4785ccfefe7c89f84ad847ca3c12f604172b321) >--- > python/samba/tests/krb5/kdc_base_test.py | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index d8f3969d228..35f168a3c83 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -237,7 +237,7 @@ class KDCBaseTest(RawKerberosTest): > > def create_account(self, samdb, name, account_type=AccountType.USER, > spn=None, upn=None, additional_details=None, >- ou=None, account_control=0): >+ ou=None, account_control=0, add_dollar=True): > '''Create an account for testing. > The dn of the created account is added to self.accounts, > which is used by tearDownClass to clean up the created accounts. >@@ -255,13 +255,14 @@ class KDCBaseTest(RawKerberosTest): > # remove the account if it exists, this will happen if a previous test > # run failed > delete_force(samdb, dn) >+ account_name = name > if account_type is self.AccountType.USER: > object_class = "user" >- account_name = name > account_control |= UF_NORMAL_ACCOUNT > else: > object_class = "computer" >- account_name = "%s$" % name >+ if add_dollar: >+ account_name += '$' > if account_type is self.AccountType.COMPUTER: > account_control |= UF_WORKSTATION_TRUST_ACCOUNT > else: >@@ -632,6 +633,7 @@ class KDCBaseTest(RawKerberosTest): > opts_default = { > 'name_prefix': None, > 'name_suffix': None, >+ 'add_dollar': True, > 'spn': None, > 'allowed_replication': False, > 'allowed_replication_mock': False, >@@ -671,6 +673,7 @@ class KDCBaseTest(RawKerberosTest): > account_type, > name_prefix, > name_suffix, >+ add_dollar, > spn, > allowed_replication, > allowed_replication_mock, >@@ -739,7 +742,8 @@ class KDCBaseTest(RawKerberosTest): > account_type=account_type, > spn=spn, > additional_details=details, >- account_control=user_account_control) >+ account_control=user_account_control, >+ add_dollar=add_dollar) > > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) >-- >2.25.1 > > >From cd7dd6089c48d790da372500cfd72866e5ffe63d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:45:08 +1300 >Subject: [PATCH 372/686] tests/krb5: Allow specifying the UPN for test > accounts > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 889476d1754f8ce2a41557ed3bf5242c1293584e) >--- > python/samba/tests/krb5/kdc_base_test.py | 4 ++++ > python/samba/tests/krb5/raw_testcase.py | 7 +++++++ > 2 files changed, 11 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 35f168a3c83..b24c6376ab0 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -300,6 +300,7 @@ class KDCBaseTest(RawKerberosTest): > else: > creds.set_workstation(name) > creds.set_dn(ldb.Dn(samdb, dn)) >+ creds.set_upn(upn) > creds.set_spn(spn) > # > # Save the account name so it can be deleted in tearDownClass >@@ -634,6 +635,7 @@ class KDCBaseTest(RawKerberosTest): > 'name_prefix': None, > 'name_suffix': None, > 'add_dollar': True, >+ 'upn': None, > 'spn': None, > 'allowed_replication': False, > 'allowed_replication_mock': False, >@@ -674,6 +676,7 @@ class KDCBaseTest(RawKerberosTest): > name_prefix, > name_suffix, > add_dollar, >+ upn, > spn, > allowed_replication, > allowed_replication_mock, >@@ -740,6 +743,7 @@ class KDCBaseTest(RawKerberosTest): > > creds, dn = self.create_account(samdb, user_name, > account_type=account_type, >+ upn=upn, > spn=spn, > additional_details=details, > account_control=user_account_control, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 0b9fe8e7a04..619a8d006b2 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -366,6 +366,7 @@ class KerberosCredentials(Credentials): > self.forced_salt = None > > self.dn = None >+ self.upn = None > self.spn = None > > def set_as_supported_enctypes(self, value): >@@ -475,6 +476,12 @@ class KerberosCredentials(Credentials): > def get_spn(self): > return self.spn > >+ def set_upn(self, upn): >+ self.upn = upn >+ >+ def get_upn(self): >+ return self.upn >+ > > class KerberosTicketCreds: > def __init__(self, ticket, session_key, >-- >2.25.1 > > >From a64242c832d855551fce5c8c7c17e615e7baa864 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:45:47 +1300 >Subject: [PATCH 373/686] tests/krb5: Fix account salt calculation to match > Windows > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 25bdf4c994e4fdb74abbacb1e22237f3f2cc37fe) >--- > python/samba/tests/krb5/raw_testcase.py | 13 +++++++++++-- > 1 file changed, 11 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 619a8d006b2..f352615db1f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -454,13 +454,22 @@ class KerberosCredentials(Credentials): > if self.forced_salt is not None: > return self.forced_salt > >+ upn = self.get_upn() >+ if upn is not None: >+ salt_name = upn.rsplit('@', 1)[0].replace('/', '') >+ else: >+ salt_name = self.get_username() >+ > if self.get_workstation(): >+ salt_name = self.get_username().lower() >+ if salt_name[-1] == '$': >+ salt_name = salt_name[:-1] > salt_string = '%shost%s.%s' % ( > self.get_realm().upper(), >- self.get_username().lower().rsplit('$', 1)[0], >+ salt_name, > self.get_realm().lower()) > else: >- salt_string = self.get_realm().upper() + self.get_username() >+ salt_string = self.get_realm().upper() + salt_name > > return salt_string.encode('utf-8') > >-- >2.25.1 > > >From dc411296f4ae704b21517ea15569c68aecb9eb75 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:46:36 +1300 >Subject: [PATCH 374/686] tests/krb5: Add tests for account salt calculation > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >[abartlet@samba.org backported from commit 46039baa81377df10e5b134e4bb064ed246795e4 > as the no_preauth side of the testsuite shows differences in enctypes > in Samba 4.14. The change is only in salt calculation so this is > not vital] >--- > python/samba/tests/krb5/as_req_tests.py | 10 + > python/samba/tests/krb5/salt_tests.py | 327 ++++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > selftest/knownfail.d/kdc-salt | 12 + > selftest/knownfail_heimdal_kdc | 108 ++++++++ > source4/selftest/tests.py | 8 + > 6 files changed, 466 insertions(+) > create mode 100755 python/samba/tests/krb5/salt_tests.py > create mode 100644 selftest/knownfail.d/kdc-salt > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 7d7baaebf24..08081928363 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -113,6 +113,13 @@ class AsReqKerberosTests(KDCBaseTest): > > def test_as_req_enc_timestamp(self): > client_creds = self.get_client_creds() >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_as_req_enc_timestamp_mac(self): >+ client_creds = self.get_mach_creds() >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def _run_as_req_enc_timestamp(self, client_creds): > client_account = client_creds.get_username() > client_as_etypes = self.get_default_enctypes() > client_kvno = client_creds.get_kvno() >@@ -197,6 +204,9 @@ class AsReqKerberosTests(KDCBaseTest): > pac_request=True) > self.assertIsNotNone(as_rep) > >+ return etype_info2 >+ >+ > if __name__ == "__main__": > global_asn1_print = False > global_hexdump = False >diff --git a/python/samba/tests/krb5/salt_tests.py b/python/samba/tests/krb5/salt_tests.py >new file mode 100755 >index 00000000000..ecbf618e40e >--- /dev/null >+++ b/python/samba/tests/krb5/salt_tests.py >@@ -0,0 +1,327 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+import ldb >+ >+from samba.tests.krb5.as_req_tests import AsReqKerberosTests >+import samba.tests.krb5.kcrypto as kcrypto >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class SaltTests(AsReqKerberosTests): >+ >+ def setUp(self): >+ super().setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def _get_creds(self, *, >+ account_type, >+ opts=None): >+ try: >+ return self.get_cached_creds( >+ account_type=account_type, >+ opts=opts) >+ except ldb.LdbError: >+ self.fail() >+ >+ def _run_salt_test(self, client_creds): >+ expected_salt = self.get_salt(client_creds) >+ self.assertIsNotNone(expected_salt) >+ >+ etype_info2 = self._run_as_req_enc_timestamp(client_creds) >+ >+ self.assertEqual(etype_info2[0]['etype'], kcrypto.Enctype.AES256) >+ self.assertEqual(etype_info2[0]['salt'], expected_salt) >+ >+ def test_salt_at_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'foo@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_case_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'Foo@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_case_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'Foo@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_double_at_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'foo@@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_double_at_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo@@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_start_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_prefix': '@foo'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_start_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_prefix': '@foo'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_end_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'foo@'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_end_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo@'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_end_no_dollar_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo@', >+ 'add_dollar': False}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_no_dollar_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'add_dollar': False}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_dollar_mid_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo$bar', >+ 'add_dollar': False}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_dollar_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'foo$bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_dollar_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo$bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_dollar_end_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'foo$'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_dollar_end_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo$'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo0'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo1'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'host/foo2'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'host/foo3'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo4@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo5@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'host/foo6@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'host/foo7@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_dollar_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo8$@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_dollar_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo9$@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_dollar_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'host/foo10$@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_dollar_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'host/foo11$@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_other_realm_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo12@other.realm'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_other_realm_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo13@other.realm'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_other_realm_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'host/foo14@other.realm'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_other_realm_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'host/foo15@other.realm'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_case_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'Foo16'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_case_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'Foo17'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_dollar_mid_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo$18@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_dollar_mid_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo$19@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_dollar_mid_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'host/foo$20@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_dollar_mid_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'host/foo$21@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_at_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo22@bar@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_at_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo23@bar@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = False >+ global_hexdump = False >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 81d78119d51..887bc29504c 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -101,6 +101,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/as_req_tests.py', > 'python/samba/tests/krb5/fast_tests.py', > 'python/samba/tests/krb5/rodc_tests.py', >+ 'python/samba/tests/krb5/salt_tests.py', > } > > >diff --git a/selftest/knownfail.d/kdc-salt b/selftest/knownfail.d/kdc-salt >new file mode 100644 >index 00000000000..1a4ecd44624 >--- /dev/null >+++ b/selftest/knownfail.d/kdc-salt >@@ -0,0 +1,12 @@ >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_case_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_case_user >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_no_dollar_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_user >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_start_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_start_user >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_user >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_double_at_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_double_at_user >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_upn_at_realm_user >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index b1d7a1ebe8f..b39b11c3c53 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -71,6 +71,114 @@ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc > # > # FAST tests > # >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 4bf4243cb59..66e53c517ed 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1270,6 +1270,14 @@ for env in ["fl2008r2dc", "fl2003dc"]: > 'TKT_SIG_SUPPORT': tkt_sig_support > }) > >+planoldpythontestsuite('fl2008r2dc', 'samba.tests.krb5.salt_tests', >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support >+ }) > > for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: > if env == "rodc": >-- >2.25.1 > > >From 8af0b160089cb749c75152d88270fd70c2c2d9ae Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 19 Oct 2021 16:01:36 +1300 >Subject: [PATCH 375/686] dsdb: Allow special chars like "@" in samAccountName > when generating the salt > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Wed Oct 20 12:54:54 UTC 2021 on sn-devel-184 > >(cherry picked from commit 5eeb441b771a1ffe1ba1c69b72e8795f525a58ed) >--- > auth/credentials/credentials_krb5.c | 12 +- > lib/krb5_wrap/krb5_samba.c | 192 +++++++++++++++--- > lib/krb5_wrap/krb5_samba.h | 13 +- > selftest/knownfail.d/kdc-salt | 11 - > source3/passdb/machine_account_secrets.c | 10 +- > .../dsdb/samdb/ldb_modules/password_hash.c | 23 ++- > 6 files changed, 195 insertions(+), 66 deletions(-) > >diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c >index d8ca6d97115..b712fa8bfd0 100644 >--- a/auth/credentials/credentials_krb5.c >+++ b/auth/credentials/credentials_krb5.c >@@ -1035,12 +1035,12 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred, > break; > } > >- ret = smb_krb5_salt_principal(realm, >- username, /* sAMAccountName */ >- upn, /* userPrincipalName */ >- uac_flags, >- mem_ctx, >- &salt_principal); >+ ret = smb_krb5_salt_principal_str(realm, >+ username, /* sAMAccountName */ >+ upn, /* userPrincipalName */ >+ uac_flags, >+ mem_ctx, >+ &salt_principal); > if (ret) { > talloc_free(mem_ctx); > return ret; >diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c >index 6ce1d09952e..6a769864361 100644 >--- a/lib/krb5_wrap/krb5_samba.c >+++ b/lib/krb5_wrap/krb5_samba.c >@@ -456,19 +456,20 @@ int smb_krb5_get_pw_salt(krb5_context context, > * > * @see smb_krb5_salt_principal2data > */ >-int smb_krb5_salt_principal(const char *realm, >+int smb_krb5_salt_principal(krb5_context krb5_ctx, >+ const char *realm, > const char *sAMAccountName, > const char *userPrincipalName, > uint32_t uac_flags, >- TALLOC_CTX *mem_ctx, >- char **_salt_principal) >+ krb5_principal *salt_princ) > { > TALLOC_CTX *frame = talloc_stackframe(); > char *upper_realm = NULL; > const char *principal = NULL; > int principal_len = 0; >+ krb5_error_code krb5_ret; > >- *_salt_principal = NULL; >+ *salt_princ = NULL; > > if (sAMAccountName == NULL) { > TALLOC_FREE(frame); >@@ -512,7 +513,6 @@ int smb_krb5_salt_principal(const char *realm, > */ > if (uac_flags & UF_TRUST_ACCOUNT_MASK) { > int computer_len = 0; >- char *tmp = NULL; > > computer_len = strlen(sAMAccountName); > if (sAMAccountName[computer_len-1] == '$') { >@@ -520,60 +520,186 @@ int smb_krb5_salt_principal(const char *realm, > } > > if (uac_flags & UF_INTERDOMAIN_TRUST_ACCOUNT) { >- principal = talloc_asprintf(frame, "krbtgt/%*.*s", >- computer_len, computer_len, >- sAMAccountName); >- if (principal == NULL) { >+ const char *krbtgt = "krbtgt"; >+ krb5_ret = krb5_build_principal_ext(krb5_ctx, >+ salt_princ, >+ strlen(upper_realm), >+ upper_realm, >+ strlen(krbtgt), >+ krbtgt, >+ computer_len, >+ sAMAccountName, >+ 0); >+ if (krb5_ret != 0) { > TALLOC_FREE(frame); >- return ENOMEM; >+ return krb5_ret; > } > } else { >- >- tmp = talloc_asprintf(frame, "host/%*.*s.%s", >- computer_len, computer_len, >- sAMAccountName, realm); >+ const char *host = "host"; >+ char *tmp = NULL; >+ char *tmp_lower = NULL; >+ >+ tmp = talloc_asprintf(frame, "%*.*s.%s", >+ computer_len, >+ computer_len, >+ sAMAccountName, >+ realm); > if (tmp == NULL) { > TALLOC_FREE(frame); > return ENOMEM; > } > >- principal = strlower_talloc(frame, tmp); >- TALLOC_FREE(tmp); >- if (principal == NULL) { >+ tmp_lower = strlower_talloc(frame, tmp); >+ if (tmp_lower == NULL) { > TALLOC_FREE(frame); > return ENOMEM; > } >- } > >- principal_len = strlen(principal); >+ krb5_ret = krb5_build_principal_ext(krb5_ctx, >+ salt_princ, >+ strlen(upper_realm), >+ upper_realm, >+ strlen(host), >+ host, >+ strlen(tmp_lower), >+ tmp_lower, >+ 0); >+ if (krb5_ret != 0) { >+ TALLOC_FREE(frame); >+ return krb5_ret; >+ } >+ } > > } else if (userPrincipalName != NULL) { >- char *p; >+ /* >+ * We parse the name not only to allow an easy >+ * replacement of the realm (no matter the realm in >+ * the UPN, the salt comes from the upper-case real >+ * realm, but also to correctly provide a salt when >+ * the UPN is host/foo.bar >+ * >+ * This can fail for a UPN of the form foo@bar@REALM >+ * (which is accepted by windows) however. >+ */ >+ krb5_ret = krb5_parse_name(krb5_ctx, >+ userPrincipalName, >+ salt_princ); > >- principal = userPrincipalName; >- p = strchr(principal, '@'); >- if (p != NULL) { >- principal_len = PTR_DIFF(p, principal); >- } else { >- principal_len = strlen(principal); >+ if (krb5_ret != 0) { >+ TALLOC_FREE(frame); >+ return krb5_ret; >+ } >+ >+ /* >+ * No matter what realm (including none) in the UPN, >+ * the realm is replaced with our upper-case realm >+ */ >+ smb_krb5_principal_set_realm(krb5_ctx, >+ *salt_princ, >+ upper_realm); >+ if (krb5_ret != 0) { >+ krb5_free_principal(krb5_ctx, *salt_princ); >+ TALLOC_FREE(frame); >+ return krb5_ret; > } > } else { > principal = sAMAccountName; > principal_len = strlen(principal); >- } > >- *_salt_principal = talloc_asprintf(mem_ctx, "%*.*s@%s", >- principal_len, principal_len, >- principal, upper_realm); >- if (*_salt_principal == NULL) { >- TALLOC_FREE(frame); >- return ENOMEM; >+ krb5_ret = krb5_build_principal_ext(krb5_ctx, >+ salt_princ, >+ strlen(upper_realm), >+ upper_realm, >+ principal_len, >+ principal, >+ 0); >+ if (krb5_ret != 0) { >+ TALLOC_FREE(frame); >+ return krb5_ret; >+ } > } > > TALLOC_FREE(frame); > return 0; > } > >+/** >+ * @brief This constructs the salt principal used by active directory >+ * >+ * Most Kerberos encryption types require a salt in order to >+ * calculate the long term private key for user/computer object >+ * based on a password. >+ * >+ * The returned _salt_principal is a string in forms like this: >+ * - host/somehost.example.com@EXAMPLE.COM >+ * - SomeAccount@EXAMPLE.COM >+ * - SomePrincipal@EXAMPLE.COM >+ * >+ * This is not the form that's used as salt, it's just >+ * the human readable form. It needs to be converted by >+ * smb_krb5_salt_principal2data(). >+ * >+ * @param[in] realm The realm the user/computer is added too. >+ * >+ * @param[in] sAMAccountName The sAMAccountName attribute of the object. >+ * >+ * @param[in] userPrincipalName The userPrincipalName attribute of the object >+ * or NULL is not available. >+ * >+ * @param[in] uac_flags UF_ACCOUNT_TYPE_MASKed userAccountControl field >+ * >+ * @param[in] mem_ctx The TALLOC_CTX to allocate _salt_principal. >+ * >+ * @param[out] _salt_principal The resulting principal as string. >+ * >+ * @retval 0 Success; otherwise - Kerberos error codes >+ * >+ * @see smb_krb5_salt_principal2data >+ */ >+int smb_krb5_salt_principal_str(const char *realm, >+ const char *sAMAccountName, >+ const char *userPrincipalName, >+ uint32_t uac_flags, >+ TALLOC_CTX *mem_ctx, >+ char **_salt_principal_str) >+{ >+ krb5_principal salt_principal = NULL; >+ char *salt_principal_malloc; >+ krb5_context krb5_ctx; >+ krb5_error_code krb5_ret >+ = smb_krb5_init_context_common(&krb5_ctx); >+ if (krb5_ret != 0) { >+ DBG_ERR("kerberos init context failed (%s)\n", >+ error_message(krb5_ret)); >+ return krb5_ret; >+ } >+ >+ krb5_ret = smb_krb5_salt_principal(krb5_ctx, >+ realm, >+ sAMAccountName, >+ userPrincipalName, >+ uac_flags, >+ &salt_principal); >+ >+ krb5_ret = krb5_unparse_name(krb5_ctx, salt_principal, >+ &salt_principal_malloc); >+ if (krb5_ret != 0) { >+ krb5_free_principal(krb5_ctx, salt_principal); >+ DBG_ERR("kerberos unparse of salt principal failed (%s)\n", >+ error_message(krb5_ret)); >+ return krb5_ret; >+ } >+ krb5_free_principal(krb5_ctx, salt_principal); >+ *_salt_principal_str >+ = talloc_strdup(mem_ctx, salt_principal_malloc); >+ krb5_free_unparsed_name(krb5_ctx, salt_principal_malloc); >+ >+ if (*_salt_principal_str == NULL) { >+ return ENOMEM; >+ } >+ return 0; >+} >+ > /** > * @brief Converts the salt principal string into the salt data blob > * >diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h >index b6ee04f60fe..e7e08211fa5 100644 >--- a/lib/krb5_wrap/krb5_samba.h >+++ b/lib/krb5_wrap/krb5_samba.h >@@ -350,12 +350,19 @@ krb5_error_code ms_suptypes_to_ietf_enctypes(TALLOC_CTX *mem_ctx, > int smb_krb5_get_pw_salt(krb5_context context, > krb5_const_principal host_princ, > krb5_data *psalt); >-int smb_krb5_salt_principal(const char *realm, >+int smb_krb5_salt_principal(krb5_context krb5_ctx, >+ const char *realm, > const char *sAMAccountName, > const char *userPrincipalName, > uint32_t uac_flags, >- TALLOC_CTX *mem_ctx, >- char **_salt_principal); >+ krb5_principal *salt_princ); >+ >+int smb_krb5_salt_principal_str(const char *realm, >+ const char *sAMAccountName, >+ const char *userPrincipalName, >+ uint32_t uac_flags, >+ TALLOC_CTX *mem_ctx, >+ char **_salt_principal); > int smb_krb5_salt_principal2data(krb5_context context, > const char *salt_principal, > TALLOC_CTX *mem_ctx, >diff --git a/selftest/knownfail.d/kdc-salt b/selftest/knownfail.d/kdc-salt >index 1a4ecd44624..a671e4d93eb 100644 >--- a/selftest/knownfail.d/kdc-salt >+++ b/selftest/knownfail.d/kdc-salt >@@ -1,12 +1 @@ >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_case_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_case_user >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_no_dollar_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_user >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_start_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_start_user >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_user >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_double_at_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_double_at_user > ^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_upn_at_realm_user >diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c >index dfc21f295a1..daa565c9097 100644 >--- a/source3/passdb/machine_account_secrets.c >+++ b/source3/passdb/machine_account_secrets.c >@@ -1610,11 +1610,11 @@ NTSTATUS secrets_store_JoinCtx(const struct libnet_JoinCtx *r) > if (info->salt_principal == NULL && r->out.domain_is_ad) { > char *p = NULL; > >- ret = smb_krb5_salt_principal(info->domain_info.dns_domain.string, >- info->account_name, >- NULL /* userPrincipalName */, >- UF_WORKSTATION_TRUST_ACCOUNT, >- info, &p); >+ ret = smb_krb5_salt_principal_str(info->domain_info.dns_domain.string, >+ info->account_name, >+ NULL /* userPrincipalName */, >+ UF_WORKSTATION_TRUST_ACCOUNT, >+ info, &p); > if (ret != 0) { > status = krb5_to_nt_status(ret); > DBG_ERR("smb_krb5_salt_principal() failed " >diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c >index 5f571033004..71845b24ad8 100644 >--- a/source4/dsdb/samdb/ldb_modules/password_hash.c >+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c >@@ -672,8 +672,8 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) > { > struct ldb_context *ldb; > krb5_error_code krb5_ret; >- char *salt_principal = NULL; >- char *salt_data = NULL; >+ krb5_principal salt_principal = NULL; >+ krb5_data salt_data; > krb5_data salt; > krb5_keyblock key; > krb5_data cleartext_data; >@@ -684,11 +684,11 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) > cleartext_data.length = io->n.cleartext_utf8->length; > > uac_flags = io->u.userAccountControl & UF_ACCOUNT_TYPE_MASK; >- krb5_ret = smb_krb5_salt_principal(io->ac->status->domain_data.realm, >+ krb5_ret = smb_krb5_salt_principal(io->smb_krb5_context->krb5_context, >+ io->ac->status->domain_data.realm, > io->u.sAMAccountName, > io->u.user_principal_name, > uac_flags, >- io->ac, > &salt_principal); > if (krb5_ret) { > ldb_asprintf_errstring(ldb, >@@ -702,8 +702,10 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) > /* > * create salt from salt_principal > */ >- krb5_ret = smb_krb5_salt_principal2data(io->smb_krb5_context->krb5_context, >- salt_principal, io->ac, &salt_data); >+ krb5_ret = smb_krb5_get_pw_salt(io->smb_krb5_context->krb5_context, >+ salt_principal, &salt_data); >+ >+ krb5_free_principal(io->smb_krb5_context->krb5_context, salt_principal); > if (krb5_ret) { > ldb_asprintf_errstring(ldb, > "setup_kerberos_keys: " >@@ -712,12 +714,17 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) > krb5_ret, io->ac)); > return LDB_ERR_OPERATIONS_ERROR; > } >- io->g.salt = salt_data; > > /* now use the talloced copy of the salt */ >- salt.data = discard_const(io->g.salt); >+ salt.data = talloc_strndup(io->ac, >+ (char *)salt_data.data, >+ salt_data.length); >+ io->g.salt = salt.data; > salt.length = strlen(io->g.salt); > >+ smb_krb5_free_data_contents(io->smb_krb5_context->krb5_context, >+ &salt_data); >+ > /* > * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of > * the salt and the cleartext password >-- >2.25.1 > > >From be4c6d1d6bcb00079555a383602a23bfb31a0f6c Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 22 Oct 2021 10:50:36 +1300 >Subject: [PATCH 376/686] lib/krb5_wrap: Fix missing error check in new salt > code > >CID 1492905: Control flow issues (DEADCODE) > >This was a regression in 5eeb441b771a1ffe1ba1c69b72e8795f525a58ed. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Sat Oct 23 08:07:13 UTC 2021 on sn-devel-184 > >(cherry picked from commit 5094d986b7686f057195dcb10764295b88967019) > >Autobuild-User(v4-13-test): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(v4-13-test): Wed Oct 27 23:29:34 UTC 2021 on sn-devel-184 >--- > lib/krb5_wrap/krb5_samba.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > >diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c >index 6a769864361..24b43218917 100644 >--- a/lib/krb5_wrap/krb5_samba.c >+++ b/lib/krb5_wrap/krb5_samba.c >@@ -594,9 +594,9 @@ int smb_krb5_salt_principal(krb5_context krb5_ctx, > * No matter what realm (including none) in the UPN, > * the realm is replaced with our upper-case realm > */ >- smb_krb5_principal_set_realm(krb5_ctx, >- *salt_princ, >- upper_realm); >+ krb5_ret = smb_krb5_principal_set_realm(krb5_ctx, >+ *salt_princ, >+ upper_realm); > if (krb5_ret != 0) { > krb5_free_principal(krb5_ctx, *salt_princ); > TALLOC_FREE(frame); >-- >2.25.1 > > >From b161ee7b11d66cef5a8bb521b6aeb54c4efbbd2d Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 5 May 2020 13:47:39 +1200 >Subject: [PATCH 377/686] CVE-2020-25722 Fix clang 9 missing-field-initializer > warnings > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >[abartlet@samba.org backported from commit 13a2f70a4dd6dd68e0dbd0379d35409c5f100f06 > due to wscript changes] > >[jsutton@samba.org Adapted to fix conflicts and remove changes to > missing files] >--- > auth/credentials/pycredentials.c | 2 +- > examples/libsmbclient/testbrowse.c | 4 +--- > lib/crypto/py_crypto.c | 2 +- > lib/ldb-samba/pyldb.c | 2 +- > lib/ldb-samba/samba_extensions.c | 4 ++-- > lib/ldb/pyldb.c | 16 ++++++++-------- > lib/ldb/tools/cmdline.c | 2 +- > lib/talloc/pytalloc.c | 2 +- > lib/talloc/test_pytalloc.c | 2 +- > lib/tdb/pytdb.c | 2 +- > lib/tevent/pytevent.c | 16 ++++++++-------- > libcli/nbt/pynbt.c | 2 +- > libcli/security/pysecurity.c | 2 +- > libgpo/pygpo.c | 8 ++++---- > librpc/tools/ndrdump.c | 2 +- > pidl/lib/Parse/Pidl/Samba4/Python.pm | 2 +- > python/pyglue.c | 2 +- > source3/libsmb/pylibsmb.c | 2 +- > source3/param/pyparam.c | 2 +- > source3/passdb/py_passdb.c | 4 ++-- > source3/smbd/posix_acls.c | 2 +- > source3/smbd/pysmbd.c | 2 +- > source3/torture/cmd_vfs.c | 2 +- > source3/utils/smbcontrol.c | 2 +- > source4/auth/gensec/pygensec.c | 2 +- > source4/auth/pyauth.c | 2 +- > source4/client/cifsdd.c | 2 +- > source4/dns_server/dlz_bind9.c | 2 +- > source4/dns_server/pydns.c | 2 +- > source4/dsdb/pydsdb.c | 2 +- > source4/lib/policy/pypolicy.c | 2 +- > source4/lib/registry/pyregistry.c | 6 +++--- > source4/lib/registry/tools/regdiff.c | 2 +- > source4/lib/registry/tools/regpatch.c | 2 +- > source4/lib/registry/tools/regshell.c | 4 ++-- > source4/lib/registry/tools/regtree.c | 2 +- > source4/librpc/ndr/py_security.c | 8 ++++---- > source4/librpc/ndr/py_xattr.c | 2 +- > source4/ntvfs/posix/python/pyposix_eadb.c | 2 +- > source4/ntvfs/posix/python/pyxattr_native.c | 2 +- > source4/ntvfs/posix/python/pyxattr_tdb.c | 2 +- > source4/param/pyparam.c | 6 +++--- > source4/torture/gentest.c | 2 +- > source4/torture/locktest.c | 2 +- > source4/torture/masktest.c | 2 +- > source4/torture/smbtorture.c | 2 +- > source4/torture/vfs/fruit.c | 2 +- > 47 files changed, 74 insertions(+), 76 deletions(-) > >diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c >index b4239730818..de766641920 100644 >--- a/auth/credentials/pycredentials.c >+++ b/auth/credentials/pycredentials.c >@@ -878,7 +878,7 @@ static PyObject *py_ccache_name(PyObject *self, PyObject *unused) > static PyMethodDef py_ccache_container_methods[] = { > { "get_name", py_ccache_name, METH_NOARGS, > "S.get_name() -> name\nObtain KRB5 credentials cache name." }, >- { NULL } >+ {0} > }; > > PyTypeObject PyCredentialCacheContainer = { >diff --git a/examples/libsmbclient/testbrowse.c b/examples/libsmbclient/testbrowse.c >index 0629653ef8b..1609e2f4f91 100644 >--- a/examples/libsmbclient/testbrowse.c >+++ b/examples/libsmbclient/testbrowse.c >@@ -65,9 +65,7 @@ int main(int argc, const char *argv[]) > "contextauth", 'C', POPT_ARG_NONE, &context_auth, > 0, "Use new authentication function with context", "integer" > }, >- { >- NULL >- } >+ {0} > }; > > setbuf(stdout, NULL); >diff --git a/lib/crypto/py_crypto.c b/lib/crypto/py_crypto.c >index bf7f9f4481c..d5d728c3878 100644 >--- a/lib/crypto/py_crypto.c >+++ b/lib/crypto/py_crypto.c >@@ -67,7 +67,7 @@ static const char py_crypto_arcfour_crypt_blob_doc[] = "arcfour_crypt_blob(data, > > static PyMethodDef py_crypto_methods[] = { > { "arcfour_crypt_blob", (PyCFunction)py_crypto_arcfour_crypt_blob, METH_VARARGS, py_crypto_arcfour_crypt_blob_doc }, >- { NULL }, >+ {0}, > }; > > static struct PyModuleDef moduledef = { >diff --git a/lib/ldb-samba/pyldb.c b/lib/ldb-samba/pyldb.c >index 57c5397bc06..b13f1d320f4 100644 >--- a/lib/ldb-samba/pyldb.c >+++ b/lib/ldb-samba/pyldb.c >@@ -235,7 +235,7 @@ static PyMethodDef py_samba_ldb_methods[] = { > { "set_session_info", (PyCFunction)py_ldb_set_session_info, METH_VARARGS, > "set_session_info(session_info)\n" > "Set session info to use when connecting." }, >- { NULL }, >+ {0}, > }; > > static struct PyModuleDef moduledef = { >diff --git a/lib/ldb-samba/samba_extensions.c b/lib/ldb-samba/samba_extensions.c >index 45b01e1b447..65a4079ec97 100644 >--- a/lib/ldb-samba/samba_extensions.c >+++ b/lib/ldb-samba/samba_extensions.c >@@ -41,7 +41,7 @@ > static unsigned calculate_popt_array_length(struct poptOption *opts) > { > unsigned i; >- struct poptOption zero_opt = { NULL }; >+ struct poptOption zero_opt = { 0 }; > for (i=0; memcmp(&zero_opt, &opts[i], sizeof(zero_opt)) != 0; i++) ; > return i; > } >@@ -51,7 +51,7 @@ static struct poptOption cmdline_extensions[] = { > POPT_COMMON_CREDENTIALS > POPT_COMMON_CONNECTION > POPT_COMMON_VERSION >- { NULL } >+ {0} > }; > > /* >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index 0c6e5ad857f..6423db22e49 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -758,7 +758,7 @@ static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args) > { > unsigned int num = 0; > char *name = NULL, *value = NULL; >- struct ldb_val val = { NULL, }; >+ struct ldb_val val = { 0 }; > int err; > Py_ssize_t size = 0; > >@@ -875,7 +875,7 @@ static PyMethodDef py_ldb_dn_methods[] = { > { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS, > "S.get_rdn_value() -> string\n" > "get the RDN attribute value as a binary string" }, >- { NULL } >+ {0} > }; > > static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self) >@@ -2407,7 +2407,7 @@ static PyMethodDef py_ldb_methods[] = { > { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS, > "S._register_test_extensions() -> None\n" > "Register internal extensions used in testing" }, >- { NULL }, >+ {0}, > }; > > static PyObject *PyLdbModule_FromModule(struct ldb_module *mod) >@@ -2734,7 +2734,7 @@ static PyMethodDef py_ldb_search_iterator_methods[] = { > "S.result() -> ldb.Result (without msgs and referrals)\n" }, > { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS, > "S.abandon()\n" }, >- { NULL } >+ {0} > }; > > static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self) >@@ -2929,7 +2929,7 @@ static PyMethodDef py_ldb_module_methods[] = { > { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL }, > { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL }, > { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL }, >- { NULL }, >+ {0}, > }; > > static void py_ldb_module_dealloc(PyLdbModuleObject *self) >@@ -3107,7 +3107,7 @@ static PyMethodDef py_ldb_msg_element_methods[] = { > { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL }, > { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL }, > { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL }, >- { NULL }, >+ {0}, > }; > > static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self) >@@ -3616,7 +3616,7 @@ static PyMethodDef py_ldb_msg_methods[] = { > { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS, > "S.add(element)\n\n" > "Add an element to this message." }, >- { NULL }, >+ {0}, > }; > > static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self) >@@ -4295,7 +4295,7 @@ static PyMethodDef py_ldb_global_methods[] = { > { "binary_decode", py_binary_decode, METH_VARARGS, > "S.binary_decode(string) -> string\n\n" > "Perform a RFC2254 binary decode on a string" }, >- { NULL } >+ {0} > }; > > #define MODULE_DOC "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server." >diff --git a/lib/ldb/tools/cmdline.c b/lib/ldb/tools/cmdline.c >index a2fe97ee6b2..b0f4c5c2141 100644 >--- a/lib/ldb/tools/cmdline.c >+++ b/lib/ldb/tools/cmdline.c >@@ -59,7 +59,7 @@ static struct poptOption builtin_popt_options[] = { > { "relax", 0, POPT_ARG_NONE, NULL, CMDLINE_RELAX, "pass relax control", NULL }, > { "cross-ncs", 0, POPT_ARG_NONE, NULL, 'N', "search across NC boundaries", NULL }, > { "extended-dn", 0, POPT_ARG_NONE, NULL, 'E', "show extended DNs", NULL }, >- { NULL } >+ {0} > }; > > void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f) >diff --git a/lib/talloc/pytalloc.c b/lib/talloc/pytalloc.c >index e583c05ea6f..801e0243c51 100644 >--- a/lib/talloc/pytalloc.c >+++ b/lib/talloc/pytalloc.c >@@ -75,7 +75,7 @@ static PyMethodDef talloc_methods[] = { > "enable tracking of the NULL object"}, > { "total_blocks", (PyCFunction)pytalloc_total_blocks, METH_VARARGS, > "return talloc block count"}, >- { NULL } >+ {0} > }; > > /** >diff --git a/lib/talloc/test_pytalloc.c b/lib/talloc/test_pytalloc.c >index a7c31c1ad5e..113caa9ce0b 100644 >--- a/lib/talloc/test_pytalloc.c >+++ b/lib/talloc/test_pytalloc.c >@@ -89,7 +89,7 @@ static PyMethodDef test_talloc_methods[] = { > "call pytalloc_reference_ex"}, > { "base_reference", (PyCFunction)testpytalloc_base_reference, METH_VARARGS, > "call pytalloc_reference_ex"}, >- { NULL } >+ {0} > }; > > static PyTypeObject DObject_Type; >diff --git a/lib/tdb/pytdb.c b/lib/tdb/pytdb.c >index 78a20cc09c4..32708e63efc 100644 >--- a/lib/tdb/pytdb.c >+++ b/lib/tdb/pytdb.c >@@ -533,7 +533,7 @@ static PyMethodDef tdb_object_methods[] = { > "S.enable_seqnum() -> None" }, > { "increment_seqnum_nonblock", (PyCFunction)obj_increment_seqnum_nonblock, METH_NOARGS, > "S.increment_seqnum_nonblock() -> None" }, >- { NULL } >+ {0} > }; > > static PyObject *obj_get_hash_size(PyTdbObject *self, void *closure) >diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c >index a46ba02b575..14039628e78 100644 >--- a/lib/tevent/pytevent.c >+++ b/lib/tevent/pytevent.c >@@ -268,7 +268,7 @@ static PyMethodDef py_tevent_queue_methods[] = { > "S.start()" }, > { "add", (PyCFunction)py_tevent_queue_add, METH_VARARGS, > "S.add(ctx, req, trigger, baton)" }, >- { NULL }, >+ {0}, > }; > > static PyObject *py_tevent_context_wakeup_send(PyObject *self, PyObject *args) >@@ -389,7 +389,7 @@ struct PyGetSetDef py_tevent_timer_getset[] = { > .get = (getter)py_tevent_timer_get_active, > .doc = discard_const_p(char, "true if the timer is scheduled to run"), > }, >- {NULL}, >+ {0}, > }; > > static PyTypeObject TeventTimer_Type = { >@@ -570,7 +570,7 @@ static PyMethodDef py_tevent_context_methods[] = { > METH_VARARGS, "S.add_timer_offset(offset_seconds, handler) -> timer" }, > { "add_fd", (PyCFunction)py_tevent_context_add_fd, > METH_VARARGS, "S.add_fd(fd, flags, handler) -> fd" }, >- { NULL }, >+ {0}, > }; > > static PyObject *py_tevent_req_wakeup_recv(PyObject *self) >@@ -609,7 +609,7 @@ static PyGetSetDef py_tevent_req_getsetters[] = { > .get = (getter)py_tevent_req_is_in_progress, > .doc = discard_const_p(char, "Whether the request is in progress"), > }, >- { NULL } >+ {0} > }; > > static PyObject *py_tevent_req_post(PyObject *self, PyObject *args) >@@ -672,7 +672,7 @@ static PyMethodDef py_tevent_req_methods[] = { > METH_VARARGS, "set_endtime(ctx, endtime)" }, > { "cancel", (PyCFunction)py_tevent_req_cancel, > METH_NOARGS, "cancel()" }, >- { NULL } >+ {0} > }; > > static void py_tevent_req_dealloc(TeventReq_Object *self) >@@ -701,7 +701,7 @@ static PyGetSetDef py_tevent_queue_getsetters[] = { > .get = (getter)py_tevent_queue_get_length, > .doc = discard_const_p(char, "The number of elements in the queue."), > }, >- { NULL }, >+ {0}, > }; > > static void py_tevent_queue_dealloc(TeventQueue_Object *self) >@@ -731,7 +731,7 @@ static PyGetSetDef py_tevent_context_getsetters[] = { > .get = (getter)py_tevent_context_signal_support, > .doc = discard_const_p(char, "if this platform and tevent context support signal handling"), > }, >- { NULL } >+ {0} > }; > > static void py_tevent_context_dealloc(TeventContext_Object *self) >@@ -841,7 +841,7 @@ static PyMethodDef tevent_methods[] = { > METH_VARARGS, "set_default_backend(backend)" }, > { "backend_list", (PyCFunction)py_backend_list, > METH_NOARGS, "backend_list() -> list" }, >- { NULL }, >+ {0}, > }; > > #define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.") >diff --git a/libcli/nbt/pynbt.c b/libcli/nbt/pynbt.c >index 032561a4bd8..cc029b4e520 100644 >--- a/libcli/nbt/pynbt.c >+++ b/libcli/nbt/pynbt.c >@@ -385,7 +385,7 @@ static PyMethodDef py_nbt_methods[] = { > "S.name_status(name, dest, timeout=0, retries=0) -> (reply_from, name, status)\n" > "Find the status of a name" }, > >- { NULL } >+ {0} > }; > > PyTypeObject nbt_node_Type = { >diff --git a/libcli/security/pysecurity.c b/libcli/security/pysecurity.c >index 72058424d99..a9c2e1355fd 100644 >--- a/libcli/security/pysecurity.c >+++ b/libcli/security/pysecurity.c >@@ -70,7 +70,7 @@ static PyObject *py_se_access_check(PyObject *module, PyObject *args, PyObject * > static PyMethodDef py_security_methods[] = { > { "access_check", (PyCFunction)py_se_access_check, METH_VARARGS|METH_KEYWORDS, > "access_check(security_descriptor, token, access_desired) -> access_granted. Raises NT_STATUS on error, including on access check failure, returns access granted bitmask"}, >- { NULL }, >+ {0}, > }; > > static struct PyModuleDef moduledef = { >diff --git a/libgpo/pygpo.c b/libgpo/pygpo.c >index 4cfd5720065..368d7cb50ae 100644 >--- a/libgpo/pygpo.c >+++ b/libgpo/pygpo.c >@@ -66,7 +66,7 @@ static PyGetSetDef GPO_setters[] = { > NULL, NULL, NULL}, > {discard_const_p(char, "machine_extensions"), > (getter)GPO_get_machine_extensions, NULL, NULL, NULL}, >- {NULL} >+ {0} > }; > > static PyObject *py_gpo_get_unix_path(PyObject *self, PyObject *args, >@@ -119,7 +119,7 @@ out: > static PyMethodDef GPO_methods[] = { > {"get_unix_path", (PyCFunction)py_gpo_get_unix_path, METH_VARARGS | METH_KEYWORDS, > NULL }, >- {NULL} >+ {0} > }; > > static PyTypeObject GPOType = { >@@ -484,7 +484,7 @@ static PyMethodDef ADS_methods[] = { > { "get_gpo_list", (PyCFunction)py_ads_get_gpo_list, METH_VARARGS | METH_KEYWORDS, > NULL }, > #endif >- { NULL } >+ {0} > }; > > static PyTypeObject ads_ADSType = { >@@ -502,7 +502,7 @@ static PyMethodDef py_gpo_methods[] = { > {"gpo_get_sysvol_gpt_version", > (PyCFunction)py_gpo_get_sysvol_gpt_version, > METH_VARARGS, NULL}, >- {NULL} >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c >index bd4f277607b..089b160b65f 100644 >--- a/librpc/tools/ndrdump.c >+++ b/librpc/tools/ndrdump.c >@@ -274,7 +274,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > {"hex-input", 0, POPT_ARG_NONE, NULL, OPT_HEX_INPUT, "Read the input file in as a hex dump", NULL }, > POPT_COMMON_SAMBA > POPT_COMMON_VERSION >- { NULL } >+ {0} > }; > uint32_t highest_ofs; > struct dcerpc_sec_verification_trailer *sec_vt = NULL; >diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm >index 5697b52c4fe..6e4b730af6c 100644 >--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm >+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm >@@ -1387,7 +1387,7 @@ sub Interface($$$) > my ($infn, $outfn, $callfn, $prettyname, $docstring, $opnum) = @$d; > $self->pidl("{ \"$prettyname\", $docstring, (py_dcerpc_call_fn)$callfn, (py_data_pack_fn)$infn, (py_data_unpack_fn)$outfn, $opnum, &ndr_table_$interface->{NAME} },"); > } >- $self->pidl("{ NULL }"); >+ $self->pidl("{0}"); > $self->deindent; > $self->pidl("};"); > $self->pidl(""); >diff --git a/python/pyglue.c b/python/pyglue.c >index 70e211606ff..cacc8122c3f 100644 >--- a/python/pyglue.c >+++ b/python/pyglue.c >@@ -385,7 +385,7 @@ static PyMethodDef py_misc_methods[] = { > METH_VARARGS, > "generate_random_bytes(len) -> bytes\n" > "Generate random bytes with specified length." }, >- { NULL } >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c >index 7f5a07eac8a..3b3bc1f69cd 100644 >--- a/source3/libsmb/pylibsmb.c >+++ b/source3/libsmb/pylibsmb.c >@@ -1769,7 +1769,7 @@ static PyTypeObject py_cli_state_type = { > }; > > static PyMethodDef py_libsmb_methods[] = { >- { NULL }, >+ {0}, > }; > > void initlibsmb_samba_internal(void); >diff --git a/source3/param/pyparam.c b/source3/param/pyparam.c >index 4f80a0ef864..e4454f71a46 100644 >--- a/source3/param/pyparam.c >+++ b/source3/param/pyparam.c >@@ -64,7 +64,7 @@ static PyObject *py_get_context(PyObject *self) > static PyMethodDef pyparam_methods[] = { > { "get_context", (PyCFunction)py_get_context, METH_NOARGS, > "Returns LoadParm context." }, >- { NULL } >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/source3/passdb/py_passdb.c b/source3/passdb/py_passdb.c >index 0b5c720215c..1ab2fa7f585 100644 >--- a/source3/passdb/py_passdb.c >+++ b/source3/passdb/py_passdb.c >@@ -3521,7 +3521,7 @@ static PyMethodDef py_pdb_methods[] = { > { "delete_secret", py_pdb_delete_secret, METH_VARARGS, > "delete_secret(secret_name) -> None\n\n \ > Delete secret information for secret_name." }, >- { NULL }, >+ {0}, > }; > > >@@ -3724,7 +3724,7 @@ static PyMethodDef py_passdb_methods[] = { > { "reload_static_pdb", py_reload_static_pdb, METH_NOARGS, > "reload_static_pdb() -> None\n\n \ > Re-initialise the static pdb used internally. Needed if 'passdb backend' is changed." }, >- { NULL }, >+ {0}, > }; > > static struct PyModuleDef moduledef = { >diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c >index 59cd020dbed..74b087df245 100644 >--- a/source3/smbd/posix_acls.c >+++ b/source3/smbd/posix_acls.c >@@ -4662,7 +4662,7 @@ int posix_sys_acl_blob_get_file(vfs_handle_struct *handle, > TALLOC_CTX *frame = talloc_stackframe(); > /* Initialise this to zero, in a portable way */ > struct smb_acl_wrapper acl_wrapper = { >- NULL >+ 0 > }; > struct smb_filename *smb_fname = cp_smb_filename_nostream(frame, > smb_fname_in); >diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c >index 29db8eb01c4..884d05d60ab 100644 >--- a/source3/smbd/pysmbd.c >+++ b/source3/smbd/pysmbd.c >@@ -908,7 +908,7 @@ static PyMethodDef py_smbd_methods[] = { > { "create_file", > (PyCFunction)py_smbd_create_file, METH_VARARGS|METH_KEYWORDS, > NULL }, >- { NULL } >+ {0} > }; > > void initsmbd(void); >diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c >index 3ba26031ed8..8e5b87ed4c3 100644 >--- a/source3/torture/cmd_vfs.c >+++ b/source3/torture/cmd_vfs.c >@@ -2005,5 +2005,5 @@ struct cmd_set vfs_commands[] = { > { "test_chain", cmd_test_chain, "test chain code", > "test_chain" }, > { "translate_name", cmd_translate_name, "VFS translate_name()", "translate_name unix_filename" }, >- { NULL } >+ {0} > }; >diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c >index 1d60f0eeef8..a8c6a82f290 100644 >--- a/source3/utils/smbcontrol.c >+++ b/source3/utils/smbcontrol.c >@@ -1580,7 +1580,7 @@ struct poptOption help_options[] = { > NULL, NULL }, > { "help", '?', 0, NULL, '?', "Show this help message", NULL }, > { "usage", '\0', 0, NULL, 'u', "Display brief usage message", NULL }, >- { NULL } >+ {0} > } ; > > /* Main program */ >diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c >index fe4472b8ed0..9e24499a0fe 100644 >--- a/source4/auth/gensec/pygensec.c >+++ b/source4/auth/gensec/pygensec.c >@@ -716,7 +716,7 @@ static PyMethodDef py_gensec_security_methods[] = { > "S.sign_packet(data, whole_pdu) -> sig\nSign a DCERPC packet." }, > { "check_packet", (PyCFunction)py_gensec_check_packet, METH_VARARGS, > "S.check_packet(data, whole_pdu, sig)\nCheck a DCERPC packet." }, >- { NULL } >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/source4/auth/pyauth.c b/source4/auth/pyauth.c >index 26d8277887e..ea91cdad2c6 100644 >--- a/source4/auth/pyauth.c >+++ b/source4/auth/pyauth.c >@@ -422,7 +422,7 @@ static PyMethodDef py_auth_methods[] = { > (PyCFunction)py_copy_session_info, > METH_VARARGS|METH_KEYWORDS, > NULL }, >- { NULL }, >+ {0}, > }; > > static struct PyModuleDef moduledef = { >diff --git a/source4/client/cifsdd.c b/source4/client/cifsdd.c >index 7ab59cd49e2..ec2992c848d 100644 >--- a/source4/client/cifsdd.c >+++ b/source4/client/cifsdd.c >@@ -562,7 +562,7 @@ int main(int argc, const char ** argv) > POPT_COMMON_CONNECTION > POPT_COMMON_CREDENTIALS > POPT_COMMON_VERSION >- { NULL } >+ {0} > }; > > /* Block sizes. */ >diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c >index b46dec6cb35..d7df3fd1093 100644 >--- a/source4/dns_server/dlz_bind9.c >+++ b/source4/dns_server/dlz_bind9.c >@@ -508,7 +508,7 @@ static isc_result_t parse_options(struct dlz_bind9_data *state, > struct poptOption long_options[] = { > { "url", 'H', POPT_ARG_STRING, &options->url, 0, "database URL", "URL" }, > { "debug", 'd', POPT_ARG_STRING, &options->debug, 0, "debug level", "DEBUG" }, >- { NULL } >+ {0} > }; > > pc = poptGetContext("dlz_bind9", argc, argv, long_options, >diff --git a/source4/dns_server/pydns.c b/source4/dns_server/pydns.c >index 16d22dfe4b8..e373771cb4b 100644 >--- a/source4/dns_server/pydns.c >+++ b/source4/dns_server/pydns.c >@@ -335,7 +335,7 @@ static PyMethodDef py_dsdb_dns_methods[] = { > METH_VARARGS, "Replace the DNS database entries for a LDB DN"}, > { "extract", (PyCFunction)py_dsdb_dns_extract, > METH_VARARGS, "Return the DNS database entry as a python structure from an Ldb.MessageElement of type dnsRecord"}, >- { NULL } >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c >index 297943b1a54..4996bedfe76 100644 >--- a/source4/dsdb/pydsdb.c >+++ b/source4/dsdb/pydsdb.c >@@ -1460,7 +1460,7 @@ static PyMethodDef py_dsdb_methods[] = { > "_dsdb_allocate_rid(samdb)" > " -> RID" }, > { "_dsdb_load_udv_v2", (PyCFunction)py_dsdb_load_udv_v2, METH_VARARGS, NULL }, >- { NULL } >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/source4/lib/policy/pypolicy.c b/source4/lib/policy/pypolicy.c >index dd44c0fcf16..a545a05828f 100644 >--- a/source4/lib/policy/pypolicy.c >+++ b/source4/lib/policy/pypolicy.c >@@ -129,7 +129,7 @@ static PyMethodDef py_policy_methods[] = { > "get_gplink_options(options) -> list" }, > { "ads_to_dir_access_mask", (PyCFunction)py_ads_to_dir_access_mask, METH_VARARGS, > "ads_to_dir_access_mask(access_mask) -> dir_mask" }, >- { NULL } >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/source4/lib/registry/pyregistry.c b/source4/lib/registry/pyregistry.c >index 5d7f7f212b8..6f45dbcb284 100644 >--- a/source4/lib/registry/pyregistry.c >+++ b/source4/lib/registry/pyregistry.c >@@ -152,7 +152,7 @@ static PyMethodDef registry_methods[] = { > "Apply the diff from the specified file" }, > { "mount_hive", py_mount_hive, METH_VARARGS, "S.mount_hive(key, key_id, elements=None) -> None\n" > "Mount the specified key at the specified path." }, >- { NULL } >+ {0} > }; > > PyTypeObject PyRegistry = { >@@ -238,7 +238,7 @@ static PyMethodDef hive_key_methods[] = { > "Delete a value" }, > { "set_value", py_hive_key_set_value, METH_VARARGS, "S.set_value(name, type, data) -> None\n" > "Set a value" }, >- { NULL } >+ {0} > }; > > static PyObject *hive_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { >@@ -438,7 +438,7 @@ static PyMethodDef py_registry_methods[] = { > { "open_hive", (PyCFunction)py_open_hive, METH_VARARGS|METH_KEYWORDS, "open_hive(location, session_info=None, credentials=None, loadparm_context=None) -> key" }, > { "str_regtype", py_str_regtype, METH_VARARGS, "str_regtype(int) -> str" }, > { "get_predef_name", py_get_predef_name, METH_VARARGS, "get_predef_name(hkey) -> str" }, >- { NULL } >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c >index da813336b85..b5cf4dd2566 100644 >--- a/source4/lib/registry/tools/regdiff.c >+++ b/source4/lib/registry/tools/regdiff.c >@@ -82,7 +82,7 @@ int main(int argc, const char **argv) > POPT_COMMON_SAMBA > POPT_COMMON_CREDENTIALS > POPT_COMMON_VERSION >- { NULL } >+ {0} > }; > TALLOC_CTX *ctx; > void *callback_data; >diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c >index 50195fe084c..4db7a5090e0 100644 >--- a/source4/lib/registry/tools/regpatch.c >+++ b/source4/lib/registry/tools/regpatch.c >@@ -41,7 +41,7 @@ int main(int argc, const char **argv) > {"file", 'F', POPT_ARG_STRING, &file, 0, "file path", NULL }, > POPT_COMMON_SAMBA > POPT_COMMON_CREDENTIALS >- { NULL } >+ {0} > }; > > pc = poptGetContext(argv[0], argc, argv, long_options,0); >diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c >index 48251c33ea4..eebec4353cb 100644 >--- a/source4/lib/registry/tools/regshell.c >+++ b/source4/lib/registry/tools/regshell.c >@@ -380,7 +380,7 @@ static struct { > {"help", "?", "Help", cmd_help }, > {"exit", "quit", "Exit", cmd_exit }, > {"predef", "predefined", "Go to predefined key", cmd_predef }, >- {NULL } >+ {0} > }; > > static WERROR cmd_help(struct regshell_context *ctx, >@@ -570,7 +570,7 @@ int main(int argc, const char **argv) > POPT_COMMON_SAMBA > POPT_COMMON_CREDENTIALS > POPT_COMMON_VERSION >- { NULL } >+ {0} > }; > > pc = poptGetContext(argv[0], argc, argv, long_options,0); >diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c >index d4319f5f6bb..f147e2707f7 100644 >--- a/source4/lib/registry/tools/regtree.c >+++ b/source4/lib/registry/tools/regtree.c >@@ -120,7 +120,7 @@ int main(int argc, const char **argv) > POPT_COMMON_SAMBA > POPT_COMMON_CREDENTIALS > POPT_COMMON_VERSION >- { NULL } >+ {0} > }; > > pc = poptGetContext(argv[0], argc, argv, long_options,0); >diff --git a/source4/librpc/ndr/py_security.c b/source4/librpc/ndr/py_security.c >index f6094339457..7c3776127d5 100644 >--- a/source4/librpc/ndr/py_security.c >+++ b/source4/librpc/ndr/py_security.c >@@ -149,7 +149,7 @@ static PyMethodDef py_dom_sid_extra_methods[] = { > { "split", (PyCFunction)py_dom_sid_split, METH_NOARGS, > "S.split() -> (domain_sid, rid)\n" > "Split a domain sid" }, >- { NULL } >+ {0} > }; > > >@@ -305,7 +305,7 @@ static PyMethodDef py_descriptor_extra_methods[] = { > NULL }, > { "as_sddl", (PyCFunction)py_descriptor_as_sddl, METH_VARARGS, > NULL }, >- { NULL } >+ {0} > }; > > static PyObject *py_descriptor_richcmp( >@@ -454,7 +454,7 @@ static PyMethodDef py_token_extra_methods[] = { > NULL }, > { "set_privilege", (PyCFunction)py_token_set_privilege, METH_VARARGS, > NULL }, >- { NULL } >+ {0} > }; > > #define PY_TOKEN_PATCH py_token_patch >@@ -502,7 +502,7 @@ static PyMethodDef py_mod_security_extra_methods[] = { > { "random_sid", (PyCFunction)py_random_sid, METH_NOARGS, NULL }, > { "privilege_id", (PyCFunction)py_privilege_id, METH_VARARGS, NULL }, > { "privilege_name", (PyCFunction)py_privilege_name, METH_VARARGS, NULL }, >- { NULL } >+ {0} > }; > > static void py_mod_security_patch(PyObject *m) >diff --git a/source4/librpc/ndr/py_xattr.c b/source4/librpc/ndr/py_xattr.c >index 4ebf1358c55..4d62be2bbea 100644 >--- a/source4/librpc/ndr/py_xattr.c >+++ b/source4/librpc/ndr/py_xattr.c >@@ -86,7 +86,7 @@ static PyObject *py_ntacl_print(PyObject *self, PyObject *args) > static PyMethodDef py_ntacl_extra_methods[] = { > { "dump", (PyCFunction)py_ntacl_print, METH_NOARGS, > NULL }, >- { NULL } >+ {0} > }; > > static void py_xattr_NTACL_patch(PyTypeObject *type) >diff --git a/source4/ntvfs/posix/python/pyposix_eadb.c b/source4/ntvfs/posix/python/pyposix_eadb.c >index 18e240420a4..8fadaaea17e 100644 >--- a/source4/ntvfs/posix/python/pyposix_eadb.c >+++ b/source4/ntvfs/posix/python/pyposix_eadb.c >@@ -115,7 +115,7 @@ static PyMethodDef py_posix_eadb_methods[] = { > "Set the given attribute to the given value on the given file." }, > { "is_xattr_supported", (PyCFunction)py_is_xattr_supported, METH_NOARGS, > "Return true if xattr are supported on this system\n"}, >- { NULL } >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/source4/ntvfs/posix/python/pyxattr_native.c b/source4/ntvfs/posix/python/pyxattr_native.c >index 6af48348a4b..dbeb50f80c9 100644 >--- a/source4/ntvfs/posix/python/pyxattr_native.c >+++ b/source4/ntvfs/posix/python/pyxattr_native.c >@@ -104,7 +104,7 @@ static PyMethodDef py_xattr_methods[] = { > "Set the given attribute to the given value on the given file." }, > { "is_xattr_supported", (PyCFunction)py_is_xattr_supported, METH_NOARGS, > "Return true if xattr are supported on this system\n"}, >- { NULL } >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/source4/ntvfs/posix/python/pyxattr_tdb.c b/source4/ntvfs/posix/python/pyxattr_tdb.c >index 9e4e73a4049..4619133b04c 100644 >--- a/source4/ntvfs/posix/python/pyxattr_tdb.c >+++ b/source4/ntvfs/posix/python/pyxattr_tdb.c >@@ -151,7 +151,7 @@ static PyMethodDef py_xattr_methods[] = { > "Set the given attribute to the given value on the given file." }, > { "is_xattr_supported", (PyCFunction)py_is_xattr_supported, METH_NOARGS, > "Return true if xattr are supported on this system\n"}, >- { NULL } >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/source4/param/pyparam.c b/source4/param/pyparam.c >index e71bb469eee..9394d74dd2f 100644 >--- a/source4/param/pyparam.c >+++ b/source4/param/pyparam.c >@@ -446,7 +446,7 @@ static PyMethodDef py_lp_ctx_methods[] = { > { "state_path", py_state_path, METH_VARARGS, > "S.state_path(name) -> string\n" > "Returns a path in the Samba state directory." }, >- { NULL } >+ {0} > }; > > static PyObject *py_lp_ctx_default_service(PyObject *self, void *closure) >@@ -599,7 +599,7 @@ static PyObject *py_lp_service_dump(PyObject *self, PyObject *args) > static PyMethodDef py_lp_service_methods[] = { > { "dump", (PyCFunction)py_lp_service_dump, METH_VARARGS, > "S.dump(default_service, show_defaults=False, file_name='', mode='w')" }, >- { NULL } >+ {0} > }; > > PyTypeObject PyLoadparmService = { >@@ -644,7 +644,7 @@ static PyMethodDef pyparam_methods[] = { > "Returns the compiled in BINDIR." }, > { "sbin_dir", (PyCFunction)py_sbin_dir, METH_NOARGS, > "Returns the compiled in SBINDIR." }, >- { NULL } >+ {0} > }; > > static struct PyModuleDef moduledef = { >diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c >index 24228ad65d4..bce3d8da2e0 100644 >--- a/source4/torture/gentest.c >+++ b/source4/torture/gentest.c >@@ -3201,7 +3201,7 @@ int main(int argc, const char *argv[]) > POPT_COMMON_CONNECTION > POPT_COMMON_CREDENTIALS > POPT_COMMON_VERSION >- { NULL } >+ {0} > }; > TALLOC_CTX *mem_ctx = NULL; > >diff --git a/source4/torture/locktest.c b/source4/torture/locktest.c >index 704755464ed..862f87c12f9 100644 >--- a/source4/torture/locktest.c >+++ b/source4/torture/locktest.c >@@ -578,7 +578,7 @@ int main(int argc, const char *argv[]) > POPT_COMMON_CONNECTION > POPT_COMMON_CREDENTIALS > POPT_COMMON_VERSION >- { NULL } >+ {0} > }; > TALLOC_CTX *mem_ctx = NULL; > int ret = -1; >diff --git a/source4/torture/masktest.c b/source4/torture/masktest.c >index 9a047e2b708..400d79eb88d 100644 >--- a/source4/torture/masktest.c >+++ b/source4/torture/masktest.c >@@ -317,7 +317,7 @@ int main(int argc, const char *argv[]) > POPT_COMMON_CONNECTION > POPT_COMMON_CREDENTIALS > POPT_COMMON_VERSION >- { NULL } >+ {0} > }; > > setlinebuf(stdout); >diff --git a/source4/torture/smbtorture.c b/source4/torture/smbtorture.c >index 15eb81b7fea..4c09bc60268 100644 >--- a/source4/torture/smbtorture.c >+++ b/source4/torture/smbtorture.c >@@ -426,7 +426,7 @@ int main(int argc, const char *argv[]) > POPT_COMMON_CONNECTION > POPT_COMMON_CREDENTIALS > POPT_COMMON_VERSION >- { NULL } >+ {0} > }; > > setlinebuf(stdout); >diff --git a/source4/torture/vfs/fruit.c b/source4/torture/vfs/fruit.c >index a486c477a09..26199bca806 100644 >--- a/source4/torture/vfs/fruit.c >+++ b/source4/torture/vfs/fruit.c >@@ -6861,7 +6861,7 @@ static bool test_empty_stream(struct torture_context *tctx, > tcase_afpresource_rw, > tcase_foo_ro, > tcase_foo_rw, >- {NULL} >+ {0} > }; > > ret = torture_smb2_connection(tctx, &tree2); >-- >2.25.1 > > >From afa289be472988d5ccbe7d1c98ad910217d1225b Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Tue, 21 Apr 2020 15:37:40 +1200 >Subject: [PATCH 378/686] lib ldb: Limit depth of ldb_parse_tree > >Limit the number of nested conditionals allowed by ldb_parse tree to >128, to avoid potential stack overflow issues. > >Credit Oss-Fuzz > >REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19508 > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Gary Lockyer <gary@samba.org> >Autobuild-Date(master): Sun May 10 23:21:08 UTC 2020 on sn-devel-184 > >(cherry picked from commit a699256f438527455aaff6c73c88ee87ac7083ef) >--- > lib/ldb/common/ldb_parse.c | 72 +++++++++++++++++++++++------ > lib/ldb/tests/ldb_parse_test.c | 83 +++++++++++++++++++++++++++++++++- > 2 files changed, 140 insertions(+), 15 deletions(-) > >diff --git a/lib/ldb/common/ldb_parse.c b/lib/ldb/common/ldb_parse.c >index 452c5830ed5..7e15206b168 100644 >--- a/lib/ldb/common/ldb_parse.c >+++ b/lib/ldb/common/ldb_parse.c >@@ -43,6 +43,16 @@ > #include "ldb_private.h" > #include "system/locale.h" > >+/* >+ * Maximum depth of the filter parse tree, the value chosen is small enough to >+ * avoid triggering ASAN stack overflow checks. But large enough to be useful. >+ * >+ * On Windows clients the maximum number of levels of recursion allowed is 100. >+ * In the LDAP server, Windows restricts clients to 512 nested >+ * (eg) OR statements. >+ */ >+#define LDB_MAX_PARSE_TREE_DEPTH 128 >+ > static int ldb_parse_hex2char(const char *x) > { > if (isxdigit(x[0]) && isxdigit(x[1])) { >@@ -231,7 +241,11 @@ static struct ldb_val **ldb_wildcard_decode(TALLOC_CTX *mem_ctx, const char *str > return ret; > } > >-static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s); >+static struct ldb_parse_tree *ldb_parse_filter( >+ TALLOC_CTX *mem_ctx, >+ const char **s, >+ unsigned depth, >+ unsigned max_depth); > > > /* >@@ -498,7 +512,11 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char * > <or> ::= '|' <filterlist> > <filterlist> ::= <filter> | <filter> <filterlist> > */ >-static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const char **s) >+static struct ldb_parse_tree *ldb_parse_filterlist( >+ TALLOC_CTX *mem_ctx, >+ const char **s, >+ unsigned depth, >+ unsigned max_depth) > { > struct ldb_parse_tree *ret, *next; > enum ldb_parse_op op; >@@ -533,7 +551,8 @@ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const ch > return NULL; > } > >- ret->u.list.elements[0] = ldb_parse_filter(ret->u.list.elements, &p); >+ ret->u.list.elements[0] = >+ ldb_parse_filter(ret->u.list.elements, &p, depth, max_depth); > if (!ret->u.list.elements[0]) { > talloc_free(ret); > return NULL; >@@ -547,7 +566,8 @@ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const ch > break; > } > >- next = ldb_parse_filter(ret->u.list.elements, &p); >+ next = ldb_parse_filter( >+ ret->u.list.elements, &p, depth, max_depth); > if (next == NULL) { > /* an invalid filter element */ > talloc_free(ret); >@@ -576,7 +596,11 @@ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const ch > /* > <not> ::= '!' <filter> > */ >-static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s) >+static struct ldb_parse_tree *ldb_parse_not( >+ TALLOC_CTX *mem_ctx, >+ const char **s, >+ unsigned depth, >+ unsigned max_depth) > { > struct ldb_parse_tree *ret; > const char *p = *s; >@@ -593,7 +617,7 @@ static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s) > } > > ret->operation = LDB_OP_NOT; >- ret->u.isnot.child = ldb_parse_filter(ret, &p); >+ ret->u.isnot.child = ldb_parse_filter(ret, &p, depth, max_depth); > if (!ret->u.isnot.child) { > talloc_free(ret); > return NULL; >@@ -608,7 +632,11 @@ static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s) > parse a filtercomp > <filtercomp> ::= <and> | <or> | <not> | <simple> > */ >-static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const char **s) >+static struct ldb_parse_tree *ldb_parse_filtercomp( >+ TALLOC_CTX *mem_ctx, >+ const char **s, >+ unsigned depth, >+ unsigned max_depth) > { > struct ldb_parse_tree *ret; > const char *p = *s; >@@ -617,15 +645,15 @@ static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const ch > > switch (*p) { > case '&': >- ret = ldb_parse_filterlist(mem_ctx, &p); >+ ret = ldb_parse_filterlist(mem_ctx, &p, depth, max_depth); > break; > > case '|': >- ret = ldb_parse_filterlist(mem_ctx, &p); >+ ret = ldb_parse_filterlist(mem_ctx, &p, depth, max_depth); > break; > > case '!': >- ret = ldb_parse_not(mem_ctx, &p); >+ ret = ldb_parse_not(mem_ctx, &p, depth, max_depth); > break; > > case '(': >@@ -641,21 +669,34 @@ static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const ch > return ret; > } > >- > /* > <filter> ::= '(' <filtercomp> ')' > */ >-static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s) >+static struct ldb_parse_tree *ldb_parse_filter( >+ TALLOC_CTX *mem_ctx, >+ const char **s, >+ unsigned depth, >+ unsigned max_depth) > { > struct ldb_parse_tree *ret; > const char *p = *s; > >+ /* >+ * Check the depth of the parse tree, and reject the input if >+ * max_depth exceeded. This avoids stack overflow >+ * issues. >+ */ >+ if (depth > max_depth) { >+ return NULL; >+ } >+ depth++; >+ > if (*p != '(') { > return NULL; > } > p++; > >- ret = ldb_parse_filtercomp(mem_ctx, &p); >+ ret = ldb_parse_filtercomp(mem_ctx, &p, depth, max_depth); > > if (*p != ')') { > return NULL; >@@ -679,6 +720,8 @@ static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char * > */ > struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) > { >+ unsigned depth = 0; >+ > while (s && isspace((unsigned char)*s)) s++; > > if (s == NULL || *s == 0) { >@@ -686,7 +729,8 @@ struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) > } > > if (*s == '(') { >- return ldb_parse_filter(mem_ctx, &s); >+ return ldb_parse_filter( >+ mem_ctx, &s, depth, LDB_MAX_PARSE_TREE_DEPTH); > } > > return ldb_parse_simple(mem_ctx, &s); >diff --git a/lib/ldb/tests/ldb_parse_test.c b/lib/ldb/tests/ldb_parse_test.c >index a739d7795d1..d7442b954ea 100644 >--- a/lib/ldb/tests/ldb_parse_test.c >+++ b/lib/ldb/tests/ldb_parse_test.c >@@ -81,10 +81,91 @@ static void test_parse_filtertype(void **state) > test_roundtrip(ctx, " ", "(|(objectClass=*)(distinguishedName=*))"); > } > >+/* >+ * Test that a nested query with 128 levels of nesting is accepted >+ */ >+static void test_nested_filter_eq_limit(void **state) >+{ >+ struct test_ctx *ctx = >+ talloc_get_type_abort(*state, struct test_ctx); >+ >+ /* >+ * 128 nested clauses >+ */ >+ const char *nested_query = "" >+ "(|(!(|(&(|(|(|(|(|(|(|(|(|(|(|(|" >+ "(|(!(|(&(|(|(|(|(|(|(!(|(!(|(|(|" >+ "(|(!(|(&(|(|(&(|(|(|(|(|(!(!(!(|" >+ "(|(!(|(&(|(|(|(|(|(|(|(|(|(|(|(|" >+ "(|(!(|(&(|(|(|(!(|(|(&(|(|(|(|(|" >+ "(|(!(|(&(|(|(&(|(|(|(|(|(&(&(|(|" >+ "(|(!(|(&(|(|(|(|(|(|(!(|(|(|(|(|" >+ "(|(!(|(&(|(|(!(|(|(|(|(|(|(|(|(|" >+ "(a=b)" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))"; >+ >+ struct ldb_parse_tree *tree = ldb_parse_tree(ctx, nested_query); >+ >+ assert_non_null(tree); >+ /* >+ * Check that we get the same query back >+ */ >+ test_roundtrip(ctx, nested_query, nested_query); >+} >+ >+/* >+ * Test that a nested query with 129 levels of nesting is rejected. >+ */ >+static void test_nested_filter_gt_limit(void **state) >+{ >+ struct test_ctx *ctx = >+ talloc_get_type_abort(*state, struct test_ctx); >+ >+ /* >+ * 129 nested clauses >+ */ >+ const char *nested_query = "" >+ "(|(!(|(|(&(|(|(|(|(&(|(|(|(|(|(|" >+ "(|(!(|(|(&(|(|(|(|(|(|(|(|(|(|(|" >+ "(|(!(|(|(&(|(|(!(|(|(|(|(!(|(|(|" >+ "(|(!(|(|(&(|(|(|(|(|(|(|(|(|(|(|" >+ "(|(!(|(|(&(|(|(|(!(&(|(|(|(|(|(|" >+ "(|(!(|(|(&(|(|(|(|(|(|(|(|(|(|(|" >+ "(|(!(|(|(&(|(|(|(|(|(|(|(|(|(|(|" >+ "(|(!(|(|(&(|(|(|(|(|(|(|(|(&(|(|" >+ "(|" >+ "(a=b)" >+ ")" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))" >+ "))))))))))))))))"; >+ >+ struct ldb_parse_tree *tree = ldb_parse_tree(ctx, nested_query); >+ >+ assert_null(tree); >+} >+ > int main(int argc, const char **argv) > { > const struct CMUnitTest tests[] = { >- cmocka_unit_test_setup_teardown(test_parse_filtertype, setup, teardown), >+ cmocka_unit_test_setup_teardown( >+ test_parse_filtertype, setup, teardown), >+ cmocka_unit_test_setup_teardown( >+ test_nested_filter_eq_limit, setup, teardown), >+ cmocka_unit_test_setup_teardown( >+ test_nested_filter_gt_limit, setup, teardown), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.25.1 > > >From 80eae89b54d6533eddb5ac7cdae844b8710638a0 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 21 Feb 2020 08:03:57 +0100 >Subject: [PATCH 379/686] winbindd: Align integer types > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit bf07b16e30cb6be25b1e8df5c1f7cc004d078443) >--- > source3/winbindd/wb_sids2xids.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index 7ab8dd133fd..e6698f94789 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -170,7 +170,7 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > struct lsa_TransNameArray *names = NULL; > struct dcerpc_binding_handle *child_binding_handle = NULL; > NTSTATUS status; >- int i; >+ uint32_t i; > > status = wb_lookupsids_recv(subreq, state, &domains, &names); > TALLOC_FREE(subreq); >-- >2.25.1 > > >From b55301a26a305b111095548f6297c50d567ce8db Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 10 Feb 2020 11:07:27 +1300 >Subject: [PATCH 380/686] CVE-2020-25722 auth/credentials: Test connecting to > LDAP with a "virtual user" style account > >This type of account is often used by e-mail hosting platforms >that do not wish to create an AD domain for each DNS domain that >they host mail for. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13598 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 8fbdff5c3d7bc68b4c89ac460914a5d18775244e) >--- > auth/credentials/tests/bind.py | 52 ++++++++++++++++++++++++- > selftest/knownfail.d/ldap-virtual-users | 1 + > 2 files changed, 52 insertions(+), 1 deletion(-) > create mode 100644 selftest/knownfail.d/ldap-virtual-users > >diff --git a/auth/credentials/tests/bind.py b/auth/credentials/tests/bind.py >index 2eaf0c0fd08..9e2b50b3352 100755 >--- a/auth/credentials/tests/bind.py >+++ b/auth/credentials/tests/bind.py >@@ -14,7 +14,7 @@ from samba.tests.subunitrun import SubunitOptions, TestProgram > > import samba.getopt as options > >-from ldb import SCOPE_BASE, SCOPE_SUBTREE >+from ldb import SCOPE_BASE, SCOPE_SUBTREE, LdbError, ERR_INVALID_CREDENTIALS > > from samba import gensec > import samba.tests >@@ -48,6 +48,7 @@ creds = credopts.get_credentials(lp) > creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL) > > creds_machine = create_credential(lp, creds) >+creds_virtual = create_credential(lp, creds) > creds_user1 = create_credential(lp, creds) > creds_user2 = create_credential(lp, creds) > creds_user3 = create_credential(lp, creds) >@@ -71,13 +72,62 @@ class BindTests(samba.tests.TestCase): > self.schema_dn = self.info_dc["schemaNamingContext"][0] > self.domain_dn = self.info_dc["defaultNamingContext"][0] > self.config_dn = self.info_dc["configurationNamingContext"][0] >+ self.realm = self.info_dc["ldapServiceName"][0].split(b'@')[1].decode('utf-8') > self.computer_dn = "CN=centos53,CN=Computers,%s" % self.domain_dn >+ self.virtual_user_dn = "CN=frednurk@%s,CN=Computers,%s" % (self.realm, self.domain_dn) > self.password = "P@ssw0rd" > self.username = "BindTestUser" > > def tearDown(self): >+ delete_force(self.ldb, self.virtual_user_dn) > super(BindTests, self).tearDown() > >+ def test_virtual_email_account_style_bind(self): >+ # create a user in the style often deployed for authentication >+ # of virtual email account at a hosting provider >+ # >+ # The userPrincipalName must not match the samAccountName for >+ # this test to detect when the LDAP DN is being double-parsed >+ # but must be in the user@realm style to allow the account to >+ # be created >+ self.ldb.add_ldif(""" >+dn: """ + self.virtual_user_dn + """ >+cn: frednurk@""" + self.realm + """ >+displayName: Fred Nurk >+sAMAccountName: frednurk@""" + self.realm + """ >+userPrincipalName: frednurk@NOT.""" + self.realm + """ >+countryCode: 0 >+objectClass: computer >+objectClass: organizationalPerson >+objectClass: person >+objectClass: top >+objectClass: user >+""") >+ self.addCleanup(delete_force, self.ldb, self.virtual_user_dn) >+ self.ldb.modify_ldif(""" >+dn: """ + self.virtual_user_dn + """ >+changetype: modify >+replace: unicodePwd >+unicodePwd:: """ + base64.b64encode(u"\"P@ssw0rd\"".encode('utf-16-le')).decode('utf8') + """ >+""") >+ >+ self.ldb.enable_account('distinguishedName=%s' % self.virtual_user_dn) >+ >+ # do a simple bind and search with the machine account >+ creds_virtual.set_bind_dn(self.virtual_user_dn) >+ creds_virtual.set_password(self.password) >+ print("BindTest with: " + creds_virtual.get_bind_dn()) >+ try: >+ ldb_virtual = samba.tests.connect_samdb(host, credentials=creds_virtual, >+ lp=lp, ldap_only=True) >+ except LdbError as e: >+ (num, msg) = e.args >+ if num != ERR_INVALID_CREDENTIALS: >+ raise >+ self.fail(msg) >+ >+ res = ldb_virtual.search(base="", expression="", scope=SCOPE_BASE, attrs=["*"]) >+ > def test_computer_account_bind(self): > # create a computer acocount for the test > delete_force(self.ldb, self.computer_dn) >diff --git a/selftest/knownfail.d/ldap-virtual-users b/selftest/knownfail.d/ldap-virtual-users >new file mode 100644 >index 00000000000..318a2b587b7 >--- /dev/null >+++ b/selftest/knownfail.d/ldap-virtual-users >@@ -0,0 +1 @@ >+^samba4.ldap.bind\(fl2008r2dc\).__main__.BindTests.test_virtual_email_account_style_bind >\ No newline at end of file >-- >2.25.1 > > >From 343b553b52ae2fc582edaeaa914a0b148bdeb61a Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 10 Feb 2020 11:52:33 +1300 >Subject: [PATCH 381/686] CVE-2020-25722 s4-auth: Allow simple bind login of a > user with an @ in the samAccountName > >LDAP Simple BIND authentications have already been mapped to a >DOMAIN\username pair and should not be mapped twice. > >This appears to be a regression in 09e24ce40f89ac2f03d0c5fefa8b59f0d113fa6b >included in Samba 4.7. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13598 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> > >Autobuild-User(master): Isaac Boukris <iboukris@samba.org> >Autobuild-Date(master): Fri Feb 14 17:13:33 UTC 2020 on sn-devel-184 > >(cherry picked from commit f231a072d5c09a61e75091c294f722622dcd45da) >--- > selftest/knownfail.d/ldap-virtual-users | 1 - > source4/auth/ntlm/auth_sam.c | 22 +++++++++++++++++++++- > 2 files changed, 21 insertions(+), 2 deletions(-) > delete mode 100644 selftest/knownfail.d/ldap-virtual-users > >diff --git a/selftest/knownfail.d/ldap-virtual-users b/selftest/knownfail.d/ldap-virtual-users >deleted file mode 100644 >index 318a2b587b7..00000000000 >--- a/selftest/knownfail.d/ldap-virtual-users >+++ /dev/null >@@ -1 +0,0 @@ >-^samba4.ldap.bind\(fl2008r2dc\).__main__.BindTests.test_virtual_email_account_style_bind >\ No newline at end of file >diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c >index fb88cb87f66..70eddc12c53 100644 >--- a/source4/auth/ntlm/auth_sam.c >+++ b/source4/auth/ntlm/auth_sam.c >@@ -644,7 +644,27 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx > return NT_STATUS_NO_SUCH_DOMAIN; > } > >- p = strchr_m(account_name, '@'); >+ /* >+ * If we have not already mapped this user, then now is a good >+ * time to do so, before we look it up. We used to do this >+ * earlier, but in a multi-forest environment we want to do >+ * this mapping at the final domain. >+ * >+ * However, on the flip side we may have already mapped the >+ * user if this was an LDAP simple bind, in which case we >+ * really, really want to get back to exactly the same account >+ * we got the DN for. >+ */ >+ if (user_info->mapped_state == false) { >+ p = strchr_m(account_name, '@'); >+ } else { >+ /* >+ * This is slightly nicer than double-indenting the >+ * block below >+ */ >+ p = NULL; >+ } >+ > if (p != NULL) { > const char *nt4_domain = NULL; > const char *nt4_account = NULL; >-- >2.25.1 > > >From 10e7025121fb86df478ebd34408949cbf88fdbc9 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 7 Feb 2020 11:02:38 +1300 >Subject: [PATCH 382/686] CVE-2020-25722 pytests: heed assertEquals deprecation > warning en-masse > >TestCase.assertEquals() is an alias for TestCase.assertEqual() and >has been deprecated since Python 2.7. > >When we run our tests with in python developer mode (`PYTHONDEVMODE=1 >make test`) we get 580 DeprecationWarnings about this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Noel Power <npower@samba.org> > >[abartlet@samba.org backported from commit c247afbda00013bf4821e5a2d4f3166bf31814f0 > as 9873932520a10a9be0d5c5ac10a630051ed62d40 conflicts with a b"" -> b"" > change for 'in'] > >[jsutton@samba.org Adapted to fix conflicts and remove changes to > non-existing files] >--- > auth/credentials/tests/bind.py | 6 +- > buildtools/wafsamba/tests/test_abi.py | 20 +- > buildtools/wafsamba/tests/test_bundled.py | 2 +- > buildtools/wafsamba/tests/test_utils.py | 28 +- > lib/ldb-samba/tests/match_rules.py | 38 +- > python/samba/tests/__init__.py | 2 +- > python/samba/tests/audit_log_dsdb.py | 222 +-- > python/samba/tests/audit_log_pass_change.py | 94 +- > python/samba/tests/auth_log.py | 352 ++-- > python/samba/tests/auth_log_ncalrpc.py | 22 +- > python/samba/tests/auth_log_netlogon.py | 24 +- > .../tests/auth_log_netlogon_bad_creds.py | 10 +- > python/samba/tests/auth_log_pass_change.py | 6 +- > python/samba/tests/auth_log_samlogon.py | 10 +- > .../samba/tests/blackbox/traffic_learner.py | 8 +- > .../samba/tests/blackbox/traffic_summary.py | 2 +- > python/samba/tests/common.py | 24 +- > python/samba/tests/core.py | 16 +- > python/samba/tests/dcerpc/bare.py | 12 +- > python/samba/tests/dcerpc/dnsserver.py | 36 +- > python/samba/tests/dcerpc/integer.py | 22 +- > python/samba/tests/dcerpc/misc.py | 18 +- > python/samba/tests/dcerpc/raw_protocol.py | 1504 ++++++++--------- > python/samba/tests/dcerpc/raw_testcase.py | 134 +- > python/samba/tests/dcerpc/registry.py | 4 +- > python/samba/tests/dcerpc/rpc_talloc.py | 2 +- > python/samba/tests/dcerpc/rpcecho.py | 20 +- > python/samba/tests/dcerpc/sam.py | 100 +- > python/samba/tests/dcerpc/unix.py | 4 +- > python/samba/tests/dns.py | 108 +- > python/samba/tests/dns_base.py | 12 +- > python/samba/tests/dns_forwarder.py | 4 +- > python/samba/tests/dns_tkey.py | 8 +- > python/samba/tests/dns_wildcard.py | 48 +- > python/samba/tests/dsdb.py | 10 +- > python/samba/tests/dsdb_schema_attributes.py | 52 +- > python/samba/tests/encrypted_secrets.py | 2 +- > python/samba/tests/get_opt.py | 14 +- > python/samba/tests/gpo.py | 22 +- > python/samba/tests/group_audit.py | 70 +- > python/samba/tests/hostconfig.py | 10 +- > python/samba/tests/join.py | 12 +- > python/samba/tests/kcc/graph.py | 4 +- > python/samba/tests/kcc/kcc_utils.py | 4 +- > python/samba/tests/netcmd.py | 10 +- > python/samba/tests/ntacls.py | 4 +- > python/samba/tests/ntacls_backup.py | 8 +- > python/samba/tests/ntlm_auth.py | 24 +- > python/samba/tests/param.py | 14 +- > python/samba/tests/password_hash.py | 14 +- > python/samba/tests/password_hash_fl2003.py | 76 +- > python/samba/tests/password_hash_fl2008.py | 92 +- > python/samba/tests/password_hash_gpgme.py | 104 +- > python/samba/tests/password_hash_ldap.py | 2 +- > python/samba/tests/policy.py | 4 +- > python/samba/tests/posixacl.py | 466 ++--- > python/samba/tests/prefork_restart.py | 22 +- > python/samba/tests/provision.py | 24 +- > python/samba/tests/registry.py | 4 +- > python/samba/tests/s3idmapdb.py | 12 +- > python/samba/tests/s3param.py | 8 +- > python/samba/tests/s3passdb.py | 100 +- > python/samba/tests/s3registry.py | 6 +- > python/samba/tests/s3windb.py | 2 +- > python/samba/tests/samba3sam.py | 666 ++++---- > python/samba/tests/samba_tool/computer.py | 18 +- > python/samba/tests/samba_tool/forest.py | 4 +- > python/samba/tests/samba_tool/fsmo.py | 2 +- > python/samba/tests/samba_tool/group.py | 14 +- > python/samba/tests/samba_tool/ntacl.py | 40 +- > python/samba/tests/samba_tool/ou.py | 22 +- > .../tests/samba_tool/passwordsettings.py | 60 +- > python/samba/tests/samba_tool/schema.py | 12 +- > python/samba/tests/samba_tool/sites.py | 2 +- > python/samba/tests/samba_tool/timecmd.py | 4 +- > python/samba/tests/samba_tool/user.py | 40 +- > .../tests/samba_tool/user_virtualCryptSHA.py | 28 +- > .../samba/tests/samba_tool/visualize_drs.py | 2 +- > python/samba/tests/samdb_api.py | 24 +- > python/samba/tests/security.py | 38 +- > python/samba/tests/smb.py | 10 +- > python/samba/tests/strings.py | 4 +- > python/samba/tests/upgrade.py | 4 +- > python/samba/tests/upgradeprovision.py | 30 +- > python/samba/tests/upgradeprovisionneeddc.py | 8 +- > python/samba/tests/xattr.py | 6 +- > source4/dsdb/tests/python/acl.py | 178 +- > source4/dsdb/tests/python/deletetest.py | 50 +- > source4/dsdb/tests/python/dirsync.py | 4 +- > source4/dsdb/tests/python/dsdb_schema_info.py | 2 +- > source4/dsdb/tests/python/ldap.py | 670 ++++---- > source4/dsdb/tests/python/ldap_schema.py | 118 +- > source4/dsdb/tests/python/ldap_syntaxes.py | 62 +- > source4/dsdb/tests/python/notification.py | 24 +- > source4/dsdb/tests/python/password_lockout.py | 44 +- > .../tests/python/password_lockout_base.py | 50 +- > .../dsdb/tests/python/password_settings.py | 16 +- > source4/dsdb/tests/python/passwords.py | 98 +- > source4/dsdb/tests/python/rodc_rwdc.py | 24 +- > source4/dsdb/tests/python/sam.py | 376 ++--- > source4/dsdb/tests/python/sec_descriptor.py | 32 +- > source4/dsdb/tests/python/sort.py | 8 +- > source4/dsdb/tests/python/token_group.py | 18 +- > .../tests/python/tombstone_reanimation.py | 20 +- > .../dsdb/tests/python/urgent_replication.py | 32 +- > source4/dsdb/tests/python/vlv.py | 14 +- > source4/torture/drs/python/cracknames.py | 28 +- > source4/torture/drs/python/delete_object.py | 26 +- > source4/torture/drs/python/drs_base.py | 14 +- > source4/torture/drs/python/fsmo.py | 2 +- > source4/torture/drs/python/getnc_exop.py | 2 +- > source4/torture/drs/python/getncchanges.py | 2 +- > source4/torture/drs/python/repl_move.py | 138 +- > source4/torture/drs/python/repl_rodc.py | 26 +- > source4/torture/drs/python/repl_schema.py | 4 +- > source4/torture/drs/python/repl_secdesc.py | 18 +- > source4/torture/drs/python/replica_sync.py | 8 +- > .../torture/drs/python/replica_sync_rodc.py | 4 +- > source4/torture/drs/python/ridalloc_exop.py | 6 +- > .../drs/python/samba_tool_drs_no_dns.py | 24 +- > 120 files changed, 3649 insertions(+), 3649 deletions(-) > >diff --git a/auth/credentials/tests/bind.py b/auth/credentials/tests/bind.py >index 9e2b50b3352..8bee6f96c62 100755 >--- a/auth/credentials/tests/bind.py >+++ b/auth/credentials/tests/bind.py >@@ -66,7 +66,7 @@ class BindTests(samba.tests.TestCase): > > if self.info_dc is None: > res = self.ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["*"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > BindTests.info_dc = res[0] > # cache some of RootDSE props > self.schema_dn = self.info_dc["schemaNamingContext"][0] >@@ -170,7 +170,7 @@ unicodePwd:: """ + base64.b64encode(u"\"P@ssw0rd\"".encode('utf-16-le')).decode( > ldb_res = self.ldb.search(base=self.domain_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % self.username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_dn = ldb_res[0]["dn"] > self.addCleanup(delete_force, self.ldb, user_dn) > >@@ -204,7 +204,7 @@ unicodePwd:: """ + base64.b64encode(u"\"P@ssw0rd\"".encode('utf-16-le')).decode( > ldb_res = self.ldb.search(base=self.domain_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % self.username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_dn = ldb_res[0]["dn"] > self.addCleanup(delete_force, self.ldb, user_dn) > >diff --git a/buildtools/wafsamba/tests/test_abi.py b/buildtools/wafsamba/tests/test_abi.py >index d6bdb041f72..8521c49d8e8 100644 >--- a/buildtools/wafsamba/tests/test_abi.py >+++ b/buildtools/wafsamba/tests/test_abi.py >@@ -27,30 +27,30 @@ from samba.compat import StringIO > class NormaliseSignatureTests(TestCase): > > def test_function_simple(self): >- self.assertEquals("int (const struct GUID *, const struct GUID *)", >+ self.assertEqual("int (const struct GUID *, const struct GUID *)", > normalise_signature("$2 = {int (const struct GUID *, const struct GUID *)} 0xe871 <GUID_compare>")) > > def test_maps_Bool(self): > # Some types have different internal names >- self.assertEquals("bool (const struct GUID *)", >+ self.assertEqual("bool (const struct GUID *)", > normalise_signature("$1 = {_Bool (const struct GUID *)} 0xe75b <GUID_all_zero>")) > > def test_function_keep(self): >- self.assertEquals( >+ self.assertEqual( > "enum ndr_err_code (struct ndr_push *, int, const union winreg_Data *)", > normalise_signature("enum ndr_err_code (struct ndr_push *, int, const union winreg_Data *)")) > > def test_struct_constant(self): >- self.assertEquals( >+ self.assertEqual( > 'uuid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\\000", node = "\\000\\000\\000\\000\\000"}, if_version = 0', > normalise_signature('$239 = {uuid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\\000", node = "\\000\\000\\000\\000\\000"}, if_version = 0}')) > > def test_incomplete_sequence(self): > # Newer versions of gdb insert these incomplete sequence elements >- self.assertEquals( >+ self.assertEqual( > 'uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2', > normalise_signature('$244 = {uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237", <incomplete sequence \\350>, node = "\\b\\000+\\020H`"}, if_version = 2}')) >- self.assertEquals( >+ self.assertEqual( > 'uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2', > normalise_signature('$244 = {uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2}')) > >@@ -62,7 +62,7 @@ class WriteVscriptTests(TestCase): > abi_write_vscript(f, "MYLIB", "1.0", [], { > "old": "1.0", > "new": "1.0"}, ["*"]) >- self.assertEquals(f.getvalue(), """\ >+ self.assertEqual(f.getvalue(), """\ > 1.0 { > \tglobal: > \t\t*; >@@ -79,7 +79,7 @@ class WriteVscriptTests(TestCase): > abi_write_vscript(f, "MYLIB", "1.0", ["0.1"], { > "old": "0.1", > "new": "1.0"}, ["*"]) >- self.assertEquals(f.getvalue(), """\ >+ self.assertEqual(f.getvalue(), """\ > MYLIB_0.1 { > \tglobal: > \t\told; >@@ -101,7 +101,7 @@ MYLIB_0.1 { > "exc_old": "0.1", > "old": "0.1", > "new": "1.0"}, ["!exc_*"]) >- self.assertEquals(f.getvalue(), """\ >+ self.assertEqual(f.getvalue(), """\ > 1.0 { > \tglobal: > \t\t*; >@@ -120,7 +120,7 @@ MYLIB_0.1 { > "exc_bar": "1.0", > "other": "1.0" > }, ["pub_*", "!exc_*"]) >- self.assertEquals(f.getvalue(), """\ >+ self.assertEqual(f.getvalue(), """\ > 1.0 { > \tglobal: > \t\tpub_*; >diff --git a/buildtools/wafsamba/tests/test_bundled.py b/buildtools/wafsamba/tests/test_bundled.py >index c5f0db63cba..a8e982190d1 100644 >--- a/buildtools/wafsamba/tests/test_bundled.py >+++ b/buildtools/wafsamba/tests/test_bundled.py >@@ -24,4 +24,4 @@ from wafsamba.samba_bundled import ( > class TuplizeVersionTests(TestCase): > > def test_simple(self): >- self.assertEquals((1, 2, 10), tuplize_version("1.2.10")) >+ self.assertEqual((1, 2, 10), tuplize_version("1.2.10")) >diff --git a/buildtools/wafsamba/tests/test_utils.py b/buildtools/wafsamba/tests/test_utils.py >index a9578e25ae6..77fc55c0e52 100644 >--- a/buildtools/wafsamba/tests/test_utils.py >+++ b/buildtools/wafsamba/tests/test_utils.py >@@ -26,33 +26,33 @@ from wafsamba.samba_utils import ( > class ToListTests(TestCase): > > def test_none(self): >- self.assertEquals([], TO_LIST(None)) >+ self.assertEqual([], TO_LIST(None)) > > def test_already_list(self): >- self.assertEquals(["foo", "bar", 1], TO_LIST(["foo", "bar", 1])) >+ self.assertEqual(["foo", "bar", 1], TO_LIST(["foo", "bar", 1])) > > def test_default_delimiter(self): >- self.assertEquals(["foo", "bar"], TO_LIST("foo bar")) >- self.assertEquals(["foo", "bar"], TO_LIST(" foo bar ")) >- self.assertEquals(["foo ", "bar"], TO_LIST(" \"foo \" bar ")) >+ self.assertEqual(["foo", "bar"], TO_LIST("foo bar")) >+ self.assertEqual(["foo", "bar"], TO_LIST(" foo bar ")) >+ self.assertEqual(["foo ", "bar"], TO_LIST(" \"foo \" bar ")) > > def test_delimiter(self): >- self.assertEquals(["foo", "bar"], TO_LIST("foo,bar", ",")) >- self.assertEquals([" foo", "bar "], TO_LIST(" foo,bar ", ",")) >- self.assertEquals([" \" foo\"", " bar "], TO_LIST(" \" foo\", bar ", ",")) >+ self.assertEqual(["foo", "bar"], TO_LIST("foo,bar", ",")) >+ self.assertEqual([" foo", "bar "], TO_LIST(" foo,bar ", ",")) >+ self.assertEqual([" \" foo\"", " bar "], TO_LIST(" \" foo\", bar ", ",")) > > > class UniqueListTests(TestCase): > > def test_unique_list(self): >- self.assertEquals(["foo", "bar"], unique_list(["foo", "bar", "foo"])) >+ self.assertEqual(["foo", "bar"], unique_list(["foo", "bar", "foo"])) > > > class SubstVarsErrorTests(TestCase): > > def test_valid(self): >- self.assertEquals("", subst_vars_error("", {})) >- self.assertEquals("FOO bar", subst_vars_error("${F} bar", {"F": "FOO"})) >+ self.assertEqual("", subst_vars_error("", {})) >+ self.assertEqual("FOO bar", subst_vars_error("${F} bar", {"F": "FOO"})) > > def test_invalid(self): > self.assertRaises(KeyError, subst_vars_error, "${F}", {}) >@@ -63,14 +63,14 @@ class DictConcatTests(TestCase): > def test_empty(self): > ret = {} > dict_concat(ret, {}) >- self.assertEquals({}, ret) >+ self.assertEqual({}, ret) > > def test_same(self): > ret = {"foo": "bar"} > dict_concat(ret, {"foo": "bla"}) >- self.assertEquals({"foo": "bar"}, ret) >+ self.assertEqual({"foo": "bar"}, ret) > > def test_simple(self): > ret = {"foo": "bar"} > dict_concat(ret, {"blie": "bla"}) >- self.assertEquals({"foo": "bar", "blie": "bla"}, ret) >+ self.assertEqual({"foo": "bar", "blie": "bla"}, ret) >diff --git a/lib/ldb-samba/tests/match_rules.py b/lib/ldb-samba/tests/match_rules.py >index 0ad375653f6..abf485c9eab 100755 >--- a/lib/ldb-samba/tests/match_rules.py >+++ b/lib/ldb-samba/tests/match_rules.py >@@ -1132,7 +1132,7 @@ class MatchRuleConditionTests(samba.tests.TestCase): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="memberOf=cn=g1,%s" % self.ou_groups) >- self.assertEquals(len(res1), 2) >+ self.assertEqual(len(res1), 2) > dn_list = [str(res.dn) for res in res1] > self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list) > self.assertTrue("CN=u2,%s" % self.ou_users in dn_list) >@@ -1140,7 +1140,7 @@ class MatchRuleConditionTests(samba.tests.TestCase): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups) >- self.assertEquals(len(res1), 6) >+ self.assertEqual(len(res1), 6) > dn_list = [str(res.dn) for res in res1] > self.assertTrue("CN=u2,%s" % self.ou_users in dn_list) > self.assertTrue("CN=u3,%s" % self.ou_users in dn_list) >@@ -1152,18 +1152,18 @@ class MatchRuleConditionTests(samba.tests.TestCase): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="member=cn=g1,%s" % self.ou_groups) >- self.assertEquals(len(res1), 0) >+ self.assertEqual(len(res1), 0) > > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups) >- self.assertEquals(len(res1), 0) >+ self.assertEqual(len(res1), 0) > > def test_g2_members(self): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="memberOf=cn=g2,%s" % self.ou_groups) >- self.assertEquals(len(res1), 2) >+ self.assertEqual(len(res1), 2) > dn_list = [str(res.dn) for res in res1] > self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list) > self.assertTrue("CN=u2,%s" % self.ou_users in dn_list) >@@ -1171,7 +1171,7 @@ class MatchRuleConditionTests(samba.tests.TestCase): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s" % self.ou_groups) >- self.assertEquals(len(res1), 5) >+ self.assertEqual(len(res1), 5) > dn_list = [str(res.dn) for res in res1] > self.assertTrue("CN=u2,%s" % self.ou_users in dn_list) > self.assertTrue("CN=u3,%s" % self.ou_users in dn_list) >@@ -1182,20 +1182,20 @@ class MatchRuleConditionTests(samba.tests.TestCase): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="member=cn=g2,%s" % self.ou_groups) >- self.assertEquals(len(res1), 1) >- self.assertEquals(str(res1[0].dn), "CN=g1,%s" % self.ou_groups) >+ self.assertEqual(len(res1), 1) >+ self.assertEqual(str(res1[0].dn), "CN=g1,%s" % self.ou_groups) > > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="member:1.2.840.113556.1.4.1941:=cn=g2,%s" % self.ou_groups) >- self.assertEquals(len(res1), 1) >- self.assertEquals(str(res1[0].dn), "CN=g1,%s" % self.ou_groups) >+ self.assertEqual(len(res1), 1) >+ self.assertEqual(str(res1[0].dn), "CN=g1,%s" % self.ou_groups) > > def test_g3_members(self): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="memberOf=cn=g3,%s" % self.ou_groups) >- self.assertEquals(len(res1), 2) >+ self.assertEqual(len(res1), 2) > dn_list = [str(res.dn) for res in res1] > self.assertTrue("CN=u3,%s" % self.ou_users in dn_list) > self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list) >@@ -1203,7 +1203,7 @@ class MatchRuleConditionTests(samba.tests.TestCase): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s" % self.ou_groups) >- self.assertEquals(len(res1), 3) >+ self.assertEqual(len(res1), 3) > dn_list = [str(res.dn) for res in res1] > self.assertTrue("CN=u3,%s" % self.ou_users in dn_list) > self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list) >@@ -1212,13 +1212,13 @@ class MatchRuleConditionTests(samba.tests.TestCase): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="member=cn=g3,%s" % self.ou_groups) >- self.assertEquals(len(res1), 1) >- self.assertEquals(str(res1[0].dn), "CN=g2,%s" % self.ou_groups) >+ self.assertEqual(len(res1), 1) >+ self.assertEqual(str(res1[0].dn), "CN=g2,%s" % self.ou_groups) > > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="member:1.2.840.113556.1.4.1941:=cn=g3,%s" % self.ou_groups) >- self.assertEquals(len(res1), 2) >+ self.assertEqual(len(res1), 2) > dn_list = [str(res.dn) for res in res1] > self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list) > self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list) >@@ -1227,7 +1227,7 @@ class MatchRuleConditionTests(samba.tests.TestCase): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="memberOf=cn=g4,%s" % self.ou_groups) >- self.assertEquals(len(res1), 3) >+ self.assertEqual(len(res1), 3) > dn_list = [str(res.dn) for res in res1] > self.assertTrue("CN=u3,%s" % self.ou_users in dn_list) > self.assertTrue("CN=u4,%s" % self.ou_users in dn_list) >@@ -1236,7 +1236,7 @@ class MatchRuleConditionTests(samba.tests.TestCase): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups) >- self.assertEquals(len(res1), 4) >+ self.assertEqual(len(res1), 4) > dn_list = [str(res.dn) for res in res1] > self.assertTrue("CN=u3,%s" % self.ou_users in dn_list) > self.assertTrue("CN=u4,%s" % self.ou_users in dn_list) >@@ -1246,12 +1246,12 @@ class MatchRuleConditionTests(samba.tests.TestCase): > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="member=cn=g4,%s" % self.ou_groups) >- self.assertEquals(len(res1), 0) >+ self.assertEqual(len(res1), 0) > > res1 = self.ldb.search(self.ou, > scope=SCOPE_SUBTREE, > expression="member:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups) >- self.assertEquals(len(res1), 0) >+ self.assertEqual(len(res1), 0) > > def test_u1_members(self): > res1 = self.ldb.search(self.ou, >diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py >index b6d8a508d4c..525349626b4 100644 >--- a/python/samba/tests/__init__.py >+++ b/python/samba/tests/__init__.py >@@ -324,7 +324,7 @@ class TestCaseInTempDir(TestCase): > > def _remove_tempdir(self): > # Note asserting here is treated as an error rather than a test failure >- self.assertEquals([], os.listdir(self.tempdir)) >+ self.assertEqual([], os.listdir(self.tempdir)) > os.rmdir(self.tempdir) > self.tempdir = None > >diff --git a/python/samba/tests/audit_log_dsdb.py b/python/samba/tests/audit_log_dsdb.py >index 0471c22f243..b6b4512ec98 100644 >--- a/python/samba/tests/audit_log_dsdb.py >+++ b/python/samba/tests/audit_log_dsdb.py >@@ -138,18 +138,18 @@ class AuditLogDsdbTests(AuditLogTestBase): > > messages = self.waitForMessages(1, net, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["dsdbChange"] >- self.assertEquals("Modify", audit["operation"]) >+ self.assertEqual("Modify", audit["operation"]) > self.assertFalse(audit["performedAsSystem"]) > self.assertTrue(dn.lower(), audit["dn"].lower()) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > # We skip the check for self.get_service_description() as this > # is subject to a race between smbd and the s4 rpc_server code > # as to which will set the description as it is DCE/RPC over SMB >@@ -157,11 +157,11 @@ class AuditLogDsdbTests(AuditLogTestBase): > self.assertTrue(self.is_guid(audit["transactionId"])) > > attributes = audit["attributes"] >- self.assertEquals(1, len(attributes)) >+ self.assertEqual(1, len(attributes)) > actions = attributes["clearTextPassword"]["actions"] >- self.assertEquals(1, len(actions)) >+ self.assertEqual(1, len(actions)) > self.assertTrue(actions[0]["redacted"]) >- self.assertEquals("replace", actions[0]["action"]) >+ self.assertEqual("replace", actions[0]["action"]) > > def test_net_set_password(self): > >@@ -180,17 +180,17 @@ class AuditLogDsdbTests(AuditLogTestBase): > domain_name=domain) > messages = self.waitForMessages(1, net, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > audit = messages[0]["dsdbChange"] >- self.assertEquals("Modify", audit["operation"]) >+ self.assertEqual("Modify", audit["operation"]) > self.assertFalse(audit["performedAsSystem"]) >- self.assertEquals(dn, audit["dn"]) >+ self.assertEqual(dn, audit["dn"]) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > # We skip the check for self.get_service_description() as this > # is subject to a race between smbd and the s4 rpc_server code > # as to which will set the description as it is DCE/RPC over SMB >@@ -198,11 +198,11 @@ class AuditLogDsdbTests(AuditLogTestBase): > self.assertTrue(self.is_guid(audit["transactionId"])) > > attributes = audit["attributes"] >- self.assertEquals(1, len(attributes)) >+ self.assertEqual(1, len(attributes)) > actions = attributes["clearTextPassword"]["actions"] >- self.assertEquals(1, len(actions)) >+ self.assertEqual(1, len(actions)) > self.assertTrue(actions[0]["redacted"]) >- self.assertEquals("replace", actions[0]["action"]) >+ self.assertEqual("replace", actions[0]["action"]) > > def test_ldap_change_password(self): > >@@ -221,30 +221,30 @@ class AuditLogDsdbTests(AuditLogTestBase): > > messages = self.waitForMessages(1) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["dsdbChange"] >- self.assertEquals("Modify", audit["operation"]) >+ self.assertEqual("Modify", audit["operation"]) > self.assertFalse(audit["performedAsSystem"]) >- self.assertEquals(dn, audit["dn"]) >+ self.assertEqual(dn, audit["dn"]) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > > attributes = audit["attributes"] >- self.assertEquals(1, len(attributes)) >+ self.assertEqual(1, len(attributes)) > actions = attributes["userPassword"]["actions"] >- self.assertEquals(2, len(actions)) >+ self.assertEqual(2, len(actions)) > self.assertTrue(actions[0]["redacted"]) >- self.assertEquals("delete", actions[0]["action"]) >+ self.assertEqual("delete", actions[0]["action"]) > self.assertTrue(actions[1]["redacted"]) >- self.assertEquals("add", actions[1]["action"]) >+ self.assertEqual("add", actions[1]["action"]) > > def test_ldap_replace_password(self): > >@@ -260,29 +260,29 @@ class AuditLogDsdbTests(AuditLogTestBase): > > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["dsdbChange"] >- self.assertEquals("Modify", audit["operation"]) >+ self.assertEqual("Modify", audit["operation"]) > self.assertFalse(audit["performedAsSystem"]) > self.assertTrue(dn.lower(), audit["dn"].lower()) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > self.assertTrue(self.is_guid(audit["transactionId"])) > > attributes = audit["attributes"] >- self.assertEquals(1, len(attributes)) >+ self.assertEqual(1, len(attributes)) > actions = attributes["userPassword"]["actions"] >- self.assertEquals(1, len(actions)) >+ self.assertEqual(1, len(actions)) > self.assertTrue(actions[0]["redacted"]) >- self.assertEquals("replace", actions[0]["action"]) >+ self.assertEqual("replace", actions[0]["action"]) > > def test_ldap_add_user(self): > >@@ -291,41 +291,41 @@ class AuditLogDsdbTests(AuditLogTestBase): > dn = "cn=" + USER_NAME + ",cn=users," + self.base_dn > messages = self.waitForMessages(2, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(2, >+ self.assertEqual(2, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[1]["dsdbChange"] >- self.assertEquals("Add", audit["operation"]) >+ self.assertEqual("Add", audit["operation"]) > self.assertFalse(audit["performedAsSystem"]) >- self.assertEquals(dn, audit["dn"]) >+ self.assertEqual(dn, audit["dn"]) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > self.assertTrue(self.is_guid(audit["sessionId"])) > self.assertTrue(self.is_guid(audit["transactionId"])) > > attributes = audit["attributes"] >- self.assertEquals(3, len(attributes)) >+ self.assertEqual(3, len(attributes)) > > actions = attributes["objectclass"]["actions"] >- self.assertEquals(1, len(actions)) >- self.assertEquals("add", actions[0]["action"]) >- self.assertEquals(1, len(actions[0]["values"])) >- self.assertEquals("user", actions[0]["values"][0]["value"]) >+ self.assertEqual(1, len(actions)) >+ self.assertEqual("add", actions[0]["action"]) >+ self.assertEqual(1, len(actions[0]["values"])) >+ self.assertEqual("user", actions[0]["values"][0]["value"]) > > actions = attributes["sAMAccountName"]["actions"] >- self.assertEquals(1, len(actions)) >- self.assertEquals("add", actions[0]["action"]) >- self.assertEquals(1, len(actions[0]["values"])) >- self.assertEquals(USER_NAME, actions[0]["values"][0]["value"]) >+ self.assertEqual(1, len(actions)) >+ self.assertEqual("add", actions[0]["action"]) >+ self.assertEqual(1, len(actions[0]["values"])) >+ self.assertEqual(USER_NAME, actions[0]["values"][0]["value"]) > > actions = attributes["userPassword"]["actions"] >- self.assertEquals(1, len(actions)) >- self.assertEquals("add", actions[0]["action"]) >+ self.assertEqual(1, len(actions)) >+ self.assertEqual("add", actions[0]["action"]) > self.assertTrue(actions[0]["redacted"]) > > def test_samdb_delete_user(self): >@@ -337,28 +337,28 @@ class AuditLogDsdbTests(AuditLogTestBase): > > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["dsdbChange"] >- self.assertEquals("Delete", audit["operation"]) >+ self.assertEqual("Delete", audit["operation"]) > self.assertFalse(audit["performedAsSystem"]) > self.assertTrue(dn.lower(), audit["dn"].lower()) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) >- self.assertEquals(0, audit["statusCode"]) >- self.assertEquals("Success", audit["status"]) >+ self.assertEqual(0, audit["statusCode"]) >+ self.assertEqual("Success", audit["status"]) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > > transactionId = audit["transactionId"] > message = self.waitForTransaction(transactionId) > audit = message["dsdbTransaction"] >- self.assertEquals("commit", audit["action"]) >+ self.assertEqual("commit", audit["action"]) > self.assertTrue(self.is_guid(audit["transactionId"])) > self.assertTrue(audit["duration"] > 0) > >@@ -377,28 +377,28 @@ class AuditLogDsdbTests(AuditLogTestBase): > > messages = self.waitForMessages(1) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["dsdbChange"] >- self.assertEquals("Delete", audit["operation"]) >+ self.assertEqual("Delete", audit["operation"]) > self.assertFalse(audit["performedAsSystem"]) > self.assertTrue(dn.lower(), audit["dn"].lower()) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) >- self.assertEquals(ERR_NO_SUCH_OBJECT, audit["statusCode"]) >- self.assertEquals("No such object", audit["status"]) >+ self.assertEqual(ERR_NO_SUCH_OBJECT, audit["statusCode"]) >+ self.assertEqual("No such object", audit["status"]) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > > transactionId = audit["transactionId"] > message = self.waitForTransaction(transactionId) > audit = message["dsdbTransaction"] >- self.assertEquals("rollback", audit["action"]) >+ self.assertEqual("rollback", audit["action"]) > self.assertTrue(self.is_guid(audit["transactionId"])) > self.assertTrue(audit["duration"] > 0) > >@@ -425,42 +425,42 @@ class AuditLogDsdbTests(AuditLogTestBase): > > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["dsdbChange"] >- self.assertEquals("Add", audit["operation"]) >+ self.assertEqual("Add", audit["operation"]) > self.assertTrue(audit["performedAsSystem"]) > self.assertTrue(dn.lower(), audit["dn"].lower()) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > > # We skip the check for self.get_service_description() as this > # is subject to a race between smbd and the s4 rpc_server code > # as to which will set the description as it is DCE/RPC over SMB > > attributes = audit["attributes"] >- self.assertEquals(2, len(attributes)) >+ self.assertEqual(2, len(attributes)) > > object_class = attributes["objectClass"] >- self.assertEquals(1, len(object_class["actions"])) >+ self.assertEqual(1, len(object_class["actions"])) > action = object_class["actions"][0] >- self.assertEquals("add", action["action"]) >+ self.assertEqual("add", action["action"]) > values = action["values"] >- self.assertEquals(1, len(values)) >- self.assertEquals("secret", values[0]["value"]) >+ self.assertEqual(1, len(values)) >+ self.assertEqual("secret", values[0]["value"]) > > cn = attributes["cn"] >- self.assertEquals(1, len(cn["actions"])) >+ self.assertEqual(1, len(cn["actions"])) > action = cn["actions"][0] >- self.assertEquals("add", action["action"]) >+ self.assertEqual("add", action["action"]) > values = action["values"] >- self.assertEquals(1, len(values)) >- self.assertEquals("Test Secret", values[0]["value"]) >+ self.assertEqual(1, len(values)) >+ self.assertEqual("Test Secret", values[0]["value"]) > > # > # Now delete the secret. >@@ -473,20 +473,20 @@ class AuditLogDsdbTests(AuditLogTestBase): > lsa_conn.DeleteObject(h) > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > dn = "cn=Test Secret,CN=System," + self.base_dn > audit = messages[0]["dsdbChange"] >- self.assertEquals("Delete", audit["operation"]) >+ self.assertEqual("Delete", audit["operation"]) > self.assertTrue(audit["performedAsSystem"]) > self.assertTrue(dn.lower(), audit["dn"].lower()) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > > # We skip the check for self.get_service_description() as this > # is subject to a race between smbd and the s4 rpc_server code >@@ -508,30 +508,30 @@ class AuditLogDsdbTests(AuditLogTestBase): > > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["dsdbChange"] >- self.assertEquals("Modify", audit["operation"]) >+ self.assertEqual("Modify", audit["operation"]) > self.assertFalse(audit["performedAsSystem"]) >- self.assertEquals(dn, audit["dn"]) >+ self.assertEqual(dn, audit["dn"]) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > > attributes = audit["attributes"] >- self.assertEquals(1, len(attributes)) >+ self.assertEqual(1, len(attributes)) > actions = attributes["carLicense"]["actions"] >- self.assertEquals(1, len(actions)) >- self.assertEquals("add", actions[0]["action"]) >+ self.assertEqual(1, len(actions)) >+ self.assertEqual("add", actions[0]["action"]) > values = actions[0]["values"] >- self.assertEquals(1, len(values)) >- self.assertEquals("license-01", values[0]["value"]) >+ self.assertEqual(1, len(values)) >+ self.assertEqual("license-01", values[0]["value"]) > > # > # Add an another value to the attribute >@@ -545,17 +545,17 @@ class AuditLogDsdbTests(AuditLogTestBase): > > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > attributes = messages[0]["dsdbChange"]["attributes"] >- self.assertEquals(1, len(attributes)) >+ self.assertEqual(1, len(attributes)) > actions = attributes["carLicense"]["actions"] >- self.assertEquals(1, len(actions)) >- self.assertEquals("add", actions[0]["action"]) >+ self.assertEqual(1, len(actions)) >+ self.assertEqual("add", actions[0]["action"]) > values = actions[0]["values"] >- self.assertEquals(1, len(values)) >- self.assertEquals("license-02", values[0]["value"]) >+ self.assertEqual(1, len(values)) >+ self.assertEqual("license-02", values[0]["value"]) > > # > # Add an another two values to the attribute >@@ -570,18 +570,18 @@ class AuditLogDsdbTests(AuditLogTestBase): > > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > attributes = messages[0]["dsdbChange"]["attributes"] >- self.assertEquals(1, len(attributes)) >+ self.assertEqual(1, len(attributes)) > actions = attributes["carLicense"]["actions"] >- self.assertEquals(1, len(actions)) >- self.assertEquals("add", actions[0]["action"]) >+ self.assertEqual(1, len(actions)) >+ self.assertEqual("add", actions[0]["action"]) > values = actions[0]["values"] >- self.assertEquals(2, len(values)) >- self.assertEquals("license-03", values[0]["value"]) >- self.assertEquals("license-04", values[1]["value"]) >+ self.assertEqual(2, len(values)) >+ self.assertEqual("license-03", values[0]["value"]) >+ self.assertEqual("license-04", values[1]["value"]) > > # > # delete two values to the attribute >@@ -596,18 +596,18 @@ class AuditLogDsdbTests(AuditLogTestBase): > > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > attributes = messages[0]["dsdbChange"]["attributes"] >- self.assertEquals(1, len(attributes)) >+ self.assertEqual(1, len(attributes)) > actions = attributes["carLicense"]["actions"] >- self.assertEquals(1, len(actions)) >- self.assertEquals("delete", actions[0]["action"]) >+ self.assertEqual(1, len(actions)) >+ self.assertEqual("delete", actions[0]["action"]) > values = actions[0]["values"] >- self.assertEquals(2, len(values)) >- self.assertEquals("license-03", values[0]["value"]) >- self.assertEquals("license-04", values[1]["value"]) >+ self.assertEqual(2, len(values)) >+ self.assertEqual("license-03", values[0]["value"]) >+ self.assertEqual("license-04", values[1]["value"]) > > # > # replace two values to the attribute >@@ -622,15 +622,15 @@ class AuditLogDsdbTests(AuditLogTestBase): > > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > attributes = messages[0]["dsdbChange"]["attributes"] >- self.assertEquals(1, len(attributes)) >+ self.assertEqual(1, len(attributes)) > actions = attributes["carLicense"]["actions"] >- self.assertEquals(1, len(actions)) >- self.assertEquals("replace", actions[0]["action"]) >+ self.assertEqual(1, len(actions)) >+ self.assertEqual("replace", actions[0]["action"]) > values = actions[0]["values"] >- self.assertEquals(2, len(values)) >- self.assertEquals("license-05", values[0]["value"]) >- self.assertEquals("license-06", values[1]["value"]) >+ self.assertEqual(2, len(values)) >+ self.assertEqual("license-05", values[0]["value"]) >+ self.assertEqual("license-06", values[1]["value"]) >diff --git a/python/samba/tests/audit_log_pass_change.py b/python/samba/tests/audit_log_pass_change.py >index d580698b3ba..f7e8423f696 100644 >--- a/python/samba/tests/audit_log_pass_change.py >+++ b/python/samba/tests/audit_log_pass_change.py >@@ -120,19 +120,19 @@ class AuditLogPassChangeTests(AuditLogTestBase): > > messages = self.waitForMessages(1, net, dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > audit = messages[0]["passwordChange"] >- self.assertEquals(EVT_ID_PASSWORD_CHANGE, audit["eventId"]) >- self.assertEquals("Change", audit["action"]) >- self.assertEquals(dn, audit["dn"]) >+ self.assertEqual(EVT_ID_PASSWORD_CHANGE, audit["eventId"]) >+ self.assertEqual("Change", audit["action"]) >+ self.assertEqual(dn, audit["dn"]) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "DCE/RPC") >+ self.assertEqual(service_description, "DCE/RPC") > self.assertTrue(self.is_guid(audit["transactionId"])) > > def test_net_set_password_user_without_permission(self): >@@ -148,23 +148,23 @@ class AuditLogPassChangeTests(AuditLogTestBase): > dn = "CN=" + SECOND_USER_NAME + ",CN=Users," + self.base_dn > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["passwordChange"] >- self.assertEquals(EVT_ID_PASSWORD_RESET, audit["eventId"]) >- self.assertEquals("Reset", audit["action"]) >- self.assertEquals(dn, audit["dn"]) >+ self.assertEqual(EVT_ID_PASSWORD_RESET, audit["eventId"]) >+ self.assertEqual("Reset", audit["action"]) >+ self.assertEqual(dn, audit["dn"]) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > self.assertTrue(self.is_guid(audit["transactionId"])) >- self.assertEquals(0, audit["statusCode"]) >- self.assertEquals("Success", audit["status"]) >+ self.assertEqual(0, audit["statusCode"]) >+ self.assertEqual("Success", audit["status"]) > self.discardMessages() > > creds = self.insta_creds( >@@ -189,23 +189,23 @@ class AuditLogPassChangeTests(AuditLogTestBase): > dn = "CN=" + USER_NAME + ",CN=Users," + self.base_dn > messages = self.waitForMessages(1, net, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["passwordChange"] >- self.assertEquals(EVT_ID_PASSWORD_RESET, audit["eventId"]) >- self.assertEquals("Reset", audit["action"]) >- self.assertEquals(dn, audit["dn"]) >+ self.assertEqual(EVT_ID_PASSWORD_RESET, audit["eventId"]) >+ self.assertEqual("Reset", audit["action"]) >+ self.assertEqual(dn, audit["dn"]) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "DCE/RPC") >+ self.assertEqual(service_description, "DCE/RPC") > self.assertTrue(self.is_guid(audit["transactionId"])) >- self.assertEquals(ERR_INSUFFICIENT_ACCESS_RIGHTS, audit["statusCode"]) >- self.assertEquals("insufficient access rights", audit["status"]) >+ self.assertEqual(ERR_INSUFFICIENT_ACCESS_RIGHTS, audit["statusCode"]) >+ self.assertEqual("insufficient access rights", audit["status"]) > > def test_net_set_password(self): > >@@ -226,22 +226,22 @@ class AuditLogPassChangeTests(AuditLogTestBase): > dn = "CN=" + USER_NAME + ",CN=Users," + self.base_dn > messages = self.waitForMessages(1, net, dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["passwordChange"] >- self.assertEquals(EVT_ID_PASSWORD_RESET, audit["eventId"]) >- self.assertEquals("Reset", audit["action"]) >- self.assertEquals(dn, audit["dn"]) >+ self.assertEqual(EVT_ID_PASSWORD_RESET, audit["eventId"]) >+ self.assertEqual("Reset", audit["action"]) >+ self.assertEqual(dn, audit["dn"]) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "DCE/RPC") >+ self.assertEqual(service_description, "DCE/RPC") > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > self.assertTrue(self.is_guid(audit["transactionId"])) > > def test_ldap_change_password(self): >@@ -260,21 +260,21 @@ class AuditLogPassChangeTests(AuditLogTestBase): > > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["passwordChange"] >- self.assertEquals(EVT_ID_PASSWORD_CHANGE, audit["eventId"]) >- self.assertEquals("Change", audit["action"]) >- self.assertEquals(dn, audit["dn"]) >+ self.assertEqual(EVT_ID_PASSWORD_CHANGE, audit["eventId"]) >+ self.assertEqual("Change", audit["action"]) >+ self.assertEqual(dn, audit["dn"]) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > self.assertTrue(self.is_guid(audit["transactionId"])) > > def test_ldap_replace_password(self): >@@ -291,21 +291,21 @@ class AuditLogPassChangeTests(AuditLogTestBase): > > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > > audit = messages[0]["passwordChange"] >- self.assertEquals(EVT_ID_PASSWORD_RESET, audit["eventId"]) >- self.assertEquals("Reset", audit["action"]) >- self.assertEquals(dn, audit["dn"]) >+ self.assertEqual(EVT_ID_PASSWORD_RESET, audit["eventId"]) >+ self.assertEqual("Reset", audit["action"]) >+ self.assertEqual(dn, audit["dn"]) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > self.assertTrue(self.is_guid(audit["transactionId"])) > > def test_ldap_add_user(self): >@@ -315,7 +315,7 @@ class AuditLogPassChangeTests(AuditLogTestBase): > dn = "cn=" + USER_NAME + ",cn=users," + self.base_dn > messages = self.waitForMessages(1, dn=dn) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > >@@ -323,14 +323,14 @@ class AuditLogPassChangeTests(AuditLogTestBase): > # The first message should be the reset from the Setup code. > # > audit = messages[0]["passwordChange"] >- self.assertEquals(EVT_ID_PASSWORD_RESET, audit["eventId"]) >- self.assertEquals("Reset", audit["action"]) >- self.assertEquals(dn, audit["dn"]) >+ self.assertEqual(EVT_ID_PASSWORD_RESET, audit["eventId"]) >+ self.assertEqual("Reset", audit["action"]) >+ self.assertEqual(dn, audit["dn"]) > self.assertRegexpMatches(audit["remoteAddress"], > self.remoteAddress) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > self.assertTrue(self.is_guid(audit["sessionId"])) > self.assertTrue(self.is_guid(audit["transactionId"])) >diff --git a/python/samba/tests/auth_log.py b/python/samba/tests/auth_log.py >index c0d0aab94aa..362793ae35a 100644 >--- a/python/samba/tests/auth_log.py >+++ b/python/samba/tests/auth_log.py >@@ -82,9 +82,9 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > > # Handle explicit smb2, smb1 or auto negotiation > if "smb2" in binding_list: >- self.assertEquals(serviceDescription, "SMB2") >+ self.assertEqual(serviceDescription, "SMB2") > elif "smb1" in binding_list: >- self.assertEquals(serviceDescription, "SMB") >+ self.assertEqual(serviceDescription, "SMB") > else: > self.assertIn(serviceDescription, ["SMB", "SMB2"]) > >@@ -92,30 +92,30 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > binding, protection): > > expected_messages = len(authTypes) >- self.assertEquals(expected_messages, >+ self.assertEqual(expected_messages, > len(messages), > "Did not receive the expected number of messages") > > # Check the first message it should be an Authentication > msg = messages[0] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals( >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual( > EVT_ID_SUCCESSFUL_LOGON, msg["Authentication"]["eventId"]) >- self.assertEquals( >+ self.assertEqual( > EVT_LOGON_NETWORK, msg["Authentication"]["logonType"]) > self._assert_ncacn_np_serviceDescription( > binding, msg["Authentication"]["serviceDescription"]) >- self.assertEquals(authTypes[1], >+ self.assertEqual(authTypes[1], > msg["Authentication"]["authDescription"]) > > # Check the second message it should be an Authorization > msg = messages[1] >- self.assertEquals("Authorization", msg["type"]) >+ self.assertEqual("Authorization", msg["type"]) > self._assert_ncacn_np_serviceDescription( > binding, msg["Authorization"]["serviceDescription"]) >- self.assertEquals(authTypes[2], msg["Authorization"]["authType"]) >- self.assertEquals("SMB", msg["Authorization"]["transportProtection"]) >+ self.assertEqual(authTypes[2], msg["Authorization"]["authType"]) >+ self.assertEqual("SMB", msg["Authorization"]["transportProtection"]) > self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"])) > > # Check the third message it should be an Authentication >@@ -125,17 +125,17 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > return (desc == "DCE/RPC" or desc == service) > > msg = messages[2] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) > self.assertTrue( > checkServiceDescription( > msg["Authentication"]["serviceDescription"])) > >- self.assertEquals(authTypes[3], >+ self.assertEqual(authTypes[3], > msg["Authentication"]["authDescription"]) >- self.assertEquals( >+ self.assertEqual( > EVT_ID_SUCCESSFUL_LOGON, msg["Authentication"]["eventId"]) >- self.assertEquals( >+ self.assertEqual( > EVT_LOGON_NETWORK, msg["Authentication"]["logonType"]) > > def rpc_ncacn_np_krb5_check( >@@ -147,7 +147,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > protection): > > expected_messages = len(authTypes) >- self.assertEquals(expected_messages, >+ self.assertEqual(expected_messages, > len(messages), > "Did not receive the expected number of messages") > >@@ -155,39 +155,39 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > # This is almost certainly Authentication over UDP, and is probably > # returning message too big, > msg = messages[0] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("Kerberos KDC", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("Kerberos KDC", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals(authTypes[1], >+ self.assertEqual(authTypes[1], > msg["Authentication"]["authDescription"]) >- self.assertEquals( >+ self.assertEqual( > EVT_ID_SUCCESSFUL_LOGON, msg["Authentication"]["eventId"]) >- self.assertEquals( >+ self.assertEqual( > EVT_LOGON_NETWORK, msg["Authentication"]["logonType"]) > > # Check the second message it should be an Authentication > # This this the TCP Authentication in response to the message too big > # response to the UDP Authentication > msg = messages[1] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("Kerberos KDC", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("Kerberos KDC", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals(authTypes[2], >+ self.assertEqual(authTypes[2], > msg["Authentication"]["authDescription"]) >- self.assertEquals( >+ self.assertEqual( > EVT_ID_SUCCESSFUL_LOGON, msg["Authentication"]["eventId"]) >- self.assertEquals( >+ self.assertEqual( > EVT_LOGON_NETWORK, msg["Authentication"]["logonType"]) > > # Check the third message it should be an Authorization > msg = messages[2] >- self.assertEquals("Authorization", msg["type"]) >+ self.assertEqual("Authorization", msg["type"]) > self._assert_ncacn_np_serviceDescription( > binding, msg["Authorization"]["serviceDescription"]) >- self.assertEquals(authTypes[3], msg["Authorization"]["authType"]) >- self.assertEquals("SMB", msg["Authorization"]["transportProtection"]) >+ self.assertEqual(authTypes[3], msg["Authorization"]["authType"]) >+ self.assertEqual("SMB", msg["Authorization"]["transportProtection"]) > self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"])) > > def test_rpc_ncacn_np_ntlm_dns_sign(self): >@@ -306,73 +306,73 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > binding, protection): > > expected_messages = len(authTypes) >- self.assertEquals(expected_messages, >+ self.assertEqual(expected_messages, > len(messages), > "Did not receive the expected number of messages") > > # Check the first message it should be an Authorization > msg = messages[0] >- self.assertEquals("Authorization", msg["type"]) >- self.assertEquals("DCE/RPC", >+ self.assertEqual("Authorization", msg["type"]) >+ self.assertEqual("DCE/RPC", > msg["Authorization"]["serviceDescription"]) >- self.assertEquals(authTypes[1], msg["Authorization"]["authType"]) >- self.assertEquals("NONE", msg["Authorization"]["transportProtection"]) >+ self.assertEqual(authTypes[1], msg["Authorization"]["authType"]) >+ self.assertEqual("NONE", msg["Authorization"]["transportProtection"]) > self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"])) > > # Check the second message it should be an Authentication > msg = messages[1] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("DCE/RPC", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("DCE/RPC", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals(authTypes[2], >+ self.assertEqual(authTypes[2], > msg["Authentication"]["authDescription"]) >- self.assertEquals( >+ self.assertEqual( > EVT_ID_SUCCESSFUL_LOGON, msg["Authentication"]["eventId"]) >- self.assertEquals( >+ self.assertEqual( > EVT_LOGON_NETWORK, msg["Authentication"]["logonType"]) > > def rpc_ncacn_ip_tcp_krb5_check(self, messages, authTypes, service, > binding, protection): > > expected_messages = len(authTypes) >- self.assertEquals(expected_messages, >+ self.assertEqual(expected_messages, > len(messages), > "Did not receive the expected number of messages") > > # Check the first message it should be an Authorization > msg = messages[0] >- self.assertEquals("Authorization", msg["type"]) >- self.assertEquals("DCE/RPC", >+ self.assertEqual("Authorization", msg["type"]) >+ self.assertEqual("DCE/RPC", > msg["Authorization"]["serviceDescription"]) >- self.assertEquals(authTypes[1], msg["Authorization"]["authType"]) >- self.assertEquals("NONE", msg["Authorization"]["transportProtection"]) >+ self.assertEqual(authTypes[1], msg["Authorization"]["authType"]) >+ self.assertEqual("NONE", msg["Authorization"]["transportProtection"]) > self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"])) > > # Check the second message it should be an Authentication > msg = messages[1] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("Kerberos KDC", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("Kerberos KDC", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals(authTypes[2], >+ self.assertEqual(authTypes[2], > msg["Authentication"]["authDescription"]) >- self.assertEquals( >+ self.assertEqual( > EVT_ID_SUCCESSFUL_LOGON, msg["Authentication"]["eventId"]) >- self.assertEquals( >+ self.assertEqual( > EVT_LOGON_NETWORK, msg["Authentication"]["logonType"]) > > # Check the third message it should be an Authentication > msg = messages[2] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("Kerberos KDC", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("Kerberos KDC", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals(authTypes[2], >+ self.assertEqual(authTypes[2], > msg["Authentication"]["authDescription"]) >- self.assertEquals( >+ self.assertEqual( > EVT_ID_SUCCESSFUL_LOGON, msg["Authentication"]["eventId"]) >- self.assertEquals( >+ self.assertEqual( > EVT_LOGON_NETWORK, msg["Authentication"]["logonType"]) > > def test_rpc_ncacn_ip_tcp_ntlm_dns_sign(self): >@@ -464,36 +464,36 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > credentials=self.get_credentials()) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(3, >+ self.assertEqual(3, > len(messages), > "Did not receive the expected number of messages") > > # Check the first message it should be an Authentication > msg = messages[0] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("Kerberos KDC", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("Kerberos KDC", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("ENC-TS Pre-authentication", >+ self.assertEqual("ENC-TS Pre-authentication", > msg["Authentication"]["authDescription"]) > self.assertTrue(msg["Authentication"]["duration"] > 0) >- self.assertEquals( >+ self.assertEqual( > EVT_ID_SUCCESSFUL_LOGON, msg["Authentication"]["eventId"]) >- self.assertEquals( >+ self.assertEqual( > EVT_LOGON_NETWORK, msg["Authentication"]["logonType"]) > > # Check the second message it should be an Authentication > msg = messages[1] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("Kerberos KDC", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("Kerberos KDC", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("ENC-TS Pre-authentication", >+ self.assertEqual("ENC-TS Pre-authentication", > msg["Authentication"]["authDescription"]) > self.assertTrue(msg["Authentication"]["duration"] > 0) >- self.assertEquals( >+ self.assertEqual( > EVT_ID_SUCCESSFUL_LOGON, msg["Authentication"]["eventId"]) >- self.assertEquals( >+ self.assertEqual( > EVT_LOGON_NETWORK, msg["Authentication"]["logonType"]) > > def test_ldap_ntlm(self): >@@ -509,20 +509,20 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > credentials=self.get_credentials()) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(2, >+ self.assertEqual(2, > len(messages), > "Did not receive the expected number of messages") > # Check the first message it should be an Authentication > msg = messages[0] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("LDAP", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("LDAP", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("NTLMSSP", msg["Authentication"]["authDescription"]) >+ self.assertEqual("NTLMSSP", msg["Authentication"]["authDescription"]) > self.assertTrue(msg["Authentication"]["duration"] > 0) >- self.assertEquals( >+ self.assertEqual( > EVT_ID_SUCCESSFUL_LOGON, msg["Authentication"]["eventId"]) >- self.assertEquals( >+ self.assertEqual( > EVT_LOGON_NETWORK, msg["Authentication"]["logonType"]) > > def test_ldap_simple_bind(self): >@@ -541,21 +541,21 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > credentials=creds) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(2, >+ self.assertEqual(2, > len(messages), > "Did not receive the expected number of messages") > > # Check the first message it should be an Authentication > msg = messages[0] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("LDAP", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("LDAP", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("simple bind", >+ self.assertEqual("simple bind", > msg["Authentication"]["authDescription"]) >- self.assertEquals( >+ self.assertEqual( > EVT_ID_SUCCESSFUL_LOGON, msg["Authentication"]["eventId"]) >- self.assertEquals( >+ self.assertEqual( > EVT_LOGON_NETWORK_CLEAR_TEXT, msg["Authentication"]["logonType"]) > > def test_ldap_simple_bind_bad_password(self): >@@ -583,10 +583,10 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > credentials=creds) > except LdbError: > thrown = True >- self.assertEquals(thrown, True) >+ self.assertEqual(thrown, True) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > >@@ -613,10 +613,10 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > credentials=creds) > except LdbError: > thrown = True >- self.assertEquals(thrown, True) >+ self.assertEqual(thrown, True) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > >@@ -643,10 +643,10 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > credentials=creds) > except LdbError: > thrown = True >- self.assertEquals(thrown, True) >+ self.assertEqual(thrown, True) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > >@@ -668,7 +668,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > credentials=creds) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(0, >+ self.assertEqual(0, > len(messages), > "Did not receive the expected number of messages") > >@@ -694,7 +694,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > pass > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > >@@ -712,33 +712,33 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > creds=creds) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(3, >+ self.assertEqual(3, > len(messages), > "Did not receive the expected number of messages") > # Check the first message it should be an Authentication > msg = messages[0] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("Kerberos KDC", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("Kerberos KDC", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("ENC-TS Pre-authentication", >+ self.assertEqual("ENC-TS Pre-authentication", > msg["Authentication"]["authDescription"]) >- self.assertEquals(EVT_ID_SUCCESSFUL_LOGON, >+ self.assertEqual(EVT_ID_SUCCESSFUL_LOGON, > msg["Authentication"]["eventId"]) >- self.assertEquals(EVT_LOGON_NETWORK, >+ self.assertEqual(EVT_LOGON_NETWORK, > msg["Authentication"]["logonType"]) > > # Check the second message it should be an Authentication > msg = messages[1] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("Kerberos KDC", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("Kerberos KDC", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("ENC-TS Pre-authentication", >+ self.assertEqual("ENC-TS Pre-authentication", > msg["Authentication"]["authDescription"]) >- self.assertEquals(EVT_ID_SUCCESSFUL_LOGON, >+ self.assertEqual(EVT_ID_SUCCESSFUL_LOGON, > msg["Authentication"]["eventId"]) >- self.assertEquals(EVT_LOGON_NETWORK, >+ self.assertEqual(EVT_LOGON_NETWORK, > msg["Authentication"]["logonType"]) > > def test_smb_bad_password(self): >@@ -762,10 +762,10 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > creds=creds) > except NTSTATUSError: > thrown = True >- self.assertEquals(thrown, True) >+ self.assertEqual(thrown, True) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > >@@ -794,10 +794,10 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > creds=creds) > except NTSTATUSError: > thrown = True >- self.assertEquals(thrown, True) >+ self.assertEqual(thrown, True) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > >@@ -816,42 +816,42 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > call(["bin/smbclient", path, auth, "-mNT1", "-c quit"]) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(3, >+ self.assertEqual(3, > len(messages), > "Did not receive the expected number of messages") > > # Check the first message it should be an Authentication > msg = messages[0] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_NO_SUCH_USER", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_NO_SUCH_USER", > msg["Authentication"]["status"]) >- self.assertEquals("SMB", >+ self.assertEqual("SMB", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("NTLMSSP", >+ self.assertEqual("NTLMSSP", > msg["Authentication"]["authDescription"]) >- self.assertEquals("No-Password", >+ self.assertEqual("No-Password", > msg["Authentication"]["passwordType"]) >- self.assertEquals(EVT_ID_UNSUCCESSFUL_LOGON, >+ self.assertEqual(EVT_ID_UNSUCCESSFUL_LOGON, > msg["Authentication"]["eventId"]) >- self.assertEquals(EVT_LOGON_NETWORK, >+ self.assertEqual(EVT_LOGON_NETWORK, > msg["Authentication"]["logonType"]) > > # Check the second message it should be an Authentication > msg = messages[1] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", > msg["Authentication"]["status"]) >- self.assertEquals("SMB", >+ self.assertEqual("SMB", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("NTLMSSP", >+ self.assertEqual("NTLMSSP", > msg["Authentication"]["authDescription"]) >- self.assertEquals("No-Password", >+ self.assertEqual("No-Password", > msg["Authentication"]["passwordType"]) >- self.assertEquals("ANONYMOUS LOGON", >+ self.assertEqual("ANONYMOUS LOGON", > msg["Authentication"]["becameAccount"]) >- self.assertEquals(EVT_ID_SUCCESSFUL_LOGON, >+ self.assertEqual(EVT_ID_SUCCESSFUL_LOGON, > msg["Authentication"]["eventId"]) >- self.assertEquals(EVT_LOGON_NETWORK, >+ self.assertEqual(EVT_LOGON_NETWORK, > msg["Authentication"]["logonType"]) > > def test_smb2_anonymous(self): >@@ -869,42 +869,42 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > call(["bin/smbclient", path, auth, "-mSMB3", "-c quit"]) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(3, >+ self.assertEqual(3, > len(messages), > "Did not receive the expected number of messages") > > # Check the first message it should be an Authentication > msg = messages[0] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_NO_SUCH_USER", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_NO_SUCH_USER", > msg["Authentication"]["status"]) >- self.assertEquals("SMB2", >+ self.assertEqual("SMB2", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("NTLMSSP", >+ self.assertEqual("NTLMSSP", > msg["Authentication"]["authDescription"]) >- self.assertEquals("No-Password", >+ self.assertEqual("No-Password", > msg["Authentication"]["passwordType"]) >- self.assertEquals(EVT_ID_UNSUCCESSFUL_LOGON, >+ self.assertEqual(EVT_ID_UNSUCCESSFUL_LOGON, > msg["Authentication"]["eventId"]) >- self.assertEquals(EVT_LOGON_NETWORK, >+ self.assertEqual(EVT_LOGON_NETWORK, > msg["Authentication"]["logonType"]) > > # Check the second message it should be an Authentication > msg = messages[1] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", > msg["Authentication"]["status"]) >- self.assertEquals("SMB2", >+ self.assertEqual("SMB2", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("NTLMSSP", >+ self.assertEqual("NTLMSSP", > msg["Authentication"]["authDescription"]) >- self.assertEquals("No-Password", >+ self.assertEqual("No-Password", > msg["Authentication"]["passwordType"]) >- self.assertEquals("ANONYMOUS LOGON", >+ self.assertEqual("ANONYMOUS LOGON", > msg["Authentication"]["becameAccount"]) >- self.assertEquals(EVT_ID_SUCCESSFUL_LOGON, >+ self.assertEqual(EVT_ID_SUCCESSFUL_LOGON, > msg["Authentication"]["eventId"]) >- self.assertEquals(EVT_LOGON_NETWORK, >+ self.assertEqual(EVT_LOGON_NETWORK, > msg["Authentication"]["logonType"]) > > def test_smb_no_krb_spnego(self): >@@ -922,22 +922,22 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > creds=creds) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(2, >+ self.assertEqual(2, > len(messages), > "Did not receive the expected number of messages") > # Check the first message it should be an Authentication > msg = messages[0] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("SMB", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("SMB", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("NTLMSSP", >+ self.assertEqual("NTLMSSP", > msg["Authentication"]["authDescription"]) >- self.assertEquals("NTLMv2", >+ self.assertEqual("NTLMv2", > msg["Authentication"]["passwordType"]) >- self.assertEquals(EVT_ID_SUCCESSFUL_LOGON, >+ self.assertEqual(EVT_ID_SUCCESSFUL_LOGON, > msg["Authentication"]["eventId"]) >- self.assertEquals(EVT_LOGON_NETWORK, >+ self.assertEqual(EVT_LOGON_NETWORK, > msg["Authentication"]["logonType"]) > > def test_smb_no_krb_spnego_bad_password(self): >@@ -965,10 +965,10 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > creds=creds) > except NTSTATUSError: > thrown = True >- self.assertEquals(thrown, True) >+ self.assertEqual(thrown, True) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > >@@ -997,10 +997,10 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > creds=creds) > except NTSTATUSError: > thrown = True >- self.assertEquals(thrown, True) >+ self.assertEqual(thrown, True) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > >@@ -1021,22 +1021,22 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > use_spnego=False) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(2, >+ self.assertEqual(2, > len(messages), > "Did not receive the expected number of messages") > # Check the first message it should be an Authentication > msg = messages[0] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("SMB", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("SMB", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("bare-NTLM", >+ self.assertEqual("bare-NTLM", > msg["Authentication"]["authDescription"]) >- self.assertEquals("NTLMv1", >+ self.assertEqual("NTLMv1", > msg["Authentication"]["passwordType"]) >- self.assertEquals(EVT_ID_SUCCESSFUL_LOGON, >+ self.assertEqual(EVT_ID_SUCCESSFUL_LOGON, > msg["Authentication"]["eventId"]) >- self.assertEquals(EVT_LOGON_NETWORK, >+ self.assertEqual(EVT_LOGON_NETWORK, > msg["Authentication"]["logonType"]) > > def test_smb_no_krb_no_spnego_no_ntlmv2_bad_password(self): >@@ -1066,10 +1066,10 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > use_spnego=False) > except NTSTATUSError: > thrown = True >- self.assertEquals(thrown, True) >+ self.assertEqual(thrown, True) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > >@@ -1100,10 +1100,10 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > use_spnego=False) > except NTSTATUSError: > thrown = True >- self.assertEquals(thrown, True) >+ self.assertEqual(thrown, True) > > messages = self.waitForMessages(isLastExpectedMessage) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > >@@ -1434,11 +1434,11 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > > # Check the second to last message it should be an Authorization > msg = messages[-2] >- self.assertEquals("Authorization", msg["type"]) >- self.assertEquals("DCE/RPC", >+ self.assertEqual("Authorization", msg["type"]) >+ self.assertEqual("DCE/RPC", > msg["Authorization"]["serviceDescription"]) >- self.assertEquals("schannel", msg["Authorization"]["authType"]) >- self.assertEquals("SEAL", msg["Authorization"]["transportProtection"]) >+ self.assertEqual("schannel", msg["Authorization"]["authType"]) >+ self.assertEqual("SEAL", msg["Authorization"]["transportProtection"]) > self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"])) > > # Signed logons get promoted to sealed, this test ensures that >@@ -1477,9 +1477,9 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): > > # Check the second to last message it should be an Authorization > msg = messages[-2] >- self.assertEquals("Authorization", msg["type"]) >- self.assertEquals("DCE/RPC", >+ self.assertEqual("Authorization", msg["type"]) >+ self.assertEqual("DCE/RPC", > msg["Authorization"]["serviceDescription"]) >- self.assertEquals("schannel", msg["Authorization"]["authType"]) >- self.assertEquals("SEAL", msg["Authorization"]["transportProtection"]) >+ self.assertEqual("schannel", msg["Authorization"]["authType"]) >+ self.assertEqual("SEAL", msg["Authorization"]["transportProtection"]) > self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"])) >diff --git a/python/samba/tests/auth_log_ncalrpc.py b/python/samba/tests/auth_log_ncalrpc.py >index 1281d28040e..511e575d9bd 100644 >--- a/python/samba/tests/auth_log_ncalrpc.py >+++ b/python/samba/tests/auth_log_ncalrpc.py >@@ -58,30 +58,30 @@ class AuthLogTestsNcalrpc(samba.tests.auth_log_base.AuthLogTestBase): > def rpc_ncacn_np_ntlm_check(self, messages, authTypes, protection): > > expected_messages = len(authTypes) >- self.assertEquals(expected_messages, >+ self.assertEqual(expected_messages, > len(messages), > "Did not receive the expected number of messages") > > # Check the first message it should be an Authorization > msg = messages[0] >- self.assertEquals("Authorization", msg["type"]) >- self.assertEquals("DCE/RPC", >+ self.assertEqual("Authorization", msg["type"]) >+ self.assertEqual("DCE/RPC", > msg["Authorization"]["serviceDescription"]) >- self.assertEquals(authTypes[1], msg["Authorization"]["authType"]) >- self.assertEquals("NONE", msg["Authorization"]["transportProtection"]) >+ self.assertEqual(authTypes[1], msg["Authorization"]["authType"]) >+ self.assertEqual("NONE", msg["Authorization"]["transportProtection"]) > self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"])) > > # Check the second message it should be an Authentication > msg = messages[1] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"]) >- self.assertEquals("DCE/RPC", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NT_STATUS_OK", msg["Authentication"]["status"]) >+ self.assertEqual("DCE/RPC", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals(authTypes[2], >+ self.assertEqual(authTypes[2], > msg["Authentication"]["authDescription"]) >- self.assertEquals(EVT_ID_SUCCESSFUL_LOGON, >+ self.assertEqual(EVT_ID_SUCCESSFUL_LOGON, > msg["Authentication"]["eventId"]) >- self.assertEquals(EVT_LOGON_NETWORK, >+ self.assertEqual(EVT_LOGON_NETWORK, > msg["Authentication"]["logonType"]) > > def test_ncalrpc_ntlm_dns_sign(self): >diff --git a/python/samba/tests/auth_log_netlogon.py b/python/samba/tests/auth_log_netlogon.py >index 83ffd33c1a6..2b5965e29e9 100644 >--- a/python/samba/tests/auth_log_netlogon.py >+++ b/python/samba/tests/auth_log_netlogon.py >@@ -105,33 +105,33 @@ class AuthLogTestsNetLogon(samba.tests.auth_log_base.AuthLogTestBase): > def netlogon_check(self, messages): > > expected_messages = 5 >- self.assertEquals(expected_messages, >+ self.assertEqual(expected_messages, > len(messages), > "Did not receive the expected number of messages") > > # Check the first message it should be an Authorization > msg = messages[0] >- self.assertEquals("Authorization", msg["type"]) >- self.assertEquals("DCE/RPC", >+ self.assertEqual("Authorization", msg["type"]) >+ self.assertEqual("DCE/RPC", > msg["Authorization"]["serviceDescription"]) >- self.assertEquals("ncalrpc", msg["Authorization"]["authType"]) >- self.assertEquals("NONE", msg["Authorization"]["transportProtection"]) >+ self.assertEqual("ncalrpc", msg["Authorization"]["authType"]) >+ self.assertEqual("NONE", msg["Authorization"]["transportProtection"]) > self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"])) > > # Check the fourth message it should be a NETLOGON Authentication > msg = messages[3] >- self.assertEquals("Authentication", msg["type"]) >- self.assertEquals("NETLOGON", >+ self.assertEqual("Authentication", msg["type"]) >+ self.assertEqual("NETLOGON", > msg["Authentication"]["serviceDescription"]) >- self.assertEquals("ServerAuthenticate", >+ self.assertEqual("ServerAuthenticate", > msg["Authentication"]["authDescription"]) >- self.assertEquals("NT_STATUS_OK", >+ self.assertEqual("NT_STATUS_OK", > msg["Authentication"]["status"]) >- self.assertEquals("HMAC-SHA256", >+ self.assertEqual("HMAC-SHA256", > msg["Authentication"]["passwordType"]) >- self.assertEquals(EVT_ID_SUCCESSFUL_LOGON, >+ self.assertEqual(EVT_ID_SUCCESSFUL_LOGON, > msg["Authentication"]["eventId"]) >- self.assertEquals(EVT_LOGON_NETWORK, >+ self.assertEqual(EVT_LOGON_NETWORK, > msg["Authentication"]["logonType"]) > > def test_netlogon(self): >diff --git a/python/samba/tests/auth_log_netlogon_bad_creds.py b/python/samba/tests/auth_log_netlogon_bad_creds.py >index 3b699bb6505..682ff770827 100644 >--- a/python/samba/tests/auth_log_netlogon_bad_creds.py >+++ b/python/samba/tests/auth_log_netlogon_bad_creds.py >@@ -109,17 +109,17 @@ class AuthLogTestsNetLogonBadCreds(samba.tests.auth_log_base.AuthLogTestBase): > def netlogon_check(self, messages): > > expected_messages = 4 >- self.assertEquals(expected_messages, >+ self.assertEqual(expected_messages, > len(messages), > "Did not receive the expected number of messages") > > # Check the first message it should be an Authorization > msg = messages[0] >- self.assertEquals("Authorization", msg["type"]) >- self.assertEquals("DCE/RPC", >+ self.assertEqual("Authorization", msg["type"]) >+ self.assertEqual("DCE/RPC", > msg["Authorization"]["serviceDescription"]) >- self.assertEquals("ncalrpc", msg["Authorization"]["authType"]) >- self.assertEquals("NONE", msg["Authorization"]["transportProtection"]) >+ self.assertEqual("ncalrpc", msg["Authorization"]["authType"]) >+ self.assertEqual("NONE", msg["Authorization"]["transportProtection"]) > self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"])) > > def test_netlogon_bad_machine_name(self): >diff --git a/python/samba/tests/auth_log_pass_change.py b/python/samba/tests/auth_log_pass_change.py >index f0a0ee68d17..c9e0481d539 100644 >--- a/python/samba/tests/auth_log_pass_change.py >+++ b/python/samba/tests/auth_log_pass_change.py >@@ -135,7 +135,7 @@ class AuthLogPassChangeTests(samba.tests.auth_log_base.AuthLogTestBase): > username=USER_NAME) > except Exception: > exception_thrown = True >- self.assertEquals(True, exception_thrown, >+ self.assertEqual(True, exception_thrown, > "Expected exception not thrown") > > messages = self.waitForMessages(isLastExpectedMessage) >@@ -170,7 +170,7 @@ class AuthLogPassChangeTests(samba.tests.auth_log_base.AuthLogTestBase): > username="badUser") > except Exception: > exception_thrown = True >- self.assertEquals(True, exception_thrown, >+ self.assertEqual(True, exception_thrown, > "Expected exception not thrown") > > messages = self.waitForMessages(isLastExpectedMessage) >@@ -205,7 +205,7 @@ class AuthLogPassChangeTests(samba.tests.auth_log_base.AuthLogTestBase): > username=USER_NAME) > except Exception: > exception_thrown = True >- self.assertEquals(True, exception_thrown, >+ self.assertEqual(True, exception_thrown, > "Expected exception not thrown") > > messages = self.waitForMessages(isLastExpectedMessage) >diff --git a/python/samba/tests/auth_log_samlogon.py b/python/samba/tests/auth_log_samlogon.py >index eeb64df41eb..e2d5d241af3 100644 >--- a/python/samba/tests/auth_log_samlogon.py >+++ b/python/samba/tests/auth_log_samlogon.py >@@ -162,17 +162,17 @@ class AuthLogTestsSamLogon(samba.tests.auth_log_base.AuthLogTestBase): > > messages = self.remove_netlogon_messages(messages) > expected_messages = 5 >- self.assertEquals(expected_messages, >+ self.assertEqual(expected_messages, > len(messages), > "Did not receive the expected number of messages") > > # Check the first message it should be an Authorization > msg = messages[0] >- self.assertEquals("Authorization", msg["type"]) >- self.assertEquals("DCE/RPC", >+ self.assertEqual("Authorization", msg["type"]) >+ self.assertEqual("DCE/RPC", > msg["Authorization"]["serviceDescription"]) >- self.assertEquals("ncalrpc", msg["Authorization"]["authType"]) >- self.assertEquals("NONE", msg["Authorization"]["transportProtection"]) >+ self.assertEqual("ncalrpc", msg["Authorization"]["authType"]) >+ self.assertEqual("NONE", msg["Authorization"]["transportProtection"]) > self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"])) > > def test_ncalrpc_samlogon(self): >diff --git a/python/samba/tests/blackbox/traffic_learner.py b/python/samba/tests/blackbox/traffic_learner.py >index bf2bb722d2e..ac941cea81c 100644 >--- a/python/samba/tests/blackbox/traffic_learner.py >+++ b/python/samba/tests/blackbox/traffic_learner.py >@@ -57,13 +57,13 @@ class TrafficLearnerTests(BlackboxTestCase): > actual_ngrams = {k: sorted(v) for k, v in actual.ngrams.items()} > expected_ngrams = {k: sorted(v) for k, v in expected.ngrams.items()} > >- self.assertEquals(expected_ngrams, actual_ngrams) >+ self.assertEqual(expected_ngrams, actual_ngrams) > > actual_details = {k: sorted(v) for k, v in actual.query_details.items()} > expected_details = {k: sorted(v) for k, v in expected.query_details.items()} >- self.assertEquals(expected_details, actual_details) >- self.assertEquals(expected.cumulative_duration, actual.cumulative_duration) >- self.assertEquals(expected.packet_rate, actual.packet_rate) >+ self.assertEqual(expected_details, actual_details) >+ self.assertEqual(expected.cumulative_duration, actual.cumulative_duration) >+ self.assertEqual(expected.packet_rate, actual.packet_rate) > > with open(expected_fn) as f1, open(output) as f2: > expected_json = json.load(f1) >diff --git a/python/samba/tests/blackbox/traffic_summary.py b/python/samba/tests/blackbox/traffic_summary.py >index c0be4c082e6..b895083fdb5 100644 >--- a/python/samba/tests/blackbox/traffic_summary.py >+++ b/python/samba/tests/blackbox/traffic_summary.py >@@ -50,4 +50,4 @@ class TrafficSummaryTests(BlackboxTestCase): > self.check_run(command) > expected = open(EXPECTED_FN).readlines() > actual = open(output).readlines() >- self.assertEquals(expected, actual) >+ self.assertEqual(expected, actual) >diff --git a/python/samba/tests/common.py b/python/samba/tests/common.py >index 2b7d22fd629..b7248b0826e 100644 >--- a/python/samba/tests/common.py >+++ b/python/samba/tests/common.py >@@ -27,18 +27,18 @@ from samba.samdb import SamDB, dsdb_Dn > class CommonTests(samba.tests.TestCaseInTempDir): > > def test_normalise_int32(self): >- self.assertEquals('17', normalise_int32(17)) >- self.assertEquals('17', normalise_int32('17')) >- self.assertEquals('-123', normalise_int32('-123')) >- self.assertEquals('-1294967296', normalise_int32('3000000000')) >+ self.assertEqual('17', normalise_int32(17)) >+ self.assertEqual('17', normalise_int32('17')) >+ self.assertEqual('-123', normalise_int32('-123')) >+ self.assertEqual('-1294967296', normalise_int32('3000000000')) > > def test_dsdb_Dn_binary(self): > url = self.tempdir + "/test_dsdb_Dn_binary.ldb" > sam = samba.Ldb(url=url) > dn1 = dsdb_Dn(sam, "DC=foo,DC=bar") > dn2 = dsdb_Dn(sam, "B:8:0000000D:<GUID=b3f0ec29-17f4-452a-b002-963e1909d101>;DC=samba,DC=example,DC=com") >- self.assertEquals(dn2.binary, "0000000D") >- self.assertEquals(13, dn2.get_binary_integer()) >+ self.assertEqual(dn2.binary, "0000000D") >+ self.assertEqual(13, dn2.get_binary_integer()) > os.unlink(url) > > def test_dsdb_Dn_sorted(self): >@@ -53,14 +53,14 @@ class CommonTests(samba.tests.TestCaseInTempDir): > dn6 = dsdb_Dn(sam, "<GUID=00000000-27f4-452a-b002-963e1909d101>;OU=dn6,DC=samba,DC=example,DC=com") > unsorted_links14 = [dn1, dn2, dn3, dn4] > sorted_vals14 = [str(dn) for dn in sorted(unsorted_links14)] >- self.assertEquals(sorted_vals14[0], str(dn3)) >- self.assertEquals(sorted_vals14[1], str(dn2)) >- self.assertEquals(sorted_vals14[2], str(dn1)) >- self.assertEquals(sorted_vals14[3], str(dn4)) >+ self.assertEqual(sorted_vals14[0], str(dn3)) >+ self.assertEqual(sorted_vals14[1], str(dn2)) >+ self.assertEqual(sorted_vals14[2], str(dn1)) >+ self.assertEqual(sorted_vals14[3], str(dn4)) > unsorted_links56 = [dn5, dn6] > sorted_vals56 = [str(dn) for dn in sorted(unsorted_links56)] >- self.assertEquals(sorted_vals56[0], str(dn6)) >- self.assertEquals(sorted_vals56[1], str(dn5)) >+ self.assertEqual(sorted_vals56[0], str(dn6)) >+ self.assertEqual(sorted_vals56[1], str(dn5)) > finally: > del sam > os.unlink(url) >diff --git a/python/samba/tests/core.py b/python/samba/tests/core.py >index 2614e9c9962..e3b44d18696 100644 >--- a/python/samba/tests/core.py >+++ b/python/samba/tests/core.py >@@ -27,22 +27,22 @@ from samba.tests import TestCase, TestCaseInTempDir > class SubstituteVarTestCase(TestCase): > > def test_empty(self): >- self.assertEquals("", samba.substitute_var("", {})) >+ self.assertEqual("", samba.substitute_var("", {})) > > def test_nothing(self): >- self.assertEquals("foo bar", >+ self.assertEqual("foo bar", > samba.substitute_var("foo bar", {"bar": "bla"})) > > def test_replace(self): >- self.assertEquals("foo bla", >+ self.assertEqual("foo bla", > samba.substitute_var("foo ${bar}", {"bar": "bla"})) > > def test_broken(self): >- self.assertEquals("foo ${bdkjfhsdkfh sdkfh ", >+ self.assertEqual("foo ${bdkjfhsdkfh sdkfh ", > samba.substitute_var("foo ${bdkjfhsdkfh sdkfh ", {"bar": "bla"})) > > def test_unknown_var(self): >- self.assertEquals("foo ${bla} gsff", >+ self.assertEqual("foo ${bla} gsff", > samba.substitute_var("foo ${bla} gsff", {"bar": "bla"})) > > def test_check_all_substituted(self): >@@ -58,7 +58,7 @@ class ArcfourTestCase(TestCase): > plain = b'abcdefghi' > crypt_expected = b'\xda\x91Z\xb0l\xd7\xb9\xcf\x99' > crypt_calculated = arcfour_encrypt(key, plain) >- self.assertEquals(crypt_expected, crypt_calculated) >+ self.assertEqual(crypt_expected, crypt_calculated) > > > class StringToByteArrayTestCase(TestCase): >@@ -66,7 +66,7 @@ class StringToByteArrayTestCase(TestCase): > def test_byte_array(self): > expected = [218, 145, 90, 176, 108, 215, 185, 207, 153] > calculated = string_to_byte_array('\xda\x91Z\xb0l\xd7\xb9\xcf\x99') >- self.assertEquals(expected, calculated) >+ self.assertEqual(expected, calculated) > > > class LdbExtensionTests(TestCaseInTempDir): >@@ -76,7 +76,7 @@ class LdbExtensionTests(TestCaseInTempDir): > l = samba.Ldb(path) > try: > l.add({"dn": "foo=dc", "bar": "bla"}) >- self.assertEquals(b"bla", >+ self.assertEqual(b"bla", > l.searchone(basedn=ldb.Dn(l, "foo=dc"), attribute="bar")) > finally: > del l >diff --git a/python/samba/tests/dcerpc/bare.py b/python/samba/tests/dcerpc/bare.py >index bb25546ddc7..622965277e7 100644 >--- a/python/samba/tests/dcerpc/bare.py >+++ b/python/samba/tests/dcerpc/bare.py >@@ -31,7 +31,7 @@ class BareTestCase(samba.tests.TestCase): > x = ClientConnection("ncalrpc:localhost[DEFAULT]", > ("60a15ec5-4de8-11d7-a637-005056a20182", 1), > lp_ctx=samba.tests.env_loadparm()) >- self.assertEquals(b"\x01\x00\x00\x00", x.request(0, chr(0) * 4)) >+ self.assertEqual(b"\x01\x00\x00\x00", x.request(0, chr(0) * 4)) > > def test_two_contexts(self): > x = ClientConnection("ncalrpc:localhost[DEFAULT]", >@@ -40,15 +40,15 @@ class BareTestCase(samba.tests.TestCase): > y = ClientConnection("ncalrpc:localhost", > ("60a15ec5-4de8-11d7-a637-005056a20182", 1), > basis_connection=x, lp_ctx=samba.tests.env_loadparm()) >- self.assertEquals(24, len(x.request(0, chr(0) * 8))) >- self.assertEquals(b"\x01\x00\x00\x00", y.request(0, chr(0) * 4)) >+ self.assertEqual(24, len(x.request(0, chr(0) * 8))) >+ self.assertEqual(b"\x01\x00\x00\x00", y.request(0, chr(0) * 4)) > > def test_bare_tcp(self): > # Connect to the echo pipe > x = ClientConnection("ncacn_ip_tcp:%s" % os.environ["SERVER"], > ("60a15ec5-4de8-11d7-a637-005056a20182", 1), > lp_ctx=samba.tests.env_loadparm()) >- self.assertEquals(b"\x01\x00\x00\x00", x.request(0, chr(0) * 4)) >+ self.assertEqual(b"\x01\x00\x00\x00", x.request(0, chr(0) * 4)) > > def test_two_contexts_tcp(self): > x = ClientConnection("ncacn_ip_tcp:%s" % os.environ["SERVER"], >@@ -57,5 +57,5 @@ class BareTestCase(samba.tests.TestCase): > y = ClientConnection("ncacn_ip_tcp:%s" % os.environ["SERVER"], > ("60a15ec5-4de8-11d7-a637-005056a20182", 1), > basis_connection=x, lp_ctx=samba.tests.env_loadparm()) >- self.assertEquals(24, len(x.request(0, chr(0) * 8))) >- self.assertEquals(b"\x01\x00\x00\x00", y.request(0, chr(0) * 4)) >+ self.assertEqual(24, len(x.request(0, chr(0) * 8))) >+ self.assertEqual(b"\x01\x00\x00\x00", y.request(0, chr(0) * 4)) >diff --git a/python/samba/tests/dcerpc/dnsserver.py b/python/samba/tests/dcerpc/dnsserver.py >index c6a150c876f..540ba009850 100644 >--- a/python/samba/tests/dcerpc/dnsserver.py >+++ b/python/samba/tests/dcerpc/dnsserver.py >@@ -840,21 +840,21 @@ class DnsserverTests(RpcInterfaceTestCase): > self.server, > None, > 'ServerInfo') >- self.assertEquals(dnsserver.DNSSRV_TYPEID_SERVER_INFO_W2K, typeid) >+ self.assertEqual(dnsserver.DNSSRV_TYPEID_SERVER_INFO_W2K, typeid) > > typeid, result = self.conn.DnssrvQuery2(dnsserver.DNS_CLIENT_VERSION_DOTNET, > 0, > self.server, > None, > 'ServerInfo') >- self.assertEquals(dnsserver.DNSSRV_TYPEID_SERVER_INFO_DOTNET, typeid) >+ self.assertEqual(dnsserver.DNSSRV_TYPEID_SERVER_INFO_DOTNET, typeid) > > typeid, result = self.conn.DnssrvQuery2(dnsserver.DNS_CLIENT_VERSION_LONGHORN, > 0, > self.server, > None, > 'ServerInfo') >- self.assertEquals(dnsserver.DNSSRV_TYPEID_SERVER_INFO, typeid) >+ self.assertEqual(dnsserver.DNSSRV_TYPEID_SERVER_INFO, typeid) > > > # This test is to confirm that we do not support multizone operations, >@@ -936,7 +936,7 @@ class DnsserverTests(RpcInterfaceTestCase): > 'EnumZones', > dnsserver.DNSSRV_TYPEID_DWORD, > request_filter) >- self.assertEquals(1, zones.dwZoneCount) >+ self.assertEqual(1, zones.dwZoneCount) > > # Delete zone > self.conn.DnssrvOperation2(client_version, >@@ -955,7 +955,7 @@ class DnsserverTests(RpcInterfaceTestCase): > 'EnumZones', > dnsserver.DNSSRV_TYPEID_DWORD, > request_filter) >- self.assertEquals(0, zones.dwZoneCount) >+ self.assertEqual(0, zones.dwZoneCount) > > def test_complexoperation2(self): > client_version = dnsserver.DNS_CLIENT_VERSION_LONGHORN >@@ -969,8 +969,8 @@ class DnsserverTests(RpcInterfaceTestCase): > 'EnumZones', > dnsserver.DNSSRV_TYPEID_DWORD, > request_filter) >- self.assertEquals(dnsserver.DNSSRV_TYPEID_ZONE_LIST, typeid) >- self.assertEquals(3, zones.dwZoneCount) >+ self.assertEqual(dnsserver.DNSSRV_TYPEID_ZONE_LIST, typeid) >+ self.assertEqual(3, zones.dwZoneCount) > > request_filter = (dnsserver.DNS_ZONE_REQUEST_REVERSE | > dnsserver.DNS_ZONE_REQUEST_PRIMARY) >@@ -981,8 +981,8 @@ class DnsserverTests(RpcInterfaceTestCase): > 'EnumZones', > dnsserver.DNSSRV_TYPEID_DWORD, > request_filter) >- self.assertEquals(dnsserver.DNSSRV_TYPEID_ZONE_LIST, typeid) >- self.assertEquals(0, zones.dwZoneCount) >+ self.assertEqual(dnsserver.DNSSRV_TYPEID_ZONE_LIST, typeid) >+ self.assertEqual(0, zones.dwZoneCount) > > def test_enumrecords2(self): > client_version = dnsserver.DNS_CLIENT_VERSION_LONGHORN >@@ -999,7 +999,7 @@ class DnsserverTests(RpcInterfaceTestCase): > select_flags, > None, > None) >- self.assertEquals(14, roothints.count) # 1 NS + 13 A records (a-m) >+ self.assertEqual(14, roothints.count) # 1 NS + 13 A records (a-m) > > def test_updaterecords2(self): > client_version = dnsserver.DNS_CLIENT_VERSION_LONGHORN >@@ -1031,10 +1031,10 @@ class DnsserverTests(RpcInterfaceTestCase): > select_flags, > None, > None) >- self.assertEquals(1, result.count) >- self.assertEquals(1, result.rec[0].wRecordCount) >- self.assertEquals(dnsp.DNS_TYPE_A, result.rec[0].records[0].wType) >- self.assertEquals('1.2.3.4', result.rec[0].records[0].data) >+ self.assertEqual(1, result.count) >+ self.assertEqual(1, result.rec[0].wRecordCount) >+ self.assertEqual(dnsp.DNS_TYPE_A, result.rec[0].records[0].wType) >+ self.assertEqual('1.2.3.4', result.rec[0].records[0].data) > > # Update record > add_rec_buf = dnsserver.DNS_RPC_RECORD_BUF() >@@ -1059,10 +1059,10 @@ class DnsserverTests(RpcInterfaceTestCase): > select_flags, > None, > None) >- self.assertEquals(1, result.count) >- self.assertEquals(1, result.rec[0].wRecordCount) >- self.assertEquals(dnsp.DNS_TYPE_A, result.rec[0].records[0].wType) >- self.assertEquals('5.6.7.8', result.rec[0].records[0].data) >+ self.assertEqual(1, result.count) >+ self.assertEqual(1, result.rec[0].wRecordCount) >+ self.assertEqual(dnsp.DNS_TYPE_A, result.rec[0].records[0].wType) >+ self.assertEqual('5.6.7.8', result.rec[0].records[0].data) > > # Delete record > del_rec_buf = dnsserver.DNS_RPC_RECORD_BUF() >diff --git a/python/samba/tests/dcerpc/integer.py b/python/samba/tests/dcerpc/integer.py >index 2825c670843..69a6a09a381 100644 >--- a/python/samba/tests/dcerpc/integer.py >+++ b/python/samba/tests/dcerpc/integer.py >@@ -26,12 +26,12 @@ class IntegerTests(samba.tests.TestCase): > def test_uint32_into_hyper(self): > s = server_id.server_id() > s.unique_id = server_id.NONCLUSTER_VNN >- self.assertEquals(s.unique_id, 0xFFFFFFFF) >+ self.assertEqual(s.unique_id, 0xFFFFFFFF) > > def test_int_into_hyper(self): > s = server_id.server_id() > s.unique_id = 1 >- self.assertEquals(s.unique_id, 1) >+ self.assertEqual(s.unique_id, 1) > > def test_negative_int_into_hyper(self): > s = server_id.server_id() >@@ -57,7 +57,7 @@ class IntegerTests(samba.tests.TestCase): > def test_int_into_int32(self): > s = srvsvc.NetRemoteTODInfo() > s.timezone = 5 >- self.assertEquals(s.timezone, 5) >+ self.assertEqual(s.timezone, 5) > > def test_uint32_into_int32(self): > s = srvsvc.NetRemoteTODInfo() >@@ -75,7 +75,7 @@ class IntegerTests(samba.tests.TestCase): > # s.timezone = 5L > # but that is a syntax error in py3. > s.timezone = (5 << 65) >> 65 >- self.assertEquals(s.timezone, 5) >+ self.assertEqual(s.timezone, 5) > > def test_larger_long_int_into_int32(self): > s = srvsvc.NetRemoteTODInfo() >@@ -87,7 +87,7 @@ class IntegerTests(samba.tests.TestCase): > def test_larger_int_into_int32(self): > s = srvsvc.NetRemoteTODInfo() > s.timezone = 2147483647 >- self.assertEquals(s.timezone, 2147483647) >+ self.assertEqual(s.timezone, 2147483647) > > def test_float_into_int32(self): > s = srvsvc.NetRemoteTODInfo() >@@ -106,7 +106,7 @@ class IntegerTests(samba.tests.TestCase): > def test_negative_int_into_int32(self): > s = srvsvc.NetRemoteTODInfo() > s.timezone = -2147483648 >- self.assertEquals(s.timezone, -2147483648) >+ self.assertEqual(s.timezone, -2147483648) > > def test_negative_into_uint32(self): > s = server_id.server_id() >@@ -139,7 +139,7 @@ class IntegerTests(samba.tests.TestCase): > def test_enum_into_uint16(self): > g = misc.GUID() > g.time_mid = misc.SEC_CHAN_DOMAIN >- self.assertEquals(g.time_mid, misc.SEC_CHAN_DOMAIN) >+ self.assertEqual(g.time_mid, misc.SEC_CHAN_DOMAIN) > > def test_bitmap_into_uint16(self): > g = misc.GUID() >@@ -170,22 +170,22 @@ class IntegerTests(samba.tests.TestCase): > def test_int_into_int64(self): > s = samr.DomInfo1() > s.max_password_age = 5 >- self.assertEquals(s.max_password_age, 5) >+ self.assertEqual(s.max_password_age, 5) > > def test_negative_int_into_int64(self): > s = samr.DomInfo1() > s.max_password_age = -5 >- self.assertEquals(s.max_password_age, -5) >+ self.assertEqual(s.max_password_age, -5) > > def test_larger_int_into_int64(self): > s = samr.DomInfo1() > s.max_password_age = server_id.NONCLUSTER_VNN >- self.assertEquals(s.max_password_age, 0xFFFFFFFF) >+ self.assertEqual(s.max_password_age, 0xFFFFFFFF) > > def test_larger_negative_int_into_int64(self): > s = samr.DomInfo1() > s.max_password_age = -2147483649 >- self.assertEquals(s.max_password_age, -2147483649) >+ self.assertEqual(s.max_password_age, -2147483649) > > def test_int_list_over_list(self): > g = misc.GUID() >diff --git a/python/samba/tests/dcerpc/misc.py b/python/samba/tests/dcerpc/misc.py >index d2ba1843a0e..009d8d02768 100644 >--- a/python/samba/tests/dcerpc/misc.py >+++ b/python/samba/tests/dcerpc/misc.py >@@ -36,11 +36,11 @@ class GUIDTests(samba.tests.TestCase): > > def test_str(self): > guid = misc.GUID(text1) >- self.assertEquals(text1, str(guid)) >+ self.assertEqual(text1, str(guid)) > > def test_repr(self): > guid = misc.GUID(text1) >- self.assertEquals("GUID('%s')" % text1, repr(guid)) >+ self.assertEqual("GUID('%s')" % text1, repr(guid)) > > def test_compare_different(self): > guid1 = misc.GUID(text1) >@@ -53,8 +53,8 @@ class GUIDTests(samba.tests.TestCase): > guid1 = misc.GUID(text1) > guid2 = misc.GUID(text1) > self.assertTrue(guid1 == guid2) >- self.assertEquals(guid1, guid2) >- self.assertEquals(0, cmp(guid1, guid2)) >+ self.assertEqual(guid1, guid2) >+ self.assertEqual(0, cmp(guid1, guid2)) > > def test_valid_formats(self): > fmts = [ >@@ -70,7 +70,7 @@ class GUIDTests(samba.tests.TestCase): > ] > for fmt in fmts: > guid = misc.GUID(fmt) >- self.assertEquals(text3, str(guid)) >+ self.assertEqual(text3, str(guid)) > > def test_invalid_formats(self): > fmts = [ >@@ -95,13 +95,13 @@ class PolicyHandleTests(samba.tests.TestCase): > > def test_init(self): > x = misc.policy_handle(text1, 1) >- self.assertEquals(1, x.handle_type) >- self.assertEquals(text1, str(x.uuid)) >+ self.assertEqual(1, x.handle_type) >+ self.assertEqual(text1, str(x.uuid)) > > def test_repr(self): > x = misc.policy_handle(text1, 42) >- self.assertEquals("policy_handle(%d, '%s')" % (42, text1), repr(x)) >+ self.assertEqual("policy_handle(%d, '%s')" % (42, text1), repr(x)) > > def test_str(self): > x = misc.policy_handle(text1, 42) >- self.assertEquals("%d, %s" % (42, text1), str(x)) >+ self.assertEqual("%d, %s" % (42, text1), str(x)) >diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py >index e2c45603d39..c4c9cbfa299 100755 >--- a/python/samba/tests/dcerpc/raw_protocol.py >+++ b/python/samba/tests/dcerpc/raw_protocol.py >@@ -64,19 +64,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > pfc_flags=rep_pfc_flags, auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > # And now try a request > req = self.generate_request(call_id=1, >@@ -88,8 +88,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > def _test_no_auth_request_alter_pfc_flags(self, req_pfc_flags, rep_pfc_flags): >@@ -107,19 +107,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > # And now try a alter context > req = self.generate_alter(call_id=0, pfc_flags=req_pfc_flags, ctx_list=[ctx1]) >@@ -127,19 +127,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > pfc_flags=rep_pfc_flags, auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >- self.assertEquals(rep.u.secondary_address, "") >+ self.assertEqual(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address, "") > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > # And now try a request > req = self.generate_request(call_id=1, >@@ -151,8 +151,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > def test_no_auth_request(self): >@@ -359,11 +359,11 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.reject_reason, >+ self.assertEqual(rep.u.reject_reason, > dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) >- self.assertEquals(rep.u.num_versions, 1) >- self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) >- self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) >+ self.assertEqual(rep.u.num_versions, 1) >+ self.assertEqual(rep.u.versions[0].rpc_vers, req.rpc_vers) >+ self.assertEqual(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) > self.assertPadding(rep.u._pad, 3) > > def test_invalid_auth_noctx(self): >@@ -373,11 +373,11 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.reject_reason, >+ self.assertEqual(rep.u.reject_reason, > dcerpc.DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED) >- self.assertEquals(rep.u.num_versions, 1) >- self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) >- self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) >+ self.assertEqual(rep.u.num_versions, 1) >+ self.assertEqual(rep.u.versions[0].rpc_vers, req.rpc_vers) >+ self.assertEqual(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) > self.assertPadding(rep.u._pad, 3) > > def test_no_auth_valid_valid_request(self): >@@ -395,19 +395,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > # Send a bind again > tsf2_list = [ndr32] >@@ -422,11 +422,11 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.reject_reason, >+ self.assertEqual(rep.u.reject_reason, > dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) >- self.assertEquals(rep.u.num_versions, 1) >- self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) >- self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) >+ self.assertEqual(rep.u.num_versions, 1) >+ self.assertEqual(rep.u.versions[0].rpc_vers, req.rpc_vers) >+ self.assertEqual(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) > self.assertPadding(rep.u._pad, 3) > > # wait for a disconnect >@@ -441,11 +441,11 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.reject_reason, >+ self.assertEqual(rep.u.reject_reason, > dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) >- self.assertEquals(rep.u.num_versions, 1) >- self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) >- self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) >+ self.assertEqual(rep.u.num_versions, 1) >+ self.assertEqual(rep.u.versions[0].rpc_vers, req.rpc_vers) >+ self.assertEqual(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) > self.assertPadding(rep.u._pad, 3) > > # wait for a disconnect >@@ -468,19 +468,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > # Send a alter > req = self.generate_alter(call_id=1, ctx_list=[]) >@@ -491,12 +491,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -520,19 +520,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > # Send a alter > req = self.generate_alter(call_id=1, ctx_list=[ctx1]) >@@ -540,18 +540,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > req = self.generate_request(call_id=2, > context_id=ctx1.context_id, >@@ -564,12 +564,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, ctx1.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_OP_RNG_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, ctx1.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_OP_RNG_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > def test_no_auth_presentation_ctx_invalid1(self): > ndr32 = base.transfer_syntax_ndr() >@@ -588,19 +588,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > # Send a alter > req = self.generate_alter(call_id=1, ctx_list=[ctx1]) >@@ -608,18 +608,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > req = self.generate_request(call_id=2, > context_id=12345, >@@ -632,12 +632,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_UNKNOWN_IF) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_UNKNOWN_IF) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # Send a alter again to prove the connection is still alive > req = self.generate_alter(call_id=3, ctx_list=[ctx1]) >@@ -645,18 +645,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > def test_no_auth_presentation_ctx_invalid2(self): > ndr32 = base.transfer_syntax_ndr() >@@ -675,11 +675,11 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.reject_reason, >+ self.assertEqual(rep.u.reject_reason, > dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) >- self.assertEquals(rep.u.num_versions, 1) >- self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) >- self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) >+ self.assertEqual(rep.u.num_versions, 1) >+ self.assertEqual(rep.u.versions[0].rpc_vers, req.rpc_vers) >+ self.assertEqual(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) > self.assertPadding(rep.u._pad, 3) > > # wait for a disconnect >@@ -704,19 +704,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > tsf1b_list = [] > ctx1b = dcerpc.ctx_list() >@@ -734,12 +734,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -764,19 +764,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > # With a known but wrong syntax we get a protocol error > # see test_no_auth_presentation_ctx_valid2 >@@ -796,12 +796,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -825,19 +825,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > # With a unknown but wrong syntaxes we get NO protocol error > # see test_no_auth_presentation_ctx_invalid4 >@@ -854,18 +854,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > req = self.generate_request(call_id=2, > context_id=ctx1a.context_id, >@@ -878,12 +878,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, ctx1a.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_OP_RNG_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, ctx1a.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_OP_RNG_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > def test_no_auth_presentation_ctx_no_ndr64(self): > ndr32 = base.transfer_syntax_ndr() >@@ -901,19 +901,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > tsf0_list = [ndr32] > ctx0 = dcerpc.ctx_list() >@@ -927,18 +927,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > req = self.generate_request(call_id=1, > context_id=ctx0.context_id, >@@ -949,8 +949,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > tsf1_list = [zero_syntax, ndr32] >@@ -965,18 +965,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > req = self.generate_request(call_id=1, > context_id=ctx1.context_id, >@@ -987,8 +987,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > tsf2_list = [ndr32, ndr32] >@@ -1003,18 +1003,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > req = self.generate_request(call_id=1, > context_id=ctx2.context_id, >@@ -1025,8 +1025,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > tsf3_list = [ndr32] >@@ -1048,23 +1048,23 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 2) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 2) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.ctx_list[1].result, >+ self.assertEqual(rep.u.ctx_list[1].result, > dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) >- self.assertEquals(rep.u.ctx_list[1].reason, >+ self.assertEqual(rep.u.ctx_list[1].reason, > dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[1].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > req = self.generate_request(call_id=1, > context_id=ctx3.context_id, >@@ -1075,8 +1075,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > req = self.generate_alter(call_id=43, ctx_list=[ctx4, ctx3]) >@@ -1084,23 +1084,23 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 2) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 2) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.ctx_list[1].result, >+ self.assertEqual(rep.u.ctx_list[1].result, > dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) >- self.assertEquals(rep.u.ctx_list[1].reason, >+ self.assertEqual(rep.u.ctx_list[1].reason, > dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[1].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > req = self.generate_request(call_id=1, > context_id=ctx4.context_id, >@@ -1111,8 +1111,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > req = self.generate_request(call_id=1, >@@ -1124,8 +1124,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > req = self.generate_alter(call_id=44, ctx_list=[ctx4, ctx4]) >@@ -1133,23 +1133,23 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 2) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 2) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.ctx_list[1].result, >+ self.assertEqual(rep.u.ctx_list[1].result, > dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) >- self.assertEquals(rep.u.ctx_list[1].reason, >+ self.assertEqual(rep.u.ctx_list[1].reason, > dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[1].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > req = self.generate_request(call_id=1, > context_id=ctx4.context_id, >@@ -1160,8 +1160,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > req = self.generate_request(call_id=1, >@@ -1173,8 +1173,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > tsf5mgmt_list = [ndr32] >@@ -1196,23 +1196,23 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 2) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 2) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.ctx_list[1].result, >+ self.assertEqual(rep.u.ctx_list[1].result, > dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) >- self.assertEquals(rep.u.ctx_list[1].reason, >+ self.assertEqual(rep.u.ctx_list[1].reason, > dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[1].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > req = self.generate_request(call_id=1, > context_id=ctx5mgmt.context_id, >@@ -1223,8 +1223,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > req = self.generate_alter(call_id=55, ctx_list=[ctx5mgmt, ctx5epm]) >@@ -1232,23 +1232,23 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 2) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 2) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.ctx_list[1].result, >+ self.assertEqual(rep.u.ctx_list[1].result, > dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) >- self.assertEquals(rep.u.ctx_list[1].reason, >+ self.assertEqual(rep.u.ctx_list[1].reason, > dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[1].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > req = self.generate_request(call_id=1, > context_id=ctx5mgmt.context_id, >@@ -1259,8 +1259,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > def test_no_auth_bind_time_none_simple(self): >@@ -1281,18 +1281,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) >- self.assertEquals(rep.u.ctx_list[0].reason, features) >+ self.assertEqual(rep.u.ctx_list[0].reason, features) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > def test_no_auth_bind_time_none_ignore_additional(self): > features1 = 0 >@@ -1317,18 +1317,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) >- self.assertEquals(rep.u.ctx_list[0].reason, features1) >+ self.assertEqual(rep.u.ctx_list[0].reason, features1) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > def test_no_auth_bind_time_only_first(self): > features1 = dcerpc.DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN >@@ -1351,19 +1351,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > def test_no_auth_bind_time_twice(self): > features1 = dcerpc.DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN >@@ -1393,11 +1393,11 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.reject_reason, >+ self.assertEqual(rep.u.reject_reason, > dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) >- self.assertEquals(rep.u.num_versions, 1) >- self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) >- self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) >+ self.assertEqual(rep.u.num_versions, 1) >+ self.assertEqual(rep.u.versions[0].rpc_vers, req.rpc_vers) >+ self.assertEqual(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) > self.assertPadding(rep.u._pad, 3) > > # wait for a disconnect >@@ -1423,18 +1423,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) >- self.assertEquals(rep.u.ctx_list[0].reason, features) >+ self.assertEqual(rep.u.ctx_list[0].reason, features) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > def test_no_auth_bind_time_keep_on_orphan_ignore_additional(self): > features1 = dcerpc.DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN >@@ -1458,18 +1458,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) >- self.assertEquals(rep.u.ctx_list[0].reason, features1) >+ self.assertEqual(rep.u.ctx_list[0].reason, features1) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > def test_no_auth_bind_time_sec_ctx_ignore_additional(self): > features1 = dcerpc.DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING >@@ -1493,18 +1493,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) >- self.assertEquals(rep.u.ctx_list[0].reason, features1) >+ self.assertEqual(rep.u.ctx_list[0].reason, features1) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > def _test_auth_type_level_bind_nak(self, auth_type, auth_level, creds=None, > reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE): >@@ -1549,10 +1549,10 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.reject_reason, reason) >- self.assertEquals(rep.u.num_versions, 1) >- self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) >- self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) >+ self.assertEqual(rep.u.reject_reason, reason) >+ self.assertEqual(rep.u.num_versions, 1) >+ self.assertEqual(rep.u.versions[0].rpc_vers, req.rpc_vers) >+ self.assertEqual(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) > self.assertPadding(rep.u._pad, 3) > > # wait for a disconnect >@@ -1616,19 +1616,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(len(rep.u.auth_info), 0) >+ self.assertEqual(len(rep.u.auth_info), 0) > > # And now try a request without auth_info > req = self.generate_request(call_id=2, >@@ -1640,8 +1640,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > auth_info = self.generate_auth(auth_type=auth_type, >@@ -1660,12 +1660,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -1704,19 +1704,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, rep_both) >- self.assertEquals(rep.u.max_recv_frag, rep_both) >+ self.assertEqual(rep.u.max_xmit_frag, rep_both) >+ self.assertEqual(rep.u.max_recv_frag, rep_both) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > assoc_group_id = rep.u.assoc_group_id > if alter_xmit is None: >@@ -1735,18 +1735,18 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, rep_both) >- self.assertEquals(rep.u.max_recv_frag, rep_both) >- self.assertEquals(rep.u.assoc_group_id, rep.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.max_xmit_frag, rep_both) >+ self.assertEqual(rep.u.max_recv_frag, rep_both) >+ self.assertEqual(rep.u.assoc_group_id, rep.u.assoc_group_id) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > chunk_size = rep_both - dcerpc.DCERPC_REQUEST_LENGTH > req = self.generate_request(call_id=2, >@@ -1759,8 +1759,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > chunk_size = 5840 - dcerpc.DCERPC_REQUEST_LENGTH >@@ -1774,8 +1774,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > chunk_size += 1 >@@ -1790,12 +1790,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -1862,19 +1862,19 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >- self.assertEquals(rep.u.auth_info, b'\0' * 0) >+ self.assertEqual(rep.u.auth_info, b'\0' * 0) > > # And now try a request without auth_info > req = self.generate_request(call_id=2, >@@ -1887,8 +1887,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > req = self.generate_request(call_id=3, >@@ -1901,8 +1901,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > req = self.generate_request(call_id=4, >@@ -1915,8 +1915,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > def _get_netlogon_ctx(self): >@@ -1993,12 +1993,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, fault_first) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, fault_first) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -2013,12 +2013,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, fault_last) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, fault_last) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -2035,12 +2035,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, fault_last) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, fault_last) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -2051,13 +2051,13 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > >- self.assertEquals(len(rep.u.stub_and_verifier), 12) >+ self.assertEqual(len(rep.u.stub_and_verifier), 12) > status = struct.unpack_from("<I", rep.u.stub_and_verifier, len(rep.u.stub_and_verifier) - 4) >- self.assertEquals(status[0], 0) >+ self.assertEqual(status[0], 0) > > def test_fragmented_requests01(self): > return self._test_fragmented_requests(remaining=0x400000, >@@ -2097,12 +2097,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -2127,12 +2127,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -2194,12 +2194,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_NO_CALL_ACTIVE) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_FAULT_NO_CALL_ACTIVE) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -2242,13 +2242,13 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > >- self.assertEquals(len(rep.u.stub_and_verifier), 12) >+ self.assertEqual(len(rep.u.stub_and_verifier), 12) > status = struct.unpack_from("<I", rep.u.stub_and_verifier, len(rep.u.stub_and_verifier) - 4) >- self.assertEquals(status[0], 0) >+ self.assertEqual(status[0], 0) > > def test_last_cancel_requests(self): > (ctx, rep, real_stub) = self._get_netlogon_ctx() >@@ -2276,13 +2276,13 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > >- self.assertEquals(len(rep.u.stub_and_verifier), 12) >+ self.assertEqual(len(rep.u.stub_and_verifier), 12) > status = struct.unpack_from("<I", rep.u.stub_and_verifier, len(rep.u.stub_and_verifier) - 4) >- self.assertEquals(status[0], 0) >+ self.assertEqual(status[0], 0) > > def test_mix_requests(self): > (ctx, rep, real_stub) = self._get_netlogon_ctx() >@@ -2312,12 +2312,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_LAST, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > def test_co_cancel_no_request(self): > ndr32 = base.transfer_syntax_ndr() >@@ -2340,8 +2340,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > def test_co_cancel_request_after_first(self): >@@ -2375,8 +2375,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > # And now try a request >@@ -2389,8 +2389,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > def test_orphaned_no_request(self): >@@ -2414,8 +2414,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > def test_orphaned_request_after_first_last(self): >@@ -2449,8 +2449,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > # And now try a request >@@ -2463,8 +2463,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > def test_orphaned_request_after_first_mpx_last(self): >@@ -2502,8 +2502,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > # And now try a request >@@ -2516,8 +2516,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > def test_orphaned_request_after_first_no_last(self): >@@ -2551,12 +2551,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req1.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req1.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, req1.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -2599,12 +2599,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req2.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -2646,16 +2646,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -2678,15 +2678,15 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >- self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.assoc_group_id, req.u.assoc_group_id) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -2706,8 +2706,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT >@@ -2726,8 +2726,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > # Now a request with auth_info DCERPC_AUTH_LEVEL_INTEGRITY >@@ -2746,12 +2746,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -2793,16 +2793,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -2825,15 +2825,15 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >- self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.assoc_group_id, req.u.assoc_group_id) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -2859,12 +2859,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -2906,17 +2906,17 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) > assoc_group_id = rep.u.assoc_group_id >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -2944,12 +2944,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -2989,16 +2989,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3030,12 +3030,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -3078,16 +3078,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3108,15 +3108,15 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >- self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.assoc_group_id, req.u.assoc_group_id) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3136,8 +3136,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT >@@ -3156,8 +3156,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > # Now a reauth >@@ -3188,12 +3188,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -3236,16 +3236,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3266,15 +3266,15 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >- self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.assoc_group_id, req.u.assoc_group_id) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3294,8 +3294,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT >@@ -3314,8 +3314,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > # Now a reauth >@@ -3345,12 +3345,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -3389,16 +3389,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3423,12 +3423,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -3473,16 +3473,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3507,12 +3507,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -3559,16 +3559,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3594,12 +3594,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -3639,16 +3639,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3674,12 +3674,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_SEC_PKG_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_FAULT_SEC_PKG_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -3726,16 +3726,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3761,12 +3761,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -3813,16 +3813,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3848,12 +3848,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -3910,16 +3910,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3955,15 +3955,15 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >- self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.assoc_group_id, req.u.assoc_group_id) >+ self.assertEqual(rep.u.secondary_address_size, 0) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -3983,8 +3983,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT >@@ -4003,8 +4003,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > self._disconnect("disconnect") >@@ -4061,13 +4061,13 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.reject_reason, >+ self.assertEqual(rep.u.reject_reason, > dcerpc.DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED) >- self.assertEquals(rep.u.num_versions, 1) >- self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) >- self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) >- self.assertEquals(len(rep.u._pad), 3) >- self.assertEquals(rep.u._pad, b'\0' * 3) >+ self.assertEqual(rep.u.num_versions, 1) >+ self.assertEqual(rep.u.versions[0].rpc_vers, req.rpc_vers) >+ self.assertEqual(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) >+ self.assertEqual(len(rep.u._pad), 3) >+ self.assertEqual(rep.u._pad, b'\0' * 3) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -4124,16 +4124,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -4174,12 +4174,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -4236,16 +4236,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -4278,8 +4278,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT >@@ -4298,8 +4298,8 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > > self._disconnect("disconnect") >@@ -4355,16 +4355,16 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.send_pdu(req) > rep = self.recv_pdu() > self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 4) >- self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEqual(rep.u.secondary_address_size, 4) >+ self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) > self.assertNotEquals(len(rep.u.auth_info), 0) >@@ -4389,12 +4389,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > # wait for a disconnect > rep = self.recv_pdu() >@@ -4504,12 +4504,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > pfc_flags=req.pfc_flags | response_fault_flags, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, ctx1.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, request_fault) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, ctx1.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, request_fault) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > if response_fault_flags & dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE: > return >@@ -4671,10 +4671,10 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=sig_size) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) >- self.assertEquals(rep.auth_length, sig_size) >+ self.assertEqual(rep.auth_length, sig_size) > > ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH > ofs_sig = rep.frag_length - rep.auth_length >@@ -4685,13 +4685,13 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep_auth_info_blob = rep_blob[ofs_trailer:] > > rep_auth_info = self.parse_auth(rep_auth_info_blob) >- self.assertEquals(rep_auth_info.auth_type, auth_type) >- self.assertEquals(rep_auth_info.auth_level, auth_level) >+ self.assertEqual(rep_auth_info.auth_type, auth_type) >+ self.assertEqual(rep_auth_info.auth_level, auth_level) > # mgmt_inq_if_ids() returns no fixed size results >- #self.assertEquals(rep_auth_info.auth_pad_length, 0) >- self.assertEquals(rep_auth_info.auth_reserved, 0) >- self.assertEquals(rep_auth_info.auth_context_id, auth_context_id) >- self.assertEquals(rep_auth_info.credentials, rep_sig) >+ #self.assertEqual(rep_auth_info.auth_pad_length, 0) >+ self.assertEqual(rep_auth_info.auth_reserved, 0) >+ self.assertEqual(rep_auth_info.auth_context_id, auth_context_id) >+ self.assertEqual(rep_auth_info.credentials, rep_sig) > > g.check_packet(rep_data, rep_whole, rep_sig) > >@@ -4739,12 +4739,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, ctx1.context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_OP_RNG_ERROR) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, ctx1.context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, dcerpc.DCERPC_NCA_S_OP_RNG_ERROR) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > > stub_bin = b'\x00' * 8 > mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT >@@ -4788,10 +4788,10 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=sig_size) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) >- self.assertEquals(rep.auth_length, sig_size) >+ self.assertEqual(rep.auth_length, sig_size) > > ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH > ofs_sig = rep.frag_length - rep.auth_length >@@ -4802,12 +4802,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep_auth_info_blob = rep_blob[ofs_trailer:] > > rep_auth_info = self.parse_auth(rep_auth_info_blob) >- self.assertEquals(rep_auth_info.auth_type, auth_type) >- self.assertEquals(rep_auth_info.auth_level, auth_level) >- self.assertEquals(rep_auth_info.auth_pad_length, 4) >- self.assertEquals(rep_auth_info.auth_reserved, 0) >- self.assertEquals(rep_auth_info.auth_context_id, auth_context_id) >- self.assertEquals(rep_auth_info.credentials, rep_sig) >+ self.assertEqual(rep_auth_info.auth_type, auth_type) >+ self.assertEqual(rep_auth_info.auth_level, auth_level) >+ self.assertEqual(rep_auth_info.auth_pad_length, 4) >+ self.assertEqual(rep_auth_info.auth_reserved, 0) >+ self.assertEqual(rep_auth_info.auth_context_id, auth_context_id) >+ self.assertEqual(rep_auth_info.credentials, rep_sig) > > g.check_packet(rep_data, rep_whole, rep_sig) > >@@ -4853,10 +4853,10 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=sig_size) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) >- self.assertEquals(rep.auth_length, sig_size) >+ self.assertEqual(rep.auth_length, sig_size) > > ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH > ofs_sig = rep.frag_length - rep.auth_length >@@ -4867,12 +4867,12 @@ class TestDCERPC_BIND(RawDCERPCTest): > rep_auth_info_blob = rep_blob[ofs_trailer:] > > rep_auth_info = self.parse_auth(rep_auth_info_blob) >- self.assertEquals(rep_auth_info.auth_type, auth_type) >- self.assertEquals(rep_auth_info.auth_level, auth_level) >- self.assertEquals(rep_auth_info.auth_pad_length, 12) >- self.assertEquals(rep_auth_info.auth_reserved, 0) >- self.assertEquals(rep_auth_info.auth_context_id, auth_context_id) >- self.assertEquals(rep_auth_info.credentials, rep_sig) >+ self.assertEqual(rep_auth_info.auth_type, auth_type) >+ self.assertEqual(rep_auth_info.auth_level, auth_level) >+ self.assertEqual(rep_auth_info.auth_pad_length, 12) >+ self.assertEqual(rep_auth_info.auth_reserved, 0) >+ self.assertEqual(rep_auth_info.auth_context_id, auth_context_id) >+ self.assertEqual(rep_auth_info.credentials, rep_sig) > > g.check_packet(rep_data, rep_whole, rep_sig) > >diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py >index 1a174363214..ba7440df13b 100644 >--- a/python/samba/tests/dcerpc/raw_testcase.py >+++ b/python/samba/tests/dcerpc/raw_testcase.py >@@ -118,9 +118,9 @@ class RawDCERPCTest(TestCase): > > def _connect_smb(self): > a = self.primary_address.split('\\') >- self.assertEquals(len(a), 3) >- self.assertEquals(a[0], "") >- self.assertEquals(a[1], "pipe") >+ self.assertEqual(len(a), 3) >+ self.assertEqual(a[0], "") >+ self.assertEqual(a[1], "pipe") > pipename = a[2] > self.s = smb_pipe_socket(self.target_hostname, > pipename, >@@ -319,20 +319,20 @@ class RawDCERPCTest(TestCase): > samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, alter_fault) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, alter_fault) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > return None > self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > pfc_flags=req.pfc_flags) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >- self.assertEquals(rep.u.assoc_group_id, assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >- self.assertEquals(rep.u.secondary_address, '') >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.assoc_group_id, assoc_group_id) >+ self.assertEqual(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address, '') > self.assertPadding(rep.u._pad1, 2) > else: > req = self.generate_bind(call_id=call_id, >@@ -345,18 +345,18 @@ class RawDCERPCTest(TestCase): > if nak_reason is not None: > self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, > auth_length=0) >- self.assertEquals(rep.u.reject_reason, nak_reason) >- self.assertEquals(rep.u.num_versions, 1) >- self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) >- self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) >+ self.assertEqual(rep.u.reject_reason, nak_reason) >+ self.assertEqual(rep.u.num_versions, 1) >+ self.assertEqual(rep.u.versions[0].rpc_vers, req.rpc_vers) >+ self.assertEqual(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) > self.assertPadding(rep.u._pad, 3) > return > self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, > pfc_flags=pfc_flags) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) > if assoc_group_id != 0: >- self.assertEquals(rep.u.assoc_group_id, assoc_group_id) >+ self.assertEqual(rep.u.assoc_group_id, assoc_group_id) > else: > self.assertNotEquals(rep.u.assoc_group_id, 0) > assoc_group_id = rep.u.assoc_group_id >@@ -367,24 +367,24 @@ class RawDCERPCTest(TestCase): > sda_pad = 4 - mod_len > else: > sda_pad = 0 >- self.assertEquals(rep.u.secondary_address_size, sda_len) >- self.assertEquals(rep.u.secondary_address, sda_str) >+ self.assertEqual(rep.u.secondary_address_size, sda_len) >+ self.assertEqual(rep.u.secondary_address, sda_str) > self.assertPadding(rep.u._pad1, sda_pad) > >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > samba.dcerpc.dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > samba.dcerpc.dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ctx.transfer_syntaxes[0]) > ack = rep > if auth_context is None: >- self.assertEquals(rep.auth_length, 0) >- self.assertEquals(len(rep.u.auth_info), 0) >+ self.assertEqual(rep.auth_length, 0) >+ self.assertEqual(len(rep.u.auth_info), 0) > return ack > self.assertNotEquals(rep.auth_length, 0) > self.assertGreater(len(rep.u.auth_info), samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH) >- self.assertEquals(rep.auth_length, len(rep.u.auth_info) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH) >+ self.assertEqual(rep.auth_length, len(rep.u.auth_info) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH) > > a = self.parse_auth(rep.u.auth_info, auth_context=auth_context) > >@@ -424,33 +424,33 @@ class RawDCERPCTest(TestCase): > samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, > auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, 0) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, alter_fault) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, 0) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, alter_fault) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > return None > self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, > pfc_flags=req.pfc_flags) >- self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >- self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >- self.assertEquals(rep.u.assoc_group_id, assoc_group_id) >- self.assertEquals(rep.u.secondary_address_size, 0) >- self.assertEquals(rep.u.secondary_address, '') >+ self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEqual(rep.u.assoc_group_id, assoc_group_id) >+ self.assertEqual(rep.u.secondary_address_size, 0) >+ self.assertEqual(rep.u.secondary_address, '') > self.assertPadding(rep.u._pad1, 2) >- self.assertEquals(rep.u.num_results, 1) >- self.assertEquals(rep.u.ctx_list[0].result, >+ self.assertEqual(rep.u.num_results, 1) >+ self.assertEqual(rep.u.ctx_list[0].result, > samba.dcerpc.dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >- self.assertEquals(rep.u.ctx_list[0].reason, >+ self.assertEqual(rep.u.ctx_list[0].reason, > samba.dcerpc.dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) > self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ctx.transfer_syntaxes[0]) > if finished: >- self.assertEquals(rep.auth_length, 0) >+ self.assertEqual(rep.auth_length, 0) > else: > self.assertNotEquals(rep.auth_length, 0) > self.assertGreaterEqual(len(rep.u.auth_info), samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH) >- self.assertEquals(rep.auth_length, len(rep.u.auth_info) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH) >+ self.assertEqual(rep.auth_length, len(rep.u.auth_info) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH) > > a = self.parse_auth(rep.u.auth_info, auth_context=auth_context) > >@@ -545,12 +545,12 @@ class RawDCERPCTest(TestCase): > self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_FAULT, req.call_id, > pfc_flags=fault_pfc_flags, auth_length=0) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, fault_context_id) >- self.assertEquals(rep.u.cancel_count, 0) >- self.assertEquals(rep.u.flags, 0) >- self.assertEquals(rep.u.status, fault_status) >- self.assertEquals(rep.u.reserved, 0) >- self.assertEquals(len(rep.u.error_and_verifier), 0) >+ self.assertEqual(rep.u.context_id, fault_context_id) >+ self.assertEqual(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.flags, 0) >+ self.assertEqual(rep.u.status, fault_status) >+ self.assertEqual(rep.u.reserved, 0) >+ self.assertEqual(len(rep.u.error_and_verifier), 0) > return > > expected_auth_length = 0 >@@ -561,8 +561,8 @@ class RawDCERPCTest(TestCase): > self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_RESPONSE, req.call_id, > auth_length=expected_auth_length) > self.assertNotEquals(rep.u.alloc_hint, 0) >- self.assertEquals(rep.u.context_id, req.u.context_id & 0xff) >- self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEqual(rep.u.context_id, req.u.context_id & 0xff) >+ self.assertEqual(rep.u.cancel_count, 0) > self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) > stub_out = self.check_response_auth(rep, rep_blob, auth_context) > self.assertEqual(len(stub_out), rep.u.alloc_hint) >@@ -783,10 +783,10 @@ class RawDCERPCTest(TestCase): > sys.stderr.write("parse_auth: %s" % samba.ndr.ndr_print(a)) > > if auth_context is not None: >- self.assertEquals(a.auth_type, auth_context["auth_type"]) >- self.assertEquals(a.auth_level, auth_context["auth_level"]) >- self.assertEquals(a.auth_reserved, 0) >- self.assertEquals(a.auth_context_id, auth_context["auth_context_id"]) >+ self.assertEqual(a.auth_type, auth_context["auth_type"]) >+ self.assertEqual(a.auth_level, auth_context["auth_level"]) >+ self.assertEqual(a.auth_reserved, 0) >+ self.assertEqual(a.auth_context_id, auth_context["auth_context_id"]) > > self.assertLessEqual(a.auth_pad_length, dcerpc.DCERPC_AUTH_PAD_ALIGNMENT) > self.assertLessEqual(a.auth_pad_length, stub_len) >@@ -797,11 +797,11 @@ class RawDCERPCTest(TestCase): > auth_pad_length=None): > > if auth_context is None: >- self.assertEquals(rep.auth_length, 0) >+ self.assertEqual(rep.auth_length, 0) > return rep.u.stub_and_verifier > > if auth_context["auth_level"] == dcerpc.DCERPC_AUTH_LEVEL_CONNECT: >- self.assertEquals(rep.auth_length, 0) >+ self.assertEqual(rep.auth_length, 0) > return rep.u.stub_and_verifier > > self.assertGreater(rep.auth_length, 0) >@@ -818,8 +818,8 @@ class RawDCERPCTest(TestCase): > auth_context=auth_context, > stub_len=len(rep_data)) > if auth_pad_length is not None: >- self.assertEquals(rep_auth_info.auth_pad_length, auth_pad_length) >- self.assertEquals(rep_auth_info.credentials, rep_sig) >+ self.assertEqual(rep_auth_info.auth_pad_length, auth_pad_length) >+ self.assertEqual(rep_auth_info.credentials, rep_sig) > > if auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PRIVACY: > # TODO: not yet supported here >@@ -925,13 +925,13 @@ class RawDCERPCTest(TestCase): > elif auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PACKET: > req_sig = auth_context["gensec"].sign_packet(req_data, req_whole) > elif auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_CONNECT: >- self.assertEquals(auth_context["auth_type"], >+ self.assertEqual(auth_context["auth_type"], > dcerpc.DCERPC_AUTH_TYPE_NTLMSSP) > req_sig = b"\x01" +b"\x00" *15 > else: > return req >- self.assertEquals(len(req_sig), req.auth_length) >- self.assertEquals(len(req_sig), sig_size) >+ self.assertEqual(len(req_sig), req.auth_length) >+ self.assertEqual(len(req_sig), sig_size) > > stub_sig_ofs = len(req.u.stub_and_verifier) - sig_size > stub = req.u.stub_and_verifier[0:stub_sig_ofs] + req_sig >@@ -1147,7 +1147,7 @@ class RawDCERPCTest(TestCase): > return > > def assertPadding(self, pad, length): >- self.assertEquals(len(pad), length) >+ self.assertEqual(len(pad), length) > # > # sometimes windows sends random bytes > # >@@ -1157,7 +1157,7 @@ class RawDCERPCTest(TestCase): > if self.ignore_random_pad: > return > zero_pad = b'\0' * length >- self.assertEquals(pad, zero_pad) >+ self.assertEqual(pad, zero_pad) > > def assertEqualsStrLower(self, s1, s2): >- self.assertEquals(str(s1).lower(), str(s2).lower()) >+ self.assertEqual(str(s1).lower(), str(s2).lower()) >diff --git a/python/samba/tests/dcerpc/registry.py b/python/samba/tests/dcerpc/registry.py >index 279eeb1cc82..04838ff6f1b 100644 >--- a/python/samba/tests/dcerpc/registry.py >+++ b/python/samba/tests/dcerpc/registry.py >@@ -40,12 +40,12 @@ class WinregTests(RpcInterfaceTestCase): > def test_getversion(self): > handle = self.get_hklm() > version = self.conn.GetVersion(handle) >- self.assertEquals(int, version.__class__) >+ self.assertEqual(int, version.__class__) > self.conn.CloseKey(handle) > > def test_getkeyinfo(self): > handle = self.conn.OpenHKLM(None, > winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) > x = self.conn.QueryInfoKey(handle, winreg.String()) >- self.assertEquals(9, len(x)) # should return a 9-tuple >+ self.assertEqual(9, len(x)) # should return a 9-tuple > self.conn.CloseKey(handle) >diff --git a/python/samba/tests/dcerpc/rpc_talloc.py b/python/samba/tests/dcerpc/rpc_talloc.py >index 191e70c9702..4d50f382d45 100644 >--- a/python/samba/tests/dcerpc/rpc_talloc.py >+++ b/python/samba/tests/dcerpc/rpc_talloc.py >@@ -45,7 +45,7 @@ class TallocTests(samba.tests.TestCase): > nblocks = talloc.total_blocks(object) > if object is None: > nblocks -= self.initial_blocks >- self.assertEquals(nblocks, num_expected) >+ self.assertEqual(nblocks, num_expected) > > def get_rodc_partial_attribute_set(self): > '''get a list of attributes for RODC replication''' >diff --git a/python/samba/tests/dcerpc/rpcecho.py b/python/samba/tests/dcerpc/rpcecho.py >index 0711ae41546..0ae86c56350 100644 >--- a/python/samba/tests/dcerpc/rpcecho.py >+++ b/python/samba/tests/dcerpc/rpcecho.py >@@ -30,33 +30,33 @@ class RpcEchoTests(RpcInterfaceTestCase): > > def test_two_contexts(self): > self.conn2 = echo.rpcecho("ncalrpc:", self.get_loadparm(), basis_connection=self.conn) >- self.assertEquals(3, self.conn2.AddOne(2)) >+ self.assertEqual(3, self.conn2.AddOne(2)) > > def test_abstract_syntax(self): >- self.assertEquals(("60a15ec5-4de8-11d7-a637-005056a20182", 1), >+ self.assertEqual(("60a15ec5-4de8-11d7-a637-005056a20182", 1), > self.conn.abstract_syntax) > > def test_addone(self): >- self.assertEquals(2, self.conn.AddOne(1)) >+ self.assertEqual(2, self.conn.AddOne(1)) > > def test_echodata(self): >- self.assertEquals([1, 2, 3], self.conn.EchoData([1, 2, 3])) >+ self.assertEqual([1, 2, 3], self.conn.EchoData([1, 2, 3])) > > def test_call(self): >- self.assertEquals(u"foobar", self.conn.TestCall(u"foobar")) >+ self.assertEqual(u"foobar", self.conn.TestCall(u"foobar")) > > def test_surrounding(self): > surrounding_struct = echo.Surrounding() > surrounding_struct.x = 4 > surrounding_struct.surrounding = [1, 2, 3, 4] > y = self.conn.TestSurrounding(surrounding_struct) >- self.assertEquals(8 * [0], y.surrounding) >+ self.assertEqual(8 * [0], y.surrounding) > > def test_manual_request(self): >- self.assertEquals(b"\x01\x00\x00\x00", self.conn.request(0, chr(0) * 4)) >+ self.assertEqual(b"\x01\x00\x00\x00", self.conn.request(0, chr(0) * 4)) > > def test_server_name(self): >- self.assertEquals(None, self.conn.server_name) >+ self.assertEqual(None, self.conn.server_name) > > > class NdrEchoTests(TestCase): >@@ -64,8 +64,8 @@ class NdrEchoTests(TestCase): > def test_info1_push(self): > x = echo.info1() > x.v = 42 >- self.assertEquals(b"\x2a", ndr_pack(x)) >+ self.assertEqual(b"\x2a", ndr_pack(x)) > > def test_info1_pull(self): > x = ndr_unpack(echo.info1, b"\x42") >- self.assertEquals(x.v, 66) >+ self.assertEqual(x.v, 66) >diff --git a/python/samba/tests/dcerpc/sam.py b/python/samba/tests/dcerpc/sam.py >index ab710861383..f2dcb66c25c 100644 >--- a/python/samba/tests/dcerpc/sam.py >+++ b/python/samba/tests/dcerpc/sam.py >@@ -196,8 +196,8 @@ class SamrTests(RpcInterfaceTestCase): > (ts, rs, actual) = self.conn.QueryDisplayInfo( > self.domain_handle, level, 0, 1024, 4294967295) > >- self.assertEquals(len(expected), ts) >- self.assertEquals(len(expected), rs) >+ self.assertEqual(len(expected), ts) >+ self.assertEqual(len(expected), rs) > check_results(expected, actual.entries) > > # >@@ -205,8 +205,8 @@ class SamrTests(RpcInterfaceTestCase): > # results returned from the first query, should return the same results > (ts1, rs1, actual1) = self.conn.QueryDisplayInfo( > self.domain_handle, level, 0, rs, 4294967295) >- self.assertEquals(ts, ts1) >- self.assertEquals(rs, rs1) >+ self.assertEqual(ts, ts1) >+ self.assertEqual(rs, rs1) > check_results(expected, actual1.entries) > > # >@@ -215,8 +215,8 @@ class SamrTests(RpcInterfaceTestCase): > self.assertTrue(ts > 2) > (ts2, rs2, actual2) = self.conn.QueryDisplayInfo( > self.domain_handle, level, (ts - 2), 2, 4294967295) >- self.assertEquals(ts, ts2) >- self.assertEquals(2, rs2) >+ self.assertEqual(ts, ts2) >+ self.assertEqual(2, rs2) > check_results(list(expected)[-2:], actual2.entries) > > # >@@ -225,8 +225,8 @@ class SamrTests(RpcInterfaceTestCase): > self.assertTrue(ts > 2) > (ts2, rs2, actual2) = self.conn.QueryDisplayInfo( > self.domain_handle, level, 0, 2, 4294967295) >- self.assertEquals(ts, ts2) >- self.assertEquals(2, rs2) >+ self.assertEqual(ts, ts2) >+ self.assertEqual(2, rs2) > check_results(list(expected)[:2], actual2.entries) > > # >@@ -236,8 +236,8 @@ class SamrTests(RpcInterfaceTestCase): > self.assertTrue(ts > 3) > (ts2, rs2, actual2) = self.conn.QueryDisplayInfo( > self.domain_handle, level, 1, 2, 4294967295) >- self.assertEquals(ts, ts2) >- self.assertEquals(2, rs2) >+ self.assertEqual(ts, ts2) >+ self.assertEqual(2, rs2) > check_results(list(expected)[1:2], actual2.entries) > > # >@@ -253,8 +253,8 @@ class SamrTests(RpcInterfaceTestCase): > # should not be present > (ts3, rs3, actual3) = self.conn.QueryDisplayInfo( > self.domain_handle, level, 1, 1024, 4294967295) >- self.assertEquals(ts, ts3) >- self.assertEquals(len(expected) - 1, rs3) >+ self.assertEqual(ts, ts3) >+ self.assertEqual(len(expected) - 1, rs3) > check_results(list(expected)[1:], actual3.entries) > > # >@@ -264,8 +264,8 @@ class SamrTests(RpcInterfaceTestCase): > new = self.samdb.search(expression=select, attrs=attributes) > (ts4, rs4, actual4) = self.conn.QueryDisplayInfo( > self.domain_handle, level, 0, 1024, 4294967295) >- self.assertEquals(len(expected) + len(dns), ts4) >- self.assertEquals(len(expected) + len(dns), rs4) >+ self.assertEqual(len(expected) + len(dns), ts4) >+ self.assertEqual(len(expected) + len(dns), rs4) > check_results(new, actual4.entries) > > # Delete the added DN's and query all but the first entry. >@@ -274,7 +274,7 @@ class SamrTests(RpcInterfaceTestCase): > self.delete_dns(dns) > (ts5, rs5, actual5) = self.conn.QueryDisplayInfo( > self.domain_handle, level, 1, 1024, 4294967295) >- self.assertEquals(len(expected) + len(dns), ts5) >+ self.assertEqual(len(expected) + len(dns), ts5) > # The deleted results will be filtered from the result set so should > # be missing from the returned results. > # Note: depending on the GUID order, the first result in the cache may >@@ -294,8 +294,8 @@ class SamrTests(RpcInterfaceTestCase): > # Should return no data. > (ts6, rs6, actual6) = self.conn.QueryDisplayInfo( > self.domain_handle, level, ts5, 1, 4294967295) >- self.assertEquals(ts5, ts6) >- self.assertEquals(0, rs6) >+ self.assertEqual(ts5, ts6) >+ self.assertEqual(0, rs6) > > self.conn.Close(self.handle) > >@@ -309,7 +309,7 @@ class SamrTests(RpcInterfaceTestCase): > # in the same order > for (e, a) in zip(expected, actual): > self.assertTrue(isinstance(a, samr.DispEntryGeneral)) >- self.assertEquals(str(e["sAMAccountName"]), >+ self.assertEqual(str(e["sAMAccountName"]), > str(a.account_name)) > > # The displayName and description are optional. >@@ -320,12 +320,12 @@ class SamrTests(RpcInterfaceTestCase): > if a.full_name.length == 0: > self.assertFalse("displayName" in e) > else: >- self.assertEquals(str(e["displayName"]), str(a.full_name)) >+ self.assertEqual(str(e["displayName"]), str(a.full_name)) > > if a.description.length == 0: > self.assertFalse("description" in e) > else: >- self.assertEquals(str(e["description"]), >+ self.assertEqual(str(e["description"]), > str(a.description)) > # Create four user accounts > # to ensure that we have the minimum needed for the tests. >@@ -349,7 +349,7 @@ class SamrTests(RpcInterfaceTestCase): > # in the same order > for (e, a) in zip(expected, actual): > self.assertTrue(isinstance(a, samr.DispEntryFull)) >- self.assertEquals(str(e["sAMAccountName"]), >+ self.assertEqual(str(e["sAMAccountName"]), > str(a.account_name)) > > # The description is optional. >@@ -360,7 +360,7 @@ class SamrTests(RpcInterfaceTestCase): > if a.description.length == 0: > self.assertFalse("description" in e) > else: >- self.assertEquals(str(e["description"]), >+ self.assertEqual(str(e["description"]), > str(a.description)) > > # Create four computer accounts >@@ -385,7 +385,7 @@ class SamrTests(RpcInterfaceTestCase): > # in the same order > for (e, a) in zip(expected, actual): > self.assertTrue(isinstance(a, samr.DispEntryFullGroup)) >- self.assertEquals(str(e["sAMAccountName"]), >+ self.assertEqual(str(e["sAMAccountName"]), > str(a.account_name)) > > # The description is optional. >@@ -396,7 +396,7 @@ class SamrTests(RpcInterfaceTestCase): > if a.description.length == 0: > self.assertFalse("description" in e) > else: >- self.assertEquals(str(e["description"]), >+ self.assertEqual(str(e["description"]), > str(a.description)) > > # Create four groups >@@ -424,7 +424,7 @@ class SamrTests(RpcInterfaceTestCase): > self.assertTrue(isinstance(a, samr.DispEntryAscii)) > self.assertTrue( > isinstance(a.account_name, lsa.AsciiStringLarge)) >- self.assertEquals( >+ self.assertEqual( > str(e["sAMAccountName"]), str(a.account_name.string)) > > # Create four user accounts >@@ -451,7 +451,7 @@ class SamrTests(RpcInterfaceTestCase): > self.assertTrue(isinstance(a, samr.DispEntryAscii)) > self.assertTrue( > isinstance(a.account_name, lsa.AsciiStringLarge)) >- self.assertEquals( >+ self.assertEqual( > str(e["sAMAccountName"]), str(a.account_name.string)) > > # Create four groups >@@ -471,7 +471,7 @@ class SamrTests(RpcInterfaceTestCase): > def check_results(expected, actual): > for (e, a) in zip(expected, actual): > self.assertTrue(isinstance(a, samr.SamEntry)) >- self.assertEquals( >+ self.assertEqual( > str(e["sAMAccountName"]), str(a.name.string)) > > # Create four groups >@@ -500,7 +500,7 @@ class SamrTests(RpcInterfaceTestCase): > max_size = calc_max_size(len(expected) + 10) > (resume_handle, actual, num_entries) = self.conn.EnumDomainGroups( > self.domain_handle, 0, max_size) >- self.assertEquals(len(expected), num_entries) >+ self.assertEqual(len(expected), num_entries) > check_results(expected, actual.entries) > > # >@@ -510,7 +510,7 @@ class SamrTests(RpcInterfaceTestCase): > max_size = calc_max_size(4) > (resume_handle, actual, num_entries) = self.conn.EnumDomainGroups( > self.domain_handle, 0, max_size) >- self.assertEquals(4, num_entries) >+ self.assertEqual(4, num_entries) > check_results(expected[:4], actual.entries) > > # >@@ -522,8 +522,8 @@ class SamrTests(RpcInterfaceTestCase): > (resume_handle, a, num_entries) = self.conn.EnumDomainGroups( > self.domain_handle, rh, max_size) > >- self.assertEquals(0, num_entries) >- self.assertEquals(0, resume_handle) >+ self.assertEqual(0, num_entries) >+ self.assertEqual(0, resume_handle) > > # > # Enumerate through the domain groups one element at a time. >@@ -533,7 +533,7 @@ class SamrTests(RpcInterfaceTestCase): > (resume_handle, a, num_entries) = self.conn.EnumDomainGroups( > self.domain_handle, 0, max_size) > while resume_handle: >- self.assertEquals(1, num_entries) >+ self.assertEqual(1, num_entries) > actual.append(a.entries[0]) > (resume_handle, a, num_entries) = self.conn.EnumDomainGroups( > self.domain_handle, resume_handle, max_size) >@@ -551,14 +551,14 @@ class SamrTests(RpcInterfaceTestCase): > self.domain_handle, 0, max_size) > extra_dns = self.create_groups([1000, 1002, 1003, 1004]) > while resume_handle: >- self.assertEquals(1, num_entries) >+ self.assertEqual(1, num_entries) > actual.append(a.entries[0]) > (resume_handle, a, num_entries) = self.conn.EnumDomainGroups( > self.domain_handle, resume_handle, max_size) > if num_entries: > actual.append(a.entries[0]) > >- self.assertEquals(len(expected), len(actual)) >+ self.assertEqual(len(expected), len(actual)) > check_results(expected, actual) > > # >@@ -567,7 +567,7 @@ class SamrTests(RpcInterfaceTestCase): > max_size = calc_max_size(len(expected) + len(extra_dns) + 10) > (resume_handle, actual, num_entries) = self.conn.EnumDomainGroups( > self.domain_handle, 0, max_size) >- self.assertEquals(len(expected) + len(extra_dns), num_entries) >+ self.assertEqual(len(expected) + len(extra_dns), num_entries) > > # > # Get a new expected result set by querying the database directly >@@ -593,14 +593,14 @@ class SamrTests(RpcInterfaceTestCase): > self.domain_handle, 0, max_size) > self.delete_dns(extra_dns) > while resume_handle and num_entries: >- self.assertEquals(1, num_entries) >+ self.assertEqual(1, num_entries) > actual.append(a.entries[0]) > (resume_handle, a, num_entries) = self.conn.EnumDomainGroups( > self.domain_handle, resume_handle, max_size) > if num_entries: > actual.append(a.entries[0]) > >- self.assertEquals(len(expected), len(actual)) >+ self.assertEqual(len(expected), len(actual)) > check_results(expected, actual) > > self.delete_dns(dns) >@@ -609,7 +609,7 @@ class SamrTests(RpcInterfaceTestCase): > def check_results(expected, actual): > for (e, a) in zip(expected, actual): > self.assertTrue(isinstance(a, samr.SamEntry)) >- self.assertEquals( >+ self.assertEqual( > str(e["sAMAccountName"]), str(a.name.string)) > > # Create four users >@@ -636,7 +636,7 @@ class SamrTests(RpcInterfaceTestCase): > max_size = calc_max_size(len(expected) + 10) > (resume_handle, actual, num_entries) = self.conn.EnumDomainUsers( > self.domain_handle, 0, 0, max_size) >- self.assertEquals(len(expected), num_entries) >+ self.assertEqual(len(expected), num_entries) > check_results(expected, actual.entries) > > # >@@ -645,7 +645,7 @@ class SamrTests(RpcInterfaceTestCase): > max_size = calc_max_size(4) > (resume_handle, actual, num_entries) = self.conn.EnumDomainUsers( > self.domain_handle, 0, 0, max_size) >- self.assertEquals(4, num_entries) >+ self.assertEqual(4, num_entries) > check_results(expected[:4], actual.entries) > > # >@@ -657,8 +657,8 @@ class SamrTests(RpcInterfaceTestCase): > (resume_handle, a, num_entries) = self.conn.EnumDomainUsers( > self.domain_handle, rh, 0, max_size) > >- self.assertEquals(0, num_entries) >- self.assertEquals(0, resume_handle) >+ self.assertEqual(0, num_entries) >+ self.assertEqual(0, resume_handle) > > # > # Enumerate through the domain users one element at a time. >@@ -669,14 +669,14 @@ class SamrTests(RpcInterfaceTestCase): > (resume_handle, a, num_entries) = self.conn.EnumDomainUsers( > self.domain_handle, 0, 0, max_size) > while resume_handle: >- self.assertEquals(1, num_entries) >+ self.assertEqual(1, num_entries) > actual.append(a.entries[0]) > (resume_handle, a, num_entries) = self.conn.EnumDomainUsers( > self.domain_handle, resume_handle, 0, max_size) > if num_entries: > actual.append(a.entries[0]) > >- self.assertEquals(len(expected), len(actual)) >+ self.assertEqual(len(expected), len(actual)) > check_results(expected, actual) > > # >@@ -691,14 +691,14 @@ class SamrTests(RpcInterfaceTestCase): > self.domain_handle, 0, 0, max_size) > extra_dns = self.create_users([1000, 1002, 1003, 1004]) > while resume_handle: >- self.assertEquals(1, num_entries) >+ self.assertEqual(1, num_entries) > actual.append(a.entries[0]) > (resume_handle, a, num_entries) = self.conn.EnumDomainUsers( > self.domain_handle, resume_handle, 0, max_size) > if num_entries: > actual.append(a.entries[0]) > >- self.assertEquals(len(expected), len(actual)) >+ self.assertEqual(len(expected), len(actual)) > check_results(expected, actual) > > # >@@ -708,7 +708,7 @@ class SamrTests(RpcInterfaceTestCase): > max_size = calc_max_size(len(expected) + len(extra_dns) + 10) > (resume_handle, actual, num_entries) = self.conn.EnumDomainUsers( > self.domain_handle, 0, 0, max_size) >- self.assertEquals(len(expected) + len(extra_dns), num_entries) >+ self.assertEqual(len(expected) + len(extra_dns), num_entries) > > # > # Get a new expected result set by querying the database directly >@@ -722,7 +722,7 @@ class SamrTests(RpcInterfaceTestCase): > # > # Now check that we read the new entries. > # >- self.assertEquals(len(expected01), num_entries) >+ self.assertEqual(len(expected01), num_entries) > check_results(expected01, actual.entries) > > # >@@ -737,14 +737,14 @@ class SamrTests(RpcInterfaceTestCase): > self.domain_handle, 0, 0, max_size) > self.delete_dns(extra_dns) > while resume_handle and num_entries: >- self.assertEquals(1, num_entries) >+ self.assertEqual(1, num_entries) > actual.append(a.entries[0]) > (resume_handle, a, num_entries) = self.conn.EnumDomainUsers( > self.domain_handle, resume_handle, 0, max_size) > if num_entries: > actual.append(a.entries[0]) > >- self.assertEquals(len(expected), len(actual)) >+ self.assertEqual(len(expected), len(actual)) > check_results(expected, actual) > > self.delete_dns(dns) >diff --git a/python/samba/tests/dcerpc/unix.py b/python/samba/tests/dcerpc/unix.py >index 77a5c221eab..0b56babdd14 100644 >--- a/python/samba/tests/dcerpc/unix.py >+++ b/python/samba/tests/dcerpc/unix.py >@@ -30,8 +30,8 @@ class UnixinfoTests(RpcInterfaceTestCase): > > def test_getpwuid_int(self): > infos = self.conn.GetPWUid(range(512)) >- self.assertEquals(512, len(infos)) >- self.assertEquals("/bin/false", infos[0].shell) >+ self.assertEqual(512, len(infos)) >+ self.assertEqual("/bin/false", infos[0].shell) > self.assertTrue(isinstance(infos[0].homedir, text_type)) > > def test_gidtosid(self): >diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py >index 531f0c47d84..83c6772288b 100644 >--- a/python/samba/tests/dns.py >+++ b/python/samba/tests/dns.py >@@ -94,8 +94,8 @@ class TestSimpleQueries(DNSTest): > self.dns_transaction_udp(p, host=server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rdata, >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rdata, > self.server_ip) > > def test_one_SOA_query(self): >@@ -113,8 +113,8 @@ class TestSimpleQueries(DNSTest): > self.dns_transaction_udp(p, host=server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals( >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual( > response.answers[0].rdata.mname.upper(), > ("%s.%s" % (self.server, self.get_dns_domain())).upper()) > >@@ -133,8 +133,8 @@ class TestSimpleQueries(DNSTest): > self.dns_transaction_tcp(p, host=server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rdata, >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rdata, > self.server_ip) > > def test_one_mx_query(self): >@@ -152,7 +152,7 @@ class TestSimpleQueries(DNSTest): > self.dns_transaction_udp(p, host=server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 0) >+ self.assertEqual(response.ancount, 0) > > p = self.make_name_packet(dns.DNS_OPCODE_QUERY) > questions = [] >@@ -167,7 +167,7 @@ class TestSimpleQueries(DNSTest): > self.dns_transaction_udp(p, host=server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_NXDOMAIN) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 0) >+ self.assertEqual(response.ancount, 0) > > def test_two_queries(self): > "create a query packet containing two query records" >@@ -215,11 +215,11 @@ class TestSimpleQueries(DNSTest): > > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, num_answers) >- self.assertEquals(response.answers[0].rdata, >+ self.assertEqual(response.ancount, num_answers) >+ self.assertEqual(response.answers[0].rdata, > self.server_ip) > if dc_ipv6 is not None: >- self.assertEquals(response.answers[1].rdata, dc_ipv6) >+ self.assertEqual(response.answers[1].rdata, dc_ipv6) > > def test_qclass_none_query(self): > "create a QCLASS_NONE query" >@@ -260,7 +260,7 @@ class TestSimpleQueries(DNSTest): > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) > # We don't get SOA records for single hosts >- self.assertEquals(response.ancount, 0) >+ self.assertEqual(response.ancount, 0) > # But we do respond with an authority section > self.assertEqual(response.nscount, 1) > >@@ -278,8 +278,8 @@ class TestSimpleQueries(DNSTest): > self.dns_transaction_udp(p, host=server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rdata.minimum, 3600) >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rdata.minimum, 3600) > > > class TestDNSUpdates(DNSTest): >@@ -735,12 +735,12 @@ class TestComplexQueries(DNSTest): > self.dns_transaction_udp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 2) >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_CNAME) >- self.assertEquals(response.answers[0].rdata, "%s.%s" % >+ self.assertEqual(response.ancount, 2) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_CNAME) >+ self.assertEqual(response.answers[0].rdata, "%s.%s" % > (self.server, self.get_dns_domain())) >- self.assertEquals(response.answers[1].rr_type, dns.DNS_QTYPE_A) >- self.assertEquals(response.answers[1].rdata, >+ self.assertEqual(response.answers[1].rr_type, dns.DNS_QTYPE_A) >+ self.assertEqual(response.answers[1].rdata, > self.server_ip) > > finally: >@@ -791,18 +791,18 @@ class TestComplexQueries(DNSTest): > self.dns_transaction_udp(p, host=server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 3) >+ self.assertEqual(response.ancount, 3) > >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_CNAME) >- self.assertEquals(response.answers[0].name, name1) >- self.assertEquals(response.answers[0].rdata, name2) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_CNAME) >+ self.assertEqual(response.answers[0].name, name1) >+ self.assertEqual(response.answers[0].rdata, name2) > >- self.assertEquals(response.answers[1].rr_type, dns.DNS_QTYPE_CNAME) >- self.assertEquals(response.answers[1].name, name2) >- self.assertEquals(response.answers[1].rdata, name0) >+ self.assertEqual(response.answers[1].rr_type, dns.DNS_QTYPE_CNAME) >+ self.assertEqual(response.answers[1].name, name2) >+ self.assertEqual(response.answers[1].rdata, name0) > >- self.assertEquals(response.answers[2].rr_type, dns.DNS_QTYPE_A) >- self.assertEquals(response.answers[2].rdata, >+ self.assertEqual(response.answers[2].rr_type, dns.DNS_QTYPE_A) >+ self.assertEqual(response.answers[2].rdata, > self.server_ip) > > def test_invalid_empty_cname(self): >@@ -836,15 +836,15 @@ class TestComplexQueries(DNSTest): > > # CNAME should return all intermediate results! > # Only the A records exists, not the TXT. >- self.assertEquals(response.ancount, 2) >+ self.assertEqual(response.ancount, 2) > >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_CNAME) >- self.assertEquals(response.answers[0].name, name1) >- self.assertEquals(response.answers[0].rdata, name2) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_CNAME) >+ self.assertEqual(response.answers[0].name, name1) >+ self.assertEqual(response.answers[0].rdata, name2) > >- self.assertEquals(response.answers[1].rr_type, dns.DNS_QTYPE_CNAME) >- self.assertEquals(response.answers[1].name, name2) >- self.assertEquals(response.answers[1].rdata, name0) >+ self.assertEqual(response.answers[1].rr_type, dns.DNS_QTYPE_CNAME) >+ self.assertEqual(response.answers[1].name, name2) >+ self.assertEqual(response.answers[1].rdata, name0) > > def test_cname_loop(self): > cname1 = "cnamelooptestrec." + self.get_dns_domain() >@@ -867,7 +867,7 @@ class TestComplexQueries(DNSTest): > self.dns_transaction_udp(p, host=self.server_ip) > > max_recursion_depth = 20 >- self.assertEquals(len(response.answers), max_recursion_depth) >+ self.assertEqual(len(response.answers), max_recursion_depth) > > # Make sure cname limit doesn't count other records. This is a generic > # test called in tests below >@@ -1006,8 +1006,8 @@ class TestInvalidQueries(DNSTest): > self.dns_transaction_udp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rdata, >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rdata, > self.server_ip) > > def test_one_a_reply(self): >@@ -1035,7 +1035,7 @@ class TestInvalidQueries(DNSTest): > tcp_packet += send_packet > s.send(tcp_packet, 0) > recv_packet = s.recv(0xffff + 2, 0) >- self.assertEquals(0, len(recv_packet)) >+ self.assertEqual(0, len(recv_packet)) > except socket.timeout: > # Windows chooses not to respond to incorrectly formatted queries. > # Although this appears to be non-deterministic even for the same >@@ -1428,29 +1428,29 @@ class TestZones(DNSTest): > expr = "(dnsProperty:1.3.6.1.4.1.7165.4.5.3:=1)" > res = samdb.search(base=self.zone_dn, scope=ldb.SCOPE_SUBTREE, > expression=expr, attrs=["*"]) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # No value for tombstone time > try: > expr = "(dnsRecord:1.3.6.1.4.1.7165.4.5.3:=)" > res = samdb.search(base=self.zone_dn, scope=ldb.SCOPE_SUBTREE, > expression=expr, attrs=["*"]) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > self.fail("Exception: ldb.ldbError not generated") > except ldb.LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > > # Tombstone time = - > try: > expr = "(dnsRecord:1.3.6.1.4.1.7165.4.5.3:=-)" > res = samdb.search(base=self.zone_dn, scope=ldb.SCOPE_SUBTREE, > expression=expr, attrs=["*"]) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > self.fail("Exception: ldb.ldbError not generated") > except ldb.LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > > # Tombstone time longer than 64 characters > try: >@@ -1458,22 +1458,22 @@ class TestZones(DNSTest): > expr = expr.format("1" * 65) > res = samdb.search(base=self.zone_dn, scope=ldb.SCOPE_SUBTREE, > expression=expr, attrs=["*"]) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > self.fail("Exception: ldb.ldbError not generated") > except ldb.LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > > # Non numeric Tombstone time > try: > expr = "(dnsRecord:1.3.6.1.4.1.7165.4.5.3:=expired)" > res = samdb.search(base=self.zone_dn, scope=ldb.SCOPE_SUBTREE, > expression=expr, attrs=["*"]) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > self.fail("Exception: ldb.ldbError not generated") > except ldb.LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > > # Non system session > try: >@@ -1484,11 +1484,11 @@ class TestZones(DNSTest): > expr = "(dnsRecord:1.3.6.1.4.1.7165.4.5.3:=2)" > res = db.search(base=self.zone_dn, scope=ldb.SCOPE_SUBTREE, > expression=expr, attrs=["*"]) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > self.fail("Exception: ldb.ldbError not generated") > except ldb.LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > > def test_basic_scavenging(self): > lp = self.get_loadparm() >@@ -1666,22 +1666,22 @@ class TestZones(DNSTest): > # Windows returns OK while BIND logically seems to return NXDOMAIN > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_NXDOMAIN) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 0) >+ self.assertEqual(response.ancount, 0) > > self.create_zone(zone) > (response, response_packet) =\ > self.dns_transaction_udp(p, host=server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_SOA) >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_SOA) > > self.delete_zone(zone) > (response, response_packet) =\ > self.dns_transaction_udp(p, host=server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_NXDOMAIN) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 0) >+ self.assertEqual(response.ancount, 0) > > > class TestRPCRoundtrip(DNSTest): >diff --git a/python/samba/tests/dns_base.py b/python/samba/tests/dns_base.py >index 56c02dd6e51..f26c117c793 100644 >--- a/python/samba/tests/dns_base.py >+++ b/python/samba/tests/dns_base.py >@@ -63,19 +63,19 @@ class DNSTest(TestCaseInTempDir): > > def assert_rcode_equals(self, rcode, expected): > "Helper function to check return code" >- self.assertEquals(rcode, expected, "Expected RCODE %s, got %s" % >+ self.assertEqual(rcode, expected, "Expected RCODE %s, got %s" % > (self.errstr(expected), self.errstr(rcode))) > > def assert_dns_rcode_equals(self, packet, rcode): > "Helper function to check return code" > p_errcode = packet.operation & 0x000F >- self.assertEquals(p_errcode, rcode, "Expected RCODE %s, got %s" % >+ self.assertEqual(p_errcode, rcode, "Expected RCODE %s, got %s" % > (self.errstr(rcode), self.errstr(p_errcode))) > > def assert_dns_opcode_equals(self, packet, opcode): > "Helper function to check opcode" > p_opcode = packet.operation & 0x7800 >- self.assertEquals(p_opcode, opcode, "Expected OPCODE %s, got %s" % >+ self.assertEqual(p_opcode, opcode, "Expected OPCODE %s, got %s" % > (opcode, p_opcode)) > > def make_name_packet(self, opcode, qid=None): >@@ -164,7 +164,7 @@ class DNSTest(TestCaseInTempDir): > > # unpacking and packing again should produce same bytestream > my_packet = ndr.ndr_pack(response) >- self.assertEquals(my_packet, recv_packet[2:]) >+ self.assertEqual(my_packet, recv_packet[2:]) > return (response, recv_packet[2:]) > > def make_txt_update(self, prefix, txt_array, domain=None): >@@ -203,8 +203,8 @@ class DNSTest(TestCaseInTempDir): > (response, response_packet) =\ > self.dns_transaction_udp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rdata.txt.str, txt_array) >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rdata.txt.str, txt_array) > > > class DNSTKeyTest(DNSTest): >diff --git a/python/samba/tests/dns_forwarder.py b/python/samba/tests/dns_forwarder.py >index 8178678e885..e4c34441a93 100644 >--- a/python/samba/tests/dns_forwarder.py >+++ b/python/samba/tests/dns_forwarder.py >@@ -82,13 +82,13 @@ class DNSTest(TestCase): > def assert_dns_rcode_equals(self, packet, rcode): > "Helper function to check return code" > p_errcode = packet.operation & 0x000F >- self.assertEquals(p_errcode, rcode, "Expected RCODE %s, got %s" % >+ self.assertEqual(p_errcode, rcode, "Expected RCODE %s, got %s" % > (self.errcodes[rcode], self.errcodes[p_errcode])) > > def assert_dns_opcode_equals(self, packet, opcode): > "Helper function to check opcode" > p_opcode = packet.operation & 0x7800 >- self.assertEquals(p_opcode, opcode, "Expected OPCODE %s, got %s" % >+ self.assertEqual(p_opcode, opcode, "Expected OPCODE %s, got %s" % > (opcode, p_opcode)) > > def make_name_packet(self, opcode, qid=None): >diff --git a/python/samba/tests/dns_tkey.py b/python/samba/tests/dns_tkey.py >index 8dd1b551670..07316271d56 100644 >--- a/python/samba/tests/dns_tkey.py >+++ b/python/samba/tests/dns_tkey.py >@@ -80,8 +80,8 @@ class TestDNSUpdates(DNSTKeyTest): > (response, response_p) = self.dns_transaction_udp(p, self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_NOTAUTH) > tsig_record = response.additional[0].rdata >- self.assertEquals(tsig_record.error, dns.DNS_RCODE_BADKEY) >- self.assertEquals(tsig_record.mac_size, 0) >+ self.assertEqual(tsig_record.error, dns.DNS_RCODE_BADKEY) >+ self.assertEqual(tsig_record.mac_size, 0) > > rcode = self.search_record(self.newrecname) > self.assert_rcode_equals(rcode, dns.DNS_RCODE_NXDOMAIN) >@@ -96,8 +96,8 @@ class TestDNSUpdates(DNSTKeyTest): > (response, response_p) = self.dns_transaction_udp(p, self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_NOTAUTH) > tsig_record = response.additional[0].rdata >- self.assertEquals(tsig_record.error, dns.DNS_RCODE_BADSIG) >- self.assertEquals(tsig_record.mac_size, 0) >+ self.assertEqual(tsig_record.error, dns.DNS_RCODE_BADSIG) >+ self.assertEqual(tsig_record.mac_size, 0) > > rcode = self.search_record(self.newrecname) > self.assert_rcode_equals(rcode, dns.DNS_RCODE_NXDOMAIN) >diff --git a/python/samba/tests/dns_wildcard.py b/python/samba/tests/dns_wildcard.py >index 01e06b8e262..38232a4df07 100644 >--- a/python/samba/tests/dns_wildcard.py >+++ b/python/samba/tests/dns_wildcard.py >@@ -168,9 +168,9 @@ class TestWildCardQueries(DNSTest): > self.dns_transaction_udp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_A) >- self.assertEquals(response.answers[0].rdata, WILDCARD_IP) >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A) >+ self.assertEqual(response.answers[0].rdata, WILDCARD_IP) > > def test_one_a_query_match_wildcard_2_labels(self): > """ Query an A record, should match the wild card entry >@@ -192,9 +192,9 @@ class TestWildCardQueries(DNSTest): > self.dns_transaction_udp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_A) >- self.assertEquals(response.answers[0].rdata, WILDCARD_IP) >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A) >+ self.assertEqual(response.answers[0].rdata, WILDCARD_IP) > > def test_one_a_query_wildcard_entry(self): > "Query the wildcard entry" >@@ -214,9 +214,9 @@ class TestWildCardQueries(DNSTest): > self.dns_transaction_udp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_A) >- self.assertEquals(response.answers[0].rdata, WILDCARD_IP) >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A) >+ self.assertEqual(response.answers[0].rdata, WILDCARD_IP) > > def test_one_a_query_exact_match(self): > """Query an entry that matches the wild card but has an exact match as >@@ -237,9 +237,9 @@ class TestWildCardQueries(DNSTest): > self.dns_transaction_udp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_A) >- self.assertEquals(response.answers[0].rdata, EXACT_IP) >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A) >+ self.assertEqual(response.answers[0].rdata, EXACT_IP) > > def test_one_a_query_match_wildcard_l2(self): > "Query an A record, should match the level 2 wildcard entry" >@@ -259,9 +259,9 @@ class TestWildCardQueries(DNSTest): > self.dns_transaction_udp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_A) >- self.assertEquals(response.answers[0].rdata, LEVEL2_WILDCARD_IP) >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A) >+ self.assertEqual(response.answers[0].rdata, LEVEL2_WILDCARD_IP) > > def test_one_a_query_match_wildcard_l2_2_labels(self): > """Query an A record, should match the level 2 wild card entry >@@ -283,9 +283,9 @@ class TestWildCardQueries(DNSTest): > self.dns_transaction_udp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_A) >- self.assertEquals(response.answers[0].rdata, LEVEL2_WILDCARD_IP) >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A) >+ self.assertEqual(response.answers[0].rdata, LEVEL2_WILDCARD_IP) > > def test_one_a_query_exact_match_l2(self): > """Query an entry that matches the wild card but has an exact match as >@@ -306,9 +306,9 @@ class TestWildCardQueries(DNSTest): > self.dns_transaction_udp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_A) >- self.assertEquals(response.answers[0].rdata, LEVEL2_EXACT_IP) >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A) >+ self.assertEqual(response.answers[0].rdata, LEVEL2_EXACT_IP) > > def test_one_a_query_wildcard_entry_l2(self): > "Query the level 2 wildcard entry" >@@ -328,9 +328,9 @@ class TestWildCardQueries(DNSTest): > self.dns_transaction_udp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_A) >- self.assertEquals(response.answers[0].rdata, LEVEL2_WILDCARD_IP) >+ self.assertEqual(response.ancount, 1) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A) >+ self.assertEqual(response.answers[0].rdata, LEVEL2_WILDCARD_IP) > > > TestProgram(module=__name__, opts=subunitopts) >diff --git a/python/samba/tests/dsdb.py b/python/samba/tests/dsdb.py >index 2432c3cd509..33cfcc12271 100644 >--- a/python/samba/tests/dsdb.py >+++ b/python/samba/tests/dsdb.py >@@ -59,7 +59,7 @@ class DsdbTests(TestCase): > > def test_get_oid_from_attrid(self): > oid = self.samdb.get_oid_from_attid(591614) >- self.assertEquals(oid, "1.2.840.113556.1.4.1790") >+ self.assertEqual(oid, "1.2.840.113556.1.4.1790") > > def test_error_replpropertymetadata(self): > res = self.samdb.search(scope=ldb.SCOPE_SUBTREE, >@@ -144,16 +144,16 @@ class DsdbTests(TestCase): > self.samdb.modify(msg, ["local_oid:1.3.6.1.4.1.7165.4.3.14:0"]) > > def test_ok_get_attribute_from_attid(self): >- self.assertEquals(self.samdb.get_attribute_from_attid(13), "description") >+ self.assertEqual(self.samdb.get_attribute_from_attid(13), "description") > > def test_ko_get_attribute_from_attid(self): >- self.assertEquals(self.samdb.get_attribute_from_attid(11979), None) >+ self.assertEqual(self.samdb.get_attribute_from_attid(11979), None) > > def test_get_attribute_replmetadata_version(self): > res = self.samdb.search(scope=ldb.SCOPE_SUBTREE, > base=self.account_dn, > attrs=["dn"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > dn = str(res[0].dn) > self.assertEqual(self.samdb.get_attribute_replmetadata_version(dn, "unicodePwd"), 2) > >@@ -161,7 +161,7 @@ class DsdbTests(TestCase): > res = self.samdb.search(scope=ldb.SCOPE_SUBTREE, > base=self.account_dn, > attrs=["dn"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > dn = str(res[0].dn) > version = self.samdb.get_attribute_replmetadata_version(dn, "description") > self.samdb.set_attribute_replmetadata_version(dn, "description", version + 2) >diff --git a/python/samba/tests/dsdb_schema_attributes.py b/python/samba/tests/dsdb_schema_attributes.py >index 5928511cd44..bb4603d4703 100644 >--- a/python/samba/tests/dsdb_schema_attributes.py >+++ b/python/samba/tests/dsdb_schema_attributes.py >@@ -41,7 +41,7 @@ class SchemaAttributesTestCase(samba.tests.TestCase): > > # fetch rootDSE > res = self.samdb.search(base="", expression="", scope=SCOPE_BASE, attrs=["*"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.schema_dn = res[0]["schemaNamingContext"][0] > self.base_dn = res[0]["defaultNamingContext"][0] > self.forest_level = int(res[0]["forestFunctionality"][0]) >@@ -100,8 +100,8 @@ systemOnly: FALSE > attr_res = self.samdb.search(base="@ATTRIBUTES", scope=ldb.SCOPE_BASE) > > self.assertIn(attr_ldap_name, attr_res[0]) >- self.assertEquals(len(attr_res[0][attr_ldap_name]), 1) >- self.assertEquals(str(attr_res[0][attr_ldap_name][0]), "CASE_INSENSITIVE") >+ self.assertEqual(len(attr_res[0][attr_ldap_name]), 1) >+ self.assertEqual(str(attr_res[0][attr_ldap_name][0]), "CASE_INSENSITIVE") > > # Check @INDEXLIST > >@@ -123,8 +123,8 @@ systemOnly: FALSE > attr_res = self.samdb.search(base="@ATTRIBUTES", scope=ldb.SCOPE_BASE) > > self.assertIn(attr_ldap_name, attr_res[0]) >- self.assertEquals(len(attr_res[0][attr_ldap_name]), 1) >- self.assertEquals(str(attr_res[0][attr_ldap_name][0]), "CASE_INSENSITIVE") >+ self.assertEqual(len(attr_res[0][attr_ldap_name]), 1) >+ self.assertEqual(str(attr_res[0][attr_ldap_name][0]), "CASE_INSENSITIVE") > > # Check @INDEXLIST > >@@ -156,12 +156,12 @@ systemOnly: FALSE > attr_res = self.samdb.search(base="@ATTRIBUTES", scope=ldb.SCOPE_BASE) > > self.assertIn(attr_ldap_name, attr_res[0]) >- self.assertEquals(len(attr_res[0][attr_ldap_name]), 1) >- self.assertEquals(str(attr_res[0][attr_ldap_name][0]), "CASE_INSENSITIVE") >+ self.assertEqual(len(attr_res[0][attr_ldap_name]), 1) >+ self.assertEqual(str(attr_res[0][attr_ldap_name][0]), "CASE_INSENSITIVE") > > self.assertIn(attr_ldap_name2, attr_res[0]) >- self.assertEquals(len(attr_res[0][attr_ldap_name2]), 1) >- self.assertEquals(str(attr_res[0][attr_ldap_name2][0]), "CASE_INSENSITIVE") >+ self.assertEqual(len(attr_res[0][attr_ldap_name2]), 1) >+ self.assertEqual(str(attr_res[0][attr_ldap_name2][0]), "CASE_INSENSITIVE") > > # Check @INDEXLIST > >@@ -180,12 +180,12 @@ systemOnly: FALSE > > res = self.samdb.search(base="@ATTRIBUTES", scope=ldb.SCOPE_BASE, > attrs=["@TEST_EXTRA"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), "@ATTRIBUTES") >- self.assertEquals(len(res[0]), 1) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), "@ATTRIBUTES") >+ self.assertEqual(len(res[0]), 1) > self.assertTrue("@TEST_EXTRA" in res[0]) >- self.assertEquals(len(res[0]["@TEST_EXTRA"]), 1) >- self.assertEquals(str(res[0]["@TEST_EXTRA"][0]), "HIDDEN") >+ self.assertEqual(len(res[0]["@TEST_EXTRA"]), 1) >+ self.assertEqual(str(res[0]["@TEST_EXTRA"][0]), "HIDDEN") > > samdb2 = samba.tests.connect_samdb(self.lp.samdb_url()) > >@@ -199,9 +199,9 @@ systemOnly: FALSE > > res = self.samdb.search(base="@ATTRIBUTES", scope=ldb.SCOPE_BASE, > attrs=["@TEST_EXTRA"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), "@ATTRIBUTES") >- self.assertEquals(len(res[0]), 0) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), "@ATTRIBUTES") >+ self.assertEqual(len(res[0]), 0) > self.assertFalse("@TEST_EXTRA" in res[0]) > > def test_modify_at_indexlist(self): >@@ -214,12 +214,12 @@ systemOnly: FALSE > > res = self.samdb.search(base="@INDEXLIST", scope=ldb.SCOPE_BASE, > attrs=["@TEST_EXTRA"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), "@INDEXLIST") >- self.assertEquals(len(res[0]), 1) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), "@INDEXLIST") >+ self.assertEqual(len(res[0]), 1) > self.assertTrue("@TEST_EXTRA" in res[0]) >- self.assertEquals(len(res[0]["@TEST_EXTRA"]), 1) >- self.assertEquals(str(res[0]["@TEST_EXTRA"][0]), "1") >+ self.assertEqual(len(res[0]["@TEST_EXTRA"]), 1) >+ self.assertEqual(str(res[0]["@TEST_EXTRA"][0]), "1") > > samdb2 = samba.tests.connect_samdb(self.lp.samdb_url()) > >@@ -233,9 +233,9 @@ systemOnly: FALSE > > res = self.samdb.search(base="@INDEXLIST", scope=ldb.SCOPE_BASE, > attrs=["@TEST_EXTRA"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), "@INDEXLIST") >- self.assertEquals(len(res[0]), 0) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), "@INDEXLIST") >+ self.assertEqual(len(res[0]), 0) > self.assertFalse("@TEST_EXTRA" in res[0]) > > def test_modify_fail_of_at_indexlist(self): >@@ -249,4 +249,4 @@ systemOnly: FALSE > self.fail("modify of @INDEXLIST with a failed constraint should fail") > except LdbError as err: > enum = err.args[0] >- self.assertEquals(enum, ldb.ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(enum, ldb.ERR_NO_SUCH_ATTRIBUTE) >diff --git a/python/samba/tests/encrypted_secrets.py b/python/samba/tests/encrypted_secrets.py >index db0822797f7..96da7048a77 100644 >--- a/python/samba/tests/encrypted_secrets.py >+++ b/python/samba/tests/encrypted_secrets.py >@@ -68,7 +68,7 @@ class EncryptedSecretsTests(TestCase): > # Now verify that the header contains the correct magic value. > encrypted = ndr_unpack(drsblobs.EncryptedSecret, blob) > magic = 0xca5caded >- self.assertEquals(magic, encrypted.header.magic) >+ self.assertEqual(magic, encrypted.header.magic) > > def test_required_features(self): > """Test that databases are provisioned with encryptedSecrets as a >diff --git a/python/samba/tests/get_opt.py b/python/samba/tests/get_opt.py >index e51c7068aba..2aad954830b 100644 >--- a/python/samba/tests/get_opt.py >+++ b/python/samba/tests/get_opt.py >@@ -32,23 +32,23 @@ import samba.tests > class KerberosOptionTests(samba.tests.TestCase): > > def test_parse_true(self): >- self.assertEquals( >+ self.assertEqual( > MUST_USE_KERBEROS, parse_kerberos_arg("yes", "--kerberos")) >- self.assertEquals( >+ self.assertEqual( > MUST_USE_KERBEROS, parse_kerberos_arg("true", "--kerberos")) >- self.assertEquals( >+ self.assertEqual( > MUST_USE_KERBEROS, parse_kerberos_arg("1", "--kerberos")) > > def test_parse_false(self): >- self.assertEquals( >+ self.assertEqual( > DONT_USE_KERBEROS, parse_kerberos_arg("no", "--kerberos")) >- self.assertEquals( >+ self.assertEqual( > DONT_USE_KERBEROS, parse_kerberos_arg("false", "--kerberos")) >- self.assertEquals( >+ self.assertEqual( > DONT_USE_KERBEROS, parse_kerberos_arg("0", "--kerberos")) > > def test_parse_auto(self): >- self.assertEquals( >+ self.assertEqual( > AUTO_USE_KERBEROS, parse_kerberos_arg("auto", "--kerberos")) > > def test_parse_invalid(self): >diff --git a/python/samba/tests/gpo.py b/python/samba/tests/gpo.py >index bf92aea77b6..dce00bd8f86 100644 >--- a/python/samba/tests/gpo.py >+++ b/python/samba/tests/gpo.py >@@ -102,11 +102,11 @@ class GPOTests(tests.TestCase): > file_sys_paths = [None, '%s\\%s' % (poldir, guid)] > ds_paths = [None, 'CN=%s,%s' % (guid, dspath)] > for i in range(0, len(gpos)): >- self.assertEquals(gpos[i].name, names[i], >+ self.assertEqual(gpos[i].name, names[i], > 'The gpo name did not match expected name %s' % gpos[i].name) >- self.assertEquals(gpos[i].file_sys_path, file_sys_paths[i], >+ self.assertEqual(gpos[i].file_sys_path, file_sys_paths[i], > 'file_sys_path did not match expected %s' % gpos[i].file_sys_path) >- self.assertEquals(gpos[i].ds_path, ds_paths[i], >+ self.assertEqual(gpos[i].ds_path, ds_paths[i], > 'ds_path did not match expected %s' % gpos[i].ds_path) > > def test_gpo_ads_does_not_segfault(self): >@@ -124,12 +124,12 @@ class GPOTests(tests.TestCase): > > with open(os.path.join(gpo_path, 'GPT.INI'), 'w') as gpt: > gpt.write(gpt_data % 42) >- self.assertEquals(gpo.gpo_get_sysvol_gpt_version(gpo_path)[1], 42, >+ self.assertEqual(gpo.gpo_get_sysvol_gpt_version(gpo_path)[1], 42, > 'gpo_get_sysvol_gpt_version() did not return the expected version') > > with open(os.path.join(gpo_path, 'GPT.INI'), 'w') as gpt: > gpt.write(gpt_data % old_vers) >- self.assertEquals(gpo.gpo_get_sysvol_gpt_version(gpo_path)[1], old_vers, >+ self.assertEqual(gpo.gpo_get_sysvol_gpt_version(gpo_path)[1], old_vers, > 'gpo_get_sysvol_gpt_version() did not return the expected version') > > def test_check_refresh_gpo_list(self): >@@ -162,7 +162,7 @@ class GPOTests(tests.TestCase): > after = realm + '/Policies/' \ > '{31B2F340-016D-11D2-945F-00C04FB984F9}/GPT.INI' > result = check_safe_path(before) >- self.assertEquals(result, after, 'check_safe_path() didn\'t' >+ self.assertEqual(result, after, 'check_safe_path() didn\'t' > ' correctly convert \\ to /') > > def test_gpt_ext_register(self): >@@ -177,7 +177,7 @@ class GPOTests(tests.TestCase): > gp_exts = list_gp_extensions(self.lp.configfile) > self.assertTrue(ext_guid in gp_exts.keys(), > 'Failed to list gp exts') >- self.assertEquals(gp_exts[ext_guid]['DllName'], ext_path, >+ self.assertEqual(gp_exts[ext_guid]['DllName'], ext_path, > 'Failed to list gp exts') > > unregister_gp_extension(ext_guid) >@@ -197,7 +197,7 @@ class GPOTests(tests.TestCase): > lp, parser = parse_gpext_conf(self.lp.configfile) > self.assertTrue('test_section' in parser.sections(), > 'test_section not found in gpext.conf') >- self.assertEquals(parser.get('test_section', 'test_var'), ext_guid, >+ self.assertEqual(parser.get('test_section', 'test_var'), ext_guid, > 'Failed to find test variable in gpext.conf') > parser.remove_section('test_section') > atomic_write_conf(lp, parser) >@@ -217,12 +217,12 @@ class GPOTests(tests.TestCase): > self.assertTrue(ret, 'Could not create the target %s' % gpttmpl) > > ret = gpupdate_force(self.lp) >- self.assertEquals(ret, 0, 'gpupdate force failed') >+ self.assertEqual(ret, 0, 'gpupdate force failed') > > gp_db = store.get_gplog(self.dc_account) > > applied_guids = gp_db.get_applied_guids() >- self.assertEquals(len(applied_guids), 2, 'The guids were not found') >+ self.assertEqual(len(applied_guids), 2, 'The guids were not found') > self.assertIn(guids[0], applied_guids, > '%s not in applied guids' % guids[0]) > self.assertIn(guids[1], applied_guids, >@@ -260,7 +260,7 @@ class GPOTests(tests.TestCase): > unstage_file(gpttmpl) > > ret = gpupdate_unapply(self.lp) >- self.assertEquals(ret, 0, 'gpupdate unapply failed') >+ self.assertEqual(ret, 0, 'gpupdate unapply failed') > > def test_process_group_policy(self): > local_path = self.lp.cache_path('gpo_cache') >diff --git a/python/samba/tests/group_audit.py b/python/samba/tests/group_audit.py >index b8c90a325d5..6f26db62be6 100644 >--- a/python/samba/tests/group_audit.py >+++ b/python/samba/tests/group_audit.py >@@ -106,7 +106,7 @@ class GroupAuditTests(AuditLogTestBase): > # > messages = self.waitForMessages(2) > print("Received %d messages" % len(messages)) >- self.assertEquals(2, >+ self.assertEqual(2, > len(messages), > "Did not receive the expected number of messages") > audit = messages[0]["groupChange"] >@@ -120,9 +120,9 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > > # Check the Add message for the new users primary group > audit = messages[1]["groupChange"] >@@ -136,8 +136,8 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >- self.assertEquals(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, >+ self.assertEqual(session_id, audit["sessionId"]) >+ self.assertEqual(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, > audit["eventId"]) > # > # Add the user to a group >@@ -147,7 +147,7 @@ class GroupAuditTests(AuditLogTestBase): > self.ldb.add_remove_group_members(GROUP_NAME_01, [USER_NAME]) > messages = self.waitForMessages(1) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > audit = messages[0]["groupChange"] >@@ -161,9 +161,9 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > > # > # Add the user to another group >@@ -173,7 +173,7 @@ class GroupAuditTests(AuditLogTestBase): > > messages = self.waitForMessages(1) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > audit = messages[0]["groupChange"] >@@ -187,9 +187,9 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > > # > # Remove the user from a group >@@ -201,7 +201,7 @@ class GroupAuditTests(AuditLogTestBase): > add_members_operation=False) > messages = self.waitForMessages(1) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > audit = messages[0]["groupChange"] >@@ -215,9 +215,9 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > > # > # Re-add the user to a group >@@ -227,7 +227,7 @@ class GroupAuditTests(AuditLogTestBase): > > messages = self.waitForMessages(1) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > audit = messages[0]["groupChange"] >@@ -241,9 +241,9 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > > def test_change_primary_group(self): > >@@ -252,7 +252,7 @@ class GroupAuditTests(AuditLogTestBase): > # > messages = self.waitForMessages(2) > print("Received %d messages" % len(messages)) >- self.assertEquals(2, >+ self.assertEqual(2, > len(messages), > "Did not receive the expected number of messages") > >@@ -268,9 +268,9 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") > > # Check the Add message for the new users primary group > audit = messages[1]["groupChange"] >@@ -284,8 +284,8 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >- self.assertEquals(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, >+ self.assertEqual(session_id, audit["sessionId"]) >+ self.assertEqual(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, > audit["eventId"]) > > # >@@ -297,7 +297,7 @@ class GroupAuditTests(AuditLogTestBase): > self.ldb.add_remove_group_members(GROUP_NAME_01, [USER_NAME]) > messages = self.waitForMessages(1) > print("Received %d messages" % len(messages)) >- self.assertEquals(1, >+ self.assertEqual(1, > len(messages), > "Did not receive the expected number of messages") > audit = messages[0]["groupChange"] >@@ -311,10 +311,10 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >- self.assertEquals(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, >+ self.assertEqual(service_description, "LDAP") >+ self.assertEqual(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, > audit["eventId"]) > > # >@@ -345,7 +345,7 @@ class GroupAuditTests(AuditLogTestBase): > # > messages = self.waitForMessages(3) > print("Received %d messages" % len(messages)) >- self.assertEquals(3, >+ self.assertEqual(3, > len(messages), > "Did not receive the expected number of messages") > >@@ -359,10 +359,10 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >- self.assertEquals(EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP, >+ self.assertEqual(service_description, "LDAP") >+ self.assertEqual(EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP, > audit["eventId"]) > > audit = messages[1]["groupChange"] >@@ -376,10 +376,10 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >- self.assertEquals(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, >+ self.assertEqual(service_description, "LDAP") >+ self.assertEqual(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, > audit["eventId"]) > > audit = messages[2]["groupChange"] >@@ -393,6 +393,6 @@ class GroupAuditTests(AuditLogTestBase): > self.remoteAddress) > self.assertTrue(self.is_guid(audit["sessionId"])) > session_id = self.get_session() >- self.assertEquals(session_id, audit["sessionId"]) >+ self.assertEqual(session_id, audit["sessionId"]) > service_description = self.get_service_description() >- self.assertEquals(service_description, "LDAP") >+ self.assertEqual(service_description, "LDAP") >diff --git a/python/samba/tests/hostconfig.py b/python/samba/tests/hostconfig.py >index 94f511ccf3f..0f03388d6ad 100644 >--- a/python/samba/tests/hostconfig.py >+++ b/python/samba/tests/hostconfig.py >@@ -52,18 +52,18 @@ class ShareTests(TestCase): > > def test_len_no_global(self): > shares = self._get_shares({}) >- self.assertEquals(0, len(shares)) >+ self.assertEqual(0, len(shares)) > > def test_iter(self): >- self.assertEquals([], list(self._get_shares({}))) >- self.assertEquals([], list(self._get_shares({"global": {}}))) >- self.assertEquals( >+ self.assertEqual([], list(self._get_shares({}))) >+ self.assertEqual([], list(self._get_shares({"global": {}}))) >+ self.assertEqual( > ["bla"], > list(self._get_shares({"global": {}, "bla": {}}))) > > def test_len(self): > shares = self._get_shares({"global": {}}) >- self.assertEquals(0, len(shares)) >+ self.assertEqual(0, len(shares)) > > def test_getitem_nonexistent(self): > shares = self._get_shares({"global": {}}) >diff --git a/python/samba/tests/join.py b/python/samba/tests/join.py >index 09a102e26af..836557a2ec6 100644 >--- a/python/samba/tests/join.py >+++ b/python/samba/tests/join.py >@@ -98,7 +98,7 @@ class JoinTestCase(DNSTKeyTest): > (response, response_packet) = self.dns_transaction_tcp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, len(IPs)) >+ self.assertEqual(response.ancount, len(IPs)) > > questions = [] > name = "%s._msdcs.%s" % (self.join_ctx.ntds_guid, self.join_ctx.dnsforest) >@@ -110,10 +110,10 @@ class JoinTestCase(DNSTKeyTest): > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) > >- self.assertEquals(response.ancount, 1 + len(IPs)) >- self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_CNAME) >- self.assertEquals(response.answers[0].rdata, self.join_ctx.dnshostname) >- self.assertEquals(response.answers[1].rr_type, dns.DNS_QTYPE_A) >+ self.assertEqual(response.ancount, 1 + len(IPs)) >+ self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_CNAME) >+ self.assertEqual(response.answers[0].rdata, self.join_ctx.dnshostname) >+ self.assertEqual(response.answers[1].rr_type, dns.DNS_QTYPE_A) > > def test_join_records_can_update(self): > dc_creds = Credentials() >@@ -173,4 +173,4 @@ class JoinTestCase(DNSTKeyTest): > (response, response_packet) = self.dns_transaction_tcp(p, host=self.server_ip) > self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) > self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) >- self.assertEquals(response.ancount, 1) >+ self.assertEqual(response.ancount, 1) >diff --git a/python/samba/tests/kcc/graph.py b/python/samba/tests/kcc/graph.py >index ed02b0d4ed8..b581158218c 100644 >--- a/python/samba/tests/kcc/graph.py >+++ b/python/samba/tests/kcc/graph.py >@@ -52,7 +52,7 @@ class GraphFunctionTests(samba.tests.TestCase): > ([0x03, 0x33] * 42, 42 * 6), > (list(range(7)) * 12, 12 * 9), > (list(range(4)) * 21, 21 * 4)): >- self.assertEquals(total_schedule(schedule), total) >+ self.assertEqual(total_schedule(schedule), total) > > def test_convert_schedule_to_repltimes(self): > for ntdsconn_times, repltimes in ( >@@ -63,5 +63,5 @@ class GraphFunctionTests(samba.tests.TestCase): > (list(range(7)) * 24, > [0x01, 0x23, 0x45, 0x60, 0x12, 0x34, 0x56] * 12)): > schedule = ntdsconn_schedule(ntdsconn_times) >- self.assertEquals(convert_schedule_to_repltimes(schedule), >+ self.assertEqual(convert_schedule_to_repltimes(schedule), > repltimes) >diff --git a/python/samba/tests/kcc/kcc_utils.py b/python/samba/tests/kcc/kcc_utils.py >index bad32b9ed6e..1597240efcd 100644 >--- a/python/samba/tests/kcc/kcc_utils.py >+++ b/python/samba/tests/kcc/kcc_utils.py >@@ -33,8 +33,8 @@ class ScheduleTests(samba.tests.TestCase): > def test_new_connection_schedule(self): > schedule = new_connection_schedule() > self.assertIsInstance(schedule, drsblobs.schedule) >- self.assertEquals(schedule.size, 188) >- self.assertEquals(len(schedule.dataArray[0].slots), 168) >+ self.assertEqual(schedule.size, 188) >+ self.assertEqual(len(schedule.dataArray[0].slots), 168) > > > # OK, this is pathetic, but the rest of it looks really hard, with the >diff --git a/python/samba/tests/netcmd.py b/python/samba/tests/netcmd.py >index 8efd47c18ff..cdc4e3b0c22 100644 >--- a/python/samba/tests/netcmd.py >+++ b/python/samba/tests/netcmd.py >@@ -33,7 +33,7 @@ class NetCmdTestCase(samba.tests.TestCase): > except Exception as e: > cmd.show_command_error(e) > retval = 1 >- self.assertEquals(retcode, retval) >+ self.assertEqual(retcode, retval) > return cmd.outf.getvalue(), cmd.errf.getvalue() > > def iter_all_subcommands(self): >@@ -51,8 +51,8 @@ class TestParmTests(NetCmdTestCase): > def test_no_client_ip(self): > out, err = self.run_netcmd(cmd_testparm, ["--client-name=foo"], > retcode=-1) >- self.assertEquals("", out) >- self.assertEquals( >+ self.assertEqual("", out) >+ self.assertEqual( > "ERROR: Both a DNS name and an IP address are " > "required for the host access check\n", err) > >@@ -62,12 +62,12 @@ class CommandTests(NetCmdTestCase): > def test_description(self): > class cmd_foo(Command): > """Mydescription""" >- self.assertEquals("Mydescription", cmd_foo().short_description) >+ self.assertEqual("Mydescription", cmd_foo().short_description) > > def test_name(self): > class cmd_foo(Command): > pass >- self.assertEquals("foo", cmd_foo().name) >+ self.assertEqual("foo", cmd_foo().name) > > def test_synopsis_everywhere(self): > missing = [] >diff --git a/python/samba/tests/ntacls.py b/python/samba/tests/ntacls.py >index b345b283a76..644678316c9 100644 >--- a/python/samba/tests/ntacls.py >+++ b/python/samba/tests/ntacls.py >@@ -54,7 +54,7 @@ class NtaclsTests(TestCaseInTempDir): > setntacl(lp, self.tempf, NTACL_SDDL, DOMAIN_SID) > facl = getntacl(lp, self.tempf) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(facl.as_sddl(anysid), NTACL_SDDL) >+ self.assertEqual(facl.as_sddl(anysid), NTACL_SDDL) > os.unlink(os.path.join(self.tempdir, "eadbtest.tdb")) > > def test_setntacl_getntacl_param(self): >@@ -65,7 +65,7 @@ class NtaclsTests(TestCaseInTempDir): > facl = getntacl(lp, self.tempf, "tdb", os.path.join( > self.tempdir, "eadbtest.tdb")) > domsid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(facl.as_sddl(domsid), NTACL_SDDL) >+ self.assertEqual(facl.as_sddl(domsid), NTACL_SDDL) > os.unlink(os.path.join(self.tempdir, "eadbtest.tdb")) > > def test_setntacl_invalidbackend(self): >diff --git a/python/samba/tests/ntacls_backup.py b/python/samba/tests/ntacls_backup.py >index d92299187f3..e7b9465ebf7 100644 >--- a/python/samba/tests/ntacls_backup.py >+++ b/python/samba/tests/ntacls_backup.py >@@ -116,7 +116,7 @@ class NtaclsBackupRestoreTests(SmbdBaseTests): > # This works in conjunction with the TEST_UMASK in smbd_base > # to ensure that permissions are not related to the umask > # but instead the smb.conf settings >- self.assertEquals(mode & 0o777, 0o755) >+ self.assertEqual(mode & 0o777, 0o755) > self.assertTrue(os.path.isdir(dirpath)) > > def test_smbd_create_file(self): >@@ -133,7 +133,7 @@ class NtaclsBackupRestoreTests(SmbdBaseTests): > # This works in conjunction with the TEST_UMASK in smbd_base > # to ensure that permissions are not related to the umask > # but instead the smb.conf settings >- self.assertEquals(mode & 0o777, 0o644) >+ self.assertEqual(mode & 0o777, 0o644) > > # As well as checking that unlink works, this removes the > # fake xattrs from the dev/inode based DB >@@ -156,8 +156,8 @@ class NtaclsBackupRestoreTests(SmbdBaseTests): > sd2 = self.ntacls_helper.getntacl( > file_path, as_sddl=True, direct_db_access=True) > >- self.assertEquals(sd0, sd1) >- self.assertEquals(sd1, sd2) >+ self.assertEqual(sd0, sd1) >+ self.assertEqual(sd1, sd2) > > def test_backup_online(self): > """ >diff --git a/python/samba/tests/ntlm_auth.py b/python/samba/tests/ntlm_auth.py >index c93d38a0f0f..622898d1708 100644 >--- a/python/samba/tests/ntlm_auth.py >+++ b/python/samba/tests/ntlm_auth.py >@@ -228,11 +228,11 @@ class NTLMAuthHelpersTests(NTLMAuthTestCase): > lines = out.split(b"\n") > > self.assertEqual(len(lines), 4) >- self.assertEquals(lines[0], b"Authenticated: Yes") >- self.assertEquals( >+ self.assertEqual(lines[0], b"Authenticated: Yes") >+ self.assertEqual( > lines[1], b"User-Session-Key: 3F373EA8E4AF954F14FAA506F8EEBDC4") >- self.assertEquals(lines[2], b".") >- self.assertEquals(lines[3], b"") >+ self.assertEqual(lines[2], b".") >+ self.assertEqual(lines[3], b"") > > # Break the password with a leading A on the challenge > ntlm_cmds[0] = "LANMAN-Challenge: A123456789abcdef" >@@ -247,7 +247,7 @@ class NTLMAuthHelpersTests(NTLMAuthTestCase): > > lines = out.split(b"\n") > self.assertEqual(len(lines), 5) >- self.assertEquals(lines[0], b"Authenticated: No") >+ self.assertEqual(lines[0], b"Authenticated: No") > > def test_ntlm_server_1_with_plaintext_winbind(self): > """ ntlm_auth ntlm-server-1 with plaintext password against winbind """ >@@ -270,9 +270,9 @@ class NTLMAuthHelpersTests(NTLMAuthTestCase): > lines = out.split(b"\n") > > self.assertEqual(len(lines), 3) >- self.assertEquals(lines[0], b"Authenticated: Yes") >- self.assertEquals(lines[1], b".") >- self.assertEquals(lines[2], b"") >+ self.assertEqual(lines[0], b"Authenticated: Yes") >+ self.assertEqual(lines[1], b".") >+ self.assertEqual(lines[2], b"") > > # Check membership failure > >@@ -287,9 +287,9 @@ class NTLMAuthHelpersTests(NTLMAuthTestCase): > lines = out.split(b"\n") > > self.assertEqual(len(lines), 3) >- self.assertEquals(lines[0], b"Authenticated: No") >- self.assertEquals(lines[1], b".") >- self.assertEquals(lines[2], b"") >+ self.assertEqual(lines[0], b"Authenticated: No") >+ self.assertEqual(lines[1], b".") >+ self.assertEqual(lines[2], b"") > > def test_ntlm_server_1_with_incorrect_password_winbind(self): > """ ntlm_auth ntlm-server-1 with incorrect fixed password against >@@ -313,7 +313,7 @@ class NTLMAuthHelpersTests(NTLMAuthTestCase): > lines = out.split(b"\n") > > self.assertEqual(len(lines), 5) >- self.assertEquals(lines[0], b"Authenticated: No") >+ self.assertEqual(lines[0], b"Authenticated: No") > > def test_diagnostics(self): > """ ntlm_auth diagnostics """ >diff --git a/python/samba/tests/param.py b/python/samba/tests/param.py >index 43a3452396b..0a7f86adad7 100644 >--- a/python/samba/tests/param.py >+++ b/python/samba/tests/param.py >@@ -39,12 +39,12 @@ class LoadParmTestCase(samba.tests.TestCaseInTempDir): > > def test_length(self): > file = param.LoadParm() >- self.assertEquals(0, len(file)) >+ self.assertEqual(0, len(file)) > > def test_set_workgroup(self): > file = param.LoadParm() > file.set("workgroup", "bla") >- self.assertEquals("BLA", file.get("workgroup")) >+ self.assertEqual("BLA", file.get("workgroup")) > > def test_is_mydomain(self): > file = param.LoadParm() >@@ -70,16 +70,16 @@ class LoadParmTestCase(samba.tests.TestCaseInTempDir): > def test_log_level(self): > samba_lp = param.LoadParm() > samba_lp.set("log level", "5 auth:4") >- self.assertEquals(5, samba_lp.log_level()) >+ self.assertEqual(5, samba_lp.log_level()) > > def test_dump(self): > samba_lp = param.LoadParm() > # Just test successfull method execution (outputs to stdout) >- self.assertEquals(None, samba_lp.dump()) >+ self.assertEqual(None, samba_lp.dump()) > > def test_dump_to_file(self): > samba_lp = param.LoadParm() >- self.assertEquals(None, samba_lp.dump(False, self.tempf)) >+ self.assertEqual(None, samba_lp.dump(False, self.tempf)) > content = open(self.tempf, 'r').read() > self.assertIn('[global]', content) > self.assertIn('interfaces', content) >@@ -88,12 +88,12 @@ class LoadParmTestCase(samba.tests.TestCaseInTempDir): > samba_lp = param.LoadParm() > samba_lp.load_default() > # Just test successfull method execution >- self.assertEquals(None, samba_lp.dump_a_parameter('interfaces')) >+ self.assertEqual(None, samba_lp.dump_a_parameter('interfaces')) > > def test_dump_a_parameter_to_file(self): > samba_lp = param.LoadParm() > samba_lp.load_default() >- self.assertEquals(None, >+ self.assertEqual(None, > samba_lp.dump_a_parameter('interfaces', > 'global', > self.tempf)) >diff --git a/python/samba/tests/password_hash.py b/python/samba/tests/password_hash.py >index 9892c3238a3..ec50b2b3f2e 100644 >--- a/python/samba/tests/password_hash.py >+++ b/python/samba/tests/password_hash.py >@@ -165,13 +165,13 @@ class PassWordHashTests(TestCase): > error = "Digest expected[%s], actual[%s], " \ > "user[%s], realm[%s], pass[%s]" % \ > (expected, actual, user, realm, password) >- self.assertEquals(expected, actual, error) >+ self.assertEqual(expected, actual, error) > > # Check all of the 29 expected WDigest values > # > def check_wdigests(self, digests): > >- self.assertEquals(29, digests.num_hashes) >+ self.assertEqual(29, digests.num_hashes) > > # Using the n-1 pattern in the array indexes to make it easier > # to check the tests against the spec and the samba-tool user tests. >@@ -306,15 +306,15 @@ class PassWordHashTests(TestCase): > def checkUserPassword(self, up, expected): > > # Check we've received the correct number of hashes >- self.assertEquals(len(expected), up.num_hashes) >+ self.assertEqual(len(expected), up.num_hashes) > > i = 0 > for (tag, alg, rounds) in expected: >- self.assertEquals(tag, up.hashes[i].scheme) >+ self.assertEqual(tag, up.hashes[i].scheme) > > data = up.hashes[i].value.decode('utf8').split("$") > # Check we got the expected crypt algorithm >- self.assertEquals(alg, data[1]) >+ self.assertEqual(alg, data[1]) > > if rounds is None: > cmd = "$%s$%s" % (alg, data[2]) >@@ -323,7 +323,7 @@ class PassWordHashTests(TestCase): > > # Calculate the expected hash value > expected = crypt.crypt(USER_PASS, cmd) >- self.assertEquals(expected, up.hashes[i].value.decode('utf8')) >+ self.assertEqual(expected, up.hashes[i].value.decode('utf8')) > i += 1 > > # Check that the correct nt_hash was stored for userPassword >@@ -333,4 +333,4 @@ class PassWordHashTests(TestCase): > creds.set_password(password) > expected = creds.get_nt_hash() > actual = bytearray(nt_hash) >- self.assertEquals(expected, actual) >+ self.assertEqual(expected, actual) >diff --git a/python/samba/tests/password_hash_fl2003.py b/python/samba/tests/password_hash_fl2003.py >index ab99b3b1823..c412a0676e6 100644 >--- a/python/samba/tests/password_hash_fl2003.py >+++ b/python/samba/tests/password_hash_fl2003.py >@@ -49,19 +49,19 @@ class PassWordHashFl2003Tests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(3, size) >+ self.assertEqual(3, size) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(2, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Packages", package.name) > > (pos, package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(3, pos) >- self.assertEquals("Primary:WDigest", package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Primary:WDigest", package.name) > > # Check that the WDigest values are correct. > # >@@ -78,23 +78,23 @@ class PassWordHashFl2003Tests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(4, size) >+ self.assertEqual(4, size) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, wd_package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(2, pos) >- self.assertEquals("Primary:WDigest", wd_package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Primary:WDigest", wd_package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(3, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Packages", package.name) > > (pos, up_package) = get_package(sc, "Primary:userPassword") >- self.assertEquals(4, pos) >- self.assertEquals("Primary:userPassword", up_package.name) >+ self.assertEqual(4, pos) >+ self.assertEqual("Primary:userPassword", up_package.name) > > # Check that the WDigest values are correct. > # >@@ -119,23 +119,23 @@ class PassWordHashFl2003Tests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(4, size) >+ self.assertEqual(4, size) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, wd_package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(2, pos) >- self.assertEquals("Primary:WDigest", wd_package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Primary:WDigest", wd_package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(3, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Packages", package.name) > > (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT") >- self.assertEquals(4, pos) >- self.assertEquals("Primary:CLEARTEXT", ct_package.name) >+ self.assertEqual(4, pos) >+ self.assertEqual("Primary:CLEARTEXT", ct_package.name) > > # Check that the WDigest values are correct. > # >@@ -146,7 +146,7 @@ class PassWordHashFl2003Tests(PassWordHashTests): > # Check the clear text value is correct. > ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob, > binascii.a2b_hex(ct_package.data)) >- self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext) >+ self.assertEqual(USER_PASS.encode('utf-16-le'), ct.cleartext) > > def test_userPassword_cleartext_sha512(self): > self.add_user(clear_text=True, >@@ -158,27 +158,27 @@ class PassWordHashFl2003Tests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(5, size) >+ self.assertEqual(5, size) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, wd_package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(2, pos) >- self.assertEquals("Primary:WDigest", wd_package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Primary:WDigest", wd_package.name) > > (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT") >- self.assertEquals(3, pos) >- self.assertEquals("Primary:CLEARTEXT", ct_package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Primary:CLEARTEXT", ct_package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(4, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(4, pos) >+ self.assertEqual("Packages", package.name) > > (pos, up_package) = get_package(sc, "Primary:userPassword") >- self.assertEquals(5, pos) >- self.assertEquals("Primary:userPassword", up_package.name) >+ self.assertEqual(5, pos) >+ self.assertEqual("Primary:userPassword", up_package.name) > > # Check that the WDigest values are correct. > # >@@ -189,7 +189,7 @@ class PassWordHashFl2003Tests(PassWordHashTests): > # Check the clear text value is correct. > ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob, > binascii.a2b_hex(ct_package.data)) >- self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext) >+ self.assertEqual(USER_PASS.encode('utf-16-le'), ct.cleartext) > > # Check that the userPassword hashes are computed correctly > # >diff --git a/python/samba/tests/password_hash_fl2008.py b/python/samba/tests/password_hash_fl2008.py >index 917e973cdbc..dc7020d3984 100644 >--- a/python/samba/tests/password_hash_fl2008.py >+++ b/python/samba/tests/password_hash_fl2008.py >@@ -48,22 +48,22 @@ class PassWordHashFl2008Tests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(4, size) >+ self.assertEqual(4, size) > (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos-Newer-Keys", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos-Newer-Keys", package.name) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(2, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(3, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Packages", package.name) > > (pos, package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(4, pos) >- self.assertEquals("Primary:WDigest", package.name) >+ self.assertEqual(4, pos) >+ self.assertEqual("Primary:WDigest", package.name) > > # Check that the WDigest values are correct. > # >@@ -80,27 +80,27 @@ class PassWordHashFl2008Tests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(5, size) >+ self.assertEqual(5, size) > > (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos-Newer-Keys", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos-Newer-Keys", package.name) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(2, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, wp_package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(3, pos) >- self.assertEquals("Primary:WDigest", wp_package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Primary:WDigest", wp_package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(4, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(4, pos) >+ self.assertEqual("Packages", package.name) > > (pos, up_package) = get_package(sc, "Primary:userPassword") >- self.assertEquals(5, pos) >- self.assertEquals("Primary:userPassword", up_package.name) >+ self.assertEqual(5, pos) >+ self.assertEqual("Primary:userPassword", up_package.name) > > # Check that the WDigest values are correct. > # >@@ -123,26 +123,26 @@ class PassWordHashFl2008Tests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(5, size) >+ self.assertEqual(5, size) > (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos-Newer-Keys", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos-Newer-Keys", package.name) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(2, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, wd_package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(3, pos) >- self.assertEquals("Primary:WDigest", wd_package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Primary:WDigest", wd_package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(4, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(4, pos) >+ self.assertEqual("Packages", package.name) > > (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT") >- self.assertEquals(5, pos) >- self.assertEquals("Primary:CLEARTEXT", ct_package.name) >+ self.assertEqual(5, pos) >+ self.assertEqual("Primary:CLEARTEXT", ct_package.name) > > # Check that the WDigest values are correct. > # >@@ -153,7 +153,7 @@ class PassWordHashFl2008Tests(PassWordHashTests): > # Check the clear text value is correct. > ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob, > binascii.a2b_hex(ct_package.data)) >- self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext) >+ self.assertEqual(USER_PASS.encode('utf-16-le'), ct.cleartext) > > def test_userPassword_cleartext_sha256(self): > self.add_user(clear_text=True, >@@ -165,31 +165,31 @@ class PassWordHashFl2008Tests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(6, size) >+ self.assertEqual(6, size) > > (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos-Newer-Keys", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos-Newer-Keys", package.name) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(2, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, wd_package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(3, pos) >- self.assertEquals("Primary:WDigest", wd_package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Primary:WDigest", wd_package.name) > > (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT") >- self.assertEquals(4, pos) >- self.assertEquals("Primary:CLEARTEXT", ct_package.name) >+ self.assertEqual(4, pos) >+ self.assertEqual("Primary:CLEARTEXT", ct_package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(5, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(5, pos) >+ self.assertEqual("Packages", package.name) > > (pos, up_package) = get_package(sc, "Primary:userPassword") >- self.assertEquals(6, pos) >- self.assertEquals("Primary:userPassword", up_package.name) >+ self.assertEqual(6, pos) >+ self.assertEqual("Primary:userPassword", up_package.name) > > # Check that the WDigest values are correct. > # >@@ -200,7 +200,7 @@ class PassWordHashFl2008Tests(PassWordHashTests): > # Check the clear text value is correct. > ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob, > binascii.a2b_hex(ct_package.data)) >- self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext) >+ self.assertEqual(USER_PASS.encode('utf-16-le'), ct.cleartext) > > # Check that the userPassword hashes are computed correctly > # >diff --git a/python/samba/tests/password_hash_gpgme.py b/python/samba/tests/password_hash_gpgme.py >index 42cd71d3e08..16247bc3451 100644 >--- a/python/samba/tests/password_hash_gpgme.py >+++ b/python/samba/tests/password_hash_gpgme.py >@@ -54,26 +54,26 @@ class PassWordHashGpgmeTests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(5, size) >+ self.assertEqual(5, size) > (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos-Newer-Keys", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos-Newer-Keys", package.name) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(2, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, wd_package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(3, pos) >- self.assertEquals("Primary:WDigest", wd_package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Primary:WDigest", wd_package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(4, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(4, pos) >+ self.assertEqual("Packages", package.name) > > (pos, package) = get_package(sc, "Primary:SambaGPG") >- self.assertEquals(5, pos) >- self.assertEquals("Primary:SambaGPG", package.name) >+ self.assertEqual(5, pos) >+ self.assertEqual("Primary:SambaGPG", package.name) > > # Check that the WDigest values are correct. > # >@@ -92,30 +92,30 @@ class PassWordHashGpgmeTests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(6, size) >+ self.assertEqual(6, size) > (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos-Newer-Keys", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos-Newer-Keys", package.name) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(2, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, wd_package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(3, pos) >- self.assertEquals("Primary:WDigest", wd_package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Primary:WDigest", wd_package.name) > > (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT") >- self.assertEquals(4, pos) >- self.assertEquals("Primary:CLEARTEXT", ct_package.name) >+ self.assertEqual(4, pos) >+ self.assertEqual("Primary:CLEARTEXT", ct_package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(5, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(5, pos) >+ self.assertEqual("Packages", package.name) > > (pos, package) = get_package(sc, "Primary:SambaGPG") >- self.assertEquals(6, pos) >- self.assertEquals("Primary:SambaGPG", package.name) >+ self.assertEqual(6, pos) >+ self.assertEqual("Primary:SambaGPG", package.name) > > # Check that the WDigest values are correct. > # >@@ -126,7 +126,7 @@ class PassWordHashGpgmeTests(PassWordHashTests): > # Check the clear text value is correct. > ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob, > binascii.a2b_hex(ct_package.data)) >- self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext) >+ self.assertEqual(USER_PASS.encode('utf-16-le'), ct.cleartext) > > def assert_cleartext(self, expect_cleartext, password=None): > """Checks cleartext is (or isn't) returned as expected""" >@@ -138,7 +138,7 @@ class PassWordHashGpgmeTests(PassWordHashTests): > # Check the clear-text value is correct. > ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob, > binascii.a2b_hex(ct_package.data)) >- self.assertEquals(password.encode('utf-16-le'), ct.cleartext) >+ self.assertEqual(password.encode('utf-16-le'), ct.cleartext) > else: > ct_package = get_package(sc, "Primary:CLEARTEXT") > self.assertTrue(ct_package is None, >@@ -199,31 +199,31 @@ class PassWordHashGpgmeTests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(6, size) >+ self.assertEqual(6, size) > > (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos-Newer-Keys", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos-Newer-Keys", package.name) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(2, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, wp_package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(3, pos) >- self.assertEquals("Primary:WDigest", wp_package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Primary:WDigest", wp_package.name) > > (pos, up_package) = get_package(sc, "Primary:userPassword") >- self.assertEquals(4, pos) >- self.assertEquals("Primary:userPassword", up_package.name) >+ self.assertEqual(4, pos) >+ self.assertEqual("Primary:userPassword", up_package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(5, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(5, pos) >+ self.assertEqual("Packages", package.name) > > (pos, package) = get_package(sc, "Primary:SambaGPG") >- self.assertEquals(6, pos) >- self.assertEquals("Primary:SambaGPG", package.name) >+ self.assertEqual(6, pos) >+ self.assertEqual("Primary:SambaGPG", package.name) > > # Check that the WDigest values are correct. > # >@@ -252,31 +252,31 @@ class PassWordHashGpgmeTests(PassWordHashTests): > # Check that we got all the expected supplemental credentials > # And they are in the expected order. > size = len(sc.sub.packages) >- self.assertEquals(6, size) >+ self.assertEqual(6, size) > > (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys") >- self.assertEquals(1, pos) >- self.assertEquals("Primary:Kerberos-Newer-Keys", package.name) >+ self.assertEqual(1, pos) >+ self.assertEqual("Primary:Kerberos-Newer-Keys", package.name) > > (pos, package) = get_package(sc, "Primary:Kerberos") >- self.assertEquals(2, pos) >- self.assertEquals("Primary:Kerberos", package.name) >+ self.assertEqual(2, pos) >+ self.assertEqual("Primary:Kerberos", package.name) > > (pos, wp_package) = get_package(sc, "Primary:WDigest") >- self.assertEquals(3, pos) >- self.assertEquals("Primary:WDigest", wp_package.name) >+ self.assertEqual(3, pos) >+ self.assertEqual("Primary:WDigest", wp_package.name) > > (pos, up_package) = get_package(sc, "Primary:userPassword") >- self.assertEquals(4, pos) >- self.assertEquals("Primary:userPassword", up_package.name) >+ self.assertEqual(4, pos) >+ self.assertEqual("Primary:userPassword", up_package.name) > > (pos, package) = get_package(sc, "Packages") >- self.assertEquals(5, pos) >- self.assertEquals("Packages", package.name) >+ self.assertEqual(5, pos) >+ self.assertEqual("Packages", package.name) > > (pos, package) = get_package(sc, "Primary:SambaGPG") >- self.assertEquals(6, pos) >- self.assertEquals("Primary:SambaGPG", package.name) >+ self.assertEqual(6, pos) >+ self.assertEqual("Primary:SambaGPG", package.name) > > # Check that the WDigest values are correct. > # >diff --git a/python/samba/tests/password_hash_ldap.py b/python/samba/tests/password_hash_ldap.py >index 5bb407e0906..4d6904b455b 100644 >--- a/python/samba/tests/password_hash_ldap.py >+++ b/python/samba/tests/password_hash_ldap.py >@@ -125,7 +125,7 @@ class PassWordHashLDAPTests(PassWordHashTests): > sc = self.get_supplemental_creds_drs() > > (pos, package) = get_package(sc, "Primary:WDigest") >- self.assertEquals("Primary:WDigest", package.name) >+ self.assertEqual("Primary:WDigest", package.name) > > # Check that the WDigest values are correct. > # >diff --git a/python/samba/tests/policy.py b/python/samba/tests/policy.py >index 538efcd95b0..4029150c752 100644 >--- a/python/samba/tests/policy.py >+++ b/python/samba/tests/policy.py >@@ -26,9 +26,9 @@ from samba import policy > class PolicyTests(TestCase): > > def test_get_gpo_flags(self): >- self.assertEquals(["GPO_FLAG_USER_DISABLE"], >+ self.assertEqual(["GPO_FLAG_USER_DISABLE"], > policy.get_gpo_flags(policy.GPO_FLAG_USER_DISABLE)) > > def test_get_gplink_options(self): >- self.assertEquals(["GPLINK_OPT_DISABLE"], >+ self.assertEqual(["GPLINK_OPT_DISABLE"], > policy.get_gplink_options(policy.GPLINK_OPT_DISABLE)) >diff --git a/python/samba/tests/posixacl.py b/python/samba/tests/posixacl.py >index b52289e63cf..f2ea4048a01 100644 >--- a/python/samba/tests/posixacl.py >+++ b/python/samba/tests/posixacl.py >@@ -80,7 +80,7 @@ class PosixAclMappingTests(SmbdBaseTests): > session_info=self.get_session_info()) > facl = getntacl(self.lp, self.tempf, direct_db_access=True) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(facl.as_sddl(anysid), acl) >+ self.assertEqual(facl.as_sddl(anysid), acl) > > def test_setntacl_smbd_setposixacl_getntacl(self): > acl = ACL >@@ -107,7 +107,7 @@ class PosixAclMappingTests(SmbdBaseTests): > # however, as this is direct DB access, we do not notice it > facl = getntacl(self.lp, self.tempf, direct_db_access=True) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(acl, facl.as_sddl(anysid)) >+ self.assertEqual(acl, facl.as_sddl(anysid)) > > def test_setntacl_invalidate_getntacl_smbd(self): > acl = ACL >@@ -122,7 +122,7 @@ class PosixAclMappingTests(SmbdBaseTests): > # the hash would break, and we return an ACL based only on the mode, except we set the ACL using the 'ntvfs' mode that doesn't include a hash > facl = getntacl(self.lp, self.tempf) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(acl, facl.as_sddl(anysid)) >+ self.assertEqual(acl, facl.as_sddl(anysid)) > > def test_setntacl_smbd_invalidate_getntacl_smbd(self): > acl = ACL >@@ -139,7 +139,7 @@ class PosixAclMappingTests(SmbdBaseTests): > # the hash will break, and we return an ACL based only on the mode > facl = getntacl(self.lp, self.tempf, direct_db_access=False) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) >+ self.assertEqual(simple_acl_from_posix, facl.as_sddl(anysid)) > > def test_setntacl_getntacl_smbd(self): > acl = ACL >@@ -147,7 +147,7 @@ class PosixAclMappingTests(SmbdBaseTests): > session_info=self.get_session_info()) > facl = getntacl(self.lp, self.tempf, direct_db_access=False) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(facl.as_sddl(anysid), acl) >+ self.assertEqual(facl.as_sddl(anysid), acl) > > def test_setntacl_smbd_getntacl_smbd(self): > acl = ACL >@@ -155,7 +155,7 @@ class PosixAclMappingTests(SmbdBaseTests): > session_info=self.get_session_info()) > facl = getntacl(self.lp, self.tempf, direct_db_access=False) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(facl.as_sddl(anysid), acl) >+ self.assertEqual(facl.as_sddl(anysid), acl) > > def test_setntacl_smbd_setposixacl_getntacl_smbd(self): > acl = ACL >@@ -166,7 +166,7 @@ class PosixAclMappingTests(SmbdBaseTests): > smbd.set_simple_acl(self.tempf, 0o640) > facl = getntacl(self.lp, self.tempf, direct_db_access=False) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) >+ self.assertEqual(simple_acl_from_posix, facl.as_sddl(anysid)) > > def test_setntacl_smbd_setposixacl_group_getntacl_smbd(self): > acl = ACL >@@ -182,7 +182,7 @@ class PosixAclMappingTests(SmbdBaseTests): > # This should re-calculate an ACL based on the posix details > facl = getntacl(self.lp, self.tempf, direct_db_access=False) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) >+ self.assertEqual(simple_acl_from_posix, facl.as_sddl(anysid)) > > def test_setntacl_smbd_getntacl_smbd_gpo(self): > acl = "O:DAG:DUD:P(A;OICI;0x001f01ff;;;DA)(A;OICI;0x001f01ff;;;EA)(A;OICIIO;0x001f01ff;;;CO)(A;OICI;0x001f01ff;;;DA)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)(A;OICI;0x001200a9;;;ED)S:AI(OU;CIIDSA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)(OU;CIIDSA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" >@@ -190,7 +190,7 @@ class PosixAclMappingTests(SmbdBaseTests): > session_info=self.get_session_info()) > facl = getntacl(self.lp, self.tempf, direct_db_access=False) > domsid = security.dom_sid(DOM_SID) >- self.assertEquals(facl.as_sddl(domsid), acl) >+ self.assertEqual(facl.as_sddl(domsid), acl) > > def test_setntacl_getposixacl(self): > acl = ACL >@@ -198,7 +198,7 @@ class PosixAclMappingTests(SmbdBaseTests): > session_info=self.get_session_info()) > facl = getntacl(self.lp, self.tempf) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(facl.as_sddl(anysid), acl) >+ self.assertEqual(facl.as_sddl(anysid), acl) > posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) > > def test_setposixacl_getntacl(self): >@@ -214,7 +214,7 @@ class PosixAclMappingTests(SmbdBaseTests): > facl = getntacl(self.lp, self.tempf, direct_db_access=False) > acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;%s)(A;;;;;WD)" % (user_SID, group_SID, user_SID, group_SID) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(acl, facl.as_sddl(anysid)) >+ self.assertEqual(acl, facl.as_sddl(anysid)) > > def test_setposixacl_dir_getntacl_smbd(self): > s4_passdb = passdb.PDB(self.lp.get("passdb backend")) >@@ -222,17 +222,17 @@ class PosixAclMappingTests(SmbdBaseTests): > BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) > s4_passdb = passdb.PDB(self.lp.get("passdb backend")) > (BA_id, BA_type) = s4_passdb.sid_to_id(BA_sid) >- self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(BA_type, idmap.ID_TYPE_BOTH) > SO_sid = security.dom_sid(security.SID_BUILTIN_SERVER_OPERATORS) > (SO_id, SO_type) = s4_passdb.sid_to_id(SO_sid) >- self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(SO_type, idmap.ID_TYPE_BOTH) > smbd.chown(self.tempdir, BA_id, SO_id) > smbd.set_simple_acl(self.tempdir, 0o750) > facl = getntacl(self.lp, self.tempdir, direct_db_access=False) > acl = "O:BAG:SOD:(A;;0x001f01ff;;;BA)(A;;0x001200a9;;;SO)(A;;;;;WD)(A;OICIIO;0x001f01ff;;;CO)(A;OICIIO;0x001200a9;;;CG)(A;OICIIO;0x001200a9;;;WD)" > > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(acl, facl.as_sddl(anysid)) >+ self.assertEqual(acl, facl.as_sddl(anysid)) > > def test_setposixacl_group_getntacl_smbd(self): > BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) >@@ -240,73 +240,73 @@ class PosixAclMappingTests(SmbdBaseTests): > (BA_gid, BA_type) = s4_passdb.sid_to_id(BA_sid) > group_SID = s4_passdb.gid_to_sid(os.stat(self.tempf).st_gid) > user_SID = s4_passdb.uid_to_sid(os.stat(self.tempf).st_uid) >- self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(BA_type, idmap.ID_TYPE_BOTH) > smbd.set_simple_acl(self.tempf, 0o640, BA_gid) > facl = getntacl(self.lp, self.tempf, direct_db_access=False) > domsid = passdb.get_global_sam_sid() > acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;BA)(A;;0x00120089;;;%s)(A;;;;;WD)" % (user_SID, group_SID, user_SID, group_SID) > anysid = security.dom_sid(security.SID_NT_SELF) >- self.assertEquals(acl, facl.as_sddl(anysid)) >+ self.assertEqual(acl, facl.as_sddl(anysid)) > > def test_setposixacl_getposixacl(self): > smbd.set_simple_acl(self.tempf, 0o640) > posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) >- self.assertEquals(posix_acl.count, 4, self.print_posix_acl(posix_acl)) >+ self.assertEqual(posix_acl.count, 4, self.print_posix_acl(posix_acl)) > >- self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) >- self.assertEquals(posix_acl.acl[0].a_perm, 6) >+ self.assertEqual(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) >+ self.assertEqual(posix_acl.acl[0].a_perm, 6) > >- self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >- self.assertEquals(posix_acl.acl[1].a_perm, 4) >+ self.assertEqual(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >+ self.assertEqual(posix_acl.acl[1].a_perm, 4) > >- self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >- self.assertEquals(posix_acl.acl[2].a_perm, 0) >+ self.assertEqual(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >+ self.assertEqual(posix_acl.acl[2].a_perm, 0) > >- self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) >- self.assertEquals(posix_acl.acl[3].a_perm, 7) >+ self.assertEqual(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) >+ self.assertEqual(posix_acl.acl[3].a_perm, 7) > > def test_setposixacl_dir_getposixacl(self): > smbd.set_simple_acl(self.tempdir, 0o750) > posix_acl = smbd.get_sys_acl(self.tempdir, smb_acl.SMB_ACL_TYPE_ACCESS) >- self.assertEquals(posix_acl.count, 4, self.print_posix_acl(posix_acl)) >+ self.assertEqual(posix_acl.count, 4, self.print_posix_acl(posix_acl)) > >- self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) >- self.assertEquals(posix_acl.acl[0].a_perm, 7) >+ self.assertEqual(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) >+ self.assertEqual(posix_acl.acl[0].a_perm, 7) > >- self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >- self.assertEquals(posix_acl.acl[1].a_perm, 5) >+ self.assertEqual(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >+ self.assertEqual(posix_acl.acl[1].a_perm, 5) > >- self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >- self.assertEquals(posix_acl.acl[2].a_perm, 0) >+ self.assertEqual(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >+ self.assertEqual(posix_acl.acl[2].a_perm, 0) > >- self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) >- self.assertEquals(posix_acl.acl[3].a_perm, 7) >+ self.assertEqual(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) >+ self.assertEqual(posix_acl.acl[3].a_perm, 7) > > def test_setposixacl_group_getposixacl(self): > BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) > s4_passdb = passdb.PDB(self.lp.get("passdb backend")) > (BA_gid, BA_type) = s4_passdb.sid_to_id(BA_sid) >- self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(BA_type, idmap.ID_TYPE_BOTH) > smbd.set_simple_acl(self.tempf, 0o670, BA_gid) > posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) > >- self.assertEquals(posix_acl.count, 5, self.print_posix_acl(posix_acl)) >+ self.assertEqual(posix_acl.count, 5, self.print_posix_acl(posix_acl)) > >- self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) >- self.assertEquals(posix_acl.acl[0].a_perm, 6) >+ self.assertEqual(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) >+ self.assertEqual(posix_acl.acl[0].a_perm, 6) > >- self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >- self.assertEquals(posix_acl.acl[1].a_perm, 7) >+ self.assertEqual(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >+ self.assertEqual(posix_acl.acl[1].a_perm, 7) > >- self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >- self.assertEquals(posix_acl.acl[2].a_perm, 0) >+ self.assertEqual(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >+ self.assertEqual(posix_acl.acl[2].a_perm, 0) > >- self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[3].a_perm, 7) >- self.assertEquals(posix_acl.acl[3].info.gid, BA_gid) >+ self.assertEqual(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[3].a_perm, 7) >+ self.assertEqual(posix_acl.acl[3].info.gid, BA_gid) > >- self.assertEquals(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_MASK) >- self.assertEquals(posix_acl.acl[4].a_perm, 7) >+ self.assertEqual(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_MASK) >+ self.assertEqual(posix_acl.acl[4].a_perm, 7) > > def test_setntacl_sysvol_check_getposixacl(self): > acl = provision.SYSVOL_ACL >@@ -315,7 +315,7 @@ class PosixAclMappingTests(SmbdBaseTests): > setntacl(self.lp, self.tempf, acl, str(domsid), use_ntvfs=False, > session_info=session_info) > facl = getntacl(self.lp, self.tempf) >- self.assertEquals(facl.as_sddl(domsid), acl) >+ self.assertEqual(facl.as_sddl(domsid), acl) > posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) > > nwrap_module_so_path = os.getenv('NSS_WRAPPER_MODULE_SO_PATH') >@@ -336,71 +336,71 @@ class PosixAclMappingTests(SmbdBaseTests): > # configuration. When other environments have a broad range of > # groups mapped via passdb, we can relax some of these checks > (LA_uid, LA_type) = s4_passdb.sid_to_id(LA_sid) >- self.assertEquals(LA_type, idmap.ID_TYPE_UID) >+ self.assertEqual(LA_type, idmap.ID_TYPE_UID) > (BA_gid, BA_type) = s4_passdb.sid_to_id(BA_sid) >- self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(BA_type, idmap.ID_TYPE_BOTH) > (SO_gid, SO_type) = s4_passdb.sid_to_id(SO_sid) >- self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(SO_type, idmap.ID_TYPE_BOTH) > (SY_gid, SY_type) = s4_passdb.sid_to_id(SY_sid) >- self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(SO_type, idmap.ID_TYPE_BOTH) > (AU_gid, AU_type) = s4_passdb.sid_to_id(AU_sid) >- self.assertEquals(AU_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(AU_type, idmap.ID_TYPE_BOTH) > >- self.assertEquals(posix_acl.count, 13, self.print_posix_acl(posix_acl)) >+ self.assertEqual(posix_acl.count, 13, self.print_posix_acl(posix_acl)) > >- self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[0].a_perm, 7) >- self.assertEquals(posix_acl.acl[0].info.gid, BA_gid) >+ self.assertEqual(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[0].a_perm, 7) >+ self.assertEqual(posix_acl.acl[0].info.gid, BA_gid) > >- self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_USER) > if nwrap_winbind_active or session_info: >- self.assertEquals(posix_acl.acl[1].a_perm, 7) >+ self.assertEqual(posix_acl.acl[1].a_perm, 7) > else: >- self.assertEquals(posix_acl.acl[1].a_perm, 6) >- self.assertEquals(posix_acl.acl[1].info.uid, LA_uid) >+ self.assertEqual(posix_acl.acl[1].a_perm, 6) >+ self.assertEqual(posix_acl.acl[1].info.uid, LA_uid) > >- self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >- self.assertEquals(posix_acl.acl[2].a_perm, 0) >+ self.assertEqual(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >+ self.assertEqual(posix_acl.acl[2].a_perm, 0) > >- self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_USER_OBJ) >+ self.assertEqual(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_USER_OBJ) > if nwrap_winbind_active or session_info: >- self.assertEquals(posix_acl.acl[3].a_perm, 7) >+ self.assertEqual(posix_acl.acl[3].a_perm, 7) > else: >- self.assertEquals(posix_acl.acl[3].a_perm, 6) >+ self.assertEqual(posix_acl.acl[3].a_perm, 6) > >- self.assertEquals(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[4].a_perm, 7) >- self.assertEquals(posix_acl.acl[4].info.uid, BA_gid) >+ self.assertEqual(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[4].a_perm, 7) >+ self.assertEqual(posix_acl.acl[4].info.uid, BA_gid) > >- self.assertEquals(posix_acl.acl[5].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >- self.assertEquals(posix_acl.acl[5].a_perm, 7) >+ self.assertEqual(posix_acl.acl[5].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >+ self.assertEqual(posix_acl.acl[5].a_perm, 7) > >- self.assertEquals(posix_acl.acl[6].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[6].a_perm, 5) >- self.assertEquals(posix_acl.acl[6].info.uid, SO_gid) >+ self.assertEqual(posix_acl.acl[6].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[6].a_perm, 5) >+ self.assertEqual(posix_acl.acl[6].info.uid, SO_gid) > >- self.assertEquals(posix_acl.acl[7].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[7].a_perm, 5) >- self.assertEquals(posix_acl.acl[7].info.gid, SO_gid) >+ self.assertEqual(posix_acl.acl[7].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[7].a_perm, 5) >+ self.assertEqual(posix_acl.acl[7].info.gid, SO_gid) > >- self.assertEquals(posix_acl.acl[8].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[8].a_perm, 7) >- self.assertEquals(posix_acl.acl[8].info.uid, SY_gid) >+ self.assertEqual(posix_acl.acl[8].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[8].a_perm, 7) >+ self.assertEqual(posix_acl.acl[8].info.uid, SY_gid) > >- self.assertEquals(posix_acl.acl[9].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[9].a_perm, 7) >- self.assertEquals(posix_acl.acl[9].info.gid, SY_gid) >+ self.assertEqual(posix_acl.acl[9].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[9].a_perm, 7) >+ self.assertEqual(posix_acl.acl[9].info.gid, SY_gid) > >- self.assertEquals(posix_acl.acl[10].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[10].a_perm, 5) >- self.assertEquals(posix_acl.acl[10].info.uid, AU_gid) >+ self.assertEqual(posix_acl.acl[10].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[10].a_perm, 5) >+ self.assertEqual(posix_acl.acl[10].info.uid, AU_gid) > >- self.assertEquals(posix_acl.acl[11].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[11].a_perm, 5) >- self.assertEquals(posix_acl.acl[11].info.gid, AU_gid) >+ self.assertEqual(posix_acl.acl[11].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[11].a_perm, 5) >+ self.assertEqual(posix_acl.acl[11].info.gid, AU_gid) > >- self.assertEquals(posix_acl.acl[12].a_type, smb_acl.SMB_ACL_MASK) >- self.assertEquals(posix_acl.acl[12].a_perm, 7) >+ self.assertEqual(posix_acl.acl[12].a_type, smb_acl.SMB_ACL_MASK) >+ self.assertEqual(posix_acl.acl[12].a_perm, 7) > > # check that it matches: > # user::rwx >@@ -458,7 +458,7 @@ class PosixAclMappingTests(SmbdBaseTests): > setntacl(self.lp, self.tempdir, acl, str(domsid), use_ntvfs=False, > session_info=session_info) > facl = getntacl(self.lp, self.tempdir) >- self.assertEquals(facl.as_sddl(domsid), acl) >+ self.assertEqual(facl.as_sddl(domsid), acl) > posix_acl = smbd.get_sys_acl(self.tempdir, smb_acl.SMB_ACL_TYPE_ACCESS) > > LA_sid = security.dom_sid(str(domsid) + "-" + str(security.DOMAIN_RID_ADMINISTRATOR)) >@@ -473,65 +473,65 @@ class PosixAclMappingTests(SmbdBaseTests): > # configuration. When other environments have a broad range of > # groups mapped via passdb, we can relax some of these checks > (LA_uid, LA_type) = s4_passdb.sid_to_id(LA_sid) >- self.assertEquals(LA_type, idmap.ID_TYPE_UID) >+ self.assertEqual(LA_type, idmap.ID_TYPE_UID) > (BA_gid, BA_type) = s4_passdb.sid_to_id(BA_sid) >- self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(BA_type, idmap.ID_TYPE_BOTH) > (SO_gid, SO_type) = s4_passdb.sid_to_id(SO_sid) >- self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(SO_type, idmap.ID_TYPE_BOTH) > (SY_gid, SY_type) = s4_passdb.sid_to_id(SY_sid) >- self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(SO_type, idmap.ID_TYPE_BOTH) > (AU_gid, AU_type) = s4_passdb.sid_to_id(AU_sid) >- self.assertEquals(AU_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(AU_type, idmap.ID_TYPE_BOTH) > >- self.assertEquals(posix_acl.count, 13, self.print_posix_acl(posix_acl)) >+ self.assertEqual(posix_acl.count, 13, self.print_posix_acl(posix_acl)) > >- self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[0].a_perm, 7) >- self.assertEquals(posix_acl.acl[0].info.gid, BA_gid) >+ self.assertEqual(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[0].a_perm, 7) >+ self.assertEqual(posix_acl.acl[0].info.gid, BA_gid) > >- self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[1].a_perm, 7) >- self.assertEquals(posix_acl.acl[1].info.uid, LA_uid) >+ self.assertEqual(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[1].a_perm, 7) >+ self.assertEqual(posix_acl.acl[1].info.uid, LA_uid) > >- self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >- self.assertEquals(posix_acl.acl[2].a_perm, 0) >+ self.assertEqual(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >+ self.assertEqual(posix_acl.acl[2].a_perm, 0) > >- self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_USER_OBJ) >- self.assertEquals(posix_acl.acl[3].a_perm, 7) >+ self.assertEqual(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_USER_OBJ) >+ self.assertEqual(posix_acl.acl[3].a_perm, 7) > >- self.assertEquals(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[4].a_perm, 7) >- self.assertEquals(posix_acl.acl[4].info.uid, BA_gid) >+ self.assertEqual(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[4].a_perm, 7) >+ self.assertEqual(posix_acl.acl[4].info.uid, BA_gid) > >- self.assertEquals(posix_acl.acl[5].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >- self.assertEquals(posix_acl.acl[5].a_perm, 7) >+ self.assertEqual(posix_acl.acl[5].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >+ self.assertEqual(posix_acl.acl[5].a_perm, 7) > >- self.assertEquals(posix_acl.acl[6].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[6].a_perm, 5) >- self.assertEquals(posix_acl.acl[6].info.uid, SO_gid) >+ self.assertEqual(posix_acl.acl[6].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[6].a_perm, 5) >+ self.assertEqual(posix_acl.acl[6].info.uid, SO_gid) > >- self.assertEquals(posix_acl.acl[7].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[7].a_perm, 5) >- self.assertEquals(posix_acl.acl[7].info.gid, SO_gid) >+ self.assertEqual(posix_acl.acl[7].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[7].a_perm, 5) >+ self.assertEqual(posix_acl.acl[7].info.gid, SO_gid) > >- self.assertEquals(posix_acl.acl[8].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[8].a_perm, 7) >- self.assertEquals(posix_acl.acl[8].info.uid, SY_gid) >+ self.assertEqual(posix_acl.acl[8].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[8].a_perm, 7) >+ self.assertEqual(posix_acl.acl[8].info.uid, SY_gid) > >- self.assertEquals(posix_acl.acl[9].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[9].a_perm, 7) >- self.assertEquals(posix_acl.acl[9].info.gid, SY_gid) >+ self.assertEqual(posix_acl.acl[9].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[9].a_perm, 7) >+ self.assertEqual(posix_acl.acl[9].info.gid, SY_gid) > >- self.assertEquals(posix_acl.acl[10].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[10].a_perm, 5) >- self.assertEquals(posix_acl.acl[10].info.uid, AU_gid) >+ self.assertEqual(posix_acl.acl[10].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[10].a_perm, 5) >+ self.assertEqual(posix_acl.acl[10].info.uid, AU_gid) > >- self.assertEquals(posix_acl.acl[11].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[11].a_perm, 5) >- self.assertEquals(posix_acl.acl[11].info.gid, AU_gid) >+ self.assertEqual(posix_acl.acl[11].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[11].a_perm, 5) >+ self.assertEqual(posix_acl.acl[11].info.gid, AU_gid) > >- self.assertEquals(posix_acl.acl[12].a_type, smb_acl.SMB_ACL_MASK) >- self.assertEquals(posix_acl.acl[12].a_perm, 7) >+ self.assertEqual(posix_acl.acl[12].a_type, smb_acl.SMB_ACL_MASK) >+ self.assertEqual(posix_acl.acl[12].a_perm, 7) > > # check that it matches: > # user::rwx >@@ -551,7 +551,7 @@ class PosixAclMappingTests(SmbdBaseTests): > setntacl(self.lp, self.tempdir, acl, str(domsid), use_ntvfs=False, > session_info=session_info) > facl = getntacl(self.lp, self.tempdir) >- self.assertEquals(facl.as_sddl(domsid), acl) >+ self.assertEqual(facl.as_sddl(domsid), acl) > posix_acl = smbd.get_sys_acl(self.tempdir, smb_acl.SMB_ACL_TYPE_ACCESS) > > LA_sid = security.dom_sid(str(domsid) + "-" + str(security.DOMAIN_RID_ADMINISTRATOR)) >@@ -567,75 +567,75 @@ class PosixAclMappingTests(SmbdBaseTests): > # configuration. When other environments have a broad range of > # groups mapped via passdb, we can relax some of these checks > (LA_uid, LA_type) = s4_passdb.sid_to_id(LA_sid) >- self.assertEquals(LA_type, idmap.ID_TYPE_UID) >+ self.assertEqual(LA_type, idmap.ID_TYPE_UID) > (BA_gid, BA_type) = s4_passdb.sid_to_id(BA_sid) >- self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(BA_type, idmap.ID_TYPE_BOTH) > (SO_gid, SO_type) = s4_passdb.sid_to_id(SO_sid) >- self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(SO_type, idmap.ID_TYPE_BOTH) > (SY_gid, SY_type) = s4_passdb.sid_to_id(SY_sid) >- self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(SO_type, idmap.ID_TYPE_BOTH) > (AU_gid, AU_type) = s4_passdb.sid_to_id(AU_sid) >- self.assertEquals(AU_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(AU_type, idmap.ID_TYPE_BOTH) > (PA_gid, PA_type) = s4_passdb.sid_to_id(PA_sid) >- self.assertEquals(PA_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(PA_type, idmap.ID_TYPE_BOTH) > >- self.assertEquals(posix_acl.count, 15, self.print_posix_acl(posix_acl)) >+ self.assertEqual(posix_acl.count, 15, self.print_posix_acl(posix_acl)) > >- self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[0].a_perm, 7) >- self.assertEquals(posix_acl.acl[0].info.gid, BA_gid) >+ self.assertEqual(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[0].a_perm, 7) >+ self.assertEqual(posix_acl.acl[0].info.gid, BA_gid) > >- self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[1].a_perm, 7) >- self.assertEquals(posix_acl.acl[1].info.uid, LA_uid) >+ self.assertEqual(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[1].a_perm, 7) >+ self.assertEqual(posix_acl.acl[1].info.uid, LA_uid) > >- self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >- self.assertEquals(posix_acl.acl[2].a_perm, 0) >+ self.assertEqual(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >+ self.assertEqual(posix_acl.acl[2].a_perm, 0) > >- self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_USER_OBJ) >- self.assertEquals(posix_acl.acl[3].a_perm, 7) >+ self.assertEqual(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_USER_OBJ) >+ self.assertEqual(posix_acl.acl[3].a_perm, 7) > >- self.assertEquals(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[4].a_perm, 7) >- self.assertEquals(posix_acl.acl[4].info.uid, BA_gid) >+ self.assertEqual(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[4].a_perm, 7) >+ self.assertEqual(posix_acl.acl[4].info.uid, BA_gid) > >- self.assertEquals(posix_acl.acl[5].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >- self.assertEquals(posix_acl.acl[5].a_perm, 7) >+ self.assertEqual(posix_acl.acl[5].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >+ self.assertEqual(posix_acl.acl[5].a_perm, 7) > >- self.assertEquals(posix_acl.acl[6].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[6].a_perm, 5) >- self.assertEquals(posix_acl.acl[6].info.uid, SO_gid) >+ self.assertEqual(posix_acl.acl[6].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[6].a_perm, 5) >+ self.assertEqual(posix_acl.acl[6].info.uid, SO_gid) > >- self.assertEquals(posix_acl.acl[7].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[7].a_perm, 5) >- self.assertEquals(posix_acl.acl[7].info.gid, SO_gid) >+ self.assertEqual(posix_acl.acl[7].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[7].a_perm, 5) >+ self.assertEqual(posix_acl.acl[7].info.gid, SO_gid) > >- self.assertEquals(posix_acl.acl[8].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[8].a_perm, 7) >- self.assertEquals(posix_acl.acl[8].info.uid, SY_gid) >+ self.assertEqual(posix_acl.acl[8].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[8].a_perm, 7) >+ self.assertEqual(posix_acl.acl[8].info.uid, SY_gid) > >- self.assertEquals(posix_acl.acl[9].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[9].a_perm, 7) >- self.assertEquals(posix_acl.acl[9].info.gid, SY_gid) >+ self.assertEqual(posix_acl.acl[9].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[9].a_perm, 7) >+ self.assertEqual(posix_acl.acl[9].info.gid, SY_gid) > >- self.assertEquals(posix_acl.acl[10].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[10].a_perm, 5) >- self.assertEquals(posix_acl.acl[10].info.uid, AU_gid) >+ self.assertEqual(posix_acl.acl[10].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[10].a_perm, 5) >+ self.assertEqual(posix_acl.acl[10].info.uid, AU_gid) > >- self.assertEquals(posix_acl.acl[11].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[11].a_perm, 5) >- self.assertEquals(posix_acl.acl[11].info.gid, AU_gid) >+ self.assertEqual(posix_acl.acl[11].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[11].a_perm, 5) >+ self.assertEqual(posix_acl.acl[11].info.gid, AU_gid) > >- self.assertEquals(posix_acl.acl[12].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[12].a_perm, 7) >- self.assertEquals(posix_acl.acl[12].info.uid, PA_gid) >+ self.assertEqual(posix_acl.acl[12].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[12].a_perm, 7) >+ self.assertEqual(posix_acl.acl[12].info.uid, PA_gid) > >- self.assertEquals(posix_acl.acl[13].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[13].a_perm, 7) >- self.assertEquals(posix_acl.acl[13].info.gid, PA_gid) >+ self.assertEqual(posix_acl.acl[13].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[13].a_perm, 7) >+ self.assertEqual(posix_acl.acl[13].info.gid, PA_gid) > >- self.assertEquals(posix_acl.acl[14].a_type, smb_acl.SMB_ACL_MASK) >- self.assertEquals(posix_acl.acl[14].a_perm, 7) >+ self.assertEqual(posix_acl.acl[14].a_type, smb_acl.SMB_ACL_MASK) >+ self.assertEqual(posix_acl.acl[14].a_perm, 7) > > # check that it matches: > # user::rwx >@@ -657,7 +657,7 @@ class PosixAclMappingTests(SmbdBaseTests): > setntacl(self.lp, self.tempf, acl, str(domsid), use_ntvfs=False, > session_info=session_info) > facl = getntacl(self.lp, self.tempf) >- self.assertEquals(facl.as_sddl(domsid), acl) >+ self.assertEqual(facl.as_sddl(domsid), acl) > posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) > > nwrap_module_so_path = os.getenv('NSS_WRAPPER_MODULE_SO_PATH') >@@ -679,81 +679,81 @@ class PosixAclMappingTests(SmbdBaseTests): > # configuration. When other environments have a broad range of > # groups mapped via passdb, we can relax some of these checks > (LA_uid, LA_type) = s4_passdb.sid_to_id(LA_sid) >- self.assertEquals(LA_type, idmap.ID_TYPE_UID) >+ self.assertEqual(LA_type, idmap.ID_TYPE_UID) > (BA_gid, BA_type) = s4_passdb.sid_to_id(BA_sid) >- self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(BA_type, idmap.ID_TYPE_BOTH) > (SO_gid, SO_type) = s4_passdb.sid_to_id(SO_sid) >- self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(SO_type, idmap.ID_TYPE_BOTH) > (SY_gid, SY_type) = s4_passdb.sid_to_id(SY_sid) >- self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(SO_type, idmap.ID_TYPE_BOTH) > (AU_gid, AU_type) = s4_passdb.sid_to_id(AU_sid) >- self.assertEquals(AU_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(AU_type, idmap.ID_TYPE_BOTH) > (PA_gid, PA_type) = s4_passdb.sid_to_id(PA_sid) >- self.assertEquals(PA_type, idmap.ID_TYPE_BOTH) >+ self.assertEqual(PA_type, idmap.ID_TYPE_BOTH) > >- self.assertEquals(posix_acl.count, 15, self.print_posix_acl(posix_acl)) >+ self.assertEqual(posix_acl.count, 15, self.print_posix_acl(posix_acl)) > >- self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[0].a_perm, 7) >- self.assertEquals(posix_acl.acl[0].info.gid, BA_gid) >+ self.assertEqual(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[0].a_perm, 7) >+ self.assertEqual(posix_acl.acl[0].info.gid, BA_gid) > >- self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_USER) > if nwrap_winbind_active or session_info: >- self.assertEquals(posix_acl.acl[1].a_perm, 7) >+ self.assertEqual(posix_acl.acl[1].a_perm, 7) > else: >- self.assertEquals(posix_acl.acl[1].a_perm, 6) >- self.assertEquals(posix_acl.acl[1].info.uid, LA_uid) >+ self.assertEqual(posix_acl.acl[1].a_perm, 6) >+ self.assertEqual(posix_acl.acl[1].info.uid, LA_uid) > >- self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >- self.assertEquals(posix_acl.acl[2].a_perm, 0) >+ self.assertEqual(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) >+ self.assertEqual(posix_acl.acl[2].a_perm, 0) > >- self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_USER_OBJ) >+ self.assertEqual(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_USER_OBJ) > if nwrap_winbind_active or session_info: >- self.assertEquals(posix_acl.acl[3].a_perm, 7) >+ self.assertEqual(posix_acl.acl[3].a_perm, 7) > else: >- self.assertEquals(posix_acl.acl[3].a_perm, 6) >+ self.assertEqual(posix_acl.acl[3].a_perm, 6) > >- self.assertEquals(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[4].a_perm, 7) >- self.assertEquals(posix_acl.acl[4].info.uid, BA_gid) >+ self.assertEqual(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[4].a_perm, 7) >+ self.assertEqual(posix_acl.acl[4].info.uid, BA_gid) > >- self.assertEquals(posix_acl.acl[5].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >- self.assertEquals(posix_acl.acl[5].a_perm, 7) >+ self.assertEqual(posix_acl.acl[5].a_type, smb_acl.SMB_ACL_GROUP_OBJ) >+ self.assertEqual(posix_acl.acl[5].a_perm, 7) > >- self.assertEquals(posix_acl.acl[6].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[6].a_perm, 5) >- self.assertEquals(posix_acl.acl[6].info.uid, SO_gid) >+ self.assertEqual(posix_acl.acl[6].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[6].a_perm, 5) >+ self.assertEqual(posix_acl.acl[6].info.uid, SO_gid) > >- self.assertEquals(posix_acl.acl[7].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[7].a_perm, 5) >- self.assertEquals(posix_acl.acl[7].info.gid, SO_gid) >+ self.assertEqual(posix_acl.acl[7].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[7].a_perm, 5) >+ self.assertEqual(posix_acl.acl[7].info.gid, SO_gid) > >- self.assertEquals(posix_acl.acl[8].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[8].a_perm, 7) >- self.assertEquals(posix_acl.acl[8].info.uid, SY_gid) >+ self.assertEqual(posix_acl.acl[8].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[8].a_perm, 7) >+ self.assertEqual(posix_acl.acl[8].info.uid, SY_gid) > >- self.assertEquals(posix_acl.acl[9].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[9].a_perm, 7) >- self.assertEquals(posix_acl.acl[9].info.gid, SY_gid) >+ self.assertEqual(posix_acl.acl[9].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[9].a_perm, 7) >+ self.assertEqual(posix_acl.acl[9].info.gid, SY_gid) > >- self.assertEquals(posix_acl.acl[10].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[10].a_perm, 5) >- self.assertEquals(posix_acl.acl[10].info.uid, AU_gid) >+ self.assertEqual(posix_acl.acl[10].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[10].a_perm, 5) >+ self.assertEqual(posix_acl.acl[10].info.uid, AU_gid) > >- self.assertEquals(posix_acl.acl[11].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[11].a_perm, 5) >- self.assertEquals(posix_acl.acl[11].info.gid, AU_gid) >+ self.assertEqual(posix_acl.acl[11].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[11].a_perm, 5) >+ self.assertEqual(posix_acl.acl[11].info.gid, AU_gid) > >- self.assertEquals(posix_acl.acl[12].a_type, smb_acl.SMB_ACL_USER) >- self.assertEquals(posix_acl.acl[12].a_perm, 7) >- self.assertEquals(posix_acl.acl[12].info.uid, PA_gid) >+ self.assertEqual(posix_acl.acl[12].a_type, smb_acl.SMB_ACL_USER) >+ self.assertEqual(posix_acl.acl[12].a_perm, 7) >+ self.assertEqual(posix_acl.acl[12].info.uid, PA_gid) > >- self.assertEquals(posix_acl.acl[13].a_type, smb_acl.SMB_ACL_GROUP) >- self.assertEquals(posix_acl.acl[13].a_perm, 7) >- self.assertEquals(posix_acl.acl[13].info.gid, PA_gid) >+ self.assertEqual(posix_acl.acl[13].a_type, smb_acl.SMB_ACL_GROUP) >+ self.assertEqual(posix_acl.acl[13].a_perm, 7) >+ self.assertEqual(posix_acl.acl[13].info.gid, PA_gid) > >- self.assertEquals(posix_acl.acl[14].a_type, smb_acl.SMB_ACL_MASK) >- self.assertEquals(posix_acl.acl[14].a_perm, 7) >+ self.assertEqual(posix_acl.acl[14].a_type, smb_acl.SMB_ACL_MASK) >+ self.assertEqual(posix_acl.acl[14].a_perm, 7) > > # check that it matches: > # user::rwx >diff --git a/python/samba/tests/prefork_restart.py b/python/samba/tests/prefork_restart.py >index 5233ca1f805..288f18d8736 100644 >--- a/python/samba/tests/prefork_restart.py >+++ b/python/samba/tests/prefork_restart.py >@@ -122,7 +122,7 @@ class PreforkProcessRestartTests(TestCase): > > def rpc_echo(self): > conn = echo.rpcecho("ncalrpc:", self.get_loadparm()) >- self.assertEquals([1, 2, 3], conn.EchoData([1, 2, 3])) >+ self.assertEqual([1, 2, 3], conn.EchoData([1, 2, 3])) > > def netlogon(self): > server = os.environ["SERVER"] >@@ -227,15 +227,15 @@ class PreforkProcessRestartTests(TestCase): > self.assertIsNotNone(new_pid) > > # check that the pid has not changed >- self.assertEquals(pid, new_pid) >+ self.assertEqual(pid, new_pid) > > # check that the worker processes have restarted > new_workers = self.get_worker_pids("ldap", NUM_WORKERS) > # process 0 should have a new pid the others should be unchanged > self.assertNotEquals(workers[0], new_workers[0]) >- self.assertEquals(workers[1], new_workers[1]) >- self.assertEquals(workers[2], new_workers[2]) >- self.assertEquals(workers[3], new_workers[3]) >+ self.assertEqual(workers[1], new_workers[1]) >+ self.assertEqual(workers[2], new_workers[2]) >+ self.assertEqual(workers[3], new_workers[3]) > > # check that the previous server entries have been removed. > self.check_for_duplicate_processes() >@@ -270,7 +270,7 @@ class PreforkProcessRestartTests(TestCase): > self.assertIsNotNone(new_pid) > > # check that the pid has not changed >- self.assertEquals(pid, new_pid) >+ self.assertEqual(pid, new_pid) > > # check that the worker processes have restarted > new_workers = self.get_worker_pids("ldap", NUM_WORKERS) >@@ -344,15 +344,15 @@ class PreforkProcessRestartTests(TestCase): > self.assertIsNotNone(new_pid) > > # check that the pid has not changed >- self.assertEquals(pid, new_pid) >+ self.assertEqual(pid, new_pid) > > # check that the worker processes have restarted > new_workers = self.get_worker_pids("rpc", NUM_WORKERS) > # process 0 should have a new pid the others should be unchanged > self.assertNotEquals(workers[0], new_workers[0]) >- self.assertEquals(workers[1], new_workers[1]) >- self.assertEquals(workers[2], new_workers[2]) >- self.assertEquals(workers[3], new_workers[3]) >+ self.assertEqual(workers[1], new_workers[1]) >+ self.assertEqual(workers[2], new_workers[2]) >+ self.assertEqual(workers[3], new_workers[3]) > > # check that the previous server entries have been removed. > self.check_for_duplicate_processes() >@@ -387,7 +387,7 @@ class PreforkProcessRestartTests(TestCase): > self.assertIsNotNone(new_pid) > > # check that the pid has not changed >- self.assertEquals(pid, new_pid) >+ self.assertEqual(pid, new_pid) > > # check that the worker processes have restarted > new_workers = self.get_worker_pids("rpc", NUM_WORKERS) >diff --git a/python/samba/tests/provision.py b/python/samba/tests/provision.py >index f51098629d8..43ad373b2ca 100644 >--- a/python/samba/tests/provision.py >+++ b/python/samba/tests/provision.py >@@ -66,7 +66,7 @@ class ProvisionTestCase(samba.tests.TestCaseInTempDir): > paths.dns_keytab = "no.dns.keytab" > ldb = setup_secretsdb(paths, None, None, lp=env_loadparm()) > try: >- self.assertEquals("LSA Secrets", >+ self.assertEqual("LSA Secrets", > ldb.searchone(basedn="CN=LSA Secrets", attribute="CN").decode('utf8')) > finally: > del ldb >@@ -84,14 +84,14 @@ class FindNssTests(TestCase): > self.assertRaises(KeyError, findnss, x, []) > > def test_first(self): >- self.assertEquals("bla", findnss(lambda x: "bla", ["bla"])) >+ self.assertEqual("bla", findnss(lambda x: "bla", ["bla"])) > > def test_skip_first(self): > def x(y): > if y != "bla": > raise KeyError > return "ha" >- self.assertEquals("ha", findnss(x, ["bloe", "bla"])) >+ self.assertEqual("ha", findnss(x, ["bloe", "bla"])) > > > class Disabled(object): >@@ -124,22 +124,22 @@ class Disabled(object): > class SanitizeServerRoleTests(TestCase): > > def test_same(self): >- self.assertEquals("standalone server", >+ self.assertEqual("standalone server", > sanitize_server_role("standalone server")) >- self.assertEquals("member server", >+ self.assertEqual("member server", > sanitize_server_role("member server")) > > def test_invalid(self): > self.assertRaises(ValueError, sanitize_server_role, "foo") > > def test_valid(self): >- self.assertEquals( >+ self.assertEqual( > "standalone server", > sanitize_server_role("ROLE_STANDALONE")) >- self.assertEquals( >+ self.assertEqual( > "standalone server", > sanitize_server_role("standalone")) >- self.assertEquals( >+ self.assertEqual( > "active directory domain controller", > sanitize_server_role("domain controller")) > >@@ -174,7 +174,7 @@ class ProvisionResultTests(TestCase): > def test_basic_report_logger(self): > result = self.base_result() > entries = self.report_logger(result) >- self.assertEquals(entries, [ >+ self.assertEqual(entries, [ > ('INFO', 'Once the above files are installed, your Samba AD server ' > 'will be ready to use'), > ('INFO', 'Server Role: domain controller'), >@@ -188,14 +188,14 @@ class ProvisionResultTests(TestCase): > result.adminpass_generated = True > result.adminpass = "geheim" > entries = self.report_logger(result) >- self.assertEquals(entries[1], >+ self.assertEqual(entries[1], > ("INFO", 'Admin password: geheim')) > > > class DetermineNetbiosNameTests(TestCase): > > def test_limits_to_15(self): >- self.assertEquals("A" * 15, determine_netbios_name("a" * 30)) >+ self.assertEqual("A" * 15, determine_netbios_name("a" * 30)) > > def test_strips_invalid(self): >- self.assertEquals("BLABLA", determine_netbios_name("bla/bla")) >+ self.assertEqual("BLABLA", determine_netbios_name("bla/bla")) >diff --git a/python/samba/tests/registry.py b/python/samba/tests/registry.py >index f6af5f7bd15..51b280a6348 100644 >--- a/python/samba/tests/registry.py >+++ b/python/samba/tests/registry.py >@@ -27,11 +27,11 @@ from subprocess import Popen, PIPE > class HelperTests(samba.tests.TestCase): > > def test_predef_to_name(self): >- self.assertEquals("HKEY_LOCAL_MACHINE", >+ self.assertEqual("HKEY_LOCAL_MACHINE", > registry.get_predef_name(0x80000002)) > > def test_str_regtype(self): >- self.assertEquals("REG_DWORD", registry.str_regtype(4)) >+ self.assertEqual("REG_DWORD", registry.str_regtype(4)) > > > class HiveTests(samba.tests.TestCaseInTempDir): >diff --git a/python/samba/tests/s3idmapdb.py b/python/samba/tests/s3idmapdb.py >index e3e23469493..b8d936f056f 100644 >--- a/python/samba/tests/s3idmapdb.py >+++ b/python/samba/tests/s3idmapdb.py >@@ -35,22 +35,22 @@ class IdmapDbTestCase(TestCase): > "winbindd_idmap")) > > def test_user_hwm(self): >- self.assertEquals(10000, self.idmapdb.get_user_hwm()) >+ self.assertEqual(10000, self.idmapdb.get_user_hwm()) > > def test_group_hwm(self): >- self.assertEquals(10002, self.idmapdb.get_group_hwm()) >+ self.assertEqual(10002, self.idmapdb.get_group_hwm()) > > def test_uids(self): >- self.assertEquals(1, len(list(self.idmapdb.uids()))) >+ self.assertEqual(1, len(list(self.idmapdb.uids()))) > > def test_gids(self): >- self.assertEquals(3, len(list(self.idmapdb.gids()))) >+ self.assertEqual(3, len(list(self.idmapdb.gids()))) > > def test_get_user_sid(self): >- self.assertEquals(b"S-1-5-21-58189338-3053988021-627566699-501", self.idmapdb.get_user_sid(65534)) >+ self.assertEqual(b"S-1-5-21-58189338-3053988021-627566699-501", self.idmapdb.get_user_sid(65534)) > > def test_get_group_sid(self): >- self.assertEquals(b"S-1-5-21-2447931902-1787058256-3961074038-3007", self.idmapdb.get_group_sid(10001)) >+ self.assertEqual(b"S-1-5-21-2447931902-1787058256-3961074038-3007", self.idmapdb.get_group_sid(10001)) > > def tearDown(self): > self.idmapdb.close() >diff --git a/python/samba/tests/s3param.py b/python/samba/tests/s3param.py >index bdbdbced5e0..232e79bbd5f 100644 >--- a/python/samba/tests/s3param.py >+++ b/python/samba/tests/s3param.py >@@ -44,7 +44,7 @@ class ParamTestCase(TestCaseInTempDir): > super(ParamTestCase, self).tearDown() > > def test_param(self): >- self.assertEquals("BEDWYR", self.lp.get("netbios name")) >- self.assertEquals("SAMBA", self.lp.get("workgroup")) >- self.assertEquals("USER", self.lp.get("security")) >- self.assertEquals("/mnt/cd1", self.lp.get("path", "cd1")) >+ self.assertEqual("BEDWYR", self.lp.get("netbios name")) >+ self.assertEqual("SAMBA", self.lp.get("workgroup")) >+ self.assertEqual("USER", self.lp.get("security")) >+ self.assertEqual("/mnt/cd1", self.lp.get("path", "cd1")) >diff --git a/python/samba/tests/s3passdb.py b/python/samba/tests/s3passdb.py >index 7b0f34ebca0..734ca96110a 100644 >--- a/python/samba/tests/s3passdb.py >+++ b/python/samba/tests/s3passdb.py >@@ -54,70 +54,70 @@ class PassdbTestCase(TestCaseInTempDir): > > def test_policy(self): > policy = self.pdb.get_account_policy() >- self.assertEquals(0, policy['bad lockout attempt']) >- self.assertEquals(-1, policy['disconnect time']) >- self.assertEquals(0, policy['lockout duration']) >- self.assertEquals(999999999, policy['maximum password age']) >- self.assertEquals(0, policy['minimum password age']) >- self.assertEquals(5, policy['min password length']) >- self.assertEquals(0, policy['password history']) >- self.assertEquals(0, policy['refuse machine password change']) >- self.assertEquals(0, policy['reset count minutes']) >- self.assertEquals(0, policy['user must logon to change password']) >+ self.assertEqual(0, policy['bad lockout attempt']) >+ self.assertEqual(-1, policy['disconnect time']) >+ self.assertEqual(0, policy['lockout duration']) >+ self.assertEqual(999999999, policy['maximum password age']) >+ self.assertEqual(0, policy['minimum password age']) >+ self.assertEqual(5, policy['min password length']) >+ self.assertEqual(0, policy['password history']) >+ self.assertEqual(0, policy['refuse machine password change']) >+ self.assertEqual(0, policy['reset count minutes']) >+ self.assertEqual(0, policy['user must logon to change password']) > > def test_get_sid(self): > domain_sid = passdb.get_global_sam_sid() >- self.assertEquals(dom_sid("S-1-5-21-2470180966-3899876309-2637894779"), domain_sid) >+ self.assertEqual(dom_sid("S-1-5-21-2470180966-3899876309-2637894779"), domain_sid) > > def test_usernames(self): > userlist = self.pdb.search_users(0) >- self.assertEquals(3, len(userlist)) >+ self.assertEqual(3, len(userlist)) > > def test_getuser(self): > user = self.pdb.getsampwnam("root") > >- self.assertEquals(16, user.acct_ctrl) >- self.assertEquals("", user.acct_desc) >- self.assertEquals(0, user.bad_password_count) >- self.assertEquals(0, user.bad_password_time) >- self.assertEquals(0, user.code_page) >- self.assertEquals(0, user.country_code) >- self.assertEquals("", user.dir_drive) >- self.assertEquals("BEDWYR", user.domain) >- self.assertEquals("root", user.full_name) >- self.assertEquals(dom_sid('S-1-5-21-2470180966-3899876309-2637894779-513'), user.group_sid) >- self.assertEquals("\\\\BEDWYR\\root", user.home_dir) >- self.assertEquals([-1 for i in range(21)], user.hours) >- self.assertEquals(21, user.hours_len) >- self.assertEquals(9223372036854775807, user.kickoff_time) >- self.assertEquals(None, user.lanman_passwd) >- self.assertEquals(9223372036854775807, user.logoff_time) >- self.assertEquals(0, user.logon_count) >- self.assertEquals(168, user.logon_divs) >- self.assertEquals("", user.logon_script) >- self.assertEquals(0, user.logon_time) >- self.assertEquals("", user.munged_dial) >- self.assertEquals(b'\x87\x8d\x80\x14`l\xda)gzD\xef\xa15?\xc7', user.nt_passwd) >- self.assertEquals("", user.nt_username) >- self.assertEquals(1125418267, user.pass_can_change_time) >- self.assertEquals(1125418267, user.pass_last_set_time) >- self.assertEquals(2125418266, user.pass_must_change_time) >- self.assertEquals(None, user.plaintext_passwd) >- self.assertEquals("\\\\BEDWYR\\root\\profile", user.profile_path) >- self.assertEquals(None, user.pw_history) >- self.assertEquals(dom_sid("S-1-5-21-2470180966-3899876309-2637894779-1000"), user.user_sid) >- self.assertEquals("root", user.username) >- self.assertEquals("", user.workstations) >+ self.assertEqual(16, user.acct_ctrl) >+ self.assertEqual("", user.acct_desc) >+ self.assertEqual(0, user.bad_password_count) >+ self.assertEqual(0, user.bad_password_time) >+ self.assertEqual(0, user.code_page) >+ self.assertEqual(0, user.country_code) >+ self.assertEqual("", user.dir_drive) >+ self.assertEqual("BEDWYR", user.domain) >+ self.assertEqual("root", user.full_name) >+ self.assertEqual(dom_sid('S-1-5-21-2470180966-3899876309-2637894779-513'), user.group_sid) >+ self.assertEqual("\\\\BEDWYR\\root", user.home_dir) >+ self.assertEqual([-1 for i in range(21)], user.hours) >+ self.assertEqual(21, user.hours_len) >+ self.assertEqual(9223372036854775807, user.kickoff_time) >+ self.assertEqual(None, user.lanman_passwd) >+ self.assertEqual(9223372036854775807, user.logoff_time) >+ self.assertEqual(0, user.logon_count) >+ self.assertEqual(168, user.logon_divs) >+ self.assertEqual("", user.logon_script) >+ self.assertEqual(0, user.logon_time) >+ self.assertEqual("", user.munged_dial) >+ self.assertEqual(b'\x87\x8d\x80\x14`l\xda)gzD\xef\xa15?\xc7', user.nt_passwd) >+ self.assertEqual("", user.nt_username) >+ self.assertEqual(1125418267, user.pass_can_change_time) >+ self.assertEqual(1125418267, user.pass_last_set_time) >+ self.assertEqual(2125418266, user.pass_must_change_time) >+ self.assertEqual(None, user.plaintext_passwd) >+ self.assertEqual("\\\\BEDWYR\\root\\profile", user.profile_path) >+ self.assertEqual(None, user.pw_history) >+ self.assertEqual(dom_sid("S-1-5-21-2470180966-3899876309-2637894779-1000"), user.user_sid) >+ self.assertEqual("root", user.username) >+ self.assertEqual("", user.workstations) > > def test_group_length(self): > grouplist = self.pdb.enum_group_mapping() >- self.assertEquals(13, len(grouplist)) >+ self.assertEqual(13, len(grouplist)) > > def test_get_group(self): > group = self.pdb.getgrsid(dom_sid("S-1-5-32-544")) >- self.assertEquals("Administrators", group.nt_name) >- self.assertEquals(-1, group.gid) >- self.assertEquals(5, group.sid_name_use) >+ self.assertEqual("Administrators", group.nt_name) >+ self.assertEqual(-1, group.gid) >+ self.assertEqual(5, group.sid_name_use) > > def test_groupsids(self): > grouplist = self.pdb.enum_group_mapping() >@@ -134,5 +134,5 @@ class PassdbTestCase(TestCaseInTempDir): > > def test_alias_length(self): > aliaslist = self.pdb.search_aliases() >- self.assertEquals(1, len(aliaslist)) >- self.assertEquals("Jelmers NT Group", aliaslist[0]['account_name']) >+ self.assertEqual(1, len(aliaslist)) >+ self.assertEqual("Jelmers NT Group", aliaslist[0]['account_name']) >diff --git a/python/samba/tests/s3registry.py b/python/samba/tests/s3registry.py >index e049e9de927..5e9004e4e1d 100644 >--- a/python/samba/tests/s3registry.py >+++ b/python/samba/tests/s3registry.py >@@ -39,15 +39,15 @@ class RegistryTestCase(TestCase): > super(RegistryTestCase, self).tearDown() > > def test_length(self): >- self.assertEquals(28, len(self.registry)) >+ self.assertEqual(28, len(self.registry)) > > def test_keys(self): > self.assertTrue(b"HKLM" in self.registry.keys()) > > def test_subkeys(self): >- self.assertEquals([b"SOFTWARE", b"SYSTEM"], self.registry.subkeys(b"HKLM")) >+ self.assertEqual([b"SOFTWARE", b"SYSTEM"], self.registry.subkeys(b"HKLM")) > > def test_values(self): >- self.assertEquals({b'DisplayName': (1, b'E\x00v\x00e\x00n\x00t\x00 \x00L\x00o\x00g\x00\x00\x00'), >+ self.assertEqual({b'DisplayName': (1, b'E\x00v\x00e\x00n\x00t\x00 \x00L\x00o\x00g\x00\x00\x00'), > b'ErrorControl': (4, b'\x01\x00\x00\x00')}, > self.registry.values(b"HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/EVENTLOG")) >diff --git a/python/samba/tests/s3windb.py b/python/samba/tests/s3windb.py >index 1ad9b3487ca..b92105c46b4 100644 >--- a/python/samba/tests/s3windb.py >+++ b/python/samba/tests/s3windb.py >@@ -35,7 +35,7 @@ class WinsDatabaseTestCase(TestCase): > self.winsdb = WinsDatabase(os.path.join(DATADIR, "wins.dat")) > > def test_length(self): >- self.assertEquals(22, len(self.winsdb)) >+ self.assertEqual(22, len(self.winsdb)) > > def test_first_entry(self): > self.assertEqual((1124185120, ["192.168.1.5"], 0x64), self.winsdb["ADMINISTRATOR#03"]) >diff --git a/python/samba/tests/samba3sam.py b/python/samba/tests/samba3sam.py >index 591cfebbdde..17bb4a7b7bc 100644 >--- a/python/samba/tests/samba3sam.py >+++ b/python/samba/tests/samba3sam.py >@@ -133,7 +133,7 @@ class MapBaseTestCase(TestCaseInTempDir): > sid_obj1 = samba.ndr.ndr_unpack(samba.dcerpc.security.dom_sid, > ndr_sid[0]) > sid_obj2 = samba.dcerpc.security.dom_sid(text) >- self.assertEquals(sid_obj1, sid_obj2) >+ self.assertEqual(sid_obj1, sid_obj2) > > > class Samba3SamTestCase(MapBaseTestCase): >@@ -153,36 +153,36 @@ class Samba3SamTestCase(MapBaseTestCase): > def test_search_non_mapped(self): > """Looking up by non-mapped attribute""" > msg = self.ldb.search(expression="(cn=Administrator)") >- self.assertEquals(len(msg), 1) >- self.assertEquals(str(msg[0]["cn"]), "Administrator") >+ self.assertEqual(len(msg), 1) >+ self.assertEqual(str(msg[0]["cn"]), "Administrator") > > def test_search_mapped(self): > """Looking up by mapped attribute""" > msg = self.ldb.search(expression="(name=Backup Operators)") >- self.assertEquals(len(msg), 1) >- self.assertEquals(str(msg[0]["name"]), "Backup Operators") >+ self.assertEqual(len(msg), 1) >+ self.assertEqual(str(msg[0]["name"]), "Backup Operators") > > def test_old_name_of_renamed(self): > """Looking up by old name of renamed attribute""" > msg = self.ldb.search(expression="(displayName=Backup Operators)") >- self.assertEquals(len(msg), 0) >+ self.assertEqual(len(msg), 0) > > def test_mapped_containing_sid(self): > """Looking up mapped entry containing SID""" > msg = self.ldb.search(expression="(cn=Replicator)") >- self.assertEquals(len(msg), 1) >- self.assertEquals(str(msg[0].dn), >+ self.assertEqual(len(msg), 1) >+ self.assertEqual(str(msg[0].dn), > "cn=Replicator,ou=Groups,dc=vernstok,dc=nl") > self.assertTrue("objectSid" in msg[0]) > self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-1052", > msg[0]["objectSid"]) > oc = set(msg[0]["objectClass"]) >- self.assertEquals(oc, set([b"group"])) >+ self.assertEqual(oc, set([b"group"])) > > def test_search_by_objclass(self): > """Looking up by objectClass""" > msg = self.ldb.search(expression="(|(objectClass=user)(cn=Administrator))") >- self.assertEquals(set([str(m.dn) for m in msg]), >+ self.assertEqual(set([str(m.dn) for m in msg]), > set(["unixName=Administrator,ou=Users,dc=vernstok,dc=nl", > "unixName=nobody,ou=Users,dc=vernstok,dc=nl"])) > >@@ -205,10 +205,10 @@ class Samba3SamTestCase(MapBaseTestCase): > msg = self.ldb.search(expression="(cn=Foo)", base="cn=Foo", > scope=SCOPE_BASE, > attrs=['foo', 'blah', 'cn', 'showInAdvancedViewOnly']) >- self.assertEquals(len(msg), 1) >- self.assertEquals(str(msg[0]["showInAdvancedViewOnly"]), "TRUE") >- self.assertEquals(str(msg[0]["foo"]), "bar") >- self.assertEquals(str(msg[0]["blah"]), "Blie") >+ self.assertEqual(len(msg), 1) >+ self.assertEqual(str(msg[0]["showInAdvancedViewOnly"]), "TRUE") >+ self.assertEqual(str(msg[0]["foo"]), "bar") >+ self.assertEqual(str(msg[0]["blah"]), "Blie") > > # Adding record that will be mapped > self.ldb.add({"dn": "cn=Niemand,cn=Users,dc=vernstok,dc=nl", >@@ -220,33 +220,33 @@ class Samba3SamTestCase(MapBaseTestCase): > # Checking for existence of record (remote) > msg = self.ldb.search(expression="(unixName=bin)", > attrs=['unixName', 'cn', 'dn', 'sambaUnicodePwd']) >- self.assertEquals(len(msg), 1) >- self.assertEquals(str(msg[0]["cn"]), "Niemand") >- self.assertEquals(str(msg[0]["sambaUnicodePwd"]), "geheim") >+ self.assertEqual(len(msg), 1) >+ self.assertEqual(str(msg[0]["cn"]), "Niemand") >+ self.assertEqual(str(msg[0]["sambaUnicodePwd"]), "geheim") > > # Checking for existence of record (local && remote) > msg = self.ldb.search(expression="(&(unixName=bin)(sambaUnicodePwd=geheim))", > attrs=['unixName', 'cn', 'dn', 'sambaUnicodePwd']) >- self.assertEquals(len(msg), 1) # TODO: should check with more records >- self.assertEquals(str(msg[0]["cn"]), "Niemand") >- self.assertEquals(str(msg[0]["unixName"]), "bin") >- self.assertEquals(str(msg[0]["sambaUnicodePwd"]), "geheim") >+ self.assertEqual(len(msg), 1) # TODO: should check with more records >+ self.assertEqual(str(msg[0]["cn"]), "Niemand") >+ self.assertEqual(str(msg[0]["unixName"]), "bin") >+ self.assertEqual(str(msg[0]["sambaUnicodePwd"]), "geheim") > > # Checking for existence of record (local || remote) > msg = self.ldb.search(expression="(|(unixName=bin)(sambaUnicodePwd=geheim))", > attrs=['unixName', 'cn', 'dn', 'sambaUnicodePwd']) > # print "got %d replies" % len(msg) >- self.assertEquals(len(msg), 1) # TODO: should check with more records >- self.assertEquals(str(msg[0]["cn"]), "Niemand") >- self.assertEquals(str(msg[0]["unixName"]), "bin") >- self.assertEquals(str(msg[0]["sambaUnicodePwd"]), "geheim") >+ self.assertEqual(len(msg), 1) # TODO: should check with more records >+ self.assertEqual(str(msg[0]["cn"]), "Niemand") >+ self.assertEqual(str(msg[0]["unixName"]), "bin") >+ self.assertEqual(str(msg[0]["sambaUnicodePwd"]), "geheim") > > # Checking for data in destination database > msg = self.samba3.db.search(expression="(cn=Niemand)") > self.assertTrue(len(msg) >= 1) >- self.assertEquals(str(msg[0]["sambaSID"]), >+ self.assertEqual(str(msg[0]["sambaSID"]), > "S-1-5-21-4231626423-2410014848-2360679739-2001") >- self.assertEquals(str(msg[0]["displayName"]), "Niemand") >+ self.assertEqual(str(msg[0]["displayName"]), "Niemand") > > # Adding attribute... > self.ldb.modify_ldif(""" >@@ -259,8 +259,8 @@ description: Blah > # Checking whether changes are still there... > msg = self.ldb.search(expression="(cn=Niemand)") > self.assertTrue(len(msg) >= 1) >- self.assertEquals(str(msg[0]["cn"]), "Niemand") >- self.assertEquals(str(msg[0]["description"]), "Blah") >+ self.assertEqual(str(msg[0]["cn"]), "Niemand") >+ self.assertEqual(str(msg[0]["description"]), "Blah") > > # Modifying attribute... > self.ldb.modify_ldif(""" >@@ -273,7 +273,7 @@ description: Blie > # Checking whether changes are still there... > msg = self.ldb.search(expression="(cn=Niemand)") > self.assertTrue(len(msg) >= 1) >- self.assertEquals(str(msg[0]["description"]), "Blie") >+ self.assertEqual(str(msg[0]["description"]), "Blie") > > # Deleting attribute... > self.ldb.modify_ldif(""" >@@ -293,8 +293,8 @@ delete: description > > # Checking whether DN has changed... > msg = self.ldb.search(expression="(cn=Niemand2)") >- self.assertEquals(len(msg), 1) >- self.assertEquals(str(msg[0].dn), >+ self.assertEqual(len(msg), 1) >+ self.assertEqual(str(msg[0].dn), > "cn=Niemand2,cn=Users,dc=vernstok,dc=nl") > > # Deleting record... >@@ -302,7 +302,7 @@ delete: description > > # Checking whether record is gone... > msg = self.ldb.search(expression="(cn=Niemand2)") >- self.assertEquals(len(msg), 0) >+ self.assertEqual(len(msg), 0) > > > class MapTestCase(MapBaseTestCase): >@@ -409,77 +409,77 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-1052 > dn = self.samba4.dn("cn=A") > res = self.ldb.search(dn, scope=SCOPE_BASE, > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[0]["lastLogon"]), "x") > > # Search remote record by remote DN > dn = self.samba3.dn("cn=A") > res = self.samba3.db.search(dn, scope=SCOPE_BASE, > attrs=["dnsHostName", "lastLogon", "sambaLogonTime"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) > self.assertTrue("dnsHostName" not in res[0]) > self.assertTrue("lastLogon" not in res[0]) >- self.assertEquals(str(res[0]["sambaLogonTime"]), "x") >+ self.assertEqual(str(res[0]["sambaLogonTime"]), "x") > > # Search split record by local DN > dn = self.samba4.dn("cn=X") > res = self.ldb.search(dn, scope=SCOPE_BASE, > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >- self.assertEquals(str(res[0]["dnsHostName"]), "x") >- self.assertEquals(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) >+ self.assertEqual(str(res[0]["dnsHostName"]), "x") >+ self.assertEqual(str(res[0]["lastLogon"]), "x") > > # Search split record by remote DN > dn = self.samba3.dn("cn=X") > res = self.samba3.db.search(dn, scope=SCOPE_BASE, > attrs=["dnsHostName", "lastLogon", "sambaLogonTime"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) > self.assertTrue("dnsHostName" not in res[0]) > self.assertTrue("lastLogon" not in res[0]) >- self.assertEquals(str(res[0]["sambaLogonTime"]), "x") >+ self.assertEqual(str(res[0]["sambaLogonTime"]), "x") > > # Testing search by attribute > > # Search by ignored attribute > res = self.ldb.search(expression="(revision=x)", scope=SCOPE_DEFAULT, > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 2) >+ self.assertEqual(len(res), 2) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) >- self.assertEquals(str(res[0]["dnsHostName"]), "x") >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y")) >- self.assertEquals(str(res[1]["dnsHostName"]), "y") >- self.assertEquals(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=X")) >+ self.assertEqual(str(res[0]["dnsHostName"]), "x") >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=Y")) >+ self.assertEqual(str(res[1]["dnsHostName"]), "y") >+ self.assertEqual(str(res[1]["lastLogon"]), "y") > > # Search by kept attribute > res = self.ldb.search(expression="(description=y)", > scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 2) >+ self.assertEqual(len(res), 2) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=C")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "z") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Z")) >- self.assertEquals(str(res[1]["dnsHostName"]), "z") >- self.assertEquals(str(res[1]["lastLogon"]), "z") >+ self.assertEqual(str(res[0]["lastLogon"]), "z") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=Z")) >+ self.assertEqual(str(res[1]["dnsHostName"]), "z") >+ self.assertEqual(str(res[1]["lastLogon"]), "z") > > # Search by renamed attribute > res = self.ldb.search(expression="(badPwdCount=x)", scope=SCOPE_DEFAULT, > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 2) >+ self.assertEqual(len(res), 2) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=B")) > self.assertTrue("dnsHostName" not in res[1]) >- self.assertEquals(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[1]["lastLogon"]), "y") > > # Search by converted attribute > # TODO: >@@ -487,17 +487,17 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-1052 > # errors, letting the search fail with no results. > # res = self.ldb.search("(objectSid=S-1-5-21-4231626423-2410014848-2360679739-1052)", scope=SCOPE_DEFAULT, attrs) > res = self.ldb.search(expression="(objectSid=*)", base=None, scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon", "objectSid"]) >- self.assertEquals(len(res), 4) >+ self.assertEqual(len(res), 4) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) >- self.assertEquals(str(res[1]["dnsHostName"]), "x") >- self.assertEquals(str(res[1]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=X")) >+ self.assertEqual(str(res[1]["dnsHostName"]), "x") >+ self.assertEqual(str(res[1]["lastLogon"]), "x") > self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-1052", > res[1]["objectSid"]) > self.assertTrue("objectSid" in res[1]) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[0]["lastLogon"]), "x") > self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-1052", > res[0]["objectSid"]) > self.assertTrue("objectSid" in res[0]) >@@ -507,11 +507,11 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-1052 > # a `convert_operator' by enumerating the remote db. > res = self.ldb.search(expression="(primaryGroupID=512)", > attrs=["dnsHostName", "lastLogon", "primaryGroupID"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[0]["primaryGroupID"]), "512") >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[0]["primaryGroupID"]), "512") > > # Note that Xs "objectSid" seems to be fine in the previous search for > # "objectSid"... >@@ -527,284 +527,284 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-1052 > # Search by remote name of renamed attribute */ > res = self.ldb.search(expression="(sambaBadPasswordCount=*)", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # Search by objectClass > attrs = ["dnsHostName", "lastLogon", "objectClass"] > res = self.ldb.search(expression="(objectClass=user)", attrs=attrs) >- self.assertEquals(len(res), 2) >+ self.assertEqual(len(res), 2) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[0]["objectClass"][0]), "user") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) >- self.assertEquals(str(res[1]["dnsHostName"]), "x") >- self.assertEquals(str(res[1]["lastLogon"]), "x") >- self.assertEquals(str(res[1]["objectClass"][0]), "user") >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[0]["objectClass"][0]), "user") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=X")) >+ self.assertEqual(str(res[1]["dnsHostName"]), "x") >+ self.assertEqual(str(res[1]["lastLogon"]), "x") >+ self.assertEqual(str(res[1]["objectClass"][0]), "user") > > # Prove that the objectClass is actually used for the search > res = self.ldb.search(expression="(|(objectClass=user)(badPwdCount=x))", > attrs=attrs) >- self.assertEquals(len(res), 3) >+ self.assertEqual(len(res), 3) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[0]["objectClass"][0]), "user") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[0]["objectClass"][0]), "user") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=B")) > self.assertTrue("dnsHostName" not in res[1]) >- self.assertEquals(str(res[1]["lastLogon"]), "y") >- self.assertEquals(set(res[1]["objectClass"]), set([b"top"])) >- self.assertEquals(str(res[2].dn), self.samba4.dn("cn=X")) >- self.assertEquals(str(res[2]["dnsHostName"]), "x") >- self.assertEquals(str(res[2]["lastLogon"]), "x") >- self.assertEquals(str(res[2]["objectClass"][0]), "user") >+ self.assertEqual(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(set(res[1]["objectClass"]), set([b"top"])) >+ self.assertEqual(str(res[2].dn), self.samba4.dn("cn=X")) >+ self.assertEqual(str(res[2]["dnsHostName"]), "x") >+ self.assertEqual(str(res[2]["lastLogon"]), "x") >+ self.assertEqual(str(res[2]["objectClass"][0]), "user") > > # Testing search by parse tree > > # Search by conjunction of local attributes > res = self.ldb.search(expression="(&(codePage=x)(revision=x))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 2) >+ self.assertEqual(len(res), 2) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) >- self.assertEquals(str(res[0]["dnsHostName"]), "x") >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y")) >- self.assertEquals(str(res[1]["dnsHostName"]), "y") >- self.assertEquals(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=X")) >+ self.assertEqual(str(res[0]["dnsHostName"]), "x") >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=Y")) >+ self.assertEqual(str(res[1]["dnsHostName"]), "y") >+ self.assertEqual(str(res[1]["lastLogon"]), "y") > > # Search by conjunction of remote attributes > res = self.ldb.search(expression="(&(lastLogon=x)(description=x))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 2) >+ self.assertEqual(len(res), 2) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) >- self.assertEquals(str(res[1]["dnsHostName"]), "x") >- self.assertEquals(str(res[1]["lastLogon"]), "x") >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=X")) >+ self.assertEqual(str(res[1]["dnsHostName"]), "x") >+ self.assertEqual(str(res[1]["lastLogon"]), "x") > > # Search by conjunction of local and remote attribute > res = self.ldb.search(expression="(&(codePage=x)(description=x))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 2) >+ self.assertEqual(len(res), 2) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) >- self.assertEquals(str(res[0]["dnsHostName"]), "x") >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y")) >- self.assertEquals(str(res[1]["dnsHostName"]), "y") >- self.assertEquals(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=X")) >+ self.assertEqual(str(res[0]["dnsHostName"]), "x") >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=Y")) >+ self.assertEqual(str(res[1]["dnsHostName"]), "y") >+ self.assertEqual(str(res[1]["lastLogon"]), "y") > > # Search by conjunction of local and remote attribute w/o match > attrs = ["dnsHostName", "lastLogon"] > res = self.ldb.search(expression="(&(codePage=x)(nextRid=x))", > attrs=attrs) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > res = self.ldb.search(expression="(&(revision=x)(lastLogon=z))", > attrs=attrs) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # Search by disjunction of local attributes > res = self.ldb.search(expression="(|(revision=x)(dnsHostName=x))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 2) >+ self.assertEqual(len(res), 2) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) >- self.assertEquals(str(res[0]["dnsHostName"]), "x") >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y")) >- self.assertEquals(str(res[1]["dnsHostName"]), "y") >- self.assertEquals(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=X")) >+ self.assertEqual(str(res[0]["dnsHostName"]), "x") >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=Y")) >+ self.assertEqual(str(res[1]["dnsHostName"]), "y") >+ self.assertEqual(str(res[1]["lastLogon"]), "y") > > # Search by disjunction of remote attributes > res = self.ldb.search(expression="(|(badPwdCount=x)(lastLogon=x))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 3) >+ self.assertEqual(len(res), 3) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertFalse("dnsHostName" in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=B")) > self.assertFalse("dnsHostName" in res[1]) >- self.assertEquals(str(res[1]["lastLogon"]), "y") >- self.assertEquals(str(res[2].dn), self.samba4.dn("cn=X")) >- self.assertEquals(str(res[2]["dnsHostName"]), "x") >- self.assertEquals(str(res[2]["lastLogon"]), "x") >+ self.assertEqual(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[2].dn), self.samba4.dn("cn=X")) >+ self.assertEqual(str(res[2]["dnsHostName"]), "x") >+ self.assertEqual(str(res[2]["lastLogon"]), "x") > > # Search by disjunction of local and remote attribute > res = self.ldb.search(expression="(|(revision=x)(lastLogon=y))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 3) >+ self.assertEqual(len(res), 3) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=B")) > self.assertFalse("dnsHostName" in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "y") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) >- self.assertEquals(str(res[1]["dnsHostName"]), "x") >- self.assertEquals(str(res[1]["lastLogon"]), "x") >- self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Y")) >- self.assertEquals(str(res[2]["dnsHostName"]), "y") >- self.assertEquals(str(res[2]["lastLogon"]), "y") >+ self.assertEqual(str(res[0]["lastLogon"]), "y") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=X")) >+ self.assertEqual(str(res[1]["dnsHostName"]), "x") >+ self.assertEqual(str(res[1]["lastLogon"]), "x") >+ self.assertEqual(str(res[2].dn), self.samba4.dn("cn=Y")) >+ self.assertEqual(str(res[2]["dnsHostName"]), "y") >+ self.assertEqual(str(res[2]["lastLogon"]), "y") > > # Search by disjunction of local and remote attribute w/o match > res = self.ldb.search(expression="(|(codePage=y)(nextRid=z))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # Search by negated local attribute > res = self.ldb.search(expression="(!(revision=x))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 6) >+ self.assertEqual(len(res), 6) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=B")) > self.assertTrue("dnsHostName" not in res[1]) >- self.assertEquals(str(res[1]["lastLogon"]), "y") >- self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) >+ self.assertEqual(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[2].dn), self.samba4.dn("cn=C")) > self.assertTrue("dnsHostName" not in res[2]) >- self.assertEquals(str(res[2]["lastLogon"]), "z") >- self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z")) >- self.assertEquals(str(res[3]["dnsHostName"]), "z") >- self.assertEquals(str(res[3]["lastLogon"]), "z") >+ self.assertEqual(str(res[2]["lastLogon"]), "z") >+ self.assertEqual(str(res[3].dn), self.samba4.dn("cn=Z")) >+ self.assertEqual(str(res[3]["dnsHostName"]), "z") >+ self.assertEqual(str(res[3]["lastLogon"]), "z") > > # Search by negated remote attribute > res = self.ldb.search(expression="(!(description=x))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 4) >+ self.assertEqual(len(res), 4) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=C")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "z") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Z")) >- self.assertEquals(str(res[1]["dnsHostName"]), "z") >- self.assertEquals(str(res[1]["lastLogon"]), "z") >+ self.assertEqual(str(res[0]["lastLogon"]), "z") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=Z")) >+ self.assertEqual(str(res[1]["dnsHostName"]), "z") >+ self.assertEqual(str(res[1]["lastLogon"]), "z") > > # Search by negated conjunction of local attributes > res = self.ldb.search(expression="(!(&(codePage=x)(revision=x)))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 6) >+ self.assertEqual(len(res), 6) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=B")) > self.assertTrue("dnsHostName" not in res[1]) >- self.assertEquals(str(res[1]["lastLogon"]), "y") >- self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) >+ self.assertEqual(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[2].dn), self.samba4.dn("cn=C")) > self.assertTrue("dnsHostName" not in res[2]) >- self.assertEquals(str(res[2]["lastLogon"]), "z") >- self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z")) >- self.assertEquals(str(res[3]["dnsHostName"]), "z") >- self.assertEquals(str(res[3]["lastLogon"]), "z") >+ self.assertEqual(str(res[2]["lastLogon"]), "z") >+ self.assertEqual(str(res[3].dn), self.samba4.dn("cn=Z")) >+ self.assertEqual(str(res[3]["dnsHostName"]), "z") >+ self.assertEqual(str(res[3]["lastLogon"]), "z") > > # Search by negated conjunction of remote attributes > res = self.ldb.search(expression="(!(&(lastLogon=x)(description=x)))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 6) >+ self.assertEqual(len(res), 6) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=B")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "y") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=C")) >+ self.assertEqual(str(res[0]["lastLogon"]), "y") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=C")) > self.assertTrue("dnsHostName" not in res[1]) >- self.assertEquals(str(res[1]["lastLogon"]), "z") >- self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Y")) >- self.assertEquals(str(res[2]["dnsHostName"]), "y") >- self.assertEquals(str(res[2]["lastLogon"]), "y") >- self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z")) >- self.assertEquals(str(res[3]["dnsHostName"]), "z") >- self.assertEquals(str(res[3]["lastLogon"]), "z") >+ self.assertEqual(str(res[1]["lastLogon"]), "z") >+ self.assertEqual(str(res[2].dn), self.samba4.dn("cn=Y")) >+ self.assertEqual(str(res[2]["dnsHostName"]), "y") >+ self.assertEqual(str(res[2]["lastLogon"]), "y") >+ self.assertEqual(str(res[3].dn), self.samba4.dn("cn=Z")) >+ self.assertEqual(str(res[3]["dnsHostName"]), "z") >+ self.assertEqual(str(res[3]["lastLogon"]), "z") > > # Search by negated conjunction of local and remote attribute > res = self.ldb.search(expression="(!(&(codePage=x)(description=x)))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 6) >+ self.assertEqual(len(res), 6) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=B")) > self.assertTrue("dnsHostName" not in res[1]) >- self.assertEquals(str(res[1]["lastLogon"]), "y") >- self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) >+ self.assertEqual(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[2].dn), self.samba4.dn("cn=C")) > self.assertTrue("dnsHostName" not in res[2]) >- self.assertEquals(str(res[2]["lastLogon"]), "z") >- self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z")) >- self.assertEquals(str(res[3]["dnsHostName"]), "z") >- self.assertEquals(str(res[3]["lastLogon"]), "z") >+ self.assertEqual(str(res[2]["lastLogon"]), "z") >+ self.assertEqual(str(res[3].dn), self.samba4.dn("cn=Z")) >+ self.assertEqual(str(res[3]["dnsHostName"]), "z") >+ self.assertEqual(str(res[3]["lastLogon"]), "z") > > # Search by negated disjunction of local attributes > res = self.ldb.search(expression="(!(|(revision=x)(dnsHostName=x)))", > attrs=["dnsHostName", "lastLogon"]) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=B")) > self.assertTrue("dnsHostName" not in res[1]) >- self.assertEquals(str(res[1]["lastLogon"]), "y") >- self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) >+ self.assertEqual(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[2].dn), self.samba4.dn("cn=C")) > self.assertTrue("dnsHostName" not in res[2]) >- self.assertEquals(str(res[2]["lastLogon"]), "z") >- self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z")) >- self.assertEquals(str(res[3]["dnsHostName"]), "z") >- self.assertEquals(str(res[3]["lastLogon"]), "z") >+ self.assertEqual(str(res[2]["lastLogon"]), "z") >+ self.assertEqual(str(res[3].dn), self.samba4.dn("cn=Z")) >+ self.assertEqual(str(res[3]["dnsHostName"]), "z") >+ self.assertEqual(str(res[3]["lastLogon"]), "z") > > # Search by negated disjunction of remote attributes > res = self.ldb.search(expression="(!(|(badPwdCount=x)(lastLogon=x)))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 5) >+ self.assertEqual(len(res), 5) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=C")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "z") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y")) >- self.assertEquals(str(res[1]["dnsHostName"]), "y") >- self.assertEquals(str(res[1]["lastLogon"]), "y") >- self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z")) >- self.assertEquals(str(res[2]["dnsHostName"]), "z") >- self.assertEquals(str(res[2]["lastLogon"]), "z") >+ self.assertEqual(str(res[0]["lastLogon"]), "z") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=Y")) >+ self.assertEqual(str(res[1]["dnsHostName"]), "y") >+ self.assertEqual(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[2].dn), self.samba4.dn("cn=Z")) >+ self.assertEqual(str(res[2]["dnsHostName"]), "z") >+ self.assertEqual(str(res[2]["lastLogon"]), "z") > > # Search by negated disjunction of local and remote attribute > res = self.ldb.search(expression="(!(|(revision=x)(lastLogon=y)))", > attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 5) >+ self.assertEqual(len(res), 5) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=C")) >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=C")) > self.assertTrue("dnsHostName" not in res[1]) >- self.assertEquals(str(res[1]["lastLogon"]), "z") >- self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z")) >- self.assertEquals(str(res[2]["dnsHostName"]), "z") >- self.assertEquals(str(res[2]["lastLogon"]), "z") >+ self.assertEqual(str(res[1]["lastLogon"]), "z") >+ self.assertEqual(str(res[2].dn), self.samba4.dn("cn=Z")) >+ self.assertEqual(str(res[2]["dnsHostName"]), "z") >+ self.assertEqual(str(res[2]["lastLogon"]), "z") > > # Search by complex parse tree > res = self.ldb.search(expression="(|(&(revision=x)(dnsHostName=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", attrs=["dnsHostName", "lastLogon"]) >- self.assertEquals(len(res), 7) >+ self.assertEqual(len(res), 7) > res = sorted(res, key=attrgetter('dn')) >- self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) >+ self.assertEqual(str(res[0].dn), self.samba4.dn("cn=A")) > self.assertTrue("dnsHostName" not in res[0]) >- self.assertEquals(str(res[0]["lastLogon"]), "x") >- self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) >+ self.assertEqual(str(res[0]["lastLogon"]), "x") >+ self.assertEqual(str(res[1].dn), self.samba4.dn("cn=B")) > self.assertTrue("dnsHostName" not in res[1]) >- self.assertEquals(str(res[1]["lastLogon"]), "y") >- self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) >+ self.assertEqual(str(res[1]["lastLogon"]), "y") >+ self.assertEqual(str(res[2].dn), self.samba4.dn("cn=C")) > self.assertTrue("dnsHostName" not in res[2]) >- self.assertEquals(str(res[2]["lastLogon"]), "z") >- self.assertEquals(str(res[3].dn), self.samba4.dn("cn=X")) >- self.assertEquals(str(res[3]["dnsHostName"]), "x") >- self.assertEquals(str(res[3]["lastLogon"]), "x") >- self.assertEquals(str(res[4].dn), self.samba4.dn("cn=Z")) >- self.assertEquals(str(res[4]["dnsHostName"]), "z") >- self.assertEquals(str(res[4]["lastLogon"]), "z") >+ self.assertEqual(str(res[2]["lastLogon"]), "z") >+ self.assertEqual(str(res[3].dn), self.samba4.dn("cn=X")) >+ self.assertEqual(str(res[3]["dnsHostName"]), "x") >+ self.assertEqual(str(res[3]["lastLogon"]), "x") >+ self.assertEqual(str(res[4].dn), self.samba4.dn("cn=Z")) >+ self.assertEqual(str(res[4]["dnsHostName"]), "z") >+ self.assertEqual(str(res[4]["lastLogon"]), "z") > > # Clean up > dns = [self.samba4.dn("cn=%s" % n) for n in ["A", "B", "C", "X", "Y", "Z"]] >@@ -823,19 +823,19 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-1052 > # Check it's there > attrs = ["foo", "revision", "description"] > res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >- self.assertEquals(str(res[0]["foo"]), "bar") >- self.assertEquals(str(res[0]["revision"]), "1") >- self.assertEquals(str(res[0]["description"]), "test") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) >+ self.assertEqual(str(res[0]["foo"]), "bar") >+ self.assertEqual(str(res[0]["revision"]), "1") >+ self.assertEqual(str(res[0]["description"]), "test") > # Check it's not in the local db > res = self.samba4.db.search(expression="(cn=test)", > scope=SCOPE_DEFAULT, attrs=attrs) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > # Check it's not in the remote db > res = self.samba3.db.search(expression="(cn=test)", > scope=SCOPE_DEFAULT, attrs=attrs) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # Modify local record > ldif = """ >@@ -848,28 +848,28 @@ description: foo > self.ldb.modify_ldif(ldif) > # Check in local db > res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >- self.assertEquals(str(res[0]["foo"]), "baz") >- self.assertEquals(str(res[0]["revision"]), "1") >- self.assertEquals(str(res[0]["description"]), "foo") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) >+ self.assertEqual(str(res[0]["foo"]), "baz") >+ self.assertEqual(str(res[0]["revision"]), "1") >+ self.assertEqual(str(res[0]["description"]), "foo") > > # Rename local record > dn2 = "cn=toast,dc=idealx,dc=org" > self.ldb.rename(dn, dn2) > # Check in local db > res = self.ldb.search(dn2, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn2) >- self.assertEquals(str(res[0]["foo"]), "baz") >- self.assertEquals(str(res[0]["revision"]), "1") >- self.assertEquals(str(res[0]["description"]), "foo") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn2) >+ self.assertEqual(str(res[0]["foo"]), "baz") >+ self.assertEqual(str(res[0]["revision"]), "1") >+ self.assertEqual(str(res[0]["description"]), "foo") > > # Delete local record > self.ldb.delete(dn2) > # Check it's gone > res = self.ldb.search(dn2, scope=SCOPE_BASE) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > def test_map_modify_remote_remote(self): > """Modification of remote data of remote records""" >@@ -884,22 +884,22 @@ description: foo > # Check it's there > res = self.samba3.db.search(dn2, scope=SCOPE_BASE, > attrs=["description", "sambaBadPasswordCount", "sambaNextRid"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn2) >- self.assertEquals(str(res[0]["description"]), "foo") >- self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "3") >- self.assertEquals(str(res[0]["sambaNextRid"]), "1001") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn2) >+ self.assertEqual(str(res[0]["description"]), "foo") >+ self.assertEqual(str(res[0]["sambaBadPasswordCount"]), "3") >+ self.assertEqual(str(res[0]["sambaNextRid"]), "1001") > # Check in mapped db > attrs = ["description", "badPwdCount", "nextRid"] > res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs, expression="") >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >- self.assertEquals(str(res[0]["description"]), "foo") >- self.assertEquals(str(res[0]["badPwdCount"]), "3") >- self.assertEquals(str(res[0]["nextRid"]), "1001") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) >+ self.assertEqual(str(res[0]["description"]), "foo") >+ self.assertEqual(str(res[0]["badPwdCount"]), "3") >+ self.assertEqual(str(res[0]["nextRid"]), "1001") > # Check in local db > res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # Modify remote data of remote record > ldif = """ >@@ -913,19 +913,19 @@ badPwdCount: 4 > # Check in mapped db > res = self.ldb.search(dn, scope=SCOPE_BASE, > attrs=["description", "badPwdCount", "nextRid"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >- self.assertEquals(str(res[0]["description"]), "test") >- self.assertEquals(str(res[0]["badPwdCount"]), "4") >- self.assertEquals(str(res[0]["nextRid"]), "1001") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) >+ self.assertEqual(str(res[0]["description"]), "test") >+ self.assertEqual(str(res[0]["badPwdCount"]), "4") >+ self.assertEqual(str(res[0]["nextRid"]), "1001") > # Check in remote db > res = self.samba3.db.search(dn2, scope=SCOPE_BASE, > attrs=["description", "sambaBadPasswordCount", "sambaNextRid"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn2) >- self.assertEquals(str(res[0]["description"]), "test") >- self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4") >- self.assertEquals(str(res[0]["sambaNextRid"]), "1001") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn2) >+ self.assertEqual(str(res[0]["description"]), "test") >+ self.assertEqual(str(res[0]["sambaBadPasswordCount"]), "4") >+ self.assertEqual(str(res[0]["sambaNextRid"]), "1001") > > # Rename remote record > dn2 = self.samba4.dn("cn=toast") >@@ -934,29 +934,29 @@ badPwdCount: 4 > dn = dn2 > res = self.ldb.search(dn, scope=SCOPE_BASE, > attrs=["description", "badPwdCount", "nextRid"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >- self.assertEquals(str(res[0]["description"]), "test") >- self.assertEquals(str(res[0]["badPwdCount"]), "4") >- self.assertEquals(str(res[0]["nextRid"]), "1001") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) >+ self.assertEqual(str(res[0]["description"]), "test") >+ self.assertEqual(str(res[0]["badPwdCount"]), "4") >+ self.assertEqual(str(res[0]["nextRid"]), "1001") > # Check in remote db > dn2 = self.samba3.dn("cn=toast") > res = self.samba3.db.search(dn2, scope=SCOPE_BASE, > attrs=["description", "sambaBadPasswordCount", "sambaNextRid"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn2) >- self.assertEquals(str(res[0]["description"]), "test") >- self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4") >- self.assertEquals(str(res[0]["sambaNextRid"]), "1001") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn2) >+ self.assertEqual(str(res[0]["description"]), "test") >+ self.assertEqual(str(res[0]["sambaBadPasswordCount"]), "4") >+ self.assertEqual(str(res[0]["sambaNextRid"]), "1001") > > # Delete remote record > self.ldb.delete(dn) > # Check in mapped db that it's removed > res = self.ldb.search(dn, scope=SCOPE_BASE) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > # Check in remote db > res = self.samba3.db.search(dn2, scope=SCOPE_BASE) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > def test_map_modify_remote_local(self): > """Modification of local data of remote records""" >@@ -982,22 +982,22 @@ description: test > # Check in mapped db > attrs = ["revision", "description"] > res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >- self.assertEquals(str(res[0]["description"]), "test") >- self.assertEquals(str(res[0]["revision"]), "1") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) >+ self.assertEqual(str(res[0]["description"]), "test") >+ self.assertEqual(str(res[0]["revision"]), "1") > # Check in remote db > res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn2) >- self.assertEquals(str(res[0]["description"]), "test") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn2) >+ self.assertEqual(str(res[0]["description"]), "test") > self.assertTrue("revision" not in res[0]) > # Check in local db > res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) > self.assertTrue("description" not in res[0]) >- self.assertEquals(str(res[0]["revision"]), "1") >+ self.assertEqual(str(res[0]["revision"]), "1") > > # Delete (newly) split record > self.ldb.delete(dn) >@@ -1017,29 +1017,29 @@ description: test > # Check it's there > attrs = ["description", "badPwdCount", "nextRid", "revision"] > res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >- self.assertEquals(str(res[0]["description"]), "foo") >- self.assertEquals(str(res[0]["badPwdCount"]), "3") >- self.assertEquals(str(res[0]["nextRid"]), "1001") >- self.assertEquals(str(res[0]["revision"]), "1") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) >+ self.assertEqual(str(res[0]["description"]), "foo") >+ self.assertEqual(str(res[0]["badPwdCount"]), "3") >+ self.assertEqual(str(res[0]["nextRid"]), "1001") >+ self.assertEqual(str(res[0]["revision"]), "1") > # Check in local db > res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) > self.assertTrue("description" not in res[0]) > self.assertTrue("badPwdCount" not in res[0]) > self.assertTrue("nextRid" not in res[0]) >- self.assertEquals(str(res[0]["revision"]), "1") >+ self.assertEqual(str(res[0]["revision"]), "1") > # Check in remote db > attrs = ["description", "sambaBadPasswordCount", "sambaNextRid", > "revision"] > res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn2) >- self.assertEquals(str(res[0]["description"]), "foo") >- self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "3") >- self.assertEquals(str(res[0]["sambaNextRid"]), "1001") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn2) >+ self.assertEqual(str(res[0]["description"]), "foo") >+ self.assertEqual(str(res[0]["sambaBadPasswordCount"]), "3") >+ self.assertEqual(str(res[0]["sambaNextRid"]), "1001") > self.assertTrue("revision" not in res[0]) > > # Modify of split record >@@ -1056,29 +1056,29 @@ revision: 2 > # Check in mapped db > attrs = ["description", "badPwdCount", "nextRid", "revision"] > res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >- self.assertEquals(str(res[0]["description"]), "test") >- self.assertEquals(str(res[0]["badPwdCount"]), "4") >- self.assertEquals(str(res[0]["nextRid"]), "1001") >- self.assertEquals(str(res[0]["revision"]), "2") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) >+ self.assertEqual(str(res[0]["description"]), "test") >+ self.assertEqual(str(res[0]["badPwdCount"]), "4") >+ self.assertEqual(str(res[0]["nextRid"]), "1001") >+ self.assertEqual(str(res[0]["revision"]), "2") > # Check in local db > res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) > self.assertTrue("description" not in res[0]) > self.assertTrue("badPwdCount" not in res[0]) > self.assertTrue("nextRid" not in res[0]) >- self.assertEquals(str(res[0]["revision"]), "2") >+ self.assertEqual(str(res[0]["revision"]), "2") > # Check in remote db > attrs = ["description", "sambaBadPasswordCount", "sambaNextRid", > "revision"] > res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn2) >- self.assertEquals(str(res[0]["description"]), "test") >- self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4") >- self.assertEquals(str(res[0]["sambaNextRid"]), "1001") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn2) >+ self.assertEqual(str(res[0]["description"]), "test") >+ self.assertEqual(str(res[0]["sambaBadPasswordCount"]), "4") >+ self.assertEqual(str(res[0]["sambaNextRid"]), "1001") > self.assertTrue("revision" not in res[0]) > > # Rename split record >@@ -1088,40 +1088,40 @@ revision: 2 > dn = dn2 > attrs = ["description", "badPwdCount", "nextRid", "revision"] > res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >- self.assertEquals(str(res[0]["description"]), "test") >- self.assertEquals(str(res[0]["badPwdCount"]), "4") >- self.assertEquals(str(res[0]["nextRid"]), "1001") >- self.assertEquals(str(res[0]["revision"]), "2") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) >+ self.assertEqual(str(res[0]["description"]), "test") >+ self.assertEqual(str(res[0]["badPwdCount"]), "4") >+ self.assertEqual(str(res[0]["nextRid"]), "1001") >+ self.assertEqual(str(res[0]["revision"]), "2") > # Check in local db > res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn) > self.assertTrue("description" not in res[0]) > self.assertTrue("badPwdCount" not in res[0]) > self.assertTrue("nextRid" not in res[0]) >- self.assertEquals(str(res[0]["revision"]), "2") >+ self.assertEqual(str(res[0]["revision"]), "2") > # Check in remote db > dn2 = self.samba3.dn("cn=toast") > res = self.samba3.db.search(dn2, scope=SCOPE_BASE, > attrs=["description", "sambaBadPasswordCount", "sambaNextRid", > "revision"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0].dn), dn2) >- self.assertEquals(str(res[0]["description"]), "test") >- self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4") >- self.assertEquals(str(res[0]["sambaNextRid"]), "1001") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0].dn), dn2) >+ self.assertEqual(str(res[0]["description"]), "test") >+ self.assertEqual(str(res[0]["sambaBadPasswordCount"]), "4") >+ self.assertEqual(str(res[0]["sambaNextRid"]), "1001") > self.assertTrue("revision" not in res[0]) > > # Delete split record > self.ldb.delete(dn) > # Check in mapped db > res = self.ldb.search(dn, scope=SCOPE_BASE) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > # Check in local db > res = self.samba4.db.search(dn, scope=SCOPE_BASE) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > # Check in remote db > res = self.samba3.db.search(dn2, scope=SCOPE_BASE) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) >diff --git a/python/samba/tests/samba_tool/computer.py b/python/samba/tests/samba_tool/computer.py >index 38ea5f774c4..0f51cf31c80 100644 >--- a/python/samba/tests/samba_tool/computer.py >+++ b/python/samba/tests/samba_tool/computer.py >@@ -78,10 +78,10 @@ class ComputerCmdTestCase(SambaToolCmdTest): > expectedsamaccountname = computer["name"] > if not computer["name"].endswith('$'): > expectedsamaccountname = "%s$" % computer["name"] >- self.assertEquals("%s" % found.get("name"), expectedname) >- self.assertEquals("%s" % found.get("sAMAccountName"), >+ self.assertEqual("%s" % found.get("name"), expectedname) >+ self.assertEqual("%s" % found.get("sAMAccountName"), > expectedsamaccountname) >- self.assertEquals("%s" % found.get("description"), >+ self.assertEqual("%s" % found.get("description"), > computer["description"]) > > def tearDown(self): >@@ -155,7 +155,7 @@ class ComputerCmdTestCase(SambaToolCmdTest): > "--description=%s" % computer["description"]) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > self.assertIn("Computer '%s' created successfully" % > computer["name"], out) > >@@ -165,10 +165,10 @@ class ComputerCmdTestCase(SambaToolCmdTest): > expectedsamaccountname = computer["name"] > if not computer["name"].endswith('$'): > expectedsamaccountname = "%s$" % computer["name"] >- self.assertEquals("%s" % found.get("name"), expectedname) >- self.assertEquals("%s" % found.get("sAMAccountName"), >+ self.assertEqual("%s" % found.get("name"), expectedname) >+ self.assertEqual("%s" % found.get("sAMAccountName"), > expectedsamaccountname) >- self.assertEquals("%s" % found.get("description"), >+ self.assertEqual("%s" % found.get("description"), > computer["description"]) > > def test_list(self): >@@ -204,7 +204,7 @@ class ComputerCmdTestCase(SambaToolCmdTest): > self.assertCmdSuccess(result, out, err, > "Failed to move computer '%s'" % > computer["name"]) >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > self.assertIn('Moved computer "%s"' % computer["name"], out) > > found = self._find_computer(computer["name"]) >@@ -216,7 +216,7 @@ class ComputerCmdTestCase(SambaToolCmdTest): > "CN=%s,OU=%s,%s" % > (computername, parentou["name"], > self.samdb.domain_dn())) >- self.assertEquals(found.get("dn"), newexpecteddn, >+ self.assertEqual(found.get("dn"), newexpecteddn, > "Moved computer '%s' does not exist" % > computer["name"]) > >diff --git a/python/samba/tests/samba_tool/forest.py b/python/samba/tests/samba_tool/forest.py >index 8817636bd63..f5cb3c03126 100644 >--- a/python/samba/tests/samba_tool/forest.py >+++ b/python/samba/tests/samba_tool/forest.py >@@ -50,7 +50,7 @@ class ForestCmdTestCase(SambaToolCmdTest): > os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("dsheuristics: <NO VALUE>", out) > > def test_modify_dsheuristics(self): >@@ -63,5 +63,5 @@ class ForestCmdTestCase(SambaToolCmdTest): > os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("set dsheuristics: 0000002", out) >diff --git a/python/samba/tests/samba_tool/fsmo.py b/python/samba/tests/samba_tool/fsmo.py >index 674cc0e32dc..29fe7bfe08a 100644 >--- a/python/samba/tests/samba_tool/fsmo.py >+++ b/python/samba/tests/samba_tool/fsmo.py >@@ -28,7 +28,7 @@ class FsmoCmdTestCase(SambaToolCmdTest): > (result, out, err) = self.runsubcmd("fsmo", "show") > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > > # Check that the output is sensible > samdb = self.getSamDB("-H", "ldap://%s" % os.environ["SERVER"], >diff --git a/python/samba/tests/samba_tool/group.py b/python/samba/tests/samba_tool/group.py >index 9862251ff01..1f740d34473 100644 >--- a/python/samba/tests/samba_tool/group.py >+++ b/python/samba/tests/samba_tool/group.py >@@ -45,15 +45,15 @@ class GroupCmdTestCase(SambaToolCmdTest): > (result, out, err) = self._create_group(group) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > self.assertIn("Added group %s" % group["name"], out) > > found = self._find_group(group["name"]) > > self.assertIsNotNone(found) > >- self.assertEquals("%s" % found.get("name"), group["name"]) >- self.assertEquals("%s" % found.get("description"), group["description"]) >+ self.assertEqual("%s" % found.get("name"), group["name"]) >+ self.assertEqual("%s" % found.get("description"), group["description"]) > > def tearDown(self): > super(GroupCmdTestCase, self).tearDown() >@@ -88,12 +88,12 @@ class GroupCmdTestCase(SambaToolCmdTest): > os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > self.assertIn("Added group %s" % group["name"], out) > > found = self._find_group(group["name"]) > >- self.assertEquals("%s" % found.get("samaccountname"), >+ self.assertEqual("%s" % found.get("samaccountname"), > "%s" % group["name"]) > > def test_list(self): >@@ -182,7 +182,7 @@ class GroupCmdTestCase(SambaToolCmdTest): > full_ou_dn = str(self.samdb.normalize_dn_in_domain("OU=movetest")) > (result, out, err) = self.runsubcmd("ou", "create", full_ou_dn) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > self.assertIn('Created ou "%s"' % full_ou_dn, out) > > for group in self.groups: >@@ -217,7 +217,7 @@ class GroupCmdTestCase(SambaToolCmdTest): > "-U%s%%%s" % (os.environ["DC_USERNAME"], > os.environ["DC_PASSWORD"])) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("dn: CN=Domain Users,CN=Users,DC=samba,DC=example,DC=com", out) > > def _randomGroup(self, base={}): >diff --git a/python/samba/tests/samba_tool/ntacl.py b/python/samba/tests/samba_tool/ntacl.py >index e8fee852651..7e0e2efef1c 100644 >--- a/python/samba/tests/samba_tool/ntacl.py >+++ b/python/samba/tests/samba_tool/ntacl.py >@@ -32,7 +32,7 @@ class NtACLCmdSysvolTestCase(SambaToolCmdTest): > (result, out, err) = self.runsubcmd("ntacl", "sysvolreset", > "--use-ntvfs") > self.assertCmdSuccess(result, out, err) >- self.assertEquals(out, "", "Shouldn't be any output messages") >+ self.assertEqual(out, "", "Shouldn't be any output messages") > self.assertIn("Please note that POSIX permissions have NOT been changed, only the stored NT ACL", err) > > def test_s3fs(self): >@@ -40,34 +40,34 @@ class NtACLCmdSysvolTestCase(SambaToolCmdTest): > "--use-s3fs") > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >- self.assertEquals(out, "", "Shouldn't be any output messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") >+ self.assertEqual(out, "", "Shouldn't be any output messages") > > def test_ntvfs_check(self): > (result, out, err) = self.runsubcmd("ntacl", "sysvolreset", > "--use-ntvfs") > self.assertCmdSuccess(result, out, err) >- self.assertEquals(out, "", "Shouldn't be any output messages") >+ self.assertEqual(out, "", "Shouldn't be any output messages") > self.assertIn("Please note that POSIX permissions have NOT been changed, only the stored NT ACL", err) > # Now check they were set correctly > (result, out, err) = self.runsubcmd("ntacl", "sysvolcheck") > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >- self.assertEquals(out, "", "Shouldn't be any output messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") >+ self.assertEqual(out, "", "Shouldn't be any output messages") > > def test_s3fs_check(self): > (result, out, err) = self.runsubcmd("ntacl", "sysvolreset", > "--use-s3fs") > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >- self.assertEquals(out, "", "Shouldn't be any output messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") >+ self.assertEqual(out, "", "Shouldn't be any output messages") > > # Now check they were set correctly > (result, out, err) = self.runsubcmd("ntacl", "sysvolcheck") > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >- self.assertEquals(out, "", "Shouldn't be any output messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") >+ self.assertEqual(out, "", "Shouldn't be any output messages") > > > class NtACLCmdGetSetTestCase(SambaToolCmdTest): >@@ -83,7 +83,7 @@ class NtACLCmdGetSetTestCase(SambaToolCmdTest): > (result, out, err) = self.runsubcmd("ntacl", "set", self.acl, tempf, > "--use-ntvfs") > self.assertCmdSuccess(result, out, err) >- self.assertEquals(out, "", "Shouldn't be any output messages") >+ self.assertEqual(out, "", "Shouldn't be any output messages") > self.assertIn("Please note that POSIX permissions have NOT been changed, only the stored NT ACL", err) > > def test_s3fs(self): >@@ -95,8 +95,8 @@ class NtACLCmdGetSetTestCase(SambaToolCmdTest): > "--use-s3fs") > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >- self.assertEquals(out, "", "Shouldn't be any output messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") >+ self.assertEqual(out, "", "Shouldn't be any output messages") > > def test_ntvfs_check(self): > path = os.environ['SELFTEST_PREFIX'] >@@ -106,15 +106,15 @@ class NtACLCmdGetSetTestCase(SambaToolCmdTest): > (result, out, err) = self.runsubcmd("ntacl", "set", self.acl, tempf, > "--use-ntvfs") > self.assertCmdSuccess(result, out, err) >- self.assertEquals(out, "", "Shouldn't be any output messages") >+ self.assertEqual(out, "", "Shouldn't be any output messages") > self.assertIn("Please note that POSIX permissions have NOT been changed, only the stored NT ACL", err) > > # Now check they were set correctly > (result, out, err) = self.runsubcmd("ntacl", "get", tempf, > "--use-ntvfs", "--as-sddl") > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >- self.assertEquals(self.acl + "\n", out, "Output should be the ACL") >+ self.assertEqual(err, "", "Shouldn't be any error messages") >+ self.assertEqual(self.acl + "\n", out, "Output should be the ACL") > > def test_s3fs_check(self): > path = os.environ['SELFTEST_PREFIX'] >@@ -124,12 +124,12 @@ class NtACLCmdGetSetTestCase(SambaToolCmdTest): > (result, out, err) = self.runsubcmd("ntacl", "set", self.acl, tempf, > "--use-s3fs") > self.assertCmdSuccess(result, out, err) >- self.assertEquals(out, "", "Shouldn't be any output messages") >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(out, "", "Shouldn't be any output messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > > # Now check they were set correctly > (result, out, err) = self.runsubcmd("ntacl", "get", tempf, > "--use-s3fs", "--as-sddl") > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >- self.assertEquals(self.acl + "\n", out, "Output should be the ACL") >+ self.assertEqual(err, "", "Shouldn't be any error messages") >+ self.assertEqual(self.acl + "\n", out, "Output should be the ACL") >diff --git a/python/samba/tests/samba_tool/ou.py b/python/samba/tests/samba_tool/ou.py >index d318fd3ff85..b697a783038 100644 >--- a/python/samba/tests/samba_tool/ou.py >+++ b/python/samba/tests/samba_tool/ou.py >@@ -44,7 +44,7 @@ class OUCmdTestCase(SambaToolCmdTest): > (result, out, err) = self._create_ou(ou) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > full_ou_dn = self.samdb.normalize_dn_in_domain("OU=%s" % ou["name"]) > self.assertIn('Created ou "%s"' % full_ou_dn, out) > >@@ -52,8 +52,8 @@ class OUCmdTestCase(SambaToolCmdTest): > > self.assertIsNotNone(found) > >- self.assertEquals("%s" % found.get("name"), ou["name"]) >- self.assertEquals("%s" % found.get("description"), >+ self.assertEqual("%s" % found.get("name"), ou["name"]) >+ self.assertEqual("%s" % found.get("description"), > ou["description"]) > > def tearDown(self): >@@ -91,13 +91,13 @@ class OUCmdTestCase(SambaToolCmdTest): > "--description=%s" % ou["description"]) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > full_ou_dn = self.samdb.normalize_dn_in_domain("OU=%s" % ou["name"]) > self.assertIn('Created ou "%s"' % full_ou_dn, out) > > found = self._find_ou(ou["name"]) > >- self.assertEquals("%s" % found.get("ou"), >+ self.assertEqual("%s" % found.get("ou"), > "%s" % ou["name"]) > > # try to delete all the ous we just created (with full dn) >@@ -118,13 +118,13 @@ class OUCmdTestCase(SambaToolCmdTest): > "--description=%s" % ou["description"]) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > full_ou_dn = self.samdb.normalize_dn_in_domain("OU=%s" % ou["name"]) > self.assertIn('Created ou "%s"' % full_ou_dn, out) > > found = self._find_ou(ou["name"]) > >- self.assertEquals("%s" % found.get("ou"), >+ self.assertEqual("%s" % found.get("ou"), > "%s" % ou["name"]) > > def test_list(self): >@@ -180,7 +180,7 @@ class OUCmdTestCase(SambaToolCmdTest): > "OU=%s" % parentou["name"]) > self.assertCmdSuccess(result, out, err, > "Failed to move ou '%s'" % ou["name"]) >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > full_ou_dn = self.samdb.normalize_dn_in_domain("OU=%s" % ou["name"]) > self.assertIn('Moved ou "%s"' % full_ou_dn, out) > >@@ -192,7 +192,7 @@ class OUCmdTestCase(SambaToolCmdTest): > "OU=%s,OU=%s,%s" % > (ou["name"], parentou["name"], > self.samdb.domain_dn())) >- self.assertEquals(found.get("dn"), newexpecteddn, >+ self.assertEqual(found.get("dn"), newexpecteddn, > "Moved ou '%s' does not exist" % > ou["name"]) > >@@ -213,7 +213,7 @@ class OUCmdTestCase(SambaToolCmdTest): > "--full-dn") > self.assertCmdSuccess(result, out, err, > "Failed to list ou's objects") >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > > objlist = self.samdb.search(base=self.samdb.domain_dn(), > scope=ldb.SCOPE_ONELEVEL, >@@ -229,7 +229,7 @@ class OUCmdTestCase(SambaToolCmdTest): > "--full-dn") > self.assertCmdSuccess(result, out, err, > "Failed to list ous") >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > > filter = "(objectClass=organizationalUnit)" > objlist = self.samdb.search(base=self.samdb.domain_dn(), >diff --git a/python/samba/tests/samba_tool/passwordsettings.py b/python/samba/tests/samba_tool/passwordsettings.py >index 43264b64608..4d83d346717 100644 >--- a/python/samba/tests/samba_tool/passwordsettings.py >+++ b/python/samba/tests/samba_tool/passwordsettings.py >@@ -56,7 +56,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > 'msDS-LockoutObservationWindow', > 'msDS-LockoutThreshold', 'msDS-LockoutDuration'] > res = self.ldb.search(dn, scope=ldb.SCOPE_BASE, attrs=pso_attrs) >- self.assertEquals(len(res), 1, "PSO lookup failed") >+ self.assertEqual(len(res), 1, "PSO lookup failed") > > # convert types in the PSO-settings to what the search returns, i.e. > # boolean --> string, seconds --> timestamps in -100 nanosecond units >@@ -68,23 +68,23 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > max_age = -int(pso.password_age_max * (1e7)) > > # check the PSO's settings match the search results >- self.assertEquals(str(res[0]['msDS-PasswordComplexityEnabled'][0]), >+ self.assertEqual(str(res[0]['msDS-PasswordComplexityEnabled'][0]), > complexity_str) > plaintext_res = res[0]['msDS-PasswordReversibleEncryptionEnabled'][0] >- self.assertEquals(str(plaintext_res), plaintext_str) >- self.assertEquals(int(res[0]['msDS-PasswordHistoryLength'][0]), >+ self.assertEqual(str(plaintext_res), plaintext_str) >+ self.assertEqual(int(res[0]['msDS-PasswordHistoryLength'][0]), > pso.history_len) >- self.assertEquals(int(res[0]['msDS-MinimumPasswordLength'][0]), >+ self.assertEqual(int(res[0]['msDS-MinimumPasswordLength'][0]), > pso.password_len) >- self.assertEquals(int(res[0]['msDS-MinimumPasswordAge'][0]), min_age) >- self.assertEquals(int(res[0]['msDS-MaximumPasswordAge'][0]), max_age) >- self.assertEquals(int(res[0]['msDS-LockoutObservationWindow'][0]), >+ self.assertEqual(int(res[0]['msDS-MinimumPasswordAge'][0]), min_age) >+ self.assertEqual(int(res[0]['msDS-MaximumPasswordAge'][0]), max_age) >+ self.assertEqual(int(res[0]['msDS-LockoutObservationWindow'][0]), > lockout_window) >- self.assertEquals(int(res[0]['msDS-LockoutDuration'][0]), >+ self.assertEqual(int(res[0]['msDS-LockoutDuration'][0]), > lockout_duration) >- self.assertEquals(int(res[0]['msDS-LockoutThreshold'][0]), >+ self.assertEqual(int(res[0]['msDS-LockoutThreshold'][0]), > pso.lockout_attempts) >- self.assertEquals(int(res[0]['msDS-PasswordSettingsPrecedence'][0]), >+ self.assertEqual(int(res[0]['msDS-PasswordSettingsPrecedence'][0]), > pso.precedence) > > # check we can also display the PSO via the show command >@@ -121,7 +121,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > self.obj_cleanup.append("CN=%s,%s" % (pso_name, self.pso_container)) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("successfully created", out) > self.check_pso(pso_name, expected_pso) > >@@ -163,7 +163,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > self.user_auth) > self.obj_cleanup.append("CN=%s,%s" % (pso_name, self.pso_container)) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("successfully created", out) > self.check_pso(pso_name, expected_pso) > >@@ -195,7 +195,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > > # sanity-check the cmd was successful > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("successfully created", out) > self.check_pso(pso_name, pso_settings) > >@@ -219,7 +219,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > "-H", self.server, > self.user_auth) > self.assertCmdSuccess(res, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("Successfully updated", out) > > # check the PSO's settings now reflect the new values >@@ -237,7 +237,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > "-H", self.server, > self.user_auth) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("Deleted PSO", out) > dn = "CN=%s,%s" % (pso_name, self.pso_container) > self.obj_cleanup.remove(dn) >@@ -248,7 +248,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > self.fail("PSO shouldn't exist") > except ldb.LdbError as e: > (enum, estr) = e.args >- self.assertEquals(enum, ldb.ERR_NO_SUCH_OBJECT) >+ self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) > > # run the same cmd again - it should fail because PSO no longer exists > (result, out, err) = self.runsublevelcmd("domain", ("passwordsettings", >@@ -267,7 +267,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > user.name, "-H", self.server, > self.user_auth) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > if pso is None: > self.assertIn("No PSO applies to user", out) > else: >@@ -275,9 +275,9 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > > # then check the DB tells us the same thing > if pso is None: >- self.assertEquals(user.get_resultant_PSO(), None) >+ self.assertEqual(user.get_resultant_PSO(), None) > else: >- self.assertEquals(user.get_resultant_PSO(), pso.dn) >+ self.assertEqual(user.get_resultant_PSO(), pso.dn) > > def test_pso_apply_to_user(self): > """Checks we can apply/unapply a PSO to a user""" >@@ -307,7 +307,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > group_name, "-H", self.server, > self.user_auth) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.check_pso_applied(user, pso=test_pso) > > # we should fail if we try to apply the same PSO/group twice though >@@ -324,7 +324,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > user.name, "-H", self.server, > self.user_auth) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.check_pso_applied(user, pso=test_pso) > > # check samba-tool can successfully unlink a group from a PSO >@@ -333,7 +333,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > group_name, "-H", self.server, > self.user_auth) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > # PSO still applies directly to the user, even though group was removed > self.check_pso_applied(user, pso=test_pso) > >@@ -343,7 +343,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > user.name, "-H", self.server, > self.user_auth) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.check_pso_applied(user, pso=None) > > def test_pso_unpriv(self): >@@ -418,7 +418,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > "show"), "-H", self.server, > self.user_auth) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > > # check an arbitrary setting is displayed correctly > min_pwd_len = self.ldb.get_minPwdLength() >@@ -433,16 +433,16 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > "-H", self.server, > self.user_auth) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("successful", out) >- self.assertEquals(new_len, self.ldb.get_minPwdLength()) >+ self.assertEqual(new_len, self.ldb.get_minPwdLength()) > > # check the updated value is now displayed > (result, out, err) = self.runsublevelcmd("domain", ("passwordsettings", > "show"), "-H", self.server, > self.user_auth) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("Minimum password length: %u" % new_len, out) > > def test_domain_passwordsettings_pwdage(self): >@@ -457,7 +457,7 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > "-H", self.server, > self.user_auth) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("successful", out) > self.assertNotEquals(max_pwd_age, self.ldb.get_maxPwdAge()) > >@@ -479,6 +479,6 @@ class PwdSettingsCmdTestCase(SambaToolCmdTest): > "-H", self.server, > self.user_auth) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("successful", out) > self.assertNotEquals(min_pwd_age, self.ldb.get_minPwdAge()) >diff --git a/python/samba/tests/samba_tool/schema.py b/python/samba/tests/samba_tool/schema.py >index 6d502ef4e17..e3e790924fa 100644 >--- a/python/samba/tests/samba_tool/schema.py >+++ b/python/samba/tests/samba_tool/schema.py >@@ -41,7 +41,7 @@ class SchemaCmdTestCase(SambaToolCmdTest): > os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("dn: CN=uid,CN=Schema,CN=Configuration,DC=samba,DC=example,DC=com", out) > > def test_modify_attribute_searchflags(self): >@@ -61,7 +61,7 @@ class SchemaCmdTestCase(SambaToolCmdTest): > os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("modified cn=uid,CN=Schema,CN=Configuration,DC=samba,DC=example,DC=com", out) > > (result, out, err) = self.runsublevelcmd("schema", ("attribute", >@@ -72,7 +72,7 @@ class SchemaCmdTestCase(SambaToolCmdTest): > os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("modified cn=uid,CN=Schema,CN=Configuration,DC=samba,DC=example,DC=com", out) > > (result, out, err) = self.runsublevelcmd("schema", ("attribute", >@@ -83,7 +83,7 @@ class SchemaCmdTestCase(SambaToolCmdTest): > os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("modified cn=uid,CN=Schema,CN=Configuration,DC=samba,DC=example,DC=com", out) > > def test_show_oc_attribute(self): >@@ -95,7 +95,7 @@ class SchemaCmdTestCase(SambaToolCmdTest): > os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("--- MAY contain ---", out) > self.assertIn("--- MUST contain ---", out) > >@@ -108,5 +108,5 @@ class SchemaCmdTestCase(SambaToolCmdTest): > os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("dn: CN=Person,CN=Schema,CN=Configuration,DC=samba,DC=example,DC=com", out) >diff --git a/python/samba/tests/samba_tool/sites.py b/python/samba/tests/samba_tool/sites.py >index 89197f7764a..1009cf28b98 100644 >--- a/python/samba/tests/samba_tool/sites.py >+++ b/python/samba/tests/samba_tool/sites.py >@@ -51,7 +51,7 @@ class SitesCmdTestCase(BaseSitesCmdTestCase): > > ret = self.samdb.search(base=dnsites, scope=ldb.SCOPE_ONELEVEL, > expression='(cn=%s)' % sitename) >- self.assertEquals(len(ret), 1) >+ self.assertEqual(len(ret), 1) > > # now delete it > self.samdb.delete(dnsite, ["tree_delete:0"]) >diff --git a/python/samba/tests/samba_tool/timecmd.py b/python/samba/tests/samba_tool/timecmd.py >index 1db51dc73e9..8e286f67f37 100644 >--- a/python/samba/tests/samba_tool/timecmd.py >+++ b/python/samba/tests/samba_tool/timecmd.py >@@ -39,6 +39,6 @@ class TimeCmdTestCase(SambaToolCmdTest): > def test_timefail(self): > """Run time against a non-existent server, and make sure it fails""" > (result, out, err) = self.runcmd("time", "notaserver") >- self.assertEquals(result, -1, "check for result code") >+ self.assertEqual(result, -1, "check for result code") > self.assertNotEqual(err.strip().find("NT_STATUS_OBJECT_NAME_NOT_FOUND"), -1, "ensure right error string") >- self.assertEquals(out, "", "ensure no output returned") >+ self.assertEqual(out, "", "ensure no output returned") >diff --git a/python/samba/tests/samba_tool/user.py b/python/samba/tests/samba_tool/user.py >index 77ab9bfb59d..6080abd14bb 100644 >--- a/python/samba/tests/samba_tool/user.py >+++ b/python/samba/tests/samba_tool/user.py >@@ -56,7 +56,7 @@ class UserCmdTestCase(SambaToolCmdTest): > (result, out, err) = user["createUserFn"](user) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("User '%s' created successfully" % user["name"], out) > > user["checkUserFn"](user) >@@ -103,13 +103,13 @@ class UserCmdTestCase(SambaToolCmdTest): > "-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("User '%s' created successfully" % user["name"], out) > > found = self._find_user(user["name"]) > >- self.assertEquals("%s" % found.get("cn"), "%(name)s" % user) >- self.assertEquals("%s" % found.get("name"), "%(name)s" % user) >+ self.assertEqual("%s" % found.get("cn"), "%(name)s" % user) >+ self.assertEqual("%s" % found.get("name"), "%(name)s" % user) > > def _verify_supplementalCredentials(self, ldif, > min_packages=3, >@@ -203,7 +203,7 @@ class UserCmdTestCase(SambaToolCmdTest): > "-H", "ldap://%s" % os.environ["DC_SERVER"], > "-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"])) > self.assertCmdSuccess(result, out, err, "Ensure setpassword runs") >- self.assertEquals(err, "", "setpassword with url") >+ self.assertEqual(err, "", "setpassword with url") > self.assertMatch(out, "Changed password OK", "setpassword with url") > > attributes = "sAMAccountName,unicodePwd,supplementalCredentials,virtualClearTextUTF8,virtualClearTextUTF16,virtualSSHA,virtualSambaGPG" >@@ -251,7 +251,7 @@ class UserCmdTestCase(SambaToolCmdTest): > user["name"], > "--newpassword=%s" % newpasswd) > self.assertCmdSuccess(result, out, err, "Ensure setpassword runs") >- self.assertEquals(err, "", "setpassword without url") >+ self.assertEqual(err, "", "setpassword without url") > self.assertMatch(out, "Changed password OK", "setpassword without url") > > (result, out, err) = self.runsubcmd("user", "syncpasswords", "--no-wait") >@@ -308,7 +308,7 @@ class UserCmdTestCase(SambaToolCmdTest): > "-H", "ldap://%s" % os.environ["DC_SERVER"], > "-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"])) > self.assertCmdSuccess(result, out, err, "Ensure setpassword runs") >- self.assertEquals(err, "", "setpassword with forced change") >+ self.assertEqual(err, "", "setpassword with forced change") > self.assertMatch(out, "Changed password OK", "setpassword with forced change") > > def test_setexpiry(self): >@@ -396,7 +396,7 @@ sAMAccountName: %s > full_ou_dn = str(self.samdb.normalize_dn_in_domain("OU=movetest")) > (result, out, err) = self.runsubcmd("ou", "create", full_ou_dn) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "There shouldn't be any error message") >+ self.assertEqual(err, "", "There shouldn't be any error message") > self.assertIn('Created ou "%s"' % full_ou_dn, out) > > for user in self.users: >@@ -469,7 +469,7 @@ sAMAccountName: %s > "-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("User '%s' created successfully" % user["name"], out) > > self._check_posix_user(user) >@@ -498,7 +498,7 @@ sAMAccountName: %s > "-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"])) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > self.assertIn("User '%s' created successfully" % user["name"], out) > > self._check_posix_user(user) >@@ -543,21 +543,21 @@ sAMAccountName: %s > """ check if a user from SamDB has the same attributes as its template """ > found = self._find_user(user["name"]) > >- self.assertEquals("%s" % found.get("name"), "%(given-name)s %(surname)s" % user) >- self.assertEquals("%s" % found.get("title"), user["job-title"]) >- self.assertEquals("%s" % found.get("company"), user["company"]) >- self.assertEquals("%s" % found.get("description"), user["description"]) >- self.assertEquals("%s" % found.get("department"), user["department"]) >+ self.assertEqual("%s" % found.get("name"), "%(given-name)s %(surname)s" % user) >+ self.assertEqual("%s" % found.get("title"), user["job-title"]) >+ self.assertEqual("%s" % found.get("company"), user["company"]) >+ self.assertEqual("%s" % found.get("description"), user["description"]) >+ self.assertEqual("%s" % found.get("department"), user["department"]) > > def _check_posix_user(self, user): > """ check if a posix_user from SamDB has the same attributes as its template """ > found = self._find_user(user["name"]) > >- self.assertEquals("%s" % found.get("loginShell"), user["loginShell"]) >- self.assertEquals("%s" % found.get("gecos"), user["gecos"]) >- self.assertEquals("%s" % found.get("uidNumber"), "%s" % user["uidNumber"]) >- self.assertEquals("%s" % found.get("gidNumber"), "%s" % user["gidNumber"]) >- self.assertEquals("%s" % found.get("uid"), user["uid"]) >+ self.assertEqual("%s" % found.get("loginShell"), user["loginShell"]) >+ self.assertEqual("%s" % found.get("gecos"), user["gecos"]) >+ self.assertEqual("%s" % found.get("uidNumber"), "%s" % user["uidNumber"]) >+ self.assertEqual("%s" % found.get("gidNumber"), "%s" % user["gidNumber"]) >+ self.assertEqual("%s" % found.get("uid"), user["uid"]) > self._check_user(user) > > def _create_user(self, user): >diff --git a/python/samba/tests/samba_tool/user_virtualCryptSHA.py b/python/samba/tests/samba_tool/user_virtualCryptSHA.py >index f488bc7799d..3db6ffddacd 100644 >--- a/python/samba/tests/samba_tool/user_virtualCryptSHA.py >+++ b/python/samba/tests/samba_tool/user_virtualCryptSHA.py >@@ -329,8 +329,8 @@ class UserCmdCryptShaTestCase(SambaToolCmdTest): > sha512 = _get_attribute(out, "virtualCryptSHA512") > > out = self._get_password("virtualCryptSHA256,virtualCryptSHA512") >- self.assertEquals(sha256, _get_attribute(out, "virtualCryptSHA256")) >- self.assertEquals(sha512, _get_attribute(out, "virtualCryptSHA512")) >+ self.assertEqual(sha256, _get_attribute(out, "virtualCryptSHA256")) >+ self.assertEqual(sha512, _get_attribute(out, "virtualCryptSHA512")) > > # gpg decryption not enabled. > # both virtual attributes specified, rounds specified >@@ -352,8 +352,8 @@ class UserCmdCryptShaTestCase(SambaToolCmdTest): > sha512 = _get_attribute(out, "virtualCryptSHA512") > > out = self._get_password("virtualCryptSHA256,virtualCryptSHA512") >- self.assertEquals(sha256, _get_attribute(out, "virtualCryptSHA256")) >- self.assertEquals(sha512, _get_attribute(out, "virtualCryptSHA512")) >+ self.assertEqual(sha256, _get_attribute(out, "virtualCryptSHA256")) >+ self.assertEqual(sha512, _get_attribute(out, "virtualCryptSHA512")) > > # gpg decryption not enabled. > # both virtual attributes specified, rounds specified >@@ -379,8 +379,8 @@ class UserCmdCryptShaTestCase(SambaToolCmdTest): > > out = self._get_password("virtualCryptSHA256;rounds=2561," + > "virtualCryptSHA512;rounds=5129") >- self.assertEquals(sha256, _get_attribute(out, "virtualCryptSHA256")) >- self.assertEquals(sha512, _get_attribute(out, "virtualCryptSHA512")) >+ self.assertEqual(sha256, _get_attribute(out, "virtualCryptSHA256")) >+ self.assertEqual(sha512, _get_attribute(out, "virtualCryptSHA512")) > > # Number of rounds should match that specified > self.assertTrue(sha256.startswith("{CRYPT}$5$rounds=2561")) >@@ -411,15 +411,15 @@ class UserCmdCryptShaTestCase(SambaToolCmdTest): > > out = self._get_password("virtualCryptSHA256;rounds=4000," + > "virtualCryptSHA512;rounds=5000") >- self.assertEquals(sha256, _get_attribute(out, "virtualCryptSHA256")) >- self.assertEquals(sha512, _get_attribute(out, "virtualCryptSHA512")) >+ self.assertEqual(sha256, _get_attribute(out, "virtualCryptSHA256")) >+ self.assertEqual(sha512, _get_attribute(out, "virtualCryptSHA512")) > > # As the number of rounds did not match, should have returned the > # first hash of the coresponding scheme > out = self._get_password("virtualCryptSHA256," + > "virtualCryptSHA512") >- self.assertEquals(sha256, _get_attribute(out, "virtualCryptSHA256")) >- self.assertEquals(sha512, _get_attribute(out, "virtualCryptSHA512")) >+ self.assertEqual(sha256, _get_attribute(out, "virtualCryptSHA256")) >+ self.assertEqual(sha512, _get_attribute(out, "virtualCryptSHA512")) > > # gpg decryption enabled. > # both virtual attributes specified, no rounds option >@@ -440,8 +440,8 @@ class UserCmdCryptShaTestCase(SambaToolCmdTest): > sha512 = _get_attribute(out, "virtualCryptSHA512") > > out = self._get_password("virtualCryptSHA256,virtualCryptSHA512", True) >- self.assertEquals(sha256, _get_attribute(out, "virtualCryptSHA256")) >- self.assertEquals(sha512, _get_attribute(out, "virtualCryptSHA512")) >+ self.assertEqual(sha256, _get_attribute(out, "virtualCryptSHA256")) >+ self.assertEqual(sha512, _get_attribute(out, "virtualCryptSHA512")) > > # gpg decryption enabled. > # both virtual attributes specified, rounds specified >@@ -499,8 +499,8 @@ class UserCmdCryptShaTestCase(SambaToolCmdTest): > out = self._get_password("virtualCryptSHA256;rounds=2561," + > "virtualCryptSHA512;rounds=5129", > True) >- self.assertEquals(sha256, _get_attribute(out, "virtualCryptSHA256")) >- self.assertEquals(sha512, _get_attribute(out, "virtualCryptSHA512")) >+ self.assertEqual(sha256, _get_attribute(out, "virtualCryptSHA256")) >+ self.assertEqual(sha512, _get_attribute(out, "virtualCryptSHA512")) > > # The returned hashes should specify the correct number of rounds > self.assertTrue(sha256.startswith("{CRYPT}$5$rounds=2561")) >diff --git a/python/samba/tests/samba_tool/visualize_drs.py b/python/samba/tests/samba_tool/visualize_drs.py >index 9b1588bd1ef..3eda02783f6 100644 >--- a/python/samba/tests/samba_tool/visualize_drs.py >+++ b/python/samba/tests/samba_tool/visualize_drs.py >@@ -223,7 +223,7 @@ class SambaToolVisualizeDrsTest(SambaToolCmdTest): > self.assertCmdSuccess(result, out, err) > > lines = out.splitlines() >- self.assertEquals(len(lines), 1) >+ self.assertEqual(len(lines), 1) > > line = lines[0] > self.assertTrue(line.startswith('DOMAIN')) >diff --git a/python/samba/tests/samdb_api.py b/python/samba/tests/samdb_api.py >index cf32151d259..a7260180187 100644 >--- a/python/samba/tests/samdb_api.py >+++ b/python/samba/tests/samdb_api.py >@@ -32,12 +32,12 @@ class SamDBApiTestCase(TestCaseInTempDir): > try: > os.remove(self.tempdir + "/test.db") > except OSError as e: >- self.assertEquals(e.errno, errno.ENOENT) >+ self.assertEqual(e.errno, errno.ENOENT) > > try: > os.remove(self.tempdir + "/existing.db") > except OSError as e: >- self.assertEquals(e.errno, errno.ENOENT) >+ self.assertEqual(e.errno, errno.ENOENT) > > super(SamDBApiTestCase, self).tearDown() > >@@ -58,11 +58,11 @@ class SamDBApiTestCase(TestCaseInTempDir): > self.fail("Exception not thrown ") > except LdbError as e: > (err, _) = e.args >- self.assertEquals(err, ERR_OPERATIONS_ERROR) >+ self.assertEqual(err, ERR_OPERATIONS_ERROR) > > existing = open(existing_name, "r") > contents = existing.readline() >- self.assertEquals("This is not a tdb file!!!!!!\n", contents) >+ self.assertEqual("This is not a tdb file!!!!!!\n", contents) > > # Attempt to open and existing non tdb file as a tdb file. > # Don't create new db is cleared >@@ -80,7 +80,7 @@ class SamDBApiTestCase(TestCaseInTempDir): > > existing = open(existing_name, "rb") > contents = existing.readline() >- self.assertEquals(b"TDB file\n", contents) >+ self.assertEqual(b"TDB file\n", contents) > > # > # Attempt to open an existing tdb file as a tdb file. >@@ -99,11 +99,11 @@ class SamDBApiTestCase(TestCaseInTempDir): > }) > > cn = initial.searchone("cn", dn) >- self.assertEquals(b"test_dont_create_db_existing_tdb_file", cn) >+ self.assertEqual(b"test_dont_create_db_existing_tdb_file", cn) > > second = SamDB(url="tdb://" + existing_name) > cn = second.searchone("cn", dn) >- self.assertEquals(b"test_dont_create_db_existing_tdb_file", cn) >+ self.assertEqual(b"test_dont_create_db_existing_tdb_file", cn) > > # > # Attempt to open an existing tdb file as a tdb file. >@@ -122,11 +122,11 @@ class SamDBApiTestCase(TestCaseInTempDir): > }) > > cn = initial.searchone("cn", dn) >- self.assertEquals(b"test_dont_create_db_existing_tdb_file", cn) >+ self.assertEqual(b"test_dont_create_db_existing_tdb_file", cn) > > second = SamDB(url="tdb://" + existing_name, flags=0) > cn = second.searchone("cn", dn) >- self.assertEquals(b"test_dont_create_db_existing_tdb_file", cn) >+ self.assertEqual(b"test_dont_create_db_existing_tdb_file", cn) > > # Open a non existent TDB file. > # Don't create new db is set, the default >@@ -139,13 +139,13 @@ class SamDBApiTestCase(TestCaseInTempDir): > self.fail("Exception not thrown ") > except LdbError as e1: > (err, _) = e1.args >- self.assertEquals(err, ERR_OPERATIONS_ERROR) >+ self.assertEqual(err, ERR_OPERATIONS_ERROR) > > try: > file = open(self.tempdir + "/test.db", "r") > self.fail("New database file created") > except IOError as e: >- self.assertEquals(e.errno, errno.ENOENT) >+ self.assertEqual(e.errno, errno.ENOENT) > > # Open a SamDB with the don't create new DB flag cleared. > # The underlying database file does not exist. >@@ -157,4 +157,4 @@ class SamDBApiTestCase(TestCaseInTempDir): > SamDB(url="tdb://" + self.tempdir + "/test.db", flags=0) > existing = open(self.tempdir + "/test.db", mode="rb") > contents = existing.readline() >- self.assertEquals(b"TDB file\n", contents) >+ self.assertEqual(b"TDB file\n", contents) >diff --git a/python/samba/tests/security.py b/python/samba/tests/security.py >index 1b1c1557eee..1dacf78499a 100644 >--- a/python/samba/tests/security.py >+++ b/python/samba/tests/security.py >@@ -59,11 +59,11 @@ class SecurityDescriptorTests(samba.tests.TestCase): > > def test_from_sddl(self): > desc = security.descriptor.from_sddl("O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)", security.dom_sid("S-2-0-0")) >- self.assertEquals(desc.group_sid, security.dom_sid('S-2-0-0-512')) >- self.assertEquals(desc.owner_sid, security.dom_sid('S-1-5-32-548')) >- self.assertEquals(desc.revision, 1) >- self.assertEquals(desc.sacl, None) >- self.assertEquals(desc.type, 0x8004) >+ self.assertEqual(desc.group_sid, security.dom_sid('S-2-0-0-512')) >+ self.assertEqual(desc.owner_sid, security.dom_sid('S-1-5-32-548')) >+ self.assertEqual(desc.revision, 1) >+ self.assertEqual(desc.sacl, None) >+ self.assertEqual(desc.type, 0x8004) > > def test_from_sddl_invalidsddl(self): > self.assertRaises(TypeError, security.descriptor.from_sddl, "foo", security.dom_sid("S-2-0-0")) >@@ -81,10 +81,10 @@ class SecurityDescriptorTests(samba.tests.TestCase): > dom = security.dom_sid("S-2-0-0") > desc1 = security.descriptor.from_sddl(text, dom) > desc2 = security.descriptor.from_sddl(desc1.as_sddl(dom), dom) >- self.assertEquals(desc1.group_sid, desc2.group_sid) >- self.assertEquals(desc1.owner_sid, desc2.owner_sid) >- self.assertEquals(desc1.sacl, desc2.sacl) >- self.assertEquals(desc1.type, desc2.type) >+ self.assertEqual(desc1.group_sid, desc2.group_sid) >+ self.assertEqual(desc1.owner_sid, desc2.owner_sid) >+ self.assertEqual(desc1.sacl, desc2.sacl) >+ self.assertEqual(desc1.type, desc2.type) > > def test_as_sddl_invalid(self): > text = "O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)" >@@ -97,10 +97,10 @@ class SecurityDescriptorTests(samba.tests.TestCase): > text = "O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)" > desc1 = security.descriptor.from_sddl(text, dom) > desc2 = security.descriptor.from_sddl(desc1.as_sddl(), dom) >- self.assertEquals(desc1.group_sid, desc2.group_sid) >- self.assertEquals(desc1.owner_sid, desc2.owner_sid) >- self.assertEquals(desc1.sacl, desc2.sacl) >- self.assertEquals(desc1.type, desc2.type) >+ self.assertEqual(desc1.group_sid, desc2.group_sid) >+ self.assertEqual(desc1.owner_sid, desc2.owner_sid) >+ self.assertEqual(desc1.sacl, desc2.sacl) >+ self.assertEqual(desc1.type, desc2.type) > > def test_domsid_nodomsid_as_sddl(self): > dom = security.dom_sid("S-2-0-0") >@@ -110,20 +110,20 @@ class SecurityDescriptorTests(samba.tests.TestCase): > > def test_split(self): > dom = security.dom_sid("S-2-0-7") >- self.assertEquals((security.dom_sid("S-2-0"), 7), dom.split()) >+ self.assertEqual((security.dom_sid("S-2-0"), 7), dom.split()) > > > class DomSidTests(samba.tests.TestCase): > > def test_parse_sid(self): > sid = security.dom_sid("S-1-5-21") >- self.assertEquals("S-1-5-21", str(sid)) >+ self.assertEqual("S-1-5-21", str(sid)) > > def test_sid_equal(self): > sid1 = security.dom_sid("S-1-5-21") > sid2 = security.dom_sid("S-1-5-21") >- self.assertEquals(sid1, sid1) >- self.assertEquals(sid1, sid2) >+ self.assertEqual(sid1, sid1) >+ self.assertEqual(sid1, sid2) > > def test_random(self): > sid = security.random_sid() >@@ -137,11 +137,11 @@ class DomSidTests(samba.tests.TestCase): > class PrivilegeTests(samba.tests.TestCase): > > def test_privilege_name(self): >- self.assertEquals("SeShutdownPrivilege", >+ self.assertEqual("SeShutdownPrivilege", > security.privilege_name(security.SEC_PRIV_SHUTDOWN)) > > def test_privilege_id(self): >- self.assertEquals(security.SEC_PRIV_SHUTDOWN, >+ self.assertEqual(security.SEC_PRIV_SHUTDOWN, > security.privilege_id("SeShutdownPrivilege")) > > >diff --git a/python/samba/tests/smb.py b/python/samba/tests/smb.py >index 5a52885c2f4..e43b030adcc 100644 >--- a/python/samba/tests/smb.py >+++ b/python/samba/tests/smb.py >@@ -194,14 +194,14 @@ class SMBTests(samba.tests.TestCase): > self.smb_conn.savefile(test_file, test_contents.encode('utf8')) > > contents = self.smb_conn.loadfile(test_file) >- self.assertEquals(contents.decode('utf8'), test_contents, >+ self.assertEqual(contents.decode('utf8'), test_contents, > msg='contents of test file did not match what was written') > > # check we can overwrite the file with new contents > new_contents = 'wxyz' * 128 > self.smb_conn.savefile(test_file, new_contents.encode('utf8')) > contents = self.smb_conn.loadfile(test_file) >- self.assertEquals(contents.decode('utf8'), new_contents, >+ self.assertEqual(contents.decode('utf8'), new_contents, > msg='contents of test file did not match what was written') > > # with python2 this will save/load str type (with embedded nulls) >@@ -210,7 +210,7 @@ class SMBTests(samba.tests.TestCase): > self.smb_conn.savefile(test_file, test_literal_bytes_embed_nulls) > > contents = self.smb_conn.loadfile(test_file) >- self.assertEquals(contents, test_literal_bytes_embed_nulls, >+ self.assertEqual(contents, test_literal_bytes_embed_nulls, > msg='contents of test file did not match what was written') > > # python3 only this will save/load unicode >@@ -219,7 +219,7 @@ class SMBTests(samba.tests.TestCase): > self.smb_conn.savefile(test_file, utf_contents.encode('utf8')) > > contents = self.smb_conn.loadfile(test_file) >- self.assertEquals(contents.decode('utf8'), utf_contents, >+ self.assertEqual(contents.decode('utf8'), utf_contents, > msg='contents of test file did not match what was written') > > # with python2 this will save/load str type >@@ -228,7 +228,7 @@ class SMBTests(samba.tests.TestCase): > self.smb_conn.savefile(test_file, binary_contents) > > contents = self.smb_conn.loadfile(test_file) >- self.assertEquals(contents, binary_contents, >+ self.assertEqual(contents, binary_contents, > msg='contents of test file did not match what was written') > > def make_sysvol_path(self, dirpath, filename): >diff --git a/python/samba/tests/strings.py b/python/samba/tests/strings.py >index 657d99496fc..e812df8a97e 100644 >--- a/python/samba/tests/strings.py >+++ b/python/samba/tests/strings.py >@@ -60,7 +60,7 @@ class strcasecmp_m_Tests(samba.tests.TestCase): > (KATAKANA_LETTER_A, 'a', 1), > ] > for a, b, expect in cases: >- self.assertEquals(signum(strcasecmp_m(a, b)), expect) >+ self.assertEqual(signum(strcasecmp_m(a, b)), expect) > > > class strstr_m_Tests(samba.tests.TestCase): >@@ -96,4 +96,4 @@ class strstr_m_Tests(samba.tests.TestCase): > (KATAKANA_LETTER_A * 3, 'a', None), > ] > for a, b, expect in cases: >- self.assertEquals(strstr_m(a, b), expect) >+ self.assertEqual(strstr_m(a, b), expect) >diff --git a/python/samba/tests/upgrade.py b/python/samba/tests/upgrade.py >index 9e539a98ff5..0cca2d0dc6c 100644 >--- a/python/samba/tests/upgrade.py >+++ b/python/samba/tests/upgrade.py >@@ -29,12 +29,12 @@ class WinsUpgradeTests(LdbTestCase): > } > import_wins(self.ldb, winsdb) > >- self.assertEquals( >+ self.assertEqual( > ['name=FOO,type=0x20'], > [str(m.dn) for m in > self.ldb.search(expression="(objectClass=winsRecord)")]) > > def test_version(self): > import_wins(self.ldb, {}) >- self.assertEquals("VERSION", >+ self.assertEqual("VERSION", > str(self.ldb.search(expression="(objectClass=winsMaxVersion)")[0]["cn"])) >diff --git a/python/samba/tests/upgradeprovision.py b/python/samba/tests/upgradeprovision.py >index ab091676fca..5f77a777fc9 100644 >--- a/python/samba/tests/upgradeprovision.py >+++ b/python/samba/tests/upgradeprovision.py >@@ -54,11 +54,11 @@ class UpgradeProvisionTestCase(TestCaseInTempDir): > # higher level comes after lower even if lexicographicaly closer > # ie dc=tata,dc=toto (2 levels), comes after dc=toto > # even if dc=toto is lexicographicaly after dc=tata, dc=toto >- self.assertEquals(dn_sort("dc=tata,dc=toto", "dc=toto"), 1) >- self.assertEquals(dn_sort("dc=zata", "dc=tata"), 1) >- self.assertEquals(dn_sort("dc=toto,dc=tata", >+ self.assertEqual(dn_sort("dc=tata,dc=toto", "dc=toto"), 1) >+ self.assertEqual(dn_sort("dc=zata", "dc=tata"), 1) >+ self.assertEqual(dn_sort("dc=toto,dc=tata", > "cn=foo,dc=toto,dc=tata"), -1) >- self.assertEquals(dn_sort("cn=bar, dc=toto,dc=tata", >+ self.assertEqual(dn_sort("cn=bar, dc=toto,dc=tata", > "cn=foo, dc=toto,dc=tata"), -1) > > def test_get_diff_sds(self): >@@ -81,17 +81,17 @@ class UpgradeProvisionTestCase(TestCaseInTempDir): > (A;CI;RPWPCRCCLCLORCWOWDSW;;;SA)\ > (A;CI;RP LCLORC;;;AU)(A;CI;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)S:AI(AU;CISA;WP;;;WD)(AU;CIIDSA;WP;;;WD)" > >- self.assertEquals(get_diff_sds(security.descriptor.from_sddl(sddl, domsid), >+ self.assertEqual(get_diff_sds(security.descriptor.from_sddl(sddl, domsid), > security.descriptor.from_sddl(sddl1, domsid), > domsid), "") > txt = get_diff_sds(security.descriptor.from_sddl(sddl, domsid), > security.descriptor.from_sddl(sddl2, domsid), > domsid) >- self.assertEquals(txt, "\tOwner mismatch: SA (in ref) BA(in current)\n") >+ self.assertEqual(txt, "\tOwner mismatch: SA (in ref) BA(in current)\n") > txt = get_diff_sds(security.descriptor.from_sddl(sddl, domsid), > security.descriptor.from_sddl(sddl3, domsid), > domsid) >- self.assertEquals(txt, "\tGroup mismatch: DU (in ref) BA(in current)\n") >+ self.assertEqual(txt, "\tGroup mismatch: DU (in ref) BA(in current)\n") > txt = get_diff_sds(security.descriptor.from_sddl(sddl, domsid), > security.descriptor.from_sddl(sddl4, domsid), > domsid) >@@ -99,25 +99,25 @@ class UpgradeProvisionTestCase(TestCaseInTempDir): > is the detail:\n\t\t(A;CI;RPWPCRCCLCLORCWOWDSW;;;BA) ACE is not present in\ > the reference\n\t\t(A;CI;RPWPCRCCLCLORCWOWDSW;;;SA) ACE is not present in\ > the current\n" >- self.assertEquals(txt, txtmsg) >+ self.assertEqual(txt, txtmsg) > > txt = get_diff_sds(security.descriptor.from_sddl(sddl, domsid), > security.descriptor.from_sddl(sddl5, domsid), > domsid) >- self.assertEquals(txt, "\tCurrent ACL hasn't a sacl part\n") >- self.assertEquals(get_diff_sds(security.descriptor.from_sddl(sddl, domsid), >+ self.assertEqual(txt, "\tCurrent ACL hasn't a sacl part\n") >+ self.assertEqual(get_diff_sds(security.descriptor.from_sddl(sddl, domsid), > security.descriptor.from_sddl(sddl6, domsid), > domsid), "") > > def test_construct_existor_expr(self): > res = construct_existor_expr([]) >- self.assertEquals(res, "") >+ self.assertEqual(res, "") > > res = construct_existor_expr(["foo"]) >- self.assertEquals(res, "(|(foo=*))") >+ self.assertEqual(res, "(|(foo=*))") > > res = construct_existor_expr(["foo", "bar"]) >- self.assertEquals(res, "(|(foo=*)(bar=*))") >+ self.assertEqual(res, "(|(foo=*)(bar=*))") > > > class UpdateSecretsTests(samba.tests.TestCaseInTempDir): >@@ -137,7 +137,7 @@ class UpdateSecretsTests(samba.tests.TestCaseInTempDir): > def test_trivial(self): > # Test that updating an already up-to-date secretsdb works fine > self.secretsdb = self._getCurrentFormatDb() >- self.assertEquals(None, >+ self.assertEqual(None, > update_secrets(self.referencedb, self.secretsdb, dummymessage)) > > def test_update_modules(self): >@@ -145,7 +145,7 @@ class UpdateSecretsTests(samba.tests.TestCaseInTempDir): > update_secrets(self.referencedb, empty_db, dummymessage) > newmodules = empty_db.search(base="@MODULES", scope=SCOPE_BASE) > refmodules = self.referencedb.search(base="@MODULES", scope=SCOPE_BASE) >- self.assertEquals(newmodules.msgs, refmodules.msgs) >+ self.assertEqual(newmodules.msgs, refmodules.msgs) > > def tearDown(self): > for name in ["ref.ldb", "secrets.ldb", "secrets.tdb", "secrets.tdb.bak", "secrets.ntdb"]: >diff --git a/python/samba/tests/upgradeprovisionneeddc.py b/python/samba/tests/upgradeprovisionneeddc.py >index b665e5ba3c7..45a29da0d17 100644 >--- a/python/samba/tests/upgradeprovisionneeddc.py >+++ b/python/samba/tests/upgradeprovisionneeddc.py >@@ -64,8 +64,8 @@ class UpgradeProvisionBasicLdbHelpersTestCase(TestCaseInTempDir): > ldbs = get_ldbs(paths, creds, system_session(), lp) > names = find_provision_key_parameters(ldbs.sam, ldbs.secrets, ldbs.idmap, > paths, smb_conf_path, lp) >- self.assertEquals(names.realm, "SAMBA.EXAMPLE.COM") >- self.assertEquals(str(names.rootdn).lower(), rootdn.lower()) >+ self.assertEqual(names.realm, "SAMBA.EXAMPLE.COM") >+ self.assertEqual(str(names.rootdn).lower(), rootdn.lower()) > self.assertNotEquals(names.policyid_dc, None) > self.assertNotEquals(names.ntdsguid, "") > >@@ -125,8 +125,8 @@ class UpgradeProvisionWithLdbTestCase(TestCaseInTempDir): > identic_rename(self.ldbs.sam, guestDN) > res = self.ldbs.sam.search(expression="(name=Guest)", base=rootdn, > scope=ldb.SCOPE_SUBTREE, attrs=["dn"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["dn"]), "CN=Guest,CN=Users,%s" % rootdn) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["dn"]), "CN=Guest,CN=Users,%s" % rootdn) > > def test_delta_update_basesamdb(self): > dummysampath = self._getEmptyDbName() >diff --git a/python/samba/tests/xattr.py b/python/samba/tests/xattr.py >index 5943464c047..d2aa49309f3 100644 >--- a/python/samba/tests/xattr.py >+++ b/python/samba/tests/xattr.py >@@ -66,7 +66,7 @@ class XattrTests(TestCase): > try: > samba.xattr_native.wrap_setxattr(tempf, "user.unittests", reftxt) > text = samba.xattr_native.wrap_getxattr(tempf, "user.unittests") >- self.assertEquals(text, reftxt) >+ self.assertEqual(text, reftxt) > except IOError: > raise SkipTest("the filesystem where the tests are runned do not support XATTR") > os.unlink(tempf) >@@ -106,7 +106,7 @@ class XattrTests(TestCase): > reftxt) > text = samba.xattr_tdb.wrap_getxattr(eadb_path, tempf, > "user.unittests") >- self.assertEquals(text, reftxt) >+ self.assertEqual(text, reftxt) > finally: > os.unlink(tempf) > os.unlink(eadb_path) >@@ -134,7 +134,7 @@ class XattrTests(TestCase): > reftxt) > text = samba.posix_eadb.wrap_getxattr(eadb_path, tempf, > "user.unittests") >- self.assertEquals(text, reftxt) >+ self.assertEqual(text, reftxt) > finally: > os.unlink(tempf) > os.unlink(eadb_path) >diff --git a/source4/dsdb/tests/python/acl.py b/source4/dsdb/tests/python/acl.py >index dbad8a36a8d..6c46a6130df 100755 >--- a/source4/dsdb/tests/python/acl.py >+++ b/source4/dsdb/tests/python/acl.py >@@ -207,7 +207,7 @@ class AclAddTests(AclTests): > grouptype=samba.dsdb.GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP) > except LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > # Make sure we HAVEN'T created any of two objects -- user or group >@@ -232,7 +232,7 @@ class AclAddTests(AclTests): > grouptype=samba.dsdb.GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP) > except LdbError as e1: > (num, _) = e1.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > # Make sure we HAVE created the one of two objects -- user >@@ -269,7 +269,7 @@ class AclAddTests(AclTests): > anonymous.newuser("test_add_anonymous", self.user_pass) > except LdbError as e2: > (num, _) = e2.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > else: > self.fail() > >@@ -383,7 +383,7 @@ url: www.samba.org""" > self.ldb_user.modify_ldif(ldif) > except LdbError as e3: > (num, _) = e3.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > # This 'modify' operation should always throw ERR_INSUFFICIENT_ACCESS_RIGHTS > self.fail() >@@ -412,7 +412,7 @@ url: www.samba.org""" > self.ldb_user.modify_ldif(ldif) > except LdbError as e4: > (num, _) = e4.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > # This 'modify' operation should always throw ERR_INSUFFICIENT_ACCESS_RIGHTS > self.fail() >@@ -428,7 +428,7 @@ displayName: test_changed""" > self.ldb_user.modify_ldif(ldif) > except LdbError as e5: > (num, _) = e5.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > # This 'modify' operation should always throw ERR_INSUFFICIENT_ACCESS_RIGHTS > self.fail() >@@ -456,7 +456,7 @@ url: www.samba.org""" > self.ldb_user.modify_ldif(ldif) > except LdbError as e6: > (num, _) = e6.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > # This 'modify' operation should always throw ERR_INSUFFICIENT_ACCESS_RIGHTS > self.fail() >@@ -476,7 +476,7 @@ url: www.samba.org""" > self.ldb_user.modify_ldif(ldif) > except LdbError as e7: > (num, _) = e7.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > # This 'modify' operation should always throw ERR_INSUFFICIENT_ACCESS_RIGHTS > self.fail() >@@ -495,7 +495,7 @@ url: www.samba.org""" > self.ldb_user.modify_ldif(ldif) > except LdbError as e8: > (num, _) = e8.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > # This 'modify' operation should always throw ERR_INSUFFICIENT_ACCESS_RIGHTS > self.fail() >@@ -514,7 +514,7 @@ url: www.samba.org""" > self.ldb_user.modify_ldif(ldif) > except LdbError as e9: > (num, _) = e9.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > # This 'modify' operation should always throw ERR_INSUFFICIENT_ACCESS_RIGHTS > self.fail() >@@ -530,7 +530,7 @@ adminDescription: blah blah blah""" > self.ldb_user.modify_ldif(ldif) > except LdbError as e10: > (num, _) = e10.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > # This 'modify' operation should always throw ERR_INSUFFICIENT_ACCESS_RIGHTS > self.fail() >@@ -555,7 +555,7 @@ Member: """ + self.get_user_dn(self.user_with_sm) > self.ldb_user2.modify_ldif(ldif) > except LdbError as e11: > (num, _) = e11.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > # This 'modify' operation should always throw ERR_INSUFFICIENT_ACCESS_RIGHTS > self.fail() >@@ -578,7 +578,7 @@ Member: CN=test_modify_user2,CN=Users,""" + self.base_dn > self.ldb_user2.modify_ldif(ldif) > except LdbError as e12: > (num, _) = e12.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > >@@ -599,7 +599,7 @@ Member: CN=test_modify_user2,CN=Users,""" + self.base_dn > self.ldb_user2.modify_ldif(ldif) > except LdbError as e13: > (num, _) = e13.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > >@@ -647,7 +647,7 @@ Member: CN=test_modify_user2,CN=Users,""" + self.base_dn > anonymous.modify(m) > except LdbError as e14: > (num, _) = e14.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > else: > self.fail() > >@@ -732,7 +732,7 @@ class AclSearchTests(AclTests): > """Verify access of rootDSE with the correct request""" > anonymous = SamDB(url=ldaphost, credentials=self.creds_tmp, lp=lp) > res = anonymous.search("", expression="(objectClass=*)", scope=SCOPE_BASE) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > # verify some of the attributes > # don't care about values > self.assertTrue("ldapServiceName" in res[0]) >@@ -751,14 +751,14 @@ class AclSearchTests(AclTests): > res = anonymous.search("", expression="(objectClass=*)", scope=SCOPE_SUBTREE) > except LdbError as e15: > (num, _) = e15.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > else: > self.fail() > try: > res = anonymous.search(self.base_dn, expression="(objectClass=*)", scope=SCOPE_SUBTREE) > except LdbError as e16: > (num, _) = e16.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > else: > self.fail() > try: >@@ -766,7 +766,7 @@ class AclSearchTests(AclTests): > scope=SCOPE_SUBTREE) > except LdbError as e17: > (num, _) = e17.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > else: > self.fail() > >@@ -780,13 +780,13 @@ class AclSearchTests(AclTests): > anonymous = SamDB(url=ldaphost, credentials=self.creds_tmp, lp=lp) > res = anonymous.search("OU=test_search_ou2,OU=test_search_ou1," + self.base_dn, > expression="(objectClass=*)", scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertTrue("dn" in res[0]) > self.assertTrue(res[0]["dn"] == Dn(self.ldb_admin, > "OU=test_search_ou2,OU=test_search_ou1," + self.base_dn)) > res = anonymous.search(anonymous.get_config_basedn(), expression="(objectClass=*)", > scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertTrue("dn" in res[0]) > self.assertTrue(res[0]["dn"] == Dn(self.ldb_admin, self.configuration_dn)) > >@@ -806,25 +806,25 @@ class AclSearchTests(AclTests): > # regular users must see only ou1 and ou2 > res = self.ldb_user3.search("OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 2) >+ self.assertEqual(len(res), 2) > ok_list = [Dn(self.ldb_admin, "OU=ou2,OU=ou1," + self.base_dn), > Dn(self.ldb_admin, "OU=ou1," + self.base_dn)] > > res_list = [x["dn"] for x in res if x["dn"] in ok_list] >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > # these users should see all ous > res = self.ldb_user.search("OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 6) >+ self.assertEqual(len(res), 6) > res_list = [x["dn"] for x in res if x["dn"] in self.full_list] >- self.assertEquals(sorted(res_list), sorted(self.full_list)) >+ self.assertEqual(sorted(res_list), sorted(self.full_list)) > > res = self.ldb_user2.search("OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 6) >+ self.assertEqual(len(res), 6) > res_list = [x["dn"] for x in res if x["dn"] in self.full_list] >- self.assertEquals(sorted(res_list), sorted(self.full_list)) >+ self.assertEqual(sorted(res_list), sorted(self.full_list)) > > def test_search2(self): > """Make sure users can't see us if access is explicitly denied""" >@@ -840,7 +840,7 @@ class AclSearchTests(AclTests): > scope=SCOPE_SUBTREE) > # this user should see all ous > res_list = [x["dn"] for x in res if x["dn"] in self.full_list] >- self.assertEquals(sorted(res_list), sorted(self.full_list)) >+ self.assertEqual(sorted(res_list), sorted(self.full_list)) > > # these users should see ou1, 2, 5 and 6 but not 3 and 4 > res = self.ldb_user.search("OU=ou1," + self.base_dn, expression="(objectClass=*)", >@@ -850,13 +850,13 @@ class AclSearchTests(AclTests): > Dn(self.ldb_admin, "OU=ou5,OU=ou3,OU=ou2,OU=ou1," + self.base_dn), > Dn(self.ldb_admin, "OU=ou6,OU=ou4,OU=ou2,OU=ou1," + self.base_dn)] > res_list = [x["dn"] for x in res if x["dn"] in ok_list] >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > res = self.ldb_user2.search("OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 4) >+ self.assertEqual(len(res), 4) > res_list = [x["dn"] for x in res if x["dn"] in ok_list] >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > def test_search3(self): > """Make sure users can't see ous if access is explicitly denied - 2""" >@@ -877,7 +877,7 @@ class AclSearchTests(AclTests): > scope=SCOPE_BASE) > except LdbError as e18: > (num, _) = e18.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > else: > self.fail() > >@@ -890,7 +890,7 @@ class AclSearchTests(AclTests): > res = self.ldb_user3.search("OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_SUBTREE) > res_list = [x["dn"] for x in res if x["dn"] in ok_list] >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > ok_list = [Dn(self.ldb_admin, "OU=ou2,OU=ou1," + self.base_dn), > Dn(self.ldb_admin, "OU=ou1," + self.base_dn), >@@ -900,15 +900,15 @@ class AclSearchTests(AclTests): > # should not see ou3 and ou4, but should see ou5 and ou6 > res = self.ldb_user.search("OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 4) >+ self.assertEqual(len(res), 4) > res_list = [x["dn"] for x in res if x["dn"] in ok_list] >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > res = self.ldb_user2.search("OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 4) >+ self.assertEqual(len(res), 4) > res_list = [x["dn"] for x in res if x["dn"] in ok_list] >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > def test_search4(self): > """There is no difference in visibility if the user is also creator""" >@@ -927,15 +927,15 @@ class AclSearchTests(AclTests): > Dn(self.ldb_admin, "OU=ou1," + self.base_dn)] > res = self.ldb_user3.search("OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 2) >+ self.assertEqual(len(res), 2) > res_list = [x["dn"] for x in res if x["dn"] in ok_list] >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > res = self.ldb_user.search("OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 2) >+ self.assertEqual(len(res), 2) > res_list = [x["dn"] for x in res if x["dn"] in ok_list] >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > def test_search5(self): > """Make sure users can see only attributes they are allowed to see""" >@@ -949,16 +949,16 @@ class AclSearchTests(AclTests): > res = self.ldb_user.search("OU=ou2,OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_SUBTREE) > ok_list = ['dn'] >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > res_list = list(res[0].keys()) >- self.assertEquals(res_list, ok_list) >+ self.assertEqual(res_list, ok_list) > > res = self.ldb_user.search("OU=ou2,OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_BASE, attrs=["ou"]) > >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > res_list = list(res[0].keys()) >- self.assertEquals(res_list, ok_list) >+ self.assertEqual(res_list, ok_list) > > # give read property on ou and assert user can only see dn and ou > mod = "(OA;;RP;bf9679f0-0de6-11d0-a285-00aa003049e2;;%s)" % (str(self.user_sid)) >@@ -967,9 +967,9 @@ class AclSearchTests(AclTests): > res = self.ldb_user.search("OU=ou2,OU=ou1," + self.base_dn, expression="(objectClass=*)", > scope=SCOPE_SUBTREE) > ok_list = ['dn', 'ou'] >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > res_list = list(res[0].keys()) >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > # give read property on Public Information and assert user can see ou and other members > mod = "(OA;;RP;e48d0154-bcf8-11d1-8702-00c04fb96050;;%s)" % (str(self.user_sid)) >@@ -980,7 +980,7 @@ class AclSearchTests(AclTests): > > ok_list = ['dn', 'objectClass', 'ou', 'distinguishedName', 'name', 'objectGUID', 'objectCategory'] > res_list = list(res[0].keys()) >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > def test_search6(self): > """If an attribute that cannot be read is used in a filter, it is as if the attribute does not exist""" >@@ -995,36 +995,36 @@ class AclSearchTests(AclTests): > res = self.ldb_user.search("OU=ou1," + self.base_dn, expression="(ou=ou3)", > scope=SCOPE_SUBTREE) > # nothing should be returned as ou is not accessible >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # give read property on ou and assert user can only see dn and ou > mod = "(OA;;RP;bf9679f0-0de6-11d0-a285-00aa003049e2;;%s)" % (str(self.user_sid)) > self.sd_utils.dacl_add_ace("OU=ou3,OU=ou2,OU=ou1," + self.base_dn, mod) > res = self.ldb_user.search("OU=ou1," + self.base_dn, expression="(ou=ou3)", > scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > ok_list = ['dn', 'ou'] > res_list = list(res[0].keys()) >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > # give read property on Public Information and assert user can see ou and other members > mod = "(OA;;RP;e48d0154-bcf8-11d1-8702-00c04fb96050;;%s)" % (str(self.user_sid)) > self.sd_utils.dacl_add_ace("OU=ou2,OU=ou1," + self.base_dn, mod) > res = self.ldb_user.search("OU=ou1," + self.base_dn, expression="(ou=ou2)", > scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > ok_list = ['dn', 'objectClass', 'ou', 'distinguishedName', 'name', 'objectGUID', 'objectCategory'] > res_list = list(res[0].keys()) >- self.assertEquals(sorted(res_list), sorted(ok_list)) >+ self.assertEqual(sorted(res_list), sorted(ok_list)) > > def assert_search_on_attr(self, dn, samdb, attr, expected_list): > > expected_num = len(expected_list) > res = samdb.search(dn, expression="(%s=*)" % attr, scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), expected_num) >+ self.assertEqual(len(res), expected_num) > > res_list = [ x["dn"] for x in res if x["dn"] in expected_list ] >- self.assertEquals(sorted(res_list), sorted(expected_list)) >+ self.assertEqual(sorted(res_list), sorted(expected_list)) > > def test_search7(self): > """Checks object search visibility when users don't have full rights""" >@@ -1115,7 +1115,7 @@ class AclDeleteTests(AclTests): > self.ldb_user.delete(self.get_user_dn("test_delete_user1")) > except LdbError as e19: > (num, _) = e19.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > >@@ -1154,7 +1154,7 @@ class AclDeleteTests(AclTests): > anonymous.delete(self.get_user_dn("test_anonymous")) > except LdbError as e20: > (num, _) = e20.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > else: > self.fail() > >@@ -1210,7 +1210,7 @@ class AclRenameTests(AclTests): > "CN=%s,%s,%s" % (self.testuser5, self.ou1, self.base_dn)) > except LdbError as e21: > (num, _) = e21.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > >@@ -1368,7 +1368,7 @@ class AclRenameTests(AclTests): > self.ldb_user.rename(ou2_dn, ou3_dn) > except LdbError as e22: > (num, _) = e22.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > # This rename operation should always throw ERR_INSUFFICIENT_ACCESS_RIGHTS > self.fail() >@@ -1400,7 +1400,7 @@ class AclRenameTests(AclTests): > self.ldb_admin.rename(user_dn, rename_user_dn) > except LdbError as e23: > (num, _) = e23.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > # add an allow ace so we can delete this ou >@@ -1461,7 +1461,7 @@ unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS2\"".encode('utf-16-le')). > """) > except LdbError as e24: > (num, _) = e24.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > else: > # for some reason we get constraint violation instead of insufficient access error > self.fail() >@@ -1488,7 +1488,7 @@ unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS2\"".encode('utf-16-le')). > """) > except LdbError as e25: > (num, _) = e25.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > else: > # for some reason we get constraint violation instead of insufficient access error > self.fail() >@@ -1528,7 +1528,7 @@ dBCSPwd: YYYYYYYYYYYYYYYY > """) > except LdbError as e26: > (num, _) = e26.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > else: > self.fail() > >@@ -1547,7 +1547,7 @@ userPassword: thatsAcomplPASS2 > """) > except LdbError as e27: > (num, _) = e27.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > mod = "(OA;;CR;00299570-246d-11d0-a768-00aa006e0529;;PS)" >@@ -1607,7 +1607,7 @@ unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS1\"".encode('utf-16-le')). > """) > except LdbError as e29: > (num, _) = e29.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > mod = "(OA;;CR;00299570-246d-11d0-a768-00aa006e0529;;PS)" >@@ -1630,7 +1630,7 @@ userPassword: thatsAcomplPASS1 > """) > except LdbError as e30: > (num, _) = e30.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > mod = "(OA;;CR;00299570-246d-11d0-a768-00aa006e0529;;PS)" >@@ -1645,7 +1645,7 @@ userPassword: thatsAcomplPASS1 > # This fails on Windows 2000 domain level with constraint violation > except LdbError as e31: > (num, _) = e31.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > def test_reset_password3(self): > """Grant WP and see what happens (unicodePwd)""" >@@ -1660,7 +1660,7 @@ unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS1\"".encode('utf-16-le')). > """) > except LdbError as e32: > (num, _) = e32.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > >@@ -1677,7 +1677,7 @@ userPassword: thatsAcomplPASS1 > """) > except LdbError as e33: > (num, _) = e33.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > >@@ -1706,7 +1706,7 @@ userPassword: thatsAcomplPASS1 > # This fails on Windows 2000 domain level with constraint violation > except LdbError as e34: > (num, _) = e34.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > > class AclExtendedTests(AclTests): >@@ -1836,7 +1836,7 @@ class AclUndeleteTests(AclTests): > self.ldb_admin.delete(self.get_user_dn(new_user)) > res = self.ldb_admin.search(base="<GUID=%s>" % self.GUID_string(guid), > scope=SCOPE_BASE, controls=["show_deleted:1"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > return str(res[0].dn) > > def undelete_deleted(self, olddn, newdn): >@@ -1867,7 +1867,7 @@ class AclUndeleteTests(AclTests): > self.fail() > except LdbError as e35: > (num, _) = e35.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > # seems that permissions on isDeleted and distinguishedName are irrelevant > mod = "(OD;;WP;bf96798f-0de6-11d0-a285-00aa003049e2;;%s)" % str(self.sid) >@@ -1884,7 +1884,7 @@ class AclUndeleteTests(AclTests): > self.fail() > except LdbError as e36: > (num, _) = e36.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > # undelete in an ou, in which we have no right to create children > mod = "(D;;CC;;;%s)" % str(self.sid) >@@ -1894,7 +1894,7 @@ class AclUndeleteTests(AclTests): > self.fail() > except LdbError as e37: > (num, _) = e37.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > # delete is not required > mod = "(D;;SD;;;%s)" % str(self.sid) >@@ -1909,7 +1909,7 @@ class AclUndeleteTests(AclTests): > self.fail() > except LdbError as e38: > (num, _) = e38.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > > class AclSPNTests(AclTests): >@@ -2022,7 +2022,7 @@ class AclSPNTests(AclTests): > self.replace_spn(self.ldb_user1, ctx.acct_dn, "HOST/%s/%s" % (ctx.myname, netbiosdomain)) > except LdbError as e39: > (num, _) = e39.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > mod = "(OA;;SW;f3a64788-5306-11d1-a9c5-0000f80367c1;;%s)" % str(self.user_sid1) > self.sd_utils.dacl_add_ace(ctx.acct_dn, mod) >@@ -2060,30 +2060,30 @@ class AclSPNTests(AclTests): > (ctx.myname, ctx.dnsdomain, ctx.dnsdomain)) > except LdbError as e40: > (num, _) = e40.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > try: > self.replace_spn(self.ldb_user1, ctx.acct_dn, "ldap/%s.%s/DomainDnsZones.%s" % > (ctx.myname, ctx.dnsdomain, ctx.dnsdomain)) > except LdbError as e41: > (num, _) = e41.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > try: > self.replace_spn(self.ldb_user1, ctx.acct_dn, "nosuchservice/%s/%s" % ("abcd", "abcd")) > except LdbError as e42: > (num, _) = e42.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > try: > self.replace_spn(self.ldb_user1, ctx.acct_dn, "GC/%s.%s/%s" % > (ctx.myname, ctx.dnsdomain, netbiosdomain)) > except LdbError as e43: > (num, _) = e43.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > try: > self.replace_spn(self.ldb_user1, ctx.acct_dn, "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s" % > (ctx.ntds_guid, ctx.dnsdomain)) > except LdbError as e44: > (num, _) = e44.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > def test_computer_spn(self): > # with WP, any value can be set >@@ -2128,7 +2128,7 @@ class AclSPNTests(AclTests): > self.replace_spn(self.ldb_user1, self.computerdn, "HOST/%s/%s" % (self.computername, netbiosdomain)) > except LdbError as e45: > (num, _) = e45.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > mod = "(OA;;SW;f3a64788-5306-11d1-a9c5-0000f80367c1;;%s)" % str(self.user_sid1) > self.sd_utils.dacl_add_ace(self.computerdn, mod) >@@ -2146,42 +2146,42 @@ class AclSPNTests(AclTests): > self.replace_spn(self.ldb_user1, self.computerdn, "HOST/%s/%s" % (self.computername, netbiosdomain)) > except LdbError as e46: > (num, _) = e46.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > try: > self.replace_spn(self.ldb_user1, self.computerdn, "HOST/%s.%s/%s" % > (self.computername, self.dcctx.dnsdomain, netbiosdomain)) > except LdbError as e47: > (num, _) = e47.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > try: > self.replace_spn(self.ldb_user1, self.computerdn, "HOST/%s/%s" % > (self.computername, self.dcctx.dnsdomain)) > except LdbError as e48: > (num, _) = e48.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > try: > self.replace_spn(self.ldb_user1, self.computerdn, "HOST/%s.%s/%s" % > (self.computername, self.dcctx.dnsdomain, self.dcctx.dnsdomain)) > except LdbError as e49: > (num, _) = e49.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > try: > self.replace_spn(self.ldb_user1, self.computerdn, "GC/%s.%s/%s" % > (self.computername, self.dcctx.dnsdomain, self.dcctx.dnsforest)) > except LdbError as e50: > (num, _) = e50.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > try: > self.replace_spn(self.ldb_user1, self.computerdn, "ldap/%s/%s" % (self.computername, netbiosdomain)) > except LdbError as e51: > (num, _) = e51.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > try: > self.replace_spn(self.ldb_user1, self.computerdn, "ldap/%s.%s/ForestDnsZones.%s" % > (self.computername, self.dcctx.dnsdomain, self.dcctx.dnsdomain)) > except LdbError as e52: > (num, _) = e52.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > def test_spn_rwdc(self): > self.dc_spn_test(self.dcctx) >diff --git a/source4/dsdb/tests/python/deletetest.py b/source4/dsdb/tests/python/deletetest.py >index 25a26c77221..a2a19a12650 100755 >--- a/source4/dsdb/tests/python/deletetest.py >+++ b/source4/dsdb/tests/python/deletetest.py >@@ -62,7 +62,7 @@ class BaseDeleteTests(samba.tests.TestCase): > scope=SCOPE_BASE, > controls=["show_deleted:1"], > attrs=["*", "parentGUID"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > return res[0] > > def search_dn(self, dn): >@@ -73,7 +73,7 @@ class BaseDeleteTests(samba.tests.TestCase): > scope=SCOPE_BASE, > controls=["show_deleted:1"], > attrs=["*", "parentGUID"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > return res[0] > > >@@ -85,7 +85,7 @@ class BasicDeleteTests(BaseDeleteTests): > def del_attr_values(self, delObj): > print("Checking attributes for %s" % delObj["dn"]) > >- self.assertEquals(str(delObj["isDeleted"][0]), "TRUE") >+ self.assertEqual(str(delObj["isDeleted"][0]), "TRUE") > self.assertTrue(not("objectCategory" in delObj)) > self.assertTrue(not("sAMAccountType" in delObj)) > >@@ -111,9 +111,9 @@ class BasicDeleteTests(BaseDeleteTests): > name2 = delObj["name"][0] > dn_rdn = delObj.dn.get_rdn_value() > guid = liveObj["objectGUID"][0] >- self.assertEquals(str(rdn2), ("%s\nDEL:%s" % (rdn, self.GUID_string(guid)))) >- self.assertEquals(str(name2), ("%s\nDEL:%s" % (rdn, self.GUID_string(guid)))) >- self.assertEquals(str(name2), dn_rdn) >+ self.assertEqual(str(rdn2), ("%s\nDEL:%s" % (rdn, self.GUID_string(guid)))) >+ self.assertEqual(str(name2), ("%s\nDEL:%s" % (rdn, self.GUID_string(guid)))) >+ self.assertEqual(str(name2), dn_rdn) > > def delete_deleted(self, ldb, dn): > print("Testing the deletion of the already deleted dn %s" % dn) >@@ -123,7 +123,7 @@ class BasicDeleteTests(BaseDeleteTests): > self.fail() > except LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > def test_delete_protection(self): > """Delete protection tests""" >@@ -149,7 +149,7 @@ class BasicDeleteTests(BaseDeleteTests): > self.fail() > except LdbError as e1: > (num, _) = e1.args >- self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF) >+ self.assertEqual(num, ERR_NOT_ALLOWED_ON_NON_LEAF) > > self.ldb.delete("cn=ldaptestcontainer," + self.base_dn, ["tree_delete:1"]) > >@@ -159,21 +159,21 @@ class BasicDeleteTests(BaseDeleteTests): > self.fail() > except LdbError as e2: > (num, _) = e2.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > try: > res = self.ldb.search("cn=entry1,cn=ldaptestcontainer," + self.base_dn, > scope=SCOPE_BASE, attrs=[]) > self.fail() > except LdbError as e3: > (num, _) = e3.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > try: > res = self.ldb.search("cn=entry2,cn=ldaptestcontainer," + self.base_dn, > scope=SCOPE_BASE, attrs=[]) > self.fail() > except LdbError as e4: > (num, _) = e4.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn) > delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn) >@@ -183,7 +183,7 @@ class BasicDeleteTests(BaseDeleteTests): > > res = self.ldb.search(base="", expression="", scope=SCOPE_BASE, > attrs=["dsServiceName", "dNSHostName"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > # Delete failing since DC's nTDSDSA object is protected > try: >@@ -191,11 +191,11 @@ class BasicDeleteTests(BaseDeleteTests): > self.fail() > except LdbError as e5: > (num, _) = e5.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > res = self.ldb.search(self.base_dn, attrs=["rIDSetReferences"], > expression="(&(objectClass=computer)(dNSHostName=" + str(res[0]["dNSHostName"][0]) + "))") >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > # Deletes failing since DC's rIDSet object is protected > try: >@@ -203,13 +203,13 @@ class BasicDeleteTests(BaseDeleteTests): > self.fail() > except LdbError as e6: > (num, _) = e6.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > try: > self.ldb.delete(res[0]["rIDSetReferences"][0], ["tree_delete:1"]) > self.fail() > except LdbError as e7: > (num, _) = e7.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Deletes failing since three main crossRef objects are protected > >@@ -218,43 +218,43 @@ class BasicDeleteTests(BaseDeleteTests): > self.fail() > except LdbError as e8: > (num, _) = e8.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > try: > self.ldb.delete("cn=Enterprise Schema,cn=Partitions," + self.configuration_dn, ["tree_delete:1"]) > self.fail() > except LdbError as e9: > (num, _) = e9.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > self.ldb.delete("cn=Enterprise Configuration,cn=Partitions," + self.configuration_dn) > self.fail() > except LdbError as e10: > (num, _) = e10.args >- self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF) >+ self.assertEqual(num, ERR_NOT_ALLOWED_ON_NON_LEAF) > try: > self.ldb.delete("cn=Enterprise Configuration,cn=Partitions," + self.configuration_dn, ["tree_delete:1"]) > self.fail() > except LdbError as e11: > (num, _) = e11.args >- self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF) >+ self.assertEqual(num, ERR_NOT_ALLOWED_ON_NON_LEAF) > > res = self.ldb.search("cn=Partitions," + self.configuration_dn, attrs=[], > expression="(nCName=%s)" % self.base_dn) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > try: > self.ldb.delete(res[0].dn) > self.fail() > except LdbError as e12: > (num, _) = e12.args >- self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF) >+ self.assertEqual(num, ERR_NOT_ALLOWED_ON_NON_LEAF) > try: > self.ldb.delete(res[0].dn, ["tree_delete:1"]) > self.fail() > except LdbError as e13: > (num, _) = e13.args >- self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF) >+ self.assertEqual(num, ERR_NOT_ALLOWED_ON_NON_LEAF) > > # Delete failing since "SYSTEM_FLAG_DISALLOW_DELETE" > try: >@@ -262,7 +262,7 @@ class BasicDeleteTests(BaseDeleteTests): > self.fail() > except LdbError as e14: > (num, _) = e14.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Tree-delete failing since "isCriticalSystemObject" > try: >@@ -270,7 +270,7 @@ class BasicDeleteTests(BaseDeleteTests): > self.fail() > except LdbError as e15: > (num, _) = e15.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > > class BasicTreeDeleteTests(BasicDeleteTests): >diff --git a/source4/dsdb/tests/python/dirsync.py b/source4/dsdb/tests/python/dirsync.py >index 35293c084e8..662ff3a7654 100755 >--- a/source4/dsdb/tests/python/dirsync.py >+++ b/source4/dsdb/tests/python/dirsync.py >@@ -249,7 +249,7 @@ class SimpleDirsyncTests(DirsyncBaseTests): > expression="(distinguishedName=%s)" % str(self.base_dn), > attrs=["objectGUID"], > controls=["dirsync:1:0:1"]) >- self.assertEquals(len(res.msgs), 0) >+ self.assertEqual(len(res.msgs), 0) > > # a request on the root of a NC didn't return parentGUID > res = self.ldb_admin.search(self.base_dn, >@@ -610,7 +610,7 @@ class ExtendedDirsyncTests(SimpleDirsyncTests): > controls=["dirsync:1:0:0"]) > except LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail() > >diff --git a/source4/dsdb/tests/python/dsdb_schema_info.py b/source4/dsdb/tests/python/dsdb_schema_info.py >index 8554e6c6082..f7e9a997543 100755 >--- a/source4/dsdb/tests/python/dsdb_schema_info.py >+++ b/source4/dsdb/tests/python/dsdb_schema_info.py >@@ -55,7 +55,7 @@ class SchemaInfoTestCase(samba.tests.TestCase): > > # fetch rootDSE > res = self.sam_db.search(base="", expression="", scope=SCOPE_BASE, attrs=["*"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.schema_dn = res[0]["schemaNamingContext"][0] > self.base_dn = res[0]["defaultNamingContext"][0] > self.forest_level = int(res[0]["forestFunctionality"][0]) >diff --git a/source4/dsdb/tests/python/ldap.py b/source4/dsdb/tests/python/ldap.py >index 1d4b19adcbc..5a607e9a509 100755 >--- a/source4/dsdb/tests/python/ldap.py >+++ b/source4/dsdb/tests/python/ldap.py >@@ -121,7 +121,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e1: > (num, _) = e1.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > # Invalid objectclass specified > try: >@@ -131,7 +131,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e2: > (num, _) = e2.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > > # Invalid objectCategory specified > try: >@@ -142,7 +142,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e3: > (num, _) = e3.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # Multi-valued "systemFlags" > try: >@@ -153,7 +153,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e4: > (num, _) = e4.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > # We cannot instanciate from an abstract object class ("connectionPoint" > # or "leaf"). In the first case we use "connectionPoint" (subclass of >@@ -168,7 +168,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e5: > (num, _) = e5.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > try: > self.ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, >@@ -176,7 +176,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e6: > (num, _) = e6.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # Objects instanciated using "satisfied" abstract classes (concrete > # subclasses) are allowed >@@ -194,7 +194,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e7: > (num, _) = e7.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # Test allowed system flags > self.ldb.add({ >@@ -205,7 +205,7 @@ class BasicTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["systemFlags"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["systemFlags"][0]), "0") >+ self.assertEqual(str(res[0]["systemFlags"][0]), "0") > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >@@ -237,7 +237,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e8: > (num, _) = e8.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # We cannot delete classes which weren't specified > m = Message() >@@ -249,7 +249,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e9: > (num, _) = e9.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > > # An invalid class cannot be added > m = Message() >@@ -261,7 +261,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e10: > (num, _) = e10.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > > # We cannot add a the new top-most structural class "user" here since > # we are missing at least one new mandatory attribute (in this case >@@ -275,7 +275,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e11: > (num, _) = e11.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # An already specified objectclass cannot be added another time > m = Message() >@@ -287,7 +287,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e12: > (num, _) = e12.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > # Auxiliary classes can always be added > m = Message() >@@ -307,7 +307,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e13: > (num, _) = e13.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # Objectclass replace operations can be performed as well > m = Message() >@@ -333,7 +333,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e14: > (num, _) = e14.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # More than one change operation is allowed > m = Message() >@@ -351,7 +351,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e15: > (num, _) = e15.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -362,7 +362,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e16: > (num, _) = e16.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # Classes can be removed unless attributes of them are used. > m = Message() >@@ -400,7 +400,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e17: > (num, _) = e17.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # Remove the previously specified attribute > m = Message() >@@ -433,7 +433,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e18: > (num, _) = e18.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # Add a new top-most structural class "inetOrgPerson" and remove it > # afterwards >@@ -475,8 +475,8 @@ class BasicTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["objectClass"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["objectClass"][0]), "top") >- self.assertEquals(str(res[0]["objectClass"][len(res[0]["objectClass"]) - 1]), "user") >+ self.assertEqual(str(res[0]["objectClass"][0]), "top") >+ self.assertEqual(str(res[0]["objectClass"][len(res[0]["objectClass"]) - 1]), "user") > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >@@ -489,7 +489,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e19: > (num, _) = e19.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > self.ldb.add({ >@@ -498,7 +498,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e20: > (num, _) = e20.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn) > delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn) >@@ -525,7 +525,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e21: > (num, _) = e21.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn) > >@@ -537,7 +537,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e22: > (num, _) = e22.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > self.ldb.add({ > "dn": "cn=ldaptestcontainer," + self.base_dn, >@@ -552,7 +552,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e23: > (num, _) = e23.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn) > >@@ -568,7 +568,7 @@ class BasicTests(samba.tests.TestCase): > attrs=["isCriticalSystemObject"]) > self.assertTrue(len(res) == 1) > self.assertTrue("isCriticalSystemObject" in res[0]) >- self.assertEquals(str(res[0]["isCriticalSystemObject"][0]), "TRUE") >+ self.assertEqual(str(res[0]["isCriticalSystemObject"][0]), "TRUE") > > def test_invalid_parent(self): > """Test adding an object with invalid parent""" >@@ -580,7 +580,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e24: > (num, _) = e24.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123," > + self.base_dn) >@@ -592,7 +592,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e25: > (num, _) = e25.args >- self.assertEquals(num, ERR_NAMING_VIOLATION) >+ self.assertEqual(num, ERR_NAMING_VIOLATION) > > delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn) > >@@ -610,7 +610,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e26: > (num, _) = e26.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > > self.ldb.add({ > "dn": "cn=ldaptestgroup,cn=users," + self.base_dn, >@@ -627,7 +627,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e27: > (num, _) = e27.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > > # > # When searching the unknown attribute should be ignored >@@ -662,7 +662,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e28: > (num, _) = e28.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # inadequate but schema-valid attribute specified > try: >@@ -674,7 +674,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e29: > (num, _) = e29.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > self.ldb.add({ > "dn": "cn=ldaptestobject," + self.base_dn, >@@ -692,7 +692,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e30: > (num, _) = e30.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # mandatory attribute delete trial > m = Message() >@@ -704,7 +704,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e31: > (num, _) = e31.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # mandatory attribute delete trial > m = Message() >@@ -716,7 +716,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e32: > (num, _) = e32.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn) > >@@ -730,7 +730,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e33: > (num, _) = e33.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > self.ldb.add({ > "dn": "cn=ldaptestgroup,cn=users," + self.base_dn, >@@ -745,7 +745,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e34: > (num, _) = e34.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -762,7 +762,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e35: > (num, _) = e35.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -796,7 +796,7 @@ class BasicTests(samba.tests.TestCase): > self.fail("failed to fail to add multiple managedBy attributes") > except LdbError as e36: > (num, _) = e36.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > managee = "cn=group2," + ou > self.ldb.add({ >@@ -813,7 +813,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e37: > (num, _) = e37.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > m = Message() > m.dn = Dn(ldb, managee) >@@ -830,7 +830,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e38: > (num, _) = e38.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > self.ldb.delete(ou, ['tree_delete:1']) > >@@ -916,7 +916,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e39: > (num, _) = e39.args >- self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_ATTRIBUTE_SYNTAX) > > # Too long (max. 64) > # try: >@@ -926,7 +926,7 @@ class BasicTests(samba.tests.TestCase): > # "sn": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }) > # self.fail() > # except LdbError, (num, _): >-# self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+# self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, >@@ -941,7 +941,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e40: > (num, _) = e40.args >- self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_ATTRIBUTE_SYNTAX) > > # Too long (max. 64) > # m = Message() >@@ -951,7 +951,7 @@ class BasicTests(samba.tests.TestCase): > # ldb.modify(m) > # self.fail() > # except LdbError, (num, _): >-# self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+# self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -970,14 +970,14 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e41: > (num, _) = e41.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > try: > ldb.modify(m) > self.fail() > except LdbError as e42: > (num, _) = e42.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -993,7 +993,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e43: > (num, _) = e43.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > self.ldb.add({ > "dn": "cn=ldaptestgroup,cn=users," + self.base_dn, >@@ -1008,7 +1008,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e44: > (num, _) = e44.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -1023,7 +1023,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e45: > (num, _) = e45.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -1038,7 +1038,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e46: > (num, _) = e46.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # The head NC flag cannot be set without the write flag > try: >@@ -1049,7 +1049,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e47: > (num, _) = e47.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # We cannot manipulate NCs without the head NC flag > try: >@@ -1060,7 +1060,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e48: > (num, _) = e48.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > self.ldb.add({ > "dn": "cn=ldaptestgroup,cn=users," + self.base_dn, >@@ -1075,7 +1075,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e49: > (num, _) = e49.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -1086,7 +1086,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e50: > (num, _) = e50.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -1096,7 +1096,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e51: > (num, _) = e51.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -1109,7 +1109,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e52: > (num, _) = e52.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn) > > def test_distinguished_name(self): >@@ -1125,7 +1125,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e53: > (num, _) = e53.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > > # a wrong "distinguishedName" attribute is obviously tolerated > self.ldb.add({ >@@ -1152,7 +1152,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e54: > (num, _) = e54.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -1165,7 +1165,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e55: > (num, _) = e55.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -1178,7 +1178,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e56: > (num, _) = e56.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -1191,7 +1191,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e57: > (num, _) = e57.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -1205,7 +1205,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e58: > (num, _) = e58.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > # empty RDN name > try: >@@ -1213,14 +1213,14 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e59: > (num, _) = e59.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > try: > self.ldb.search("=ldaptestgroup,cn=users," + self.base_dn, scope=SCOPE_BASE) > self.fail() > except LdbError as e60: > (num, _) = e60.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > # Add > >@@ -1232,7 +1232,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e61: > (num, _) = e61.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > # empty RDN name > try: >@@ -1242,7 +1242,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e62: > (num, _) = e62.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > # empty RDN value > try: >@@ -1252,7 +1252,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e63: > (num, _) = e63.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > # a wrong RDN candidate > try: >@@ -1262,7 +1262,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e64: > (num, _) = e64.args >- self.assertEquals(num, ERR_NAMING_VIOLATION) >+ self.assertEqual(num, ERR_NAMING_VIOLATION) > > delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn) > >@@ -1290,7 +1290,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e65: > (num, _) = e65.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > # Delete > >@@ -1300,7 +1300,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e66: > (num, _) = e66.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > # Rename > >@@ -1311,7 +1311,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e67: > (num, _) = e67.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > # new empty RDN name > try: >@@ -1320,7 +1320,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e68: > (num, _) = e68.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > # new empty RDN value > try: >@@ -1329,7 +1329,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e69: > (num, _) = e69.args >- self.assertEquals(num, ERR_NAMING_VIOLATION) >+ self.assertEqual(num, ERR_NAMING_VIOLATION) > > # new wrong RDN candidate > try: >@@ -1338,7 +1338,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e70: > (num, _) = e70.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn) > >@@ -1349,7 +1349,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e71: > (num, _) = e71.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > # names > >@@ -1362,7 +1362,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e72: > (num, _) = e72.args >- self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN) >+ self.assertEqual(num, ERR_NOT_ALLOWED_ON_RDN) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -1373,7 +1373,7 @@ class BasicTests(samba.tests.TestCase): > self.fail() > except LdbError as e73: > (num, _) = e73.args >- self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN) >+ self.assertEqual(num, ERR_NOT_ALLOWED_ON_RDN) > > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -1402,7 +1402,7 @@ objectClass: container > self.fail() > except LdbError as e74: > (num, _) = e74.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn)) > > def test_rename(self): >@@ -1413,7 +1413,7 @@ objectClass: container > self.fail() > except LdbError as e75: > (num, _) = e75.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > # inexistent object >@@ -1421,7 +1421,7 @@ objectClass: container > self.fail() > except LdbError as e76: > (num, _) = e76.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > self.ldb.add({ > "dn": "cn=ldaptestuser2,cn=users," + self.base_dn, >@@ -1437,7 +1437,7 @@ objectClass: container > self.fail() > except LdbError as e77: > (num, _) = e77.args >- self.assertEquals(num, ERR_NAMING_VIOLATION) >+ self.assertEqual(num, ERR_NAMING_VIOLATION) > > try: > # invalid parent >@@ -1445,7 +1445,7 @@ objectClass: container > self.fail() > except LdbError as e78: > (num, _) = e78.args >- self.assertEquals(num, ERR_OTHER) >+ self.assertEqual(num, ERR_OTHER) > > try: > # invalid target DN syntax >@@ -1453,7 +1453,7 @@ objectClass: container > self.fail() > except LdbError as e79: > (num, _) = e79.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > try: > # invalid RDN name >@@ -1461,7 +1461,7 @@ objectClass: container > self.fail() > except LdbError as e80: > (num, _) = e80.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn) > >@@ -1473,7 +1473,7 @@ objectClass: container > self.fail() > except LdbError as e81: > (num, _) = e81.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Limited move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE" > try: >@@ -1481,7 +1481,7 @@ objectClass: container > self.fail() > except LdbError as e82: > (num, _) = e82.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Rename failing since no "SYSTEM_FLAG_CONFIG_ALLOW_RENAME" > try: >@@ -1489,7 +1489,7 @@ objectClass: container > self.fail() > except LdbError as e83: > (num, _) = e83.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # It's not really possible to test moves on the schema partition since > # there don't exist subcontainers on it. >@@ -1500,7 +1500,7 @@ objectClass: container > self.fail() > except LdbError as e84: > (num, _) = e84.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Move failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE" > try: >@@ -1508,7 +1508,7 @@ objectClass: container > self.fail() > except LdbError as e85: > (num, _) = e85.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Rename failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME" > try: >@@ -1516,7 +1516,7 @@ objectClass: container > self.fail() > except LdbError as e86: > (num, _) = e86.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Performs some other constraints testing > >@@ -1525,7 +1525,7 @@ objectClass: container > self.fail() > except LdbError as e87: > (num, _) = e87.args >- self.assertEquals(num, ERR_OTHER) >+ self.assertEqual(num, ERR_OTHER) > > def test_rename_twice(self): > """Tests the rename operation twice - this corresponds to a past bug""" >@@ -1540,9 +1540,9 @@ objectClass: container > "objectclass": "user"}) > ldb.rename("cn=ldaptestuser5,cn=Users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn) > res = ldb.search(expression="cn=ldaptestuser5") >- self.assertEquals(len(res), 1, "Wrong number of hits for cn=ldaptestuser5") >+ self.assertEqual(len(res), 1, "Wrong number of hits for cn=ldaptestuser5") > res = ldb.search(expression="(&(cn=ldaptestuser5)(objectclass=user))") >- self.assertEquals(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))") >+ self.assertEqual(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))") > delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn) > > def test_objectGUID(self): >@@ -1557,7 +1557,7 @@ objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d > self.fail() > except LdbError as e88: > (num, _) = e88.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > self.ldb.add({ > "dn": "cn=ldaptestcontainer," + self.base_dn, >@@ -1574,7 +1574,7 @@ objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d > self.fail() > except LdbError as e89: > (num, _) = e89.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn) > >@@ -1596,7 +1596,7 @@ objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d > attrs=["parentGUID"]) > > """Check if the parentGUID is valid """ >- self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]) >+ self.assertEqual(res1[0]["parentGUID"], res2[0]["objectGUID"]) > > """Check if it returns nothing when there is no parent object - default NC""" > has_parentGUID = False >@@ -1631,7 +1631,7 @@ objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d > break > self.assertTrue(has_another_attribute) > self.assertTrue(len(res1[0]["samaccountname"]) == 1) >- self.assertEquals(str(res1[0]["samaccountname"][0]), "parentguidtest") >+ self.assertEqual(str(res1[0]["samaccountname"][0]), "parentguidtest") > > # Testing parentGUID behaviour on rename\ > >@@ -1645,7 +1645,7 @@ objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d > res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn, > scope=SCOPE_BASE, > attrs=["parentGUID"]) >- self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]) >+ self.assertEqual(res1[0]["objectGUID"], res2[0]["parentGUID"]) > > delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn) > delete_force(self.ldb, "cn=testotherusers," + self.base_dn) >@@ -1813,11 +1813,11 @@ delete: description > res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE, > attrs=["groupType"], expression="groupType=-2147483643") > >- self.assertEquals(len(res1), len(res2)) >+ self.assertEqual(len(res1), len(res2)) > > self.assertTrue(res1.count > 0) > >- self.assertEquals(str(res1[0]["groupType"][0]), "-2147483643") >+ self.assertEqual(str(res1[0]["groupType"][0]), "-2147483643") > > def test_linked_attributes(self): > """This tests the linked attribute behaviour""" >@@ -1834,7 +1834,7 @@ delete: description > "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn}) > except LdbError as e90: > (num, _) = e90.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, >@@ -1849,7 +1849,7 @@ delete: description > self.fail() > except LdbError as e91: > (num, _) = e91.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -1866,7 +1866,7 @@ delete: description > self.fail() > except LdbError as e92: > (num, _) = e92.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -1877,7 +1877,7 @@ delete: description > self.fail() > except LdbError as e93: > (num, _) = e93.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -1915,27 +1915,27 @@ delete: description > """Test Well known GUID behaviours (including DN+Binary)""" > > res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn)) >- self.assertEquals(len(res2), 1) >+ self.assertEqual(len(res2), 1) > > # Prove that the matching rule is over the whole DN+Binary > res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd")) >- self.assertEquals(len(res2), 0) >+ self.assertEqual(len(res2), 0) > # Prove that the matching rule is over the whole DN+Binary > res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=%s") % res[0].dn) >- self.assertEquals(len(res2), 0) >+ self.assertEqual(len(res2), 0) > > def test_subschemasubentry(self): > """Test subSchemaSubEntry appears when requested, but not when not requested""" > > res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["subSchemaSubEntry"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["subSchemaSubEntry"][0]), "CN=Aggregate," + self.schema_dn) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["subSchemaSubEntry"][0]), "CN=Aggregate," + self.schema_dn) > > res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["*"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertTrue("subScheamSubEntry" not in res[0]) > > def test_all(self): >@@ -1974,7 +1974,7 @@ delete: description > self.fail() > except LdbError as e94: > (num, _) = e94.args >- self.assertEquals(num, ERR_INVALID_DN_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_DN_SYNTAX) > > try: > ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn, >@@ -1985,7 +1985,7 @@ delete: description > self.fail() > except LdbError as e95: > (num, _) = e95.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn, > "objectClass": "computer", >@@ -1994,22 +1994,22 @@ delete: description > > # Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user)) > res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))") >- self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res)) >- >- self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"][0]), "ldaptestcomputer3") >- self.assertEquals(str(res[0]["name"][0]), "ldaptestcomputer3") >- self.assertEquals(str(res[0]["objectClass"][0]), "top") >- self.assertEquals(str(res[0]["objectClass"][1]), "person") >- self.assertEquals(str(res[0]["objectClass"][2]), "organizationalPerson") >- self.assertEquals(str(res[0]["objectClass"][3]), "user") >- self.assertEquals(str(res[0]["objectClass"][4]), "computer") >+ self.assertEqual(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res)) >+ >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"][0]), "ldaptestcomputer3") >+ self.assertEqual(str(res[0]["name"][0]), "ldaptestcomputer3") >+ self.assertEqual(str(res[0]["objectClass"][0]), "top") >+ self.assertEqual(str(res[0]["objectClass"][1]), "person") >+ self.assertEqual(str(res[0]["objectClass"][2]), "organizationalPerson") >+ self.assertEqual(str(res[0]["objectClass"][3]), "user") >+ self.assertEqual(str(res[0]["objectClass"][4]), "computer") > self.assertTrue("objectGUID" in res[0]) > self.assertTrue("whenCreated" in res[0]) >- self.assertEquals(str(res[0]["objectCategory"][0]), ("CN=Computer,%s" % ldb.get_schema_basedn())) >- self.assertEquals(int(res[0]["primaryGroupID"][0]), 513) >- self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT) >- self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) >+ self.assertEqual(str(res[0]["objectCategory"][0]), ("CN=Computer,%s" % ldb.get_schema_basedn())) >+ self.assertEqual(int(res[0]["primaryGroupID"][0]), 513) >+ self.assertEqual(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT) >+ self.assertEqual(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) > > delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn) > >@@ -2026,7 +2026,7 @@ servicePrincipalName: cifs/ldaptest2computer > self.fail() > except LdbError as e96: > (num, msg) = e96.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > ldb.modify_ldif(""" > dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """ >@@ -2045,7 +2045,7 @@ servicePrincipalName: host/ldaptest2computer > self.fail() > except LdbError as e97: > (num, msg) = e97.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > # Testing ranged results > ldb.modify_ldif(""" >@@ -2092,44 +2092,44 @@ servicePrincipalName: host/ldaptest2computer29 > > res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, > attrs=["servicePrincipalName;range=0-*"]) >- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)") >- self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30) >+ self.assertEqual(len(res), 1, "Could not find (cn=ldaptest2computer)") >+ self.assertEqual(len(res[0]["servicePrincipalName;range=0-*"]), 30) > > res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"]) >- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)") >- self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20) >+ self.assertEqual(len(res), 1, "Could not find (cn=ldaptest2computer)") >+ self.assertEqual(len(res[0]["servicePrincipalName;range=0-19"]), 20) > > res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"]) >- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)") >- self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30) >+ self.assertEqual(len(res), 1, "Could not find (cn=ldaptest2computer)") >+ self.assertEqual(len(res[0]["servicePrincipalName;range=0-*"]), 30) > > res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"]) >- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)") >- self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30) >+ self.assertEqual(len(res), 1, "Could not find (cn=ldaptest2computer)") >+ self.assertEqual(len(res[0]["servicePrincipalName;range=0-*"]), 30) > > res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"]) >- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)") >- self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0) >+ self.assertEqual(len(res), 1, "Could not find (cn=ldaptest2computer)") >+ self.assertEqual(len(res[0]["servicePrincipalName;range=30-*"]), 0) > > res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"]) >- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)") >- self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20) >+ self.assertEqual(len(res), 1, "Could not find (cn=ldaptest2computer)") >+ self.assertEqual(len(res[0]["servicePrincipalName;range=10-*"]), 20) > # pos_11 = res[0]["servicePrincipalName;range=10-*"][18] > > res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"]) >- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)") >- self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19) >- # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11) >+ self.assertEqual(len(res), 1, "Could not find (cn=ldaptest2computer)") >+ self.assertEqual(len(res[0]["servicePrincipalName;range=11-*"]), 19) >+ # self.assertEqual((res[0]["servicePrincipalName;range=11-*"][18]), pos_11) > > res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"]) >- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)") >- self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5) >- # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11) >+ self.assertEqual(len(res), 1, "Could not find (cn=ldaptest2computer)") >+ self.assertEqual(len(res[0]["servicePrincipalName;range=11-15"]), 5) >+ # self.assertEqual(res[0]["servicePrincipalName;range=11-15"][4], pos_11) > > res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"]) >- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)") >- self.assertEquals(len(res[0]["servicePrincipalName"]), 30) >- # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11) >+ self.assertEqual(len(res), 1, "Could not find (cn=ldaptest2computer)") >+ self.assertEqual(len(res[0]["servicePrincipalName"]), 30) >+ # self.assertEqual(res[0]["servicePrincipalName"][18], pos_11) > > delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn) > ldb.add({ >@@ -2142,133 +2142,133 @@ servicePrincipalName: host/ldaptest2computer29 > # Testing Ambigious Name Resolution > # Testing ldb.search for (&(anr=ldap testy)(objectClass=user)) > res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))") >- self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res)) >+ self.assertEqual(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res)) > > # Testing ldb.search for (&(anr=testy ldap)(objectClass=user)) > res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))") >- self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res)) >+ self.assertEqual(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res)) > > # Testing ldb.search for (&(anr=ldap)(objectClass=user)) > res = ldb.search(expression="(&(anr=ldap)(objectClass=user))") >- self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res)) >+ self.assertEqual(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res)) > > # Testing ldb.search for (&(anr==ldap)(objectClass=user)) > res = ldb.search(expression="(&(anr==ldap)(objectClass=user))") >- self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res)) >+ self.assertEqual(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res)) > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"][0]), "ldaptestuser") >- self.assertEquals(str(res[0]["name"]), "ldaptestuser") >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"][0]), "ldaptestuser") >+ self.assertEqual(str(res[0]["name"]), "ldaptestuser") > > # Testing ldb.search for (&(anr=testy)(objectClass=user)) > res = ldb.search(expression="(&(anr=testy)(objectClass=user))") >- self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res)) >+ self.assertEqual(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res)) > > # Testing ldb.search for (&(anr=testy ldap)(objectClass=user)) > res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))") >- self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res)) >+ self.assertEqual(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res)) > > # Testing ldb.search for (&(anr==testy ldap)(objectClass=user)) > # this test disabled for the moment, as anr with == tests are not understood > # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))") >-# self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res)) >+# self.assertEqual(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res)) > >-# self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn)) >-# self.assertEquals(res[0]["cn"][0], "ldaptestuser") >-# self.assertEquals(res[0]["name"][0], "ldaptestuser") >+# self.assertEqual(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn)) >+# self.assertEqual(res[0]["cn"][0], "ldaptestuser") >+# self.assertEqual(res[0]["name"][0], "ldaptestuser") > > # Testing ldb.search for (&(anr==testy ldap)(objectClass=user)) > # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))") >-# self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))") >+# self.assertEqual(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))") > >-# self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn)) >-# self.assertEquals(res[0]["cn"][0], "ldaptestuser") >-# self.assertEquals(res[0]["name"][0], "ldaptestuser") >+# self.assertEqual(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn)) >+# self.assertEqual(res[0]["cn"][0], "ldaptestuser") >+# self.assertEqual(res[0]["name"][0], "ldaptestuser") > > # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user)) > res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))") >- self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))") >+ self.assertEqual(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"]), "ldaptestuser2") >- self.assertEquals(str(res[0]["name"]), "ldaptestuser2") >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"]), "ldaptestuser2") >+ self.assertEqual(str(res[0]["name"]), "ldaptestuser2") > > # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user)) > # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))") >-# self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))") >+# self.assertEqual(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"]), "ldaptestuser2") >- self.assertEquals(str(res[0]["name"]), "ldaptestuser2") >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"]), "ldaptestuser2") >+ self.assertEqual(str(res[0]["name"]), "ldaptestuser2") > > # Testing ldb.search for (&(anr==ldap user2)(objectClass=user)) > # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))") >-# self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))") >+# self.assertEqual(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"]), "ldaptestuser2") >- self.assertEquals(str(res[0]["name"]), "ldaptestuser2") >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"]), "ldaptestuser2") >+ self.assertEqual(str(res[0]["name"]), "ldaptestuser2") > > # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user)) > # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))") >-# self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))") >+# self.assertEqual(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))") > > # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user)) > res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))") >- self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))") >+ self.assertEqual(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))") > > # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes) > # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))") >-# self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))") >+# self.assertEqual(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))") > > # Testing Renames > > attrs = ["objectGUID", "objectSid"] > # Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user)) > res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs) >- self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))") >+ self.assertEqual(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))") > > # Check rename works with extended/alternate DN forms > ldb.rename("<SID=" + get_string(ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0])) + ">", "cn=ldaptestUSER3,cn=users," + self.base_dn) > > # Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user)) > res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))") >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3") >- self.assertEquals(str(res[0]["name"]), "ldaptestUSER3") >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"]), "ldaptestUSER3") >+ self.assertEqual(str(res[0]["name"]), "ldaptestUSER3") > > #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))" > res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))") >- self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))") >+ self.assertEqual(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3") >- self.assertEquals(str(res[0]["name"]), "ldaptestUSER3") >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"]), "ldaptestUSER3") >+ self.assertEqual(str(res[0]["name"]), "ldaptestUSER3") > > #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))" > res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))") >- self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))") >+ self.assertEqual(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3") >- self.assertEquals(str(res[0]["name"]), "ldaptestUSER3") >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"]), "ldaptestUSER3") >+ self.assertEqual(str(res[0]["name"]), "ldaptestUSER3") > > #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))" > res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))") >- self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))") >+ self.assertEqual(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))") > > # Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ") - should not work > res = ldb.search(expression="(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")") >- self.assertEquals(len(res), 0, "Could find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")") >+ self.assertEqual(len(res), 0, "Could find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")") > > # Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ") > res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")") >- self.assertEquals(len(res), 1, "Could not find (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")") >- self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3") >- self.assertEquals(str(res[0]["name"]), "ldaptestUSER3") >+ self.assertEqual(len(res), 1, "Could not find (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")") >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"]), "ldaptestUSER3") >+ self.assertEqual(str(res[0]["name"]), "ldaptestUSER3") > > # ensure we cannot add it again > try: >@@ -2278,7 +2278,7 @@ servicePrincipalName: host/ldaptest2computer29 > self.fail() > except LdbError as e98: > (num, _) = e98.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # rename back > ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn) >@@ -2290,7 +2290,7 @@ servicePrincipalName: host/ldaptest2computer29 > self.fail() > except LdbError as e99: > (num, _) = e99.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > # ensure can now use that name > ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn, >@@ -2303,7 +2303,7 @@ servicePrincipalName: host/ldaptest2computer29 > self.fail() > except LdbError as e100: > (num, _) = e100.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > try: > ldb.rename("cn=ldaptestuser3,cn=users,%s" % self.base_dn, "cn=ldaptestuser3,%s" % ldb.get_config_basedn()) > self.fail() >@@ -2351,7 +2351,7 @@ member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """ > > # Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) > res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))") >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))") > > # Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn > try: >@@ -2361,7 +2361,7 @@ member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """ > self.fail(res) > except LdbError as e102: > (num, _) = e102.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn > try: >@@ -2370,20 +2370,20 @@ member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """ > self.fail() > except LdbError as e103: > (num, _) = e103.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > # Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container" > res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn) >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn) > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)) >- self.assertEquals(str(res[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper()) >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)) >+ self.assertEqual(str(res[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper()) > > time.sleep(4) > > # Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes" > res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 1, "Could not find (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)), perhaps linked attributes are not consistant with subtree renames?") >+ self.assertEqual(len(res), 1, "Could not find (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)), perhaps linked attributes are not consistant with subtree renames?") > > # Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn > try: >@@ -2391,7 +2391,7 @@ member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """ > self.fail() > except LdbError as e104: > (num, _) = e104.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn > try: >@@ -2407,21 +2407,21 @@ member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """ > self.fail() > except LdbError as e106: > (num, _) = e106.args >- self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF) >+ self.assertEqual(num, ERR_NOT_ALLOWED_ON_NON_LEAF) > > # Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn > res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn > res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn > res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > # Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn) > ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)) >@@ -2434,144 +2434,144 @@ member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """ > > # Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))" > res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))") >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"]), "ldaptestuser") >- self.assertEquals(str(res[0]["name"]), "ldaptestuser") >- self.assertEquals(set(res[0]["objectClass"]), set([b"top", b"person", b"organizationalPerson", b"user"])) >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"]), "ldaptestuser") >+ self.assertEqual(str(res[0]["name"]), "ldaptestuser") >+ self.assertEqual(set(res[0]["objectClass"]), set([b"top", b"person", b"organizationalPerson", b"user"])) > self.assertTrue("objectGUID" in res[0]) > self.assertTrue("whenCreated" in res[0]) >- self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,%s" % ldb.get_schema_basedn())) >- self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT) >- self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) >- self.assertEquals(str(res[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper()) >- self.assertEquals(len(res[0]["memberOf"]), 1) >+ self.assertEqual(str(res[0]["objectCategory"]), ("CN=Person,%s" % ldb.get_schema_basedn())) >+ self.assertEqual(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT) >+ self.assertEqual(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) >+ self.assertEqual(str(res[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper()) >+ self.assertEqual(len(res[0]["memberOf"]), 1) > > # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn() > res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn()) >- self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn()) >+ self.assertEqual(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn()) > >- self.assertEquals(res[0].dn, res2[0].dn) >+ self.assertEqual(res[0].dn, res2[0].dn) > > # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))" > res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))") >- self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3)) >+ self.assertEqual(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3)) > >- self.assertEquals(res[0].dn, res3[0].dn) >+ self.assertEqual(res[0].dn, res3[0].dn) > > if gc_ldb is not None: > # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog" > res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))") >- self.assertEquals(len(res3gc), 1) >+ self.assertEqual(len(res3gc), 1) > >- self.assertEquals(res[0].dn, res3gc[0].dn) >+ self.assertEqual(res[0].dn, res3gc[0].dn) > > # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control" > > if gc_ldb is not None: > res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"]) >- self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog") >+ self.assertEqual(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog") > >- self.assertEquals(res[0].dn, res3control[0].dn) >+ self.assertEqual(res[0].dn, res3control[0].dn) > > ldb.delete(res[0].dn) > > # Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))" > res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))") >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer") >- self.assertEquals(str(res[0]["name"]), "ldaptestcomputer") >- self.assertEquals(set(res[0]["objectClass"]), set([b"top", b"person", b"organizationalPerson", b"user", b"computer"])) >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"]), "ldaptestcomputer") >+ self.assertEqual(str(res[0]["name"]), "ldaptestcomputer") >+ self.assertEqual(set(res[0]["objectClass"]), set([b"top", b"person", b"organizationalPerson", b"user", b"computer"])) > self.assertTrue("objectGUID" in res[0]) > self.assertTrue("whenCreated" in res[0]) >- self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,%s" % ldb.get_schema_basedn())) >- self.assertEquals(int(res[0]["primaryGroupID"][0]), 513) >- self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT) >- self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) >- self.assertEquals(str(res[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper()) >- self.assertEquals(len(res[0]["memberOf"]), 1) >+ self.assertEqual(str(res[0]["objectCategory"]), ("CN=Computer,%s" % ldb.get_schema_basedn())) >+ self.assertEqual(int(res[0]["primaryGroupID"][0]), 513) >+ self.assertEqual(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT) >+ self.assertEqual(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) >+ self.assertEqual(str(res[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper()) >+ self.assertEqual(len(res[0]["memberOf"]), 1) > > # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn() > res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn()) >- self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn()) >+ self.assertEqual(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn()) > >- self.assertEquals(res[0].dn, res2[0].dn) >+ self.assertEqual(res[0].dn, res2[0].dn) > > if gc_ldb is not None: > # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) in Global Catalog" % gc_ldb.get_schema_basedn() > res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % gc_ldb.get_schema_basedn()) >- self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) In Global Catalog" % gc_ldb.get_schema_basedn()) >+ self.assertEqual(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) In Global Catalog" % gc_ldb.get_schema_basedn()) > >- self.assertEquals(res[0].dn, res2gc[0].dn) >+ self.assertEqual(res[0].dn, res2gc[0].dn) > > # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))" > res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))") >- self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))") >+ self.assertEqual(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))") > >- self.assertEquals(res[0].dn, res3[0].dn) >+ self.assertEqual(res[0].dn, res3[0].dn) > > if gc_ldb is not None: > # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog" > res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))") >- self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog") >+ self.assertEqual(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog") > >- self.assertEquals(res[0].dn, res3gc[0].dn) >+ self.assertEqual(res[0].dn, res3gc[0].dn) > > # Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))" > res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))") >- self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))") >+ self.assertEqual(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))") > >- self.assertEquals(res[0].dn, res4[0].dn) >+ self.assertEqual(res[0].dn, res4[0].dn) > > # Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))" > res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))") >- self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))") >+ self.assertEqual(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))") > >- self.assertEquals(res[0].dn, res5[0].dn) >+ self.assertEqual(res[0].dn, res5[0].dn) > > # Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))" > res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))") >- self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))") >+ self.assertEqual(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))") > >- self.assertEquals(res[0].dn, res6[0].dn) >+ self.assertEqual(res[0].dn, res6[0].dn) > > ldb.delete("<GUID=" + get_string(ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0])) + ">") > > # Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))" > res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))") >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))") > >- self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn) >- self.assertEquals(str(res[0]["cn"]), "ldaptest2computer") >- self.assertEquals(str(res[0]["name"]), "ldaptest2computer") >- self.assertEquals(list(res[0]["objectClass"]), [b"top", b"person", b"organizationalPerson", b"user", b"computer"]) >+ self.assertEqual(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn) >+ self.assertEqual(str(res[0]["cn"]), "ldaptest2computer") >+ self.assertEqual(str(res[0]["name"]), "ldaptest2computer") >+ self.assertEqual(list(res[0]["objectClass"]), [b"top", b"person", b"organizationalPerson", b"user", b"computer"]) > self.assertTrue("objectGUID" in res[0]) > self.assertTrue("whenCreated" in res[0]) >- self.assertEquals(str(res[0]["objectCategory"][0]), "CN=Computer,%s" % ldb.get_schema_basedn()) >- self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST) >- self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT) >+ self.assertEqual(str(res[0]["objectCategory"][0]), "CN=Computer,%s" % ldb.get_schema_basedn()) >+ self.assertEqual(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST) >+ self.assertEqual(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT) > > ldb.delete("<SID=" + get_string(ldb.schema_format_value("objectSID", res[0]["objectSID"][0])) + ">") > > attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"] > # Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))" > res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs) >- self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))") >+ self.assertEqual(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))") > >- self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn)) >- self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2") >- self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2") >- self.assertEquals(list(res_user[0]["objectClass"]), [b"top", b"person", b"organizationalPerson", b"user"]) >+ self.assertEqual(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res_user[0]["cn"]), "ldaptestuser2") >+ self.assertEqual(str(res_user[0]["name"]), "ldaptestuser2") >+ self.assertEqual(list(res_user[0]["objectClass"]), [b"top", b"person", b"organizationalPerson", b"user"]) > self.assertTrue("objectSid" in res_user[0]) > self.assertTrue("objectGUID" in res_user[0]) > self.assertTrue("whenCreated" in res_user[0]) > self.assertTrue("nTSecurityDescriptor" in res_user[0]) > self.assertTrue("allowedAttributes" in res_user[0]) > self.assertTrue("allowedAttributesEffective" in res_user[0]) >- self.assertEquals(str(res_user[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper()) >+ self.assertEqual(str(res_user[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper()) > > ldaptestuser2_sid = res_user[0]["objectSid"][0] > ldaptestuser2_guid = res_user[0]["objectGUID"][0] >@@ -2579,12 +2579,12 @@ member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """ > attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"] > # Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))" > res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs) >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2") >- self.assertEquals(str(res[0]["name"]), "ldaptestgroup2") >- self.assertEquals(list(res[0]["objectClass"]), [b"top", b"group"]) >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"]), "ldaptestgroup2") >+ self.assertEqual(str(res[0]["name"]), "ldaptestgroup2") >+ self.assertEqual(list(res[0]["objectClass"]), [b"top", b"group"]) > self.assertTrue("objectGUID" in res[0]) > self.assertTrue("objectSid" in res[0]) > self.assertTrue("whenCreated" in res[0]) >@@ -2597,7 +2597,7 @@ member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """ > self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP) > > res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"]) >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))") > > print(res[0]["member"]) > memberUP = [] >@@ -2659,11 +2659,11 @@ member: CN=ldaptestutf8user èùéìòà ,CN=Users,""" + self.base_dn + """ > """) > > res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs) >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["member"][0]), ("CN=ldaptestuser2,CN=Users," + self.base_dn)) >- self.assertEquals(len(res[0]["member"]), 1) >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["member"][0]), ("CN=ldaptestuser2,CN=Users," + self.base_dn)) >+ self.assertEqual(len(res[0]["member"]), 1) > > ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn)) > >@@ -2672,21 +2672,21 @@ member: CN=ldaptestutf8user èùéìòà ,CN=Users,""" + self.base_dn + """ > attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"] > # Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete" > res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs) >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn)) > self.assertTrue("member" not in res[0]) > > # Testing ldb.search for (&(cn=ldaptestutf8user ÃÃÃÃÃÃ)(objectClass=user))" > res = ldb.search(expression="(&(cn=ldaptestutf8user ÃÃÃÃÃÃ)(objectClass=user))") >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÃÃÃÃÃÃ)(objectClass=user))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÃÃÃÃÃÃ)(objectClass=user))") > res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà )(objectclass=user))") >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÃÃÃÃÃÃ)(objectClass=user))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÃÃÃÃÃÃ)(objectClass=user))") > >- self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà ,CN=Users," + self.base_dn)) >- self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà ") >- self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà ") >- self.assertEquals(list(res[0]["objectClass"]), [b"top", b"person", b"organizationalPerson", b"user"]) >+ self.assertEqual(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà ,CN=Users," + self.base_dn)) >+ self.assertEqual(str(res[0]["cn"]), "ldaptestutf8user èùéìòà ") >+ self.assertEqual(str(res[0]["name"]), "ldaptestutf8user èùéìòà ") >+ self.assertEqual(list(res[0]["objectClass"]), [b"top", b"person", b"organizationalPerson", b"user"]) > self.assertTrue("objectGUID" in res[0]) > self.assertTrue("whenCreated" in res[0]) > >@@ -2695,11 +2695,11 @@ member: CN=ldaptestutf8user èùéìòà ,CN=Users,""" + self.base_dn + """ > > # Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))" > res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))") >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))") > > # Testing ldb.search for (&(cn=ldaptestutf8user2 ÃÃÃÃÃÃ)(objectClass=user))" > res = ldb.search(expression="(&(cn=ldaptestutf8user2 ÃÃÃÃÃÃ)(objectClass=user))") >- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2 ÃÃÃÃÃÃ)(objectClass=user))") >+ self.assertEqual(len(res), 1, "Could not find (&(cn=ldaptestutf8user2 ÃÃÃÃÃÃ)(objectClass=user))") > > # delete "ldaptestutf8user2 " > ldb.delete(res[0].dn) >@@ -2708,7 +2708,7 @@ member: CN=ldaptestutf8user èùéìòà ,CN=Users,""" + self.base_dn + """ > > # Testing that we can't get at the configuration DN from the main search base" > res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"]) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # Testing that we can get at the configuration DN from the main search base on the LDAP port with the 'phantom root' search_options control" > res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"]) >@@ -2748,9 +2748,9 @@ member: CN=ldaptestutf8user èùéìòà ,CN=Users,""" + self.base_dn + """ > # Testing objectClass attribute order on "+ self.base_dn > res = ldb.search(expression="objectClass=domain", base=self.base_dn, > scope=SCOPE_BASE, attrs=["objectClass"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > >- self.assertEquals(list(res[0]["objectClass"]), [b"top", b"domain", b"domainDNS"]) >+ self.assertEqual(list(res[0]["objectClass"]), [b"top", b"domain", b"domainDNS"]) > > # check enumeration > >@@ -2840,7 +2840,7 @@ objectClass: posixAccount""" % (self.base_dn)) > self.fail() > except LdbError as e107: > (num, _) = e107.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > finally: > delete_force(self.ldb, user_dn) > # >@@ -2927,7 +2927,7 @@ nTSecurityDescriptor:: """ + desc_base64) > self.fail() > except LdbError as e108: > (num, _) = e108.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > m = Message() > m.dn = Dn(ldb, user_dn) >@@ -2938,7 +2938,7 @@ nTSecurityDescriptor:: """ + desc_base64) > self.fail() > except LdbError as e109: > (num, _) = e109.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, user_dn) >@@ -2949,7 +2949,7 @@ nTSecurityDescriptor:: """ + desc_base64) > self.fail() > except LdbError as e110: > (num, _) = e110.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > delete_force(self.ldb, user_dn) > # >@@ -3089,14 +3089,14 @@ nTSecurityDescriptor:: """ + desc_base64 > self.fail() > except LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > dshstr = dshstr + str(i) > else: > # There does not seem to be an upper limit > self.ldb.set_dsheuristics(dshstr + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") > # apart from the above, all char values are accepted > self.ldb.set_dsheuristics("123ABC-+!1asdfg@#^") >- self.assertEquals(self.ldb.get_dsheuristics(), b"123ABC-+!1asdfg@#^") >+ self.assertEqual(self.ldb.get_dsheuristics(), b"123ABC-+!1asdfg@#^") > finally: > # restore old value > self.ldb.set_dsheuristics(dsheuristics) >@@ -3106,8 +3106,8 @@ nTSecurityDescriptor:: """ + desc_base64 > really return something""" > res = self.ldb.search(attrs=["cn"], > controls=["paged_results:1:10"]) >- self.assertEquals(len(res.controls), 1) >- self.assertEquals(res.controls[0].oid, "1.2.840.113556.1.4.319") >+ self.assertEqual(len(res.controls), 1) >+ self.assertEqual(res.controls[0].oid, "1.2.840.113556.1.4.319") > s = str(res.controls[0]) > > def test_operational(self): >@@ -3118,7 +3118,7 @@ nTSecurityDescriptor:: """ + desc_base64 > attrs=["createTimeStamp", "modifyTimeStamp", > "structuralObjectClass", "whenCreated", > "whenChanged"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertTrue("createTimeStamp" in res[0]) > self.assertTrue("modifyTimeStamp" in res[0]) > self.assertTrue("structuralObjectClass" in res[0]) >@@ -3162,7 +3162,7 @@ nTSecurityDescriptor:: """ + desc_base64 > self.assertTrue(len(res) == 1) > self.assertTrue("msTSExpireDate" in res[0]) > self.assertTrue(len(res[0]["msTSExpireDate"]) == 1) >- self.assertEquals(str(res[0]["msTSExpireDate"][0]), v_get) >+ self.assertEqual(str(res[0]["msTSExpireDate"][0]), v_get) > > > class BaseDnTests(samba.tests.TestCase): >@@ -3174,30 +3174,30 @@ class BaseDnTests(samba.tests.TestCase): > def test_rootdse_attrs(self): > """Testing for all rootDSE attributes""" > res = self.ldb.search("", scope=SCOPE_BASE, attrs=[]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > def test_highestcommittedusn(self): > """Testing for highestCommittedUSN""" > res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0) > > def test_netlogon(self): > """Testing for netlogon via LDAP""" > res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"]) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > def test_netlogon_highestcommitted_usn(self): > """Testing for netlogon and highestCommittedUSN via LDAP""" > res = self.ldb.search("", scope=SCOPE_BASE, > attrs=["netlogon", "highestCommittedUSN"]) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > def test_namingContexts(self): > """Testing for namingContexts in rootDSE""" > res = self.ldb.search("", scope=SCOPE_BASE, > attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > ncs = set([]) > for nc in res[0]["namingContexts"]: >@@ -3212,7 +3212,7 @@ class BaseDnTests(samba.tests.TestCase): > """Testing the server paths in rootDSE""" > res = self.ldb.search("", scope=SCOPE_BASE, > attrs=["dsServiceName", "serverName"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > self.assertTrue("CN=Servers" in str(res[0]["dsServiceName"][0])) > self.assertTrue("CN=Sites" in str(res[0]["dsServiceName"][0])) >@@ -3225,51 +3225,51 @@ class BaseDnTests(samba.tests.TestCase): > """Testing the server paths in rootDSE""" > res = self.ldb.search("", scope=SCOPE_BASE, > attrs=["forestFunctionality", "domainFunctionality", "domainControllerFunctionality"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(len(res[0]["forestFunctionality"]), 1) >- self.assertEquals(len(res[0]["domainFunctionality"]), 1) >- self.assertEquals(len(res[0]["domainControllerFunctionality"]), 1) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(len(res[0]["forestFunctionality"]), 1) >+ self.assertEqual(len(res[0]["domainFunctionality"]), 1) >+ self.assertEqual(len(res[0]["domainControllerFunctionality"]), 1) > > self.assertTrue(int(res[0]["forestFunctionality"][0]) <= int(res[0]["domainFunctionality"][0])) > self.assertTrue(int(res[0]["domainControllerFunctionality"][0]) >= int(res[0]["domainFunctionality"][0])) > > res2 = self.ldb.search("", scope=SCOPE_BASE, > attrs=["dsServiceName", "serverName"]) >- self.assertEquals(len(res2), 1) >- self.assertEquals(len(res2[0]["dsServiceName"]), 1) >+ self.assertEqual(len(res2), 1) >+ self.assertEqual(len(res2[0]["dsServiceName"]), 1) > > res3 = self.ldb.search(res2[0]["dsServiceName"][0], scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"]) >- self.assertEquals(len(res3), 1) >- self.assertEquals(len(res3[0]["msDS-Behavior-Version"]), 1) >- self.assertEquals(int(res[0]["domainControllerFunctionality"][0]), int(res3[0]["msDS-Behavior-Version"][0])) >+ self.assertEqual(len(res3), 1) >+ self.assertEqual(len(res3[0]["msDS-Behavior-Version"]), 1) >+ self.assertEqual(int(res[0]["domainControllerFunctionality"][0]), int(res3[0]["msDS-Behavior-Version"][0])) > > res4 = self.ldb.search(ldb.domain_dn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"]) >- self.assertEquals(len(res4), 1) >- self.assertEquals(len(res4[0]["msDS-Behavior-Version"]), 1) >- self.assertEquals(int(res[0]["domainFunctionality"][0]), int(res4[0]["msDS-Behavior-Version"][0])) >+ self.assertEqual(len(res4), 1) >+ self.assertEqual(len(res4[0]["msDS-Behavior-Version"]), 1) >+ self.assertEqual(int(res[0]["domainFunctionality"][0]), int(res4[0]["msDS-Behavior-Version"][0])) > > res5 = self.ldb.search("cn=partitions,%s" % ldb.get_config_basedn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"]) >- self.assertEquals(len(res5), 1) >- self.assertEquals(len(res5[0]["msDS-Behavior-Version"]), 1) >- self.assertEquals(int(res[0]["forestFunctionality"][0]), int(res5[0]["msDS-Behavior-Version"][0])) >+ self.assertEqual(len(res5), 1) >+ self.assertEqual(len(res5[0]["msDS-Behavior-Version"]), 1) >+ self.assertEqual(int(res[0]["forestFunctionality"][0]), int(res5[0]["msDS-Behavior-Version"][0])) > > def test_dnsHostname(self): > """Testing the DNS hostname in rootDSE""" > res = self.ldb.search("", scope=SCOPE_BASE, > attrs=["dnsHostName", "serverName"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > res2 = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE, > attrs=["dNSHostName"]) >- self.assertEquals(len(res2), 1) >+ self.assertEqual(len(res2), 1) > >- self.assertEquals(res[0]["dnsHostName"][0], res2[0]["dNSHostName"][0]) >+ self.assertEqual(res[0]["dnsHostName"][0], res2[0]["dNSHostName"][0]) > > def test_ldapServiceName(self): > """Testing the ldap service name in rootDSE""" > res = self.ldb.search("", scope=SCOPE_BASE, > attrs=["ldapServiceName", "dnsHostName"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertTrue("ldapServiceName" in res[0]) > self.assertTrue("dnsHostName" in res[0]) > >@@ -3277,7 +3277,7 @@ class BaseDnTests(samba.tests.TestCase): > > given = str(res[0]["ldapServiceName"][0]) > expected = "%s:%s$@%s" % (dns_domainname.lower(), hostname.lower(), dns_domainname.upper()) >- self.assertEquals(given, expected) >+ self.assertEqual(given, expected) > > > if "://" not in host: >diff --git a/source4/dsdb/tests/python/ldap_schema.py b/source4/dsdb/tests/python/ldap_schema.py >index eca7d857698..75115e1e251 100755 >--- a/source4/dsdb/tests/python/ldap_schema.py >+++ b/source4/dsdb/tests/python/ldap_schema.py >@@ -81,7 +81,7 @@ class SchemaTests(samba.tests.TestCase): > """Testing we can read the generated schema via LDAP""" > res = self.ldb.search("cn=aggregate," + self.schema_dn, scope=SCOPE_BASE, > attrs=["objectClasses", "attributeTypes", "dITContentRules"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertTrue("dITContentRules" in res[0]) > self.assertTrue("objectClasses" in res[0]) > self.assertTrue("attributeTypes" in res[0]) >@@ -91,7 +91,7 @@ class SchemaTests(samba.tests.TestCase): > # Must keep the "*" form > res = self.ldb.search("cn=aggregate," + self.schema_dn, scope=SCOPE_BASE, > attrs=["*"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertFalse("dITContentRules" in res[0]) > self.assertFalse("objectClasses" in res[0]) > self.assertFalse("attributeTypes" in res[0]) >@@ -131,8 +131,8 @@ schemaUpdateNow: 1 > res = [] > res = self.ldb.search("cn=%s,%s" % (attr_name, self.schema_dn), scope=SCOPE_BASE, > attrs=["lDAPDisplayName", "schemaIDGUID", "msDS-IntID"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["lDAPDisplayName"][0]), attr_ldap_display_name) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["lDAPDisplayName"][0]), attr_ldap_display_name) > self.assertTrue("schemaIDGUID" in res[0]) > if "msDS-IntId" in res[0]: > msDS_IntId = int(res[0]["msDS-IntId"][0]) >@@ -168,7 +168,7 @@ systemOnly: FALSE > self.fail() > except LdbError as e1: > (num, _) = e1.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > ldif = """ > dn: CN=%s,%s""" % (class_name, self.schema_dn) + """ >@@ -193,9 +193,9 @@ systemOnly: FALSE > res = [] > res = self.ldb.search("cn=%s,%s" % (class_name, self.schema_dn), scope=SCOPE_BASE, > attrs=["lDAPDisplayName", "defaultObjectCategory", "schemaIDGUID", "distinguishedName"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["lDAPDisplayName"][0]), class_ldap_display_name) >- self.assertEquals(res[0]["defaultObjectCategory"][0], res[0]["distinguishedName"][0]) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["lDAPDisplayName"][0]), class_ldap_display_name) >+ self.assertEqual(res[0]["defaultObjectCategory"][0], res[0]["distinguishedName"][0]) > self.assertTrue("schemaIDGUID" in res[0]) > > ldif = """ >@@ -226,7 +226,7 @@ name: """ + object_name + """ > # Search for created object > obj_res = self.ldb.search("cn=%s,cn=Users,%s" % (object_name, self.base_dn), scope=SCOPE_BASE, attrs=["replPropertyMetaData"]) > >- self.assertEquals(len(obj_res), 1) >+ self.assertEqual(len(obj_res), 1) > self.assertTrue("replPropertyMetaData" in obj_res[0]) > val = obj_res[0]["replPropertyMetaData"][0] > repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob, val) >@@ -273,9 +273,9 @@ systemOnly: FALSE > res = self.ldb.search("cn=%s,%s" % (class_name, self.schema_dn), scope=SCOPE_BASE, > attrs=["lDAPDisplayName", "defaultObjectCategory", > "schemaIDGUID", "distinguishedName"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["lDAPDisplayName"][0]), class_ldap_display_name) >- self.assertEquals(res[0]["defaultObjectCategory"][0], res[0]["distinguishedName"][0]) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["lDAPDisplayName"][0]), class_ldap_display_name) >+ self.assertEqual(res[0]["defaultObjectCategory"][0], res[0]["distinguishedName"][0]) > self.assertTrue("schemaIDGUID" in res[0]) > > ldif = """ >@@ -299,7 +299,7 @@ instanceType: 4 > # Search for created object > res = [] > res = self.ldb.search("ou=%s,%s" % (object_name, self.base_dn), scope=SCOPE_BASE, attrs=["dn"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > # Delete the object > delete_force(self.ldb, "ou=%s,%s" % (object_name, self.base_dn)) > >@@ -344,7 +344,7 @@ systemOnly: FALSE > self.fail("Should have failed to add duplicate attributeID value") > except LdbError as e2: > (enum, estr) = e2.args >- self.assertEquals(enum, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(enum, ERR_UNWILLING_TO_PERFORM) > > def test_duplicate_attributeID_governsID(self): > """Testing creating a duplicate attribute and class""" >@@ -388,7 +388,7 @@ systemOnly: FALSE > self.fail("Should have failed to add duplicate governsID conflicting with attributeID value") > except LdbError as e3: > (enum, estr) = e3.args >- self.assertEquals(enum, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(enum, ERR_UNWILLING_TO_PERFORM) > > def test_duplicate_cn(self): > """Testing creating a duplicate attribute""" >@@ -431,7 +431,7 @@ systemOnly: FALSE > self.fail("Should have failed to add attribute with duplicate CN") > except LdbError as e4: > (enum, estr) = e4.args >- self.assertEquals(enum, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(enum, ERR_ENTRY_ALREADY_EXISTS) > > def test_duplicate_implicit_ldapdisplayname(self): > """Testing creating a duplicate attribute ldapdisplayname""" >@@ -475,7 +475,7 @@ systemOnly: FALSE > self.fail("Should have failed to add attribute with duplicate of the implicit ldapDisplayName") > except LdbError as e5: > (enum, estr) = e5.args >- self.assertEquals(enum, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(enum, ERR_UNWILLING_TO_PERFORM) > > def test_duplicate_explicit_ldapdisplayname(self): > """Testing creating a duplicate attribute ldapdisplayname""" >@@ -520,7 +520,7 @@ systemOnly: FALSE > self.fail("Should have failed to add attribute with duplicate ldapDisplayName") > except LdbError as e6: > (enum, estr) = e6.args >- self.assertEquals(enum, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(enum, ERR_UNWILLING_TO_PERFORM) > > def test_duplicate_explicit_ldapdisplayname_with_class(self): > """Testing creating a duplicate attribute ldapdisplayname between >@@ -568,7 +568,7 @@ systemOnly: FALSE > self.fail("Should have failed to add class with duplicate ldapDisplayName") > except LdbError as e7: > (enum, estr) = e7.args >- self.assertEquals(enum, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(enum, ERR_UNWILLING_TO_PERFORM) > > def test_duplicate_via_rename_ldapdisplayname(self): > """Testing creating a duplicate attribute ldapdisplayname""" >@@ -622,7 +622,7 @@ ldapDisplayName: """ + attr_ldap_display_name + """ > self.fail("Should have failed to modify schema to have attribute with duplicate ldapDisplayName") > except LdbError as e8: > (enum, estr) = e8.args >- self.assertEquals(enum, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(enum, ERR_UNWILLING_TO_PERFORM) > > def test_duplicate_via_rename_attributeID(self): > """Testing creating a duplicate attributeID""" >@@ -676,7 +676,7 @@ attributeId: """ + attributeID + """ > self.fail("Should have failed to modify schema to have attribute with duplicate attributeID") > except LdbError as e9: > (enum, estr) = e9.args >- self.assertEquals(enum, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(enum, ERR_CONSTRAINT_VIOLATION) > > def test_remove_ldapdisplayname(self): > """Testing removing the ldapdisplayname""" >@@ -712,7 +712,7 @@ replace: ldapDisplayName > self.fail("Should have failed to remove the ldapdisplayname") > except LdbError as e10: > (enum, estr) = e10.args >- self.assertEquals(enum, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(enum, ERR_OBJECT_CLASS_VIOLATION) > > def test_rename_ldapdisplayname(self): > """Testing renaming ldapdisplayname""" >@@ -781,7 +781,7 @@ attributeId: """ + attributeID + """.1 > self.fail("Should have failed to modify schema to have different attributeID") > except LdbError as e11: > (enum, estr) = e11.args >- self.assertEquals(enum, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(enum, ERR_CONSTRAINT_VIOLATION) > > def test_change_attributeID_same(self): > """Testing change the attributeID to the same value""" >@@ -818,7 +818,7 @@ attributeId: """ + attributeID + """ > self.fail("Should have failed to modify schema to have the same attributeID") > except LdbError as e12: > (enum, estr) = e12.args >- self.assertEquals(enum, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(enum, ERR_CONSTRAINT_VIOLATION) > > def test_generated_linkID(self): > """ >@@ -833,7 +833,7 @@ attributeId: """ + attributeID + """ > # linkID generation isn't available before 2003 > res = self.ldb.search(base="", expression="", scope=SCOPE_BASE, > attrs=["domainControllerFunctionality"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > dc_level = int(res[0]["domainControllerFunctionality"][0]) > if dc_level < DS_DOMAIN_FUNCTION_2003: > return >@@ -895,13 +895,13 @@ systemOnly: FALSE > res = self.ldb.search("CN=%s,%s" % (attr_name_1, self.schema_dn), > scope=SCOPE_BASE, > attrs=["linkID"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > linkID_1 = int(res[0]["linkID"][0]) > > res = self.ldb.search("CN=%s,%s" % (attr_name_2, self.schema_dn), > scope=SCOPE_BASE, > attrs=["linkID"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > linkID_2 = int(res[0]["linkID"][0]) > > # 0 should never be generated as a linkID >@@ -952,7 +952,7 @@ systemOnly: FALSE > self.fail("Should have failed to add duplicate linkID value") > except LdbError as e15: > (enum, estr) = e15.args >- self.assertEquals(enum, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(enum, ERR_UNWILLING_TO_PERFORM) > > # If we add another attribute with the attributeID or lDAPDisplayName > # of a forward link in its linkID field, it should add as a backlink >@@ -986,9 +986,9 @@ systemOnly: FALSE > res = self.ldb.search("CN=%s,%s" % (attr_name_3, self.schema_dn), > scope=SCOPE_BASE, > attrs=["linkID"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > linkID = int(res[0]["linkID"][0]) >- self.assertEquals(linkID, linkID_1 + 1) >+ self.assertEqual(linkID, linkID_1 + 1) > > attr_name_4 = "test-generated-linkID-backlink-2" + time.strftime("%s", time.gmtime()) + "-" + rand > attr_ldap_display_name_4 = attr_name_4.replace("-", "") >@@ -1019,9 +1019,9 @@ systemOnly: FALSE > res = self.ldb.search("CN=%s,%s" % (attr_name_4, self.schema_dn), > scope=SCOPE_BASE, > attrs=["linkID"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > linkID = int(res[0]["linkID"][0]) >- self.assertEquals(linkID, linkID_2 + 1) >+ self.assertEqual(linkID, linkID_2 + 1) > > # If we then try to add another backlink in the same way > # for the same forwards link, we should fail. >@@ -1051,7 +1051,7 @@ systemOnly: FALSE > self.fail("Should have failed to add duplicate backlink") > except LdbError as e18: > (enum, estr) = e18.args >- self.assertEquals(enum, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(enum, ERR_UNWILLING_TO_PERFORM) > > # If we try to supply the attributeID or ldapDisplayName > # of an existing backlink in the linkID field of a new link, >@@ -1082,7 +1082,7 @@ systemOnly: FALSE > self.fail("Should have failed to add backlink of backlink") > except LdbError as e19: > (enum, estr) = e19.args >- self.assertEquals(enum, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(enum, ERR_UNWILLING_TO_PERFORM) > > attr_name = "test-generated-linkID-backlink-invalid-2" + time.strftime("%s", time.gmtime()) + "-" + rand > attr_ldap_display_name = attr_name.replace("-", "") >@@ -1109,7 +1109,7 @@ systemOnly: FALSE > self.fail("Should have failed to add backlink of backlink") > except LdbError as e20: > (enum, estr) = e20.args >- self.assertEquals(enum, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(enum, ERR_UNWILLING_TO_PERFORM) > > def test_generated_mAPIID(self): > """ >@@ -1150,7 +1150,7 @@ systemOnly: FALSE > res = self.ldb.search("CN=%s,%s" % (attr_name_1, self.schema_dn), > scope=SCOPE_BASE, > attrs=["mAPIID"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > mAPIID_1 = int(res[0]["mAPIID"][0]) > > ldif = """ >@@ -1187,7 +1187,7 @@ systemOnly: FALSE > self.fail("Should have failed to add duplicate mAPIID value") > except LdbError as e22: > (enum, estr) = e22.args >- self.assertEquals(enum, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(enum, ERR_UNWILLING_TO_PERFORM) > > def test_change_governsID(self): > """Testing change the governsID""" >@@ -1225,7 +1225,7 @@ governsId: """ + governsID + """.1 > self.fail("Should have failed to modify schema to have different governsID") > except LdbError as e23: > (enum, estr) = e23.args >- self.assertEquals(enum, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(enum, ERR_CONSTRAINT_VIOLATION) > > def test_change_governsID_same(self): > """Testing change the governsID""" >@@ -1263,7 +1263,7 @@ governsId: """ + governsID + """.1 > self.fail("Should have failed to modify schema to have the same governsID") > except LdbError as e24: > (enum, estr) = e24.args >- self.assertEquals(enum, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(enum, ERR_CONSTRAINT_VIOLATION) > > > class SchemaTests_msDS_IntId(samba.tests.TestCase): >@@ -1275,7 +1275,7 @@ class SchemaTests_msDS_IntId(samba.tests.TestCase): > res = self.ldb.search(base="", expression="", scope=SCOPE_BASE, > attrs=["schemaNamingContext", "defaultNamingContext", > "forestFunctionality"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.schema_dn = res[0]["schemaNamingContext"][0] > self.base_dn = res[0]["defaultNamingContext"][0] > self.forest_level = int(res[0]["forestFunctionality"][0]) >@@ -1346,7 +1346,7 @@ systemOnly: FALSE > self.fail("Adding attribute with preset msDS-IntId should fail") > except LdbError as e25: > (num, _) = e25.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # add the new attribute and update schema > self.ldb.add_ldif(ldif) >@@ -1356,8 +1356,8 @@ systemOnly: FALSE > res = [] > res = self.ldb.search(attr_dn, scope=SCOPE_BASE, > attrs=["lDAPDisplayName", "msDS-IntId", "systemFlags"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["lDAPDisplayName"][0]), attr_ldap_name) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["lDAPDisplayName"][0]), attr_ldap_name) > if self.forest_level >= DS_DOMAIN_FUNCTION_2003: > if self._is_schema_base_object(res[0]): > self.assertTrue("msDS-IntId" not in res[0]) >@@ -1374,7 +1374,7 @@ systemOnly: FALSE > self.fail("Modifying msDS-IntId should return error") > except LdbError as e26: > (num, _) = e26.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > # 2. Create attribute with systemFlags = FLAG_SCHEMA_BASE_OBJECT > # msDS-IntId should be created if forest functional >@@ -1391,7 +1391,7 @@ systemOnly: FALSE > self.fail("Adding attribute with preset msDS-IntId should fail") > except LdbError as e27: > (num, _) = e27.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # add the new attribute and update schema > self.ldb.add_ldif(ldif) >@@ -1401,8 +1401,8 @@ systemOnly: FALSE > res = [] > res = self.ldb.search(attr_dn, scope=SCOPE_BASE, > attrs=["lDAPDisplayName", "msDS-IntId"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["lDAPDisplayName"][0]), attr_ldap_name) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["lDAPDisplayName"][0]), attr_ldap_name) > if self.forest_level >= DS_DOMAIN_FUNCTION_2003: > if self._is_schema_base_object(res[0]): > self.assertTrue("msDS-IntId" not in res[0]) >@@ -1419,7 +1419,7 @@ systemOnly: FALSE > self.fail("Modifying msDS-IntId should return error") > except LdbError as e28: > (num, _) = e28.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > def _make_class_ldif(self, class_dn, class_name, sub_oid): > ldif = """ >@@ -1456,8 +1456,8 @@ systemOnly: FALSE > self._ldap_schemaUpdateNow() > > res = self.ldb.search(class_dn, scope=SCOPE_BASE, attrs=["msDS-IntId"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["msDS-IntId"][0]), "-1993108831") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["msDS-IntId"][0]), "-1993108831") > > # add a new Class and update schema > (class_name, class_ldap_name, class_dn) = self._make_obj_names("msDS-IntId-Class-2-") >@@ -1468,7 +1468,7 @@ systemOnly: FALSE > > # Search for created Class > res = self.ldb.search(class_dn, scope=SCOPE_BASE, attrs=["msDS-IntId"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertFalse("msDS-IntId" in res[0]) > > msg = Message() >@@ -1479,7 +1479,7 @@ systemOnly: FALSE > self.fail("Modifying msDS-IntId should return error") > except LdbError as e29: > (num, _) = e29.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > # 2. Create Class with systemFlags = FLAG_SCHEMA_BASE_OBJECT > # msDS-IntId should be created if forest functional >@@ -1494,8 +1494,8 @@ systemOnly: FALSE > self.ldb.add_ldif(ldif_add) > > res = self.ldb.search(class_dn, scope=SCOPE_BASE, attrs=["msDS-IntId"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["msDS-IntId"][0]), "-1993108831") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["msDS-IntId"][0]), "-1993108831") > > # add the new Class and update schema > (class_name, class_ldap_name, class_dn) = self._make_obj_names("msDS-IntId-Class-4-") >@@ -1507,7 +1507,7 @@ systemOnly: FALSE > > # Search for created Class > res = self.ldb.search(class_dn, scope=SCOPE_BASE, attrs=["msDS-IntId"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertFalse("msDS-IntId" in res[0]) > > msg = Message() >@@ -1518,9 +1518,9 @@ systemOnly: FALSE > self.fail("Modifying msDS-IntId should return error") > except LdbError as e30: > (num, _) = e30.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > res = self.ldb.search(class_dn, scope=SCOPE_BASE, attrs=["msDS-IntId"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertFalse("msDS-IntId" in res[0]) > > def test_verify_msDS_IntId(self): >@@ -1554,7 +1554,7 @@ class SchemaTests_msDS_isRODC(samba.tests.TestCase): > self.ldb = SamDB(host, credentials=creds, > session_info=system_session(lp), lp=lp, options=ldb_options) > res = self.ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["defaultNamingContext"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.base_dn = res[0]["defaultNamingContext"][0] > > def test_objectClass_ntdsdsa(self): >@@ -1572,7 +1572,7 @@ class SchemaTests_msDS_isRODC(samba.tests.TestCase): > res_check = self.ldb.search(ntds_search_dn, attrs=["objectCategory"]) > except LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > print("Server entry %s doesn't have a NTDS settings object" % res[0]['dn']) > else: > self.assertTrue("objectCategory" in res_check[0]) >diff --git a/source4/dsdb/tests/python/ldap_syntaxes.py b/source4/dsdb/tests/python/ldap_syntaxes.py >index ff319553c05..d8efb3a105e 100755 >--- a/source4/dsdb/tests/python/ldap_syntaxes.py >+++ b/source4/dsdb/tests/python/ldap_syntaxes.py >@@ -78,8 +78,8 @@ systemOnly: FALSE > # search for created attribute > res = [] > res = self.ldb.search("cn=%s,%s" % (attr_name, self.schema_dn), scope=SCOPE_BASE, attrs=["*"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(res[0]["lDAPDisplayName"][0], attr_ldap_display_name) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(res[0]["lDAPDisplayName"][0], attr_ldap_display_name) > self.assertTrue("schemaIDGUID" in res[0]) > > class_name = "test-Class-DN-String" + time.strftime("%s", time.gmtime()) >@@ -104,9 +104,9 @@ systemOnly: FALSE > # search for created objectclass > res = [] > res = self.ldb.search("cn=%s,%s" % (class_name, self.schema_dn), scope=SCOPE_BASE, attrs=["*"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(res[0]["lDAPDisplayName"][0], class_ldap_display_name) >- self.assertEquals(res[0]["defaultObjectCategory"][0], res[0]["distinguishedName"][0]) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(res[0]["lDAPDisplayName"][0], class_ldap_display_name) >+ self.assertEqual(res[0]["defaultObjectCategory"][0], res[0]["distinguishedName"][0]) > self.assertTrue("schemaIDGUID" in res[0]) > > # store the class and the attribute >@@ -138,8 +138,8 @@ systemOnly: FALSE > # search for created attribute > res = [] > res = self.ldb.search("cn=%s,%s" % (attr_name, self.schema_dn), scope=SCOPE_BASE, attrs=["*"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(res[0]["lDAPDisplayName"][0], attr_ldap_display_name) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(res[0]["lDAPDisplayName"][0], attr_ldap_display_name) > self.assertTrue("schemaIDGUID" in res[0]) > > class_name = "test-Class-DN-Binary" + time.strftime("%s", time.gmtime()) >@@ -164,9 +164,9 @@ systemOnly: FALSE > # search for created objectclass > res = [] > res = self.ldb.search("cn=%s,%s" % (class_name, self.schema_dn), scope=SCOPE_BASE, attrs=["*"]) >- self.assertEquals(len(res), 1) >- self.assertEquals(res[0]["lDAPDisplayName"][0], class_ldap_display_name) >- self.assertEquals(res[0]["defaultObjectCategory"][0], res[0]["distinguishedName"][0]) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(res[0]["lDAPDisplayName"][0], class_ldap_display_name) >+ self.assertEqual(res[0]["defaultObjectCategory"][0], res[0]["distinguishedName"][0]) > self.assertTrue("schemaIDGUID" in res[0]) > > # store the class and the attribute >@@ -202,19 +202,19 @@ name: """ + object_name + """ > res = self.ldb.search(base=self.base_dn, > scope=SCOPE_SUBTREE, > expression="(%s=%s)" % (self.dn_string_attribute, self.base_dn)) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # search by specifying the string part only > res = self.ldb.search(base=self.base_dn, > scope=SCOPE_SUBTREE, > expression="(%s=S:5:ABCDE)" % self.dn_string_attribute) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # search by DN+Stirng > res = self.ldb.search(base=self.base_dn, > scope=SCOPE_SUBTREE, > expression="(%s=S:5:ABCDE:%s)" % (self.dn_string_attribute, self.base_dn)) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > # add object with wrong format > object_name2 = "obj-DN-String2" + time.strftime("%s", time.gmtime()) >@@ -224,7 +224,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_ATTRIBUTE_SYNTAX) > > # add object with the same dn but with different string value in case > ldif = self._get_object_ldif(object_name1, self.dn_string_class_name, self.dn_string_class_ldap_display_name, >@@ -233,7 +233,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e1: > (num, _) = e1.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # add object with the same dn but with different string value > ldif = self._get_object_ldif(object_name1, self.dn_string_class_name, self.dn_string_class_ldap_display_name, >@@ -242,7 +242,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e2: > (num, _) = e2.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # add object with the same dn but with different dn and string value > ldif = self._get_object_ldif(object_name1, self.dn_string_class_name, self.dn_string_class_ldap_display_name, >@@ -251,7 +251,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e3: > (num, _) = e3.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # add object with the same dn but with different dn value > ldif = self._get_object_ldif(object_name1, self.dn_string_class_name, self.dn_string_class_ldap_display_name, >@@ -260,7 +260,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e4: > (num, _) = e4.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # add object with GUID instead of DN > object_name3 = "obj-DN-String3" + time.strftime("%s", time.gmtime()) >@@ -270,7 +270,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e5: > (num, _) = e5.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > # add object with SID instead of DN > object_name4 = "obj-DN-String4" + time.strftime("%s", time.gmtime()) >@@ -280,7 +280,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e6: > (num, _) = e6.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > # add object with random string instead of DN > object_name5 = "obj-DN-String5" + time.strftime("%s", time.gmtime()) >@@ -290,7 +290,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e7: > (num, _) = e7.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > def test_dn_binary(self): > # add obeject with correct value >@@ -303,19 +303,19 @@ name: """ + object_name + """ > res = self.ldb.search(base=self.base_dn, > scope=SCOPE_SUBTREE, > expression="(%s=%s)" % (self.dn_binary_attribute, self.base_dn)) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # search by specifying the binary part > res = self.ldb.search(base=self.base_dn, > scope=SCOPE_SUBTREE, > expression="(%s=B:4:1234)" % self.dn_binary_attribute) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > # search by DN+Binary > res = self.ldb.search(base=self.base_dn, > scope=SCOPE_SUBTREE, > expression="(%s=B:4:1234:%s)" % (self.dn_binary_attribute, self.base_dn)) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > # add object with wrong format - 5 bytes instead of 4, 8, 16, 32... > object_name2 = "obj-DN-Binary2" + time.strftime("%s", time.gmtime()) >@@ -325,7 +325,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e8: > (num, _) = e8.args >- self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX) >+ self.assertEqual(num, ERR_INVALID_ATTRIBUTE_SYNTAX) > > # add object with the same dn but with different binary value > ldif = self._get_object_ldif(object_name1, self.dn_binary_class_name, self.dn_binary_class_ldap_display_name, >@@ -334,7 +334,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e9: > (num, _) = e9.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # add object with the same dn but with different binary and dn value > ldif = self._get_object_ldif(object_name1, self.dn_binary_class_name, self.dn_binary_class_ldap_display_name, >@@ -343,7 +343,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e10: > (num, _) = e10.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # add object with the same dn but with different dn value > ldif = self._get_object_ldif(object_name1, self.dn_binary_class_name, self.dn_binary_class_ldap_display_name, >@@ -352,7 +352,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e11: > (num, _) = e11.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # add object with GUID instead of DN > object_name3 = "obj-DN-Binary3" + time.strftime("%s", time.gmtime()) >@@ -362,7 +362,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e12: > (num, _) = e12.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > # add object with SID instead of DN > object_name4 = "obj-DN-Binary4" + time.strftime("%s", time.gmtime()) >@@ -372,7 +372,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e13: > (num, _) = e13.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > # add object with random string instead of DN > object_name5 = "obj-DN-Binary5" + time.strftime("%s", time.gmtime()) >@@ -382,7 +382,7 @@ name: """ + object_name + """ > self.ldb.add_ldif(ldif) > except LdbError as e14: > (num, _) = e14.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > > TestProgram(module=__name__, opts=subunitopts) >diff --git a/source4/dsdb/tests/python/notification.py b/source4/dsdb/tests/python/notification.py >index 15107739086..235aa8654f8 100755 >--- a/source4/dsdb/tests/python/notification.py >+++ b/source4/dsdb/tests/python/notification.py >@@ -72,7 +72,7 @@ class LDAPNotificationTest(samba.tests.TestCase): > self.base_dn = self.ldb.domain_dn() > > res = self.ldb.search("", scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > self.user_sid_dn = "<SID=%s>" % str(ndr_unpack(samba.dcerpc.security.dom_sid, res[0]["tokenGroups"][0])) > >@@ -147,7 +147,7 @@ otherLoginWorkstations: AFTER" > self.fail() > except LdbError as e10: > (num, _) = e10.args >- self.assertEquals(num, ERR_TIME_LIMIT_EXCEEDED) >+ self.assertEqual(num, ERR_TIME_LIMIT_EXCEEDED) > self.assertIsNotNone(msg3) > > self.ldb.modify_ldif(""" >@@ -212,7 +212,7 @@ delete: otherLoginWorkstations > self.fail() > except LdbError as e1: > (num, _) = e1.args >- self.assertEquals(num, ERR_TIME_LIMIT_EXCEEDED) >+ self.assertEqual(num, ERR_TIME_LIMIT_EXCEEDED) > > try: > hnd = self.ldb.search_iterator(base=self.base_dn, >@@ -227,7 +227,7 @@ delete: otherLoginWorkstations > self.fail() > except LdbError as e2: > (num, _) = e2.args >- self.assertEquals(num, ERR_TIME_LIMIT_EXCEEDED) >+ self.assertEqual(num, ERR_TIME_LIMIT_EXCEEDED) > > try: > hnd = self.ldb.search_iterator(base=self.base_dn, >@@ -242,7 +242,7 @@ delete: otherLoginWorkstations > self.fail() > except LdbError as e3: > (num, _) = e3.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > hnd = self.ldb.search_iterator(base=self.base_dn, >@@ -257,7 +257,7 @@ delete: otherLoginWorkstations > self.fail() > except LdbError as e4: > (num, _) = e4.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > hnd = self.ldb.search_iterator(base=self.base_dn, >@@ -272,7 +272,7 @@ delete: otherLoginWorkstations > self.fail() > except LdbError as e5: > (num, _) = e5.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > hnd = self.ldb.search_iterator(base=self.base_dn, >@@ -287,7 +287,7 @@ delete: otherLoginWorkstations > self.fail() > except LdbError as e6: > (num, _) = e6.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > hnd = self.ldb.search_iterator(base=self.base_dn, >@@ -302,7 +302,7 @@ delete: otherLoginWorkstations > self.fail() > except LdbError as e7: > (num, _) = e7.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > hnd = self.ldb.search_iterator(base=self.base_dn, >@@ -317,7 +317,7 @@ delete: otherLoginWorkstations > self.fail() > except LdbError as e8: > (num, _) = e8.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > res = self.ldb.search(base=self.ldb.get_schema_basedn(), > expression="(objectClass=attributeSchema)", >@@ -344,7 +344,7 @@ delete: otherLoginWorkstations > (num, _) = e9.args > if num != ERR_UNWILLING_TO_PERFORM: > print("va[%s]" % va) >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > va = "noneAttributeName" >@@ -362,7 +362,7 @@ delete: otherLoginWorkstations > (num, _) = e11.args > if num != ERR_UNWILLING_TO_PERFORM: > print("va[%s]" % va) >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > > if "://" not in url: >diff --git a/source4/dsdb/tests/python/password_lockout.py b/source4/dsdb/tests/python/password_lockout.py >index efbdeb2ed90..cbe15c33742 100755 >--- a/source4/dsdb/tests/python/password_lockout.py >+++ b/source4/dsdb/tests/python/password_lockout.py >@@ -217,7 +217,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg, msg) > > res = self._check_account(userdn, >@@ -262,7 +262,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e1: > (num, msg) = e1.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg, msg) > > res = self._check_account(userdn, >@@ -290,7 +290,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e2: > (num, msg) = e2.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg, msg) > > res = self._check_account(userdn, >@@ -318,7 +318,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e3: > (num, msg) = e3.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000775' in msg, msg) > > res = self._check_account(userdn, >@@ -344,7 +344,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e4: > (num, msg) = e4.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000775' in msg, msg) > > res = self._check_account(userdn, >@@ -370,7 +370,7 @@ userPassword: thatsAcomplPASS2x > self.fail() > except LdbError as e5: > (num, msg) = e5.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000775' in msg, msg) > > res = self._check_account(userdn, >@@ -414,7 +414,7 @@ userPassword: thatsAcomplPASS2x > self.fail() > except LdbError as e6: > (num, msg) = e6.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000775' in msg, msg) > > res = self._check_account(userdn, >@@ -460,7 +460,7 @@ unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS2x\"".encode('utf-16-le')) > self.fail() > except LdbError as e7: > (num, msg) = e7.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000775' in msg, msg) > > res = self._check_account(userdn, >@@ -522,7 +522,7 @@ userPassword: thatsAcomplPASS2XYZ > self.fail() > except LdbError as e8: > (num, msg) = e8.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg, msg) > > res = self._check_account(userdn, >@@ -549,7 +549,7 @@ userPassword: thatsAcomplPASS2XYZ > self.fail() > except LdbError as e9: > (num, msg) = e9.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg, msg) > > res = self._check_account(userdn, >@@ -679,7 +679,7 @@ userPassword: thatsAcomplPASS2XYZ > self.fail("Invalid SAMR change_password accepted") > except NTSTATUSError as e: > enum = ctypes.c_uint32(e.args[0]).value >- self.assertEquals(enum, ntstatus.NT_STATUS_WRONG_PASSWORD) >+ self.assertEqual(enum, ntstatus.NT_STATUS_WRONG_PASSWORD) > > # check the status of the account is updated after each bad attempt > account_flags = 0 >@@ -713,7 +713,7 @@ userPassword: thatsAcomplPASS2XYZ > self.fail("Invalid SAMR change_password accepted") > except NTSTATUSError as e: > enum = ctypes.c_uint32(e.args[0]).value >- self.assertEquals(enum, ntstatus.NT_STATUS_ACCOUNT_LOCKED_OUT) >+ self.assertEqual(enum, ntstatus.NT_STATUS_ACCOUNT_LOCKED_OUT) > > res = self._check_account(userdn, > badPwdCount=lockout_threshold, >@@ -801,7 +801,7 @@ unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS2\"".encode('utf-16-le')). > self.fail() > except LdbError as e10: > (num, msg) = e10.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg, msg) > > res = self._check_account(userdn, >@@ -852,7 +852,7 @@ unicodePwd:: """ + base64.b64encode(new_utf16).decode('utf8') + """ > self.fail() > except LdbError as e11: > (num, msg) = e11.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg, msg) > > res = self._check_account(userdn, >@@ -894,7 +894,7 @@ unicodePwd:: """ + base64.b64encode(new_utf16).decode('utf8') + """ > self.fail() > except LdbError as e12: > (num, msg) = e12.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg, msg) > > # this is strange, why do we have lockoutTime=badPasswordTime here? >@@ -923,7 +923,7 @@ unicodePwd:: """ + base64.b64encode(new_utf16).decode('utf8') + """ > self.fail() > except LdbError as e13: > (num, msg) = e13.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000775' in msg, msg) > > res = self._check_account(userdn, >@@ -949,7 +949,7 @@ unicodePwd:: """ + base64.b64encode(new_utf16).decode('utf8') + """ > self.fail() > except LdbError as e14: > (num, msg) = e14.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000775' in msg, msg) > > res = self._check_account(userdn, >@@ -975,7 +975,7 @@ unicodePwd:: """ + base64.b64encode(invalid_utf16).decode('utf8') + """ > self.fail() > except LdbError as e15: > (num, msg) = e15.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000775' in msg, msg) > > res = self._check_account(userdn, >@@ -1040,7 +1040,7 @@ unicodePwd:: """ + base64.b64encode(new_utf16).decode('utf8') + """ > self.fail() > except LdbError as e16: > (num, msg) = e16.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg, msg) > > res = self._check_account(userdn, >@@ -1067,7 +1067,7 @@ unicodePwd:: """ + base64.b64encode(new_utf16).decode('utf8') + """ > self.fail() > except LdbError as e17: > (num, msg) = e17.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg, msg) > > res = self._check_account(userdn, >@@ -1108,7 +1108,7 @@ unicodePwd:: """ + base64.b64encode(new_utf16).decode('utf8') + """ > self.fail() > except LdbError as e18: > (num, msg) = e18.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg, msg) > > res = self._check_account(userdn, >@@ -1240,7 +1240,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e19: > (num, msg) = e19.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > # Windows (2008 at least) seems to have some small bug here: it > # returns "0000056A" on longer (always wrong) previous passwords. > self.assertTrue('00000056' in msg, msg) >diff --git a/source4/dsdb/tests/python/password_lockout_base.py b/source4/dsdb/tests/python/password_lockout_base.py >index 24b066c188d..c936ebda607 100644 >--- a/source4/dsdb/tests/python/password_lockout_base.py >+++ b/source4/dsdb/tests/python/password_lockout_base.py >@@ -24,7 +24,7 @@ class BasePasswordTestCase(PasswordTestCase): > self.assertTrue("objectSid" in res[0]) > > (domain_sid, rid) = ndr_unpack(security.dom_sid, res[0]["objectSid"][0]).split() >- self.assertEquals(self.domain_sid, domain_sid) >+ self.assertEqual(self.domain_sid, domain_sid) > > return self.samr.OpenUser(self.samr_domain, security.SEC_FLAG_MAXIMUM_ALLOWED, rid) > >@@ -163,9 +163,9 @@ class BasePasswordTestCase(PasswordTestCase): > if msDSUserAccountControlComputed & dsdb.UF_PASSWORD_EXPIRED: > expected_acb_info |= samr.ACB_PW_EXPIRED > >- self.assertEquals(uinfo3.acct_flags, expected_acb_info) >- self.assertEquals(uinfo3.last_logon, lastLogon) >- self.assertEquals(uinfo3.logon_count, logonCount) >+ self.assertEqual(uinfo3.acct_flags, expected_acb_info) >+ self.assertEqual(uinfo3.last_logon, lastLogon) >+ self.assertEqual(uinfo3.logon_count, logonCount) > > expected_bad_password_count = 0 > if badPwdCount is not None: >@@ -173,25 +173,25 @@ class BasePasswordTestCase(PasswordTestCase): > if effective_bad_password_count is None: > effective_bad_password_count = expected_bad_password_count > >- self.assertEquals(uinfo3.bad_password_count, expected_bad_password_count) >+ self.assertEqual(uinfo3.bad_password_count, expected_bad_password_count) > > if not badPwdCountOnly: >- self.assertEquals(uinfo5.acct_flags, expected_acb_info) >- self.assertEquals(uinfo5.bad_password_count, effective_bad_password_count) >- self.assertEquals(uinfo5.last_logon, lastLogon) >- self.assertEquals(uinfo5.logon_count, logonCount) >+ self.assertEqual(uinfo5.acct_flags, expected_acb_info) >+ self.assertEqual(uinfo5.bad_password_count, effective_bad_password_count) >+ self.assertEqual(uinfo5.last_logon, lastLogon) >+ self.assertEqual(uinfo5.logon_count, logonCount) > >- self.assertEquals(uinfo16.acct_flags, expected_acb_info) >+ self.assertEqual(uinfo16.acct_flags, expected_acb_info) > >- self.assertEquals(uinfo21.acct_flags, expected_acb_info) >- self.assertEquals(uinfo21.bad_password_count, effective_bad_password_count) >- self.assertEquals(uinfo21.last_logon, lastLogon) >- self.assertEquals(uinfo21.logon_count, logonCount) >+ self.assertEqual(uinfo21.acct_flags, expected_acb_info) >+ self.assertEqual(uinfo21.bad_password_count, effective_bad_password_count) >+ self.assertEqual(uinfo21.last_logon, lastLogon) >+ self.assertEqual(uinfo21.logon_count, logonCount) > > # check LDAP again and make sure the samr.QueryUserInfo > # doesn't have any impact. > res2 = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs) >- self.assertEquals(res[0], res2[0]) >+ self.assertEqual(res[0], res2[0]) > > # in order to prevent some time resolution problems we sleep for > # 10 micro second >@@ -252,7 +252,7 @@ userPassword: """ + userpass + """ > self.fail() > except LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > # Succeed to reset everything to 0 > ldb = SamDB(url=self.host_url, credentials=creds, lp=self.lp) >@@ -266,7 +266,7 @@ userPassword: """ + userpass + """ > except LdbError as e1: > (num, msg) = e1.args > if errno is not None: >- self.assertEquals(num, errno, ("Login failed in the wrong way" >+ self.assertEqual(num, errno, ("Login failed in the wrong way" > "(got err %d, expected %d)" % > (num, errno))) > >@@ -467,7 +467,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """ > > except LdbError as e2: > (num, msg) = e2.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=2, >@@ -490,7 +490,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """ > > except LdbError as e3: > (num, msg) = e3.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=3, >@@ -511,7 +511,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """ > self.fail() > except LdbError as e4: > (num, msg) = e4.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=3, >@@ -530,7 +530,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """ > self.fail() > except LdbError as e5: > (num, msg) = e5.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=3, >@@ -549,7 +549,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """ > self.fail() > except LdbError as e6: > (num, msg) = e6.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=3, >@@ -609,7 +609,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """ > self.fail() > except LdbError as e7: > (num, msg) = e7.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=1, >@@ -629,7 +629,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """ > self.fail() > except LdbError as e8: > (num, msg) = e8.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=2, >@@ -661,7 +661,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """ > self.fail() > except LdbError as e9: > (num, msg) = e9.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=1, >diff --git a/source4/dsdb/tests/python/password_settings.py b/source4/dsdb/tests/python/password_settings.py >index 5d6deaeebe5..fcb671690c3 100644 >--- a/source4/dsdb/tests/python/password_settings.py >+++ b/source4/dsdb/tests/python/password_settings.py >@@ -107,7 +107,7 @@ class PasswordSettingsTestCase(PasswordTestCase): > self.fail("Password '%s' should have been rejected" % password) > except ldb.LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ldb.ERR_CONSTRAINT_VIOLATION, msg) >+ self.assertEqual(num, ldb.ERR_CONSTRAINT_VIOLATION, msg) > self.assertTrue('0000052D' in msg, msg) > > def assert_password_valid(self, user, password): >@@ -415,7 +415,7 @@ class PasswordSettingsTestCase(PasswordTestCase): > self.fail() > except ldb.LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ldb.ERR_NAMING_VIOLATION, msg) >+ self.assertEqual(num, ldb.ERR_NAMING_VIOLATION, msg) > # Windows returns 2099 (Illegal superior), Samba returns 2037 > # (Naming violation - "not a valid child class") > self.assertTrue('00002099' in msg or '00002037' in msg, msg) >@@ -428,7 +428,7 @@ class PasswordSettingsTestCase(PasswordTestCase): > self.fail() > except ldb.LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ldb.ERR_NAMING_VIOLATION, msg) >+ self.assertEqual(num, ldb.ERR_NAMING_VIOLATION, msg) > self.assertTrue('00002099' in msg or '00002037' in msg, msg) > > base_dn = self.ldb.get_default_basedn() >@@ -645,7 +645,7 @@ class PasswordSettingsTestCase(PasswordTestCase): > self.fail() > except ldb.LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, msg) >+ self.assertEqual(num, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, msg) > > # create a PSO as the admin user > priv_pso = PasswordSettings("priv-PSO", self.ldb, password_len=20) >@@ -658,7 +658,7 @@ class PasswordSettingsTestCase(PasswordTestCase): > self.fail() > except ldb.LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, msg) >+ self.assertEqual(num, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, msg) > self.assertTrue('00002098' in msg, msg) > > self.set_attribute(priv_pso.dn, "msDS-PSOAppliesTo", user.dn, >@@ -670,7 +670,7 @@ class PasswordSettingsTestCase(PasswordTestCase): > self.fail() > except ldb.LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, msg) >+ self.assertEqual(num, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, msg) > self.assertTrue('00002098' in msg, msg) > > priv_pso.set_precedence(100, samdb=self.ldb) >@@ -703,7 +703,7 @@ class PasswordSettingsTestCase(PasswordTestCase): > self.fail() > except ldb.LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, msg) >+ self.assertEqual(num, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, msg) > self.assertTrue('00002098' in msg, msg) > > # ...but can be performed by the admin user >@@ -796,7 +796,7 @@ unicodePwd:: %s > self.fail() > except ldb.LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ldb.ERR_CONSTRAINT_VIOLATION, msg) >+ self.assertEqual(num, ldb.ERR_CONSTRAINT_VIOLATION, msg) > self.assertTrue('0000052D' in msg, msg) > > # check setting a password that meets the PSO settings works >diff --git a/source4/dsdb/tests/python/passwords.py b/source4/dsdb/tests/python/passwords.py >index e1d0a981897..554da34828e 100755 >--- a/source4/dsdb/tests/python/passwords.py >+++ b/source4/dsdb/tests/python/passwords.py >@@ -105,7 +105,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > # Windows (2008 at least) seems to have some small bug here: it > # returns "0000056A" on longer (always wrong) previous passwords. > self.assertTrue('00000056' in msg) >@@ -134,7 +134,7 @@ add: userPassword > self.fail() > except LdbError as e1: > (num, _) = e1.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > # Enables the user account > self.ldb.enable_account("(sAMAccountName=testuser)") >@@ -165,7 +165,7 @@ add: userPassword > self.fail() > except LdbError as e2: > (num, _) = e2.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > def test_unicodePwd_hash_change(self): > """Performs a password hash change operation on 'unicodePwd' which should be prevented""" >@@ -184,7 +184,7 @@ unicodePwd: YYYYYYYYYYYYYYYY > self.fail() > except LdbError as e3: > (num, _) = e3.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > def test_unicodePwd_clear_set(self): > """Performs a password cleartext set operation on 'unicodePwd'""" >@@ -220,7 +220,7 @@ unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS4\"".encode('utf-16-le')). > self.fail() > except LdbError as e4: > (num, msg) = e4.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg) > > # A change to the same password again will not work (password history) >@@ -236,7 +236,7 @@ unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS2\"".encode('utf-16-le')). > self.fail() > except LdbError as e5: > (num, msg) = e5.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('0000052D' in msg) > > def test_dBCSPwd_hash_set(self): >@@ -252,7 +252,7 @@ unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS2\"".encode('utf-16-le')). > self.fail() > except LdbError as e6: > (num, _) = e6.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > def test_dBCSPwd_hash_change(self): > """Performs a password hash change operation on 'dBCSPwd' which should be prevented""" >@@ -270,7 +270,7 @@ dBCSPwd: YYYYYYYYYYYYYYYY > self.fail() > except LdbError as e7: > (num, _) = e7.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > def test_userPassword_clear_set(self): > """Performs a password cleartext set operation on 'userPassword'""" >@@ -310,7 +310,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e8: > (num, msg) = e8.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg) > > # A change to the same password again will not work (password history) >@@ -326,7 +326,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e9: > (num, msg) = e9.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('0000052D' in msg) > > def test_clearTextPassword_clear_set(self): >@@ -381,7 +381,7 @@ clearTextPassword:: """ + base64.b64encode("thatsAcomplPASS4".encode('utf-16-le' > (num, msg) = e12.args > # "NO_SUCH_ATTRIBUTE" is returned by Windows -> ignore it > if num != ERR_NO_SUCH_ATTRIBUTE: >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('00000056' in msg) > > # A change to the same password again will not work (password history) >@@ -399,7 +399,7 @@ clearTextPassword:: """ + base64.b64encode("thatsAcomplPASS2".encode('utf-16-le' > (num, msg) = e13.args > # "NO_SUCH_ATTRIBUTE" is returned by Windows -> ignore it > if num != ERR_NO_SUCH_ATTRIBUTE: >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > self.assertTrue('0000052D' in msg) > > def test_failures(self): >@@ -415,7 +415,7 @@ userPassword: thatsAcomplPASS1 > self.fail() > except LdbError as e14: > (num, _) = e14.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > try: > self.ldb2.modify_ldif(""" >@@ -427,7 +427,7 @@ userPassword: thatsAcomplPASS1 > self.fail() > except LdbError as e15: > (num, _) = e15.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > try: > self.ldb.modify_ldif(""" >@@ -438,7 +438,7 @@ delete: userPassword > self.fail() > except LdbError as e16: > (num, _) = e16.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > try: > self.ldb2.modify_ldif(""" >@@ -449,7 +449,7 @@ delete: userPassword > self.fail() > except LdbError as e17: > (num, _) = e17.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > try: > self.ldb.modify_ldif(""" >@@ -461,7 +461,7 @@ userPassword: thatsAcomplPASS1 > self.fail() > except LdbError as e18: > (num, _) = e18.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > self.ldb2.modify_ldif(""" >@@ -473,7 +473,7 @@ userPassword: thatsAcomplPASS1 > self.fail() > except LdbError as e19: > (num, _) = e19.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > try: > self.ldb.modify_ldif(""" >@@ -488,7 +488,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e20: > (num, _) = e20.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > try: > self.ldb2.modify_ldif(""" >@@ -503,7 +503,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e21: > (num, _) = e21.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > try: > self.ldb.modify_ldif(""" >@@ -518,7 +518,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e22: > (num, _) = e22.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > try: > self.ldb2.modify_ldif(""" >@@ -533,7 +533,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e23: > (num, _) = e23.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > try: > self.ldb.modify_ldif(""" >@@ -549,7 +549,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e24: > (num, _) = e24.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > self.ldb2.modify_ldif(""" >@@ -565,7 +565,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e25: > (num, _) = e25.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > try: > self.ldb.modify_ldif(""" >@@ -581,7 +581,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e26: > (num, _) = e26.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > self.ldb2.modify_ldif(""" >@@ -597,7 +597,7 @@ userPassword: thatsAcomplPASS2 > self.fail() > except LdbError as e27: > (num, _) = e27.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > try: > self.ldb.modify_ldif(""" >@@ -613,7 +613,7 @@ userPassword: thatsAcomplPASS3 > self.fail() > except LdbError as e28: > (num, _) = e28.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > self.ldb2.modify_ldif(""" >@@ -629,7 +629,7 @@ userPassword: thatsAcomplPASS3 > self.fail() > except LdbError as e29: > (num, _) = e29.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > # Reverse order does work > self.ldb2.modify_ldif(""" >@@ -653,7 +653,7 @@ unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS3\"".encode('utf-16-le')). > # this passes against s4 > except LdbError as e30: > (num, _) = e30.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > try: > self.ldb2.modify_ldif(""" >@@ -667,7 +667,7 @@ userPassword: thatsAcomplPASS4 > # this passes against s4 > except LdbError as e31: > (num, _) = e31.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > > # Several password changes at once are allowed > self.ldb.modify_ldif(""" >@@ -716,7 +716,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e32: > (num, _) = e32.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > try: > self.ldb.add({ >@@ -726,7 +726,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e33: > (num, _) = e33.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > try: > self.ldb.add({ >@@ -736,7 +736,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e34: > (num, _) = e34.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > try: > self.ldb.add({ >@@ -759,7 +759,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e36: > (num, _) = e36.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > m = Message() > m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) >@@ -769,7 +769,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e37: > (num, _) = e37.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > m = Message() > m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) >@@ -779,7 +779,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e38: > (num, _) = e38.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > m = Message() > m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) >@@ -800,7 +800,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e40: > (num, _) = e40.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) >@@ -810,7 +810,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e41: > (num, _) = e41.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) >@@ -820,7 +820,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e42: > (num, _) = e42.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) >@@ -841,7 +841,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e44: > (num, _) = e44.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) >@@ -851,7 +851,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e45: > (num, _) = e45.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) >@@ -861,7 +861,7 @@ userPassword: thatsAcomplPASS4 > self.fail() > except LdbError as e46: > (num, _) = e46.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > m = Message() > m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) >@@ -892,7 +892,7 @@ userPassword: thatsAcomplPASS4 > scope=SCOPE_BASE, attrs=["userPassword"]) > self.assertTrue(len(res) == 1) > self.assertTrue("userPassword" in res[0]) >- self.assertEquals(str(res[0]["userPassword"][0]), "myPassword") >+ self.assertEqual(str(res[0]["userPassword"][0]), "myPassword") > > m = Message() > m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) >@@ -904,7 +904,7 @@ userPassword: thatsAcomplPASS4 > scope=SCOPE_BASE, attrs=["userPassword"]) > self.assertTrue(len(res) == 1) > self.assertTrue("userPassword" in res[0]) >- self.assertEquals(str(res[0]["userPassword"][0]), "myPassword2") >+ self.assertEqual(str(res[0]["userPassword"][0]), "myPassword2") > > m = Message() > m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) >@@ -930,7 +930,7 @@ userPassword: thatsAcomplPASS4 > scope=SCOPE_BASE, attrs=["userPassword"]) > self.assertTrue(len(res) == 1) > self.assertTrue("userPassword" in res[0]) >- self.assertEquals(str(res[0]["userPassword"][0]), "myPassword3") >+ self.assertEqual(str(res[0]["userPassword"][0]), "myPassword3") > > # Set the test "dSHeuristics" to deactivate "userPassword" pwd changes > self.ldb.set_dsheuristics("000000002") >@@ -945,7 +945,7 @@ userPassword: thatsAcomplPASS4 > scope=SCOPE_BASE, attrs=["userPassword"]) > self.assertTrue(len(res) == 1) > self.assertTrue("userPassword" in res[0]) >- self.assertEquals(str(res[0]["userPassword"][0]), "myPassword4") >+ self.assertEqual(str(res[0]["userPassword"][0]), "myPassword4") > > # Reset the test "dSHeuristics" (reactivate "userPassword" pwd changes) > self.ldb.set_dsheuristics("000000001") >@@ -1042,7 +1042,7 @@ userPassword: thatsAcomplPASS4 > # userPassword can be read > self.assertTrue(len(res) == 1) > self.assertTrue("userPassword" in res[0]) >- self.assertEquals(str(res[0]["userPassword"][0]), "thatsAcomplPASS2") >+ self.assertEqual(str(res[0]["userPassword"][0]), "thatsAcomplPASS2") > > # Reset the test "dSHeuristics" (reactivate "userPassword" pwd changes) > self.ldb.set_dsheuristics("000000001") >@@ -1090,7 +1090,7 @@ userPassword: thatsAcomplPASS1 > """) > except LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > else: > self.fail() > >@@ -1125,7 +1125,7 @@ unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS3\"".encode('utf-16-le')). > """) > except LdbError as e: > (num, msg) = e.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > else: > self.fail() > >diff --git a/source4/dsdb/tests/python/rodc_rwdc.py b/source4/dsdb/tests/python/rodc_rwdc.py >index b8501980c67..7d0845e8836 100644 >--- a/source4/dsdb/tests/python/rodc_rwdc.py >+++ b/source4/dsdb/tests/python/rodc_rwdc.py >@@ -478,7 +478,7 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > > except LdbError as e1: > (num, msg) = e1.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=2, >@@ -501,7 +501,7 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > > except LdbError as e2: > (num, msg) = e2.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=3, >@@ -522,7 +522,7 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > self.fail() > except LdbError as e3: > (num, msg) = e3.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=3, >@@ -541,7 +541,7 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > self.fail() > except LdbError as e4: > (num, msg) = e4.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=3, >@@ -560,7 +560,7 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > self.fail() > except LdbError as e5: > (num, msg) = e5.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=3, >@@ -613,7 +613,7 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > self.fail() > except LdbError as e6: > (num, msg) = e6.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=1, >@@ -633,7 +633,7 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > self.fail() > except LdbError as e7: > (num, msg) = e7.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=2, >@@ -665,7 +665,7 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > self.fail() > except LdbError as e8: > (num, msg) = e8.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > res = self._check_account(userdn, > badPwdCount=1, >@@ -1177,7 +1177,7 @@ class RodcRwdcTests(password_lockout_base.BasePasswordTestCase): > self.fail() > except LdbError as e11: > (num, msg) = e11.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > # Succeed to reset everything to 0 > success_creds = self.insta_creds(self.template_creds, >@@ -1207,7 +1207,7 @@ class RodcRwdcTests(password_lockout_base.BasePasswordTestCase): > self.fail() > except LdbError as e12: > (num, msg) = e12.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > # Succeed to reset everything to 0 > ldb = SamDB(url=self.host_url, credentials=self.lockout1ntlm_creds, lp=self.lp) >@@ -1232,7 +1232,7 @@ class RodcRwdcTests(password_lockout_base.BasePasswordTestCase): > self.fail() > except LdbError as e13: > (num, msg) = e13.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > # Succeed to reset everything to 0 > success_creds = self.insta_creds(self.template_creds, >@@ -1262,7 +1262,7 @@ class RodcRwdcTests(password_lockout_base.BasePasswordTestCase): > self.fail() > except LdbError as e14: > (num, msg) = e14.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > > # Succeed to reset everything to 0 > ldb = SamDB(url=self.host_url, credentials=self.lockout1ntlm_creds, lp=self.lp) >diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py >index 2d39286dd2e..02a8d2d52b4 100755 >--- a/source4/dsdb/tests/python/sam.py >+++ b/source4/dsdb/tests/python/sam.py >@@ -128,7 +128,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e9: > (num, _) = e9.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > > # Try to create a user with an invalid account name >@@ -140,7 +140,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e10: > (num, _) = e10.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > > # Try to create a user with an invalid primary group >@@ -152,7 +152,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e11: > (num, _) = e11.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > > # Try to Create a user with a valid primary group >@@ -164,7 +164,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e12: > (num, _) = e12.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > > # Test to see how we should behave when the user account doesn't >@@ -178,7 +178,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e13: > (num, _) = e13.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > # Test to see how we should behave when the account isn't a user > m = Message() >@@ -190,7 +190,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e14: > (num, _) = e14.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # Test default primary groups on add operations > >@@ -201,7 +201,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["primaryGroupID"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS) >+ self.assertEqual(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS) > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >@@ -213,7 +213,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["primaryGroupID"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS) >+ self.assertEqual(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS) > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >@@ -229,7 +229,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["primaryGroupID"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["primaryGroupID"][0]), >+ self.assertEqual(int(res1[0]["primaryGroupID"][0]), > DOMAIN_RID_DOMAIN_MEMBERS) > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -243,7 +243,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["primaryGroupID"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DCS) >+ self.assertEqual(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DCS) > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >@@ -282,7 +282,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["primaryGroupID"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS) >+ self.assertEqual(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS) > > # unfortunately the INTERDOMAIN_TRUST_ACCOUNT case cannot be tested > # since such accounts aren't directly creatable (ACCESS_DENIED) >@@ -296,7 +296,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["primaryGroupID"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS) >+ self.assertEqual(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -309,7 +309,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["primaryGroupID"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS) >+ self.assertEqual(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -322,7 +322,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["primaryGroupID"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DCS) >+ self.assertEqual(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DCS) > > # Read-only DC accounts are only creatable by > # UF_WORKSTATION_TRUST_ACCOUNT and work only on DCs >= 2008 (therefore >@@ -360,7 +360,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e15: > (num, _) = e15.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # But to reset the actual "sAMAccountName" should still be possible > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, >@@ -396,7 +396,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e16: > (num, _) = e16.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Try to make group 1 primary - should be denied since it is not yet > # secondary >@@ -409,7 +409,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e17: > (num, _) = e17.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Make group 1 secondary > m = Message() >@@ -431,7 +431,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e18: > (num, _) = e18.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # Try to add group 1 also as secondary - should be denied > m = Message() >@@ -443,7 +443,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e19: > (num, _) = e19.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # Try to add invalid member to group 1 - should be denied > m = Message() >@@ -456,7 +456,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e20: > (num, _) = e20.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > # Make group 2 secondary > m = Message() >@@ -487,7 +487,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, attrs=["member"]) > self.assertTrue(len(res1) == 1) > self.assertTrue(len(res1[0]["member"]) == 1) >- self.assertEquals(str(res1[0]["member"][0]).lower(), >+ self.assertEqual(str(res1[0]["member"][0]).lower(), > ("cn=ldaptestuser,cn=users," + self.base_dn).lower()) > > res1 = ldb.search("cn=ldaptestgroup2, cn=users," + self.base_dn, >@@ -505,7 +505,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e21: > (num, _) = e21.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Delete invalid group member > m = Message() >@@ -517,7 +517,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e22: > (num, _) = e22.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Also this should be denied > try: >@@ -528,7 +528,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e23: > (num, _) = e23.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Recreate user accounts > >@@ -558,7 +558,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e24: > (num, _) = e24.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # Already added, but as <SID=...> > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, >@@ -575,7 +575,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e25: > (num, _) = e25.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > # Invalid member > m = Message() >@@ -587,7 +587,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e26: > (num, _) = e26.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > # Invalid member > m = Message() >@@ -600,7 +600,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e27: > (num, _) = e27.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > # Invalid member > m = Message() >@@ -614,7 +614,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e28: > (num, _) = e28.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn) >@@ -654,7 +654,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e29: > (num, _) = e29.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > # Delete protection tests > >@@ -669,7 +669,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -679,7 +679,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e1: > (num, _) = e1.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -690,7 +690,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e30: > (num, _) = e30.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -703,7 +703,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e31: > (num, _) = e31.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -714,7 +714,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e32: > (num, _) = e32.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -725,7 +725,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e33: > (num, _) = e33.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -736,7 +736,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e34: > (num, _) = e34.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > # Delete protection tests > >@@ -754,7 +754,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e2: > (num, _) = e2.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -764,7 +764,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e3: > (num, _) = e3.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -781,7 +781,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e35: > (num, _) = e35.args >- self.assertEquals(num, ERR_UNDEFINED_ATTRIBUTE_TYPE) >+ self.assertEqual(num, ERR_UNDEFINED_ATTRIBUTE_TYPE) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > > ldb.add({ >@@ -831,7 +831,7 @@ class SamTests(samba.tests.TestCase): > > obj_sid = get_string(ldb.schema_format_value("objectSID", res1[0]["objectSID"][0])) > rid = security.dom_sid(obj_sid).split()[1] >- self.assertEquals(primary_group_token, rid) >+ self.assertEqual(primary_group_token, rid) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -841,7 +841,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e36: > (num, _) = e36.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -909,7 +909,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e37: > (num, _) = e37.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > > try: >@@ -920,7 +920,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e38: > (num, _) = e38.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > > ldb.add({ >@@ -931,7 +931,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_GLOBAL_GROUP) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -943,7 +943,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_UNIVERSAL_GROUP) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -955,7 +955,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_LOCAL_GROUP) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -967,7 +967,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_GLOBAL_GROUP) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -979,7 +979,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_UNIVERSAL_GROUP) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -991,7 +991,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_LOCAL_GROUP) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -1009,7 +1009,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_GLOBAL_GROUP) > > # Invalid attribute >@@ -1022,7 +1022,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e39: > (num, _) = e39.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Security groups > >@@ -1038,7 +1038,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_GLOBAL_GROUP) > > # Change to "local" (shouldn't work) >@@ -1053,7 +1053,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e40: > (num, _) = e40.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Change to "universal" > >@@ -1067,7 +1067,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_UNIVERSAL_GROUP) > > # Change back to "global" >@@ -1082,7 +1082,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_GLOBAL_GROUP) > > # Change back to "universal" >@@ -1097,7 +1097,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_UNIVERSAL_GROUP) > > # Change to "local" >@@ -1112,7 +1112,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_LOCAL_GROUP) > > # Change to "global" (shouldn't work) >@@ -1127,7 +1127,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e41: > (num, _) = e41.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Change to "builtin local" (shouldn't work) > >@@ -1141,7 +1141,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e42: > (num, _) = e42.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -1158,7 +1158,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_UNIVERSAL_GROUP) > > # Change to "builtin local" (shouldn't work) >@@ -1173,7 +1173,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e43: > (num, _) = e43.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Change back to "global" > >@@ -1187,7 +1187,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_GLOBAL_GROUP) > > # Change to "builtin local" (shouldn't work) >@@ -1202,7 +1202,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e44: > (num, _) = e44.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Distribution groups > >@@ -1218,7 +1218,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_GLOBAL_GROUP) > > # Change to local (shouldn't work) >@@ -1233,7 +1233,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e45: > (num, _) = e45.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Change to "universal" > >@@ -1247,7 +1247,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_UNIVERSAL_GROUP) > > # Change back to "global" >@@ -1262,7 +1262,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_GLOBAL_GROUP) > > # Change back to "universal" >@@ -1277,7 +1277,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_UNIVERSAL_GROUP) > > # Change to "local" >@@ -1292,7 +1292,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_LOCAL_GROUP) > > # Change to "global" (shouldn't work) >@@ -1307,7 +1307,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e46: > (num, _) = e46.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Change back to "universal" > >@@ -1322,7 +1322,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e47: > (num, _) = e47.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > # Make group 2 secondary > m = Message() >@@ -1335,7 +1335,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_UNIVERSAL_GROUP) > > # Change back to "global" >@@ -1350,7 +1350,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_GLOBAL_GROUP) > > # Both group types: this performs only random checks - all possibilities >@@ -1368,7 +1368,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_GLOBAL_GROUP) > > # Change to "local" (shouldn't work) >@@ -1383,7 +1383,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e48: > (num, _) = e48.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Change to "universal" > >@@ -1397,7 +1397,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_UNIVERSAL_GROUP) > > # Change back to "global" >@@ -1412,7 +1412,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_GLOBAL_GROUP) > > # Change back to "universal" >@@ -1427,7 +1427,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_UNIVERSAL_GROUP) > > # Change to "local" >@@ -1442,7 +1442,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_DISTRIBUTION_LOCAL_GROUP) > > # Change to "global" (shouldn't work) >@@ -1457,7 +1457,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e49: > (num, _) = e49.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # Change back to "universal" > >@@ -1471,7 +1471,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_UNIVERSAL_GROUP) > > # Change back to "global" >@@ -1486,7 +1486,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_SECURITY_GLOBAL_GROUP) > > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -1536,7 +1536,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e50: > (num, msg) = e50.args >- self.assertEquals(num, ERR_OTHER) >+ self.assertEqual(num, ERR_OTHER) > self.assertTrue('00000057' in msg) > > try: >@@ -1547,7 +1547,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e51: > (num, msg) = e51.args >- self.assertEquals(num, ERR_OTHER) >+ self.assertEqual(num, ERR_OTHER) > self.assertTrue('00000057' in msg) > > ldb.add({ >@@ -1611,7 +1611,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e52: > (num, msg) = e52.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > self.assertTrue('00002085' in msg) > > try: >@@ -1627,7 +1627,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e53: > (num, msg) = e53.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > self.assertTrue('00002085' in msg) > > m = Message() >@@ -1663,7 +1663,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e54: > (num, msg) = e54.args >- self.assertEquals(num, ERR_OTHER) >+ self.assertEqual(num, ERR_OTHER) > self.assertTrue('00000057' in msg) > > m = Message() >@@ -1827,7 +1827,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e56: > (num, msg) = e56.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > self.assertTrue(error_msg_sasl_wrong_pw in msg) > > if not requires_strong_auth: >@@ -1836,7 +1836,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e4: > (num, msg) = e4.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > assertLDAPErrorMsg(msg, error_msg_simple_wrong_pw) > > m = Message() >@@ -1855,7 +1855,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e57: > (num, msg) = e57.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > assertLDAPErrorMsg(msg, error_msg_sasl_wrong_pw) > > try: >@@ -1863,7 +1863,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e58: > (num, msg) = e58.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > assertLDAPErrorMsg(msg, error_msg_sasl_must_change) > > if not requires_strong_auth: >@@ -1872,7 +1872,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e5: > (num, msg) = e5.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > assertLDAPErrorMsg(msg, error_msg_simple_wrong_pw) > > try: >@@ -1880,7 +1880,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e6: > (num, msg) = e6.args >- self.assertEquals(num, ERR_INVALID_CREDENTIALS) >+ self.assertEqual(num, ERR_INVALID_CREDENTIALS) > assertLDAPErrorMsg(msg, error_msg_simple_must_change) > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -1907,7 +1907,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_PASSWD_NOTREQD == 0) >@@ -1928,7 +1928,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -1945,7 +1945,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0) > self.assertFalse("lockoutTime" in res1[0]) >@@ -1960,7 +1960,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e59: > (num, _) = e59.args >- self.assertEquals(num, ERR_OTHER) >+ self.assertEqual(num, ERR_OTHER) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > > try: >@@ -1971,7 +1971,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e60: > (num, _) = e60.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > > try: >@@ -1981,7 +1981,7 @@ class SamTests(samba.tests.TestCase): > "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)}) > except LdbError as e61: > (num, _) = e61.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > > try: >@@ -1991,7 +1991,7 @@ class SamTests(samba.tests.TestCase): > "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)}) > except LdbError as e62: > (num, _) = e62.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > > try: >@@ -2002,7 +2002,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e63: > (num, _) = e63.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > > # Modify operation >@@ -2016,7 +2016,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0) > >@@ -2035,7 +2035,7 @@ class SamTests(samba.tests.TestCase): > ldb.modify(m) > except LdbError as e64: > (num, _) = e64.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > m = Message() >@@ -2046,7 +2046,7 @@ class SamTests(samba.tests.TestCase): > ldb.modify(m) > except LdbError as e65: > (num, _) = e65.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -2059,7 +2059,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0) > >@@ -2074,7 +2074,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0) >@@ -2096,7 +2096,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0) >@@ -2113,7 +2113,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e66: > (num, _) = e66.args >- self.assertEquals(num, ERR_OTHER) >+ self.assertEqual(num, ERR_OTHER) > > try: > m = Message() >@@ -2125,7 +2125,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e67: > (num, _) = e67.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -2144,12 +2144,12 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e68: > (num, _) = e68.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_WORKSTATION_TRUST) > > m = Message() >@@ -2162,7 +2162,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > > try: >@@ -2175,7 +2175,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e69: > (num, _) = e69.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > # With a computer object > >@@ -2195,7 +2195,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_PASSWD_NOTREQD == 0) >@@ -2216,7 +2216,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) >@@ -2233,7 +2233,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0) > self.assertFalse("lockoutTime" in res1[0]) >@@ -2248,7 +2248,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e70: > (num, _) = e70.args >- self.assertEquals(num, ERR_OTHER) >+ self.assertEqual(num, ERR_OTHER) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > > ldb.add({ >@@ -2259,7 +2259,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_WORKSTATION_TRUST) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >@@ -2270,7 +2270,7 @@ class SamTests(samba.tests.TestCase): > "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)}) > except LdbError as e71: > (num, _) = e71.args >- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > > try: >@@ -2281,7 +2281,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e72: > (num, _) = e72.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > > # Modify operation >@@ -2295,7 +2295,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0) > >@@ -2315,7 +2315,7 @@ class SamTests(samba.tests.TestCase): > ldb.modify(m) > except LdbError as e73: > (num, _) = e73.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > m = Message() >@@ -2326,7 +2326,7 @@ class SamTests(samba.tests.TestCase): > ldb.modify(m) > except LdbError as e74: > (num, _) = e74.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) >@@ -2339,7 +2339,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0) > >@@ -2354,7 +2354,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0) >@@ -2376,7 +2376,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0) >@@ -2393,7 +2393,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e75: > (num, _) = e75.args >- self.assertEquals(num, ERR_OTHER) >+ self.assertEqual(num, ERR_OTHER) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) >@@ -2405,7 +2405,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_WORKSTATION_TRUST) > > m = Message() >@@ -2418,7 +2418,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > > m = Message() >@@ -2431,7 +2431,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_WORKSTATION_TRUST) > > m = Message() >@@ -2444,7 +2444,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_NORMAL_ACCOUNT) > > m = Message() >@@ -2457,7 +2457,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_WORKSTATION_TRUST) > > m = Message() >@@ -2470,7 +2470,7 @@ class SamTests(samba.tests.TestCase): > res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["sAMAccountType"][0]), >+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), > ATYPE_WORKSTATION_TRUST) > > try: >@@ -2483,7 +2483,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e76: > (num, _) = e76.args >- self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > > # "primaryGroupID" does not change if account type remains the same > >@@ -2500,7 +2500,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["userAccountControl"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["userAccountControl"][0]), >+ self.assertEqual(int(res1[0]["userAccountControl"][0]), > UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) > > m = Message() >@@ -2527,7 +2527,7 @@ class SamTests(samba.tests.TestCase): > attrs=["userAccountControl", "primaryGroupID"]) > self.assertTrue(len(res1) == 1) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0) >- self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_ADMINS) >+ self.assertEqual(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_ADMINS) > > # For a workstation account > >@@ -2535,7 +2535,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["primaryGroupID"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS) >+ self.assertEqual(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS) > > m = Message() > m.dn = Dn(ldb, "<SID=" + ldb.get_domain_sid() + "-" + str(DOMAIN_RID_USERS) + ">") >@@ -2560,7 +2560,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["primaryGroupID"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS) >+ self.assertEqual(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS) > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn) >@@ -2953,7 +2953,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["isCriticalSystemObject"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(str(res1[0]["isCriticalSystemObject"][0]), "FALSE") >+ self.assertEqual(str(res1[0]["isCriticalSystemObject"][0]), "FALSE") > > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >@@ -2966,7 +2966,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["isCriticalSystemObject"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") >+ self.assertEqual(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") > > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >@@ -2979,7 +2979,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["isCriticalSystemObject"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") >+ self.assertEqual(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") > > # Modification tests > >@@ -2993,7 +2993,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["isCriticalSystemObject"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") >+ self.assertEqual(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) >@@ -3005,7 +3005,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["isCriticalSystemObject"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(str(res1[0]["isCriticalSystemObject"][0]), "FALSE") >+ self.assertEqual(str(res1[0]["isCriticalSystemObject"][0]), "FALSE") > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) >@@ -3018,7 +3018,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["isCriticalSystemObject"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") >+ self.assertEqual(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) >@@ -3030,7 +3030,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["isCriticalSystemObject"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") >+ self.assertEqual(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) >@@ -3042,7 +3042,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["isCriticalSystemObject"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") >+ self.assertEqual(str(res1[0]["isCriticalSystemObject"][0]), "TRUE") > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) >@@ -3054,7 +3054,7 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["isCriticalSystemObject"]) > self.assertTrue(len(res1) == 1) >- self.assertEquals(str(res1[0]["isCriticalSystemObject"][0]), "FALSE") >+ self.assertEqual(str(res1[0]["isCriticalSystemObject"][0]), "FALSE") > > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >@@ -3095,12 +3095,12 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["dNSHostName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["dNSHostName"][0]), "testname2.testdom") >+ self.assertEqual(str(res[0]["dNSHostName"][0]), "testname2.testdom") > > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname.testdom") > > m = Message() >@@ -3112,7 +3112,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname.testdom") > > m = Message() >@@ -3124,7 +3124,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname2.testdom2") > > m = Message() >@@ -3136,7 +3136,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname2.testdom2") > > m = Message() >@@ -3148,7 +3148,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname2.testdom2") > > m = Message() >@@ -3169,7 +3169,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname3.testdom3") > > m = Message() >@@ -3184,7 +3184,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname2.testdom2") > > m = Message() >@@ -3240,12 +3240,12 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["sAMAccountName"][0]), "testname$") >+ self.assertEqual(str(res[0]["sAMAccountName"][0]), "testname$") > > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname") > > m = Message() >@@ -3257,7 +3257,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname") > > m = Message() >@@ -3269,7 +3269,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname") > > m = Message() >@@ -3281,7 +3281,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/test$name") > > m = Message() >@@ -3293,7 +3293,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname2") > > m = Message() >@@ -3308,7 +3308,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname3") > > m = Message() >@@ -3323,7 +3323,7 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["servicePrincipalName"][0]), >+ self.assertEqual(str(res[0]["servicePrincipalName"][0]), > "HOST/testname2") > > m = Message() >@@ -3365,8 +3365,8 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["dNSHostName"][0]), "testname2.testdom") >- self.assertEquals(str(res[0]["sAMAccountName"][0]), "testname2$") >+ self.assertEqual(str(res[0]["dNSHostName"][0]), "testname2.testdom") >+ self.assertEqual(str(res[0]["sAMAccountName"][0]), "testname2$") > self.assertTrue(str(res[0]["servicePrincipalName"][0]) == "HOST/testname2" or > str(res[0]["servicePrincipalName"][1]) == "HOST/testname2") > self.assertTrue(str(res[0]["servicePrincipalName"][0]) == "HOST/testname2.testdom" or >@@ -3393,8 +3393,8 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["dNSHostName"][0]), "testname2.testdom") >- self.assertEquals(str(res[0]["sAMAccountName"][0]), "testname2$") >+ self.assertEqual(str(res[0]["dNSHostName"][0]), "testname2.testdom") >+ self.assertEqual(str(res[0]["sAMAccountName"][0]), "testname2$") > self.assertTrue(len(res[0]["servicePrincipalName"]) == 2) > self.assertTrue("HOST/testname2" in [str(x) for x in res[0]["servicePrincipalName"]]) > self.assertTrue("HOST/testname2.testdom" in [str(x) for x in res[0]["servicePrincipalName"]]) >@@ -3408,7 +3408,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e77: > (num, _) = e77.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) >@@ -3419,8 +3419,8 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["dNSHostName"][0]), "testname2.testdom") >- self.assertEquals(str(res[0]["sAMAccountName"][0]), "testname2$") >+ self.assertEqual(str(res[0]["dNSHostName"][0]), "testname2.testdom") >+ self.assertEqual(str(res[0]["sAMAccountName"][0]), "testname2$") > self.assertTrue(len(res[0]["servicePrincipalName"]) == 3) > self.assertTrue("HOST/testname2" in [str(x) for x in res[0]["servicePrincipalName"]]) > self.assertTrue("HOST/testname3" in [str(x) for x in res[0]["servicePrincipalName"]]) >@@ -3437,8 +3437,8 @@ class SamTests(samba.tests.TestCase): > res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, > scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"]) > self.assertTrue(len(res) == 1) >- self.assertEquals(str(res[0]["dNSHostName"][0]), "testname3.testdom") >- self.assertEquals(str(res[0]["sAMAccountName"][0]), "testname2$") >+ self.assertEqual(str(res[0]["dNSHostName"][0]), "testname3.testdom") >+ self.assertEqual(str(res[0]["sAMAccountName"][0]), "testname2$") > self.assertTrue(len(res[0]["servicePrincipalName"]) == 3) > self.assertTrue("HOST/testname2" in [str(x) for x in res[0]["servicePrincipalName"]]) > self.assertTrue("HOST/testname3" in [str(x) for x in res[0]["servicePrincipalName"]]) >@@ -3461,7 +3461,7 @@ class SamTests(samba.tests.TestCase): > self.assertTrue(len(res) == 1) > self.assertTrue("description" in res[0]) > self.assertTrue(len(res[0]["description"]) == 1) >- self.assertEquals(str(res[0]["description"][0]), "desc1") >+ self.assertEqual(str(res[0]["description"][0]), "desc1") > > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -3489,7 +3489,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e78: > (num, _) = e78.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -3514,7 +3514,7 @@ class SamTests(samba.tests.TestCase): > self.assertTrue(len(res) == 1) > self.assertTrue("description" in res[0]) > self.assertTrue(len(res[0]["description"]) == 1) >- self.assertEquals(str(res[0]["description"][0]), "desc1") >+ self.assertEqual(str(res[0]["description"][0]), "desc1") > > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -3534,7 +3534,7 @@ class SamTests(samba.tests.TestCase): > self.assertTrue(len(res) == 1) > self.assertTrue("description" in res[0]) > self.assertTrue(len(res[0]["description"]) == 1) >- self.assertEquals(str(res[0]["description"][0]), "desc1") >+ self.assertEqual(str(res[0]["description"][0]), "desc1") > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -3545,7 +3545,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e79: > (num, _) = e79.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -3556,7 +3556,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e80: > (num, _) = e80.args >- self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE) >+ self.assertEqual(num, ERR_NO_SUCH_ATTRIBUTE) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -3577,7 +3577,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e81: > (num, _) = e81.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -3588,7 +3588,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e82: > (num, _) = e82.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -3601,7 +3601,7 @@ class SamTests(samba.tests.TestCase): > self.assertTrue(len(res) == 1) > self.assertTrue("description" in res[0]) > self.assertTrue(len(res[0]["description"]) == 1) >- self.assertEquals(str(res[0]["description"][0]), "desc1") >+ self.assertEqual(str(res[0]["description"][0]), "desc1") > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -3614,7 +3614,7 @@ class SamTests(samba.tests.TestCase): > self.assertTrue(len(res) == 1) > self.assertTrue("description" in res[0]) > self.assertTrue(len(res[0]["description"]) == 1) >- self.assertEquals(str(res[0]["description"][0]), "desc2") >+ self.assertEqual(str(res[0]["description"][0]), "desc2") > > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > >@@ -3635,7 +3635,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e83: > (num, _) = e83.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > try: > self.ldb.add({ >@@ -3645,7 +3645,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e84: > (num, _) = e84.args >- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) > > # We are able to set it to a valid "nTDSDSA" entry if the server is > # capable of handling the role >@@ -3669,7 +3669,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e85: > (num, _) = e85.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) >@@ -3679,7 +3679,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e86: > (num, _) = e86.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > # We are able to set it to a valid "nTDSDSA" entry if the server is > # capable of handling the role >@@ -3715,7 +3715,7 @@ class SamTests(samba.tests.TestCase): > self.ldb.delete(pr_object[0] + "," + pr_object[1] + self.base_dn) > except LdbError as e7: > (num, _) = e7.args >- self.assertEquals(num, ERR_OTHER) >+ self.assertEqual(num, ERR_OTHER) > else: > self.fail("Deleted " + pr_object[0]) > >diff --git a/source4/dsdb/tests/python/sec_descriptor.py b/source4/dsdb/tests/python/sec_descriptor.py >index 5e0f1453423..2e1070fcffd 100755 >--- a/source4/dsdb/tests/python/sec_descriptor.py >+++ b/source4/dsdb/tests/python/sec_descriptor.py >@@ -75,7 +75,7 @@ class DescriptorTests(samba.tests.TestCase): > self.ldb_admin.search(base=class_dn, attrs=["name"]) > except LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > break > > ldif = """ >@@ -1985,31 +1985,31 @@ class RightsAttributesTests(DescriptorTests): > res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE, > attrs=["sDRightsEffective"]) > # user whould have no rights at all >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["sDRightsEffective"][0]), "0") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["sDRightsEffective"][0]), "0") > # give the user Write DACL and see what happens > mod = "(A;CI;WD;;;%s)" % str(user_sid) > self.sd_utils.dacl_add_ace(object_dn, mod) > res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE, > attrs=["sDRightsEffective"]) > # user whould have DACL_SECURITY_INFORMATION >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["sDRightsEffective"][0]), ("%d") % SECINFO_DACL) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["sDRightsEffective"][0]), ("%d") % SECINFO_DACL) > # give the user Write Owners and see what happens > mod = "(A;CI;WO;;;%s)" % str(user_sid) > self.sd_utils.dacl_add_ace(object_dn, mod) > res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE, > attrs=["sDRightsEffective"]) > # user whould have DACL_SECURITY_INFORMATION, OWNER_SECURITY_INFORMATION, GROUP_SECURITY_INFORMATION >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["sDRightsEffective"][0]), ("%d") % (SECINFO_DACL | SECINFO_GROUP | SECINFO_OWNER)) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["sDRightsEffective"][0]), ("%d") % (SECINFO_DACL | SECINFO_GROUP | SECINFO_OWNER)) > # no way to grant security privilege bu adding ACE's so we use a memeber of Domain Admins > _ldb = self.get_ldb_connection("testuser_attr2", "samba123@") > res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE, > attrs=["sDRightsEffective"]) > # user whould have DACL_SECURITY_INFORMATION, OWNER_SECURITY_INFORMATION, GROUP_SECURITY_INFORMATION >- self.assertEquals(len(res), 1) >- self.assertEquals(str(res[0]["sDRightsEffective"][0]), >+ self.assertEqual(len(res), 1) >+ self.assertEqual(str(res[0]["sDRightsEffective"][0]), > ("%d") % (SECINFO_DACL | SECINFO_GROUP | SECINFO_OWNER | SECINFO_SACL)) > > def test_allowedChildClassesEffective(self): >@@ -2024,7 +2024,7 @@ class RightsAttributesTests(DescriptorTests): > res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE, > attrs=["allowedChildClassesEffective"]) > # there should be no allowed child classes >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertFalse("allowedChildClassesEffective" in res[0].keys()) > # give the user the right to create children of type user > mod = "(OA;CI;CC;bf967aba-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) >@@ -2032,9 +2032,9 @@ class RightsAttributesTests(DescriptorTests): > res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE, > attrs=["allowedChildClassesEffective"]) > # allowedChildClassesEffective should only have one value, user >- self.assertEquals(len(res), 1) >- self.assertEquals(len(res[0]["allowedChildClassesEffective"]), 1) >- self.assertEquals(str(res[0]["allowedChildClassesEffective"][0]), "user") >+ self.assertEqual(len(res), 1) >+ self.assertEqual(len(res[0]["allowedChildClassesEffective"]), 1) >+ self.assertEqual(str(res[0]["allowedChildClassesEffective"][0]), "user") > > def test_allowedAttributesEffective(self): > object_dn = "OU=test_domain_ou1," + self.base_dn >@@ -2048,7 +2048,7 @@ class RightsAttributesTests(DescriptorTests): > res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE, > attrs=["allowedAttributesEffective"]) > # there should be no allowed attributes >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > self.assertFalse("allowedAttributesEffective" in res[0].keys()) > # give the user the right to write displayName and managedBy > mod2 = "(OA;CI;WP;bf967953-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) >@@ -2059,8 +2059,8 @@ class RightsAttributesTests(DescriptorTests): > res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE, > attrs=["allowedAttributesEffective"]) > # value should only contain user and managedBy >- self.assertEquals(len(res), 1) >- self.assertEquals(len(res[0]["allowedAttributesEffective"]), 2) >+ self.assertEqual(len(res), 1) >+ self.assertEqual(len(res[0]["allowedAttributesEffective"]), 2) > self.assertTrue(b"displayName" in res[0]["allowedAttributesEffective"]) > self.assertTrue(b"managedBy" in res[0]["allowedAttributesEffective"]) > >diff --git a/source4/dsdb/tests/python/sort.py b/source4/dsdb/tests/python/sort.py >index 19e8f7f2fcb..5663bfd2635 100644 >--- a/source4/dsdb/tests/python/sort.py >+++ b/source4/dsdb/tests/python/sort.py >@@ -230,7 +230,7 @@ class BaseSortTests(samba.tests.TestCase): > print("unnormalised:", [x[attr][0] for x in res]) > print("unnormalised: «%s»" % '» «'.join(str(x[attr][0]) > for x in res)) >- self.assertEquals(expected_order, received_order) >+ self.assertEqual(expected_order, received_order) > > def _test_server_sort_binary(self): > for attr in self.binary_sorted_keys: >@@ -247,7 +247,7 @@ class BaseSortTests(samba.tests.TestCase): > print(attr) > print(expected_order) > print(received_order) >- self.assertEquals(expected_order, received_order) >+ self.assertEqual(expected_order, received_order) > > def _test_server_sort_us_english(self): > # Windows doesn't support many matching rules, but does allow >@@ -278,7 +278,7 @@ class BaseSortTests(samba.tests.TestCase): > print("unnormalised: «%s»" % '» «'.join(str(x[attr][0]) > for x in res)) > >- self.assertEquals(expected_order, received_order) >+ self.assertEqual(expected_order, received_order) > > def _test_server_sort_different_attr(self): > >@@ -337,7 +337,7 @@ class BaseSortTests(samba.tests.TestCase): > print("Try with --elements=27 (or similar).") > print('-' * 72) > >- self.assertEquals(expected_order, received_order) >+ self.assertEqual(expected_order, received_order) > for x in res: > if sort_attr in x: > self.fail('the search for %s should not return %s' % >diff --git a/source4/dsdb/tests/python/token_group.py b/source4/dsdb/tests/python/token_group.py >index b3db24dcb4d..e12b5cd4d36 100755 >--- a/source4/dsdb/tests/python/token_group.py >+++ b/source4/dsdb/tests/python/token_group.py >@@ -67,7 +67,7 @@ class StaticTokenTest(samba.tests.TestCase): > self.base_dn = self.ldb.domain_dn() > > res = self.ldb.search("", scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > self.user_sid_dn = "<SID=%s>" % str(ndr_unpack(samba.dcerpc.security.dom_sid, res[0]["tokenGroups"][0])) > >@@ -91,7 +91,7 @@ class StaticTokenTest(samba.tests.TestCase): > self.fail(msg="This test is only valid on ldap") > > res = self.ldb.search("", scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > print("Getting tokenGroups from rootDSE") > tokengroups = [] >@@ -110,7 +110,7 @@ class StaticTokenTest(samba.tests.TestCase): > def test_dn_tokenGroups(self): > print("Getting tokenGroups from user DN") > res = self.ldb.search(self.user_sid_dn, scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > dn_tokengroups = [] > for sid in res[0]['tokenGroups']: >@@ -273,13 +273,13 @@ class DynamicTokenTest(samba.tests.TestCase): > self.ldb = self.get_ldb_connection(self.test_user, self.test_user_pass) > > res = self.ldb.search("", scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > self.user_sid = ndr_unpack(samba.dcerpc.security.dom_sid, res[0]["tokenGroups"][0]) > self.user_sid_dn = "<SID=%s>" % str(self.user_sid) > > res = self.ldb.search(self.user_sid_dn, scope=ldb.SCOPE_BASE, attrs=[]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > self.test_user_dn = res[0].dn > >@@ -323,7 +323,7 @@ class DynamicTokenTest(samba.tests.TestCase): > self.fail(msg="This test is only valid on ldap") > > res = self.ldb.search("", scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > print("Getting tokenGroups from rootDSE") > tokengroups = [] >@@ -342,7 +342,7 @@ class DynamicTokenTest(samba.tests.TestCase): > def test_dn_tokenGroups(self): > print("Getting tokenGroups from user DN") > res = self.ldb.search(self.user_sid_dn, scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > dn_tokengroups = [] > for sid in res[0]['tokenGroups']: >@@ -450,7 +450,7 @@ class DynamicTokenTest(samba.tests.TestCase): > tokenGroupsSet = set() > > res = self.ldb.search(self.user_sid_dn, scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > dn_tokengroups = [] > for sid in res[0]['tokenGroups']: >@@ -537,7 +537,7 @@ class DynamicTokenTest(samba.tests.TestCase): > tokenGroupsSet = set() > > res = self.ldb.search(self.user_sid_dn, scope=ldb.SCOPE_BASE, attrs=["tokenGroupsGlobalAndUniversal"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > dn_tokengroups = [] > for sid in res[0]['tokenGroupsGlobalAndUniversal']: >diff --git a/source4/dsdb/tests/python/tombstone_reanimation.py b/source4/dsdb/tests/python/tombstone_reanimation.py >index 9cca5436295..3c15c8e176f 100755 >--- a/source4/dsdb/tests/python/tombstone_reanimation.py >+++ b/source4/dsdb/tests/python/tombstone_reanimation.py >@@ -65,7 +65,7 @@ class RestoredObjectAttributesBaseTestCase(samba.tests.TestCase): > res = self.samdb.search(base="<GUID=%s>" % self.GUID_string(guid), > scope=SCOPE_BASE, attrs=attrs, > controls=["show_deleted:1"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > return res[0] > > def search_dn(self, dn): >@@ -73,7 +73,7 @@ class RestoredObjectAttributesBaseTestCase(samba.tests.TestCase): > base=dn, > scope=SCOPE_BASE, > controls=["show_recycled:1"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > return res[0] > > def _create_object(self, msg): >@@ -160,14 +160,14 @@ class RestoredObjectAttributesBaseTestCase(samba.tests.TestCase): > for o in repl.ctr.array: > e = expected[i] > (attid, version) = e >- self.assertEquals(attid, o.attid, >+ self.assertEqual(attid, o.attid, > "(LDAP) Wrong attid " > "for expected value %d, wanted 0x%08x got 0x%08x, " > "repl: \n%s" > % (i, attid, o.attid, ndr_print(repl))) > # Allow version to be skipped when it does not matter > if version is not None: >- self.assertEquals(o.version, version, >+ self.assertEqual(o.version, version, > "(LDAP) Wrong version for expected value %d, " > "attid 0x%08x, " > "wanted %d got %d, repl: \n%s" >@@ -208,7 +208,7 @@ class BaseRestoreObjectTestCase(RestoredObjectAttributesBaseTestCase): > self.samdb.modify(msg) > except LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) >+ self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS) > > def test_undelete(self): > print("Testing standard undelete operation") >@@ -246,14 +246,14 @@ class BaseRestoreObjectTestCase(RestoredObjectAttributesBaseTestCase): > self.fail() > except LdbError as e1: > (num, _) = e1.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > try: > self.samdb.rename(str(objDeleted1.dn), usr1, ["show_deleted:1"]) > self.fail() > except LdbError as e2: > (num, _) = e2.args >- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) > > def test_undelete_with_mod(self): > print("Testing standard undelete operation with modification of additional attributes") >@@ -313,7 +313,7 @@ class BaseRestoreObjectTestCase(RestoredObjectAttributesBaseTestCase): > self.fail() > except LdbError as e3: > (num, _) = e3.args >- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS) >+ self.assertEqual(num, ERR_ENTRY_ALREADY_EXISTS) > > def test_undelete_cross_nc(self): > print("Cross NC undelete") >@@ -345,14 +345,14 @@ class BaseRestoreObjectTestCase(RestoredObjectAttributesBaseTestCase): > self.fail() > except LdbError as e4: > (num, _) = e4.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > # try to undelete from config to base dn > try: > self.restore_deleted_object(self.samdb, objDeleted2.dn, c4) > self.fail() > except LdbError as e5: > (num, _) = e5.args >- self.assertEquals(num, ERR_OPERATIONS_ERROR) >+ self.assertEqual(num, ERR_OPERATIONS_ERROR) > # assert undeletion will work in same nc > self.restore_deleted_object(self.samdb, objDeleted1.dn, c4) > self.restore_deleted_object(self.samdb, objDeleted2.dn, c3) >diff --git a/source4/dsdb/tests/python/urgent_replication.py b/source4/dsdb/tests/python/urgent_replication.py >index 5e304cfc989..6ec698d0bbb 100755 >--- a/source4/dsdb/tests/python/urgent_replication.py >+++ b/source4/dsdb/tests/python/urgent_replication.py >@@ -41,7 +41,7 @@ class UrgentReplicationTests(samba.tests.TestCase): > ldb.delete(dn, ["relax:0"]) > except LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > def setUp(self): > super(UrgentReplicationTests, self).setUp() >@@ -96,7 +96,7 @@ systemFlags: 33554432""", ["relax:0"]) > > # urgent replication should be enabled when creation > res = self.ldb.load_partition_usn("cn=Configuration," + self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > # urgent replication should NOT be enabled when modifying > m = Message() >@@ -110,7 +110,7 @@ systemFlags: 33554432""", ["relax:0"]) > # urgent replication should be enabled when deleting > self.delete_force(self.ldb, "cn=NTDS Settings test,cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration," + self.base_dn) > res = self.ldb.load_partition_usn("cn=Configuration," + self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > self.delete_force(self.ldb, "cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration," + self.base_dn) > >@@ -129,7 +129,7 @@ systemFlags: 33554432""", ["relax:0"]) > > # urgent replication should be enabled when creating > res = self.ldb.load_partition_usn("cn=Configuration," + self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > # urgent replication should NOT be enabled when modifying > m = Message() >@@ -143,7 +143,7 @@ systemFlags: 33554432""", ["relax:0"]) > # urgent replication should be enabled when deleting > self.delete_force(self.ldb, "cn=test crossRef,CN=Partitions,CN=Configuration," + self.base_dn) > res = self.ldb.load_partition_usn("cn=Configuration," + self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > def test_attributeSchema_object(self): > """Test if the urgent replication is activated when handling an attributeSchema object""" >@@ -167,7 +167,7 @@ name: test attributeSchema""") > > # urgent replication should be enabled when creating > res = self.ldb.load_partition_usn("cn=Schema,cn=Configuration," + self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > # urgent replication should be enabled when modifying > m = Message() >@@ -176,7 +176,7 @@ name: test attributeSchema""") > "lDAPDisplayName") > self.ldb.modify(m) > res = self.ldb.load_partition_usn("cn=Schema,cn=Configuration," + self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > def test_classSchema_object(self): > """Test if the urgent replication is activated when handling a classSchema object.""" >@@ -205,7 +205,7 @@ defaultHidingValue: TRUE""") > > # urgent replication should be enabled when creating > res = self.ldb.load_partition_usn("cn=Schema,cn=Configuration," + self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > except LdbError: > print("Not testing urgent replication when creating classSchema object ...\n") >@@ -217,7 +217,7 @@ defaultHidingValue: TRUE""") > "lDAPDisplayName") > self.ldb.modify(m) > res = self.ldb.load_partition_usn("cn=Schema,cn=Configuration," + self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > def test_secret_object(self): > """Test if the urgent replication is activated when handling a secret object.""" >@@ -231,7 +231,7 @@ defaultHidingValue: TRUE""") > > # urgent replication should be enabled when creating > res = self.ldb.load_partition_usn(self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > # urgent replication should be enabled when modifying > m = Message() >@@ -240,7 +240,7 @@ defaultHidingValue: TRUE""") > "currentValue") > self.ldb.modify(m) > res = self.ldb.load_partition_usn(self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > # urgent replication should NOT be enabled when deleting > self.delete_force(self.ldb, "cn=test secret,cn=System," + self.base_dn) >@@ -262,7 +262,7 @@ rIDAvailablePool: 133001-1073741823""", ["relax:0"]) > > # urgent replication should be enabled when creating > res = self.ldb.load_partition_usn(self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > # urgent replication should be enabled when modifying > m = Message() >@@ -271,7 +271,7 @@ rIDAvailablePool: 133001-1073741823""", ["relax:0"]) > "systemFlags") > self.ldb.modify(m) > res = self.ldb.load_partition_usn(self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > # urgent replication should NOT be enabled when deleting > self.delete_force(self.ldb, "CN=RID Manager test,CN=System," + self.base_dn) >@@ -301,7 +301,7 @@ rIDAvailablePool: 133001-1073741823""", ["relax:0"]) > "userAccountControl") > self.ldb.modify(m) > res = self.ldb.load_partition_usn(self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > # urgent replication should be enabled when modifying lockoutTime > m = Message() >@@ -310,7 +310,7 @@ rIDAvailablePool: 133001-1073741823""", ["relax:0"]) > "lockoutTime") > self.ldb.modify(m) > res = self.ldb.load_partition_usn(self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > # urgent replication should be enabled when modifying pwdLastSet > m = Message() >@@ -319,7 +319,7 @@ rIDAvailablePool: 133001-1073741823""", ["relax:0"]) > "pwdLastSet") > self.ldb.modify(m) > res = self.ldb.load_partition_usn(self.base_dn) >- self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) >+ self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) > > # urgent replication should NOT be enabled when modifying a not-urgent > # attribute >diff --git a/source4/dsdb/tests/python/vlv.py b/source4/dsdb/tests/python/vlv.py >index acaf64d0faa..f7bcc63be67 100644 >--- a/source4/dsdb/tests/python/vlv.py >+++ b/source4/dsdb/tests/python/vlv.py >@@ -407,7 +407,7 @@ class VLVTests(VLVTestsBase): > print("start %d end %d" % (start, end)) > print("expected: %s" % expected_results) > print("got : %s" % results) >- self.assertEquals(expected_results, results) >+ self.assertEqual(expected_results, results) > > def test_server_vlv_with_cookie(self): > attrs = [x for x in self.users[0].keys() if x not in >@@ -538,7 +538,7 @@ class VLVTests(VLVTestsBase): > > expected_results = expected_order[start: end] > >- self.assertEquals(expected_results, results) >+ self.assertEqual(expected_results, results) > > def test_vlv_gte_with_expression(self): > """What happens when we run the VLV with an expression?""" >@@ -618,7 +618,7 @@ class VLVTests(VLVTestsBase): > if expected_results != results: > print("attr %s before %d after %d offset %d" % > (attr, before, after, offset)) >- self.assertEquals(expected_results, results) >+ self.assertEqual(expected_results, results) > > n = len(self.users) > if random.random() < 0.1 + (n < 5) * 0.05: >@@ -667,7 +667,7 @@ class VLVTests(VLVTestsBase): > controls=[sort_control, vlv_search]) > > results = [x[attr][0].upper() for x in res] >- #self.assertEquals(expected_order, results) >+ #self.assertEqual(expected_order, results) > > dn_order = [str(x['dn']) for x in res] > values = results[:] >@@ -690,7 +690,7 @@ class VLVTests(VLVTestsBase): > dn_expected = dn_order[offset - before - 1: > offset + after] > >- self.assertEquals(dn_expected, dn_results) >+ self.assertEqual(dn_expected, dn_results) > > results = [x[attr][0].upper() for x in res] > >@@ -1024,7 +1024,7 @@ class VLVTests(VLVTestsBase): > > expected_results = expected_order[start: end] > >- self.assertEquals(expected_results, results) >+ self.assertEqual(expected_results, results) > > def test_server_vlv_gte_no_cookie(self): > attrs = [x for x in self.users[0].keys() if x not in >@@ -1068,7 +1068,7 @@ class VLVTests(VLVTestsBase): > print("\nattr %s offset %d before %d " > "after %d gte %s" % > (attr, offset, before, after, gte)) >- self.assertEquals(expected_results, results) >+ self.assertEqual(expected_results, results) > > def test_multiple_searches(self): > """The maximum number of concurrent vlv searches per connection is >diff --git a/source4/torture/drs/python/cracknames.py b/source4/torture/drs/python/cracknames.py >index c35a2680ff9..e4884ea0f63 100644 >--- a/source4/torture/drs/python/cracknames.py >+++ b/source4/torture/drs/python/cracknames.py >@@ -83,8 +83,8 @@ class DrsCracknamesTestCase(drs_base.DrsBaseTestCase): > drsuapi.DRSUAPI_DS_NAME_FORMAT_FQDN_1779, > drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID) > >- self.assertEquals(ctr.count, 1) >- self.assertEquals(ctr.array[0].status, >+ self.assertEqual(ctr.count, 1) >+ self.assertEqual(ctr.array[0].status, > drsuapi.DRSUAPI_DS_NAME_STATUS_OK) > > user_guid = ctr.array[0].result_name >@@ -94,8 +94,8 @@ class DrsCracknamesTestCase(drs_base.DrsBaseTestCase): > drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID, > name_format) > >- self.assertEquals(ctr.count, 1) >- self.assertEquals(ctr.array[0].status, >+ self.assertEqual(ctr.count, 1) >+ self.assertEqual(ctr.array[0].status, > drsuapi.DRSUAPI_DS_NAME_STATUS_OK, > "Expected 0, got %s, desired format is %s" > % (ctr.array[0].status, name_format)) >@@ -104,8 +104,8 @@ class DrsCracknamesTestCase(drs_base.DrsBaseTestCase): > name_format, > drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID) > >- self.assertEquals(ctr.count, 1) >- self.assertEquals(ctr.array[0].status, >+ self.assertEqual(ctr.count, 1) >+ self.assertEqual(ctr.array[0].status, > drsuapi.DRSUAPI_DS_NAME_STATUS_OK, > "Expected 0, got %s, offered format is %s" > % (ctr.array[0].status, name_format)) >@@ -134,8 +134,8 @@ class DrsCracknamesTestCase(drs_base.DrsBaseTestCase): > drsuapi.DRSUAPI_DS_NAME_FORMAT_FQDN_1779, > drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID) > >- self.assertEquals(ctr.count, 1) >- self.assertEquals(ctr.array[0].status, >+ self.assertEqual(ctr.count, 1) >+ self.assertEqual(ctr.array[0].status, > drsuapi.DRSUAPI_DS_NAME_STATUS_OK) > > user_guid = ctr.array[0].result_name >@@ -144,8 +144,8 @@ class DrsCracknamesTestCase(drs_base.DrsBaseTestCase): > drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID, > drsuapi.DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) > >- self.assertEquals(ctr.count, 1) >- self.assertEquals(ctr.array[0].status, >+ self.assertEqual(ctr.count, 1) >+ self.assertEqual(ctr.array[0].status, > drsuapi.DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE) > > self.ldb_dc1.delete(user) >@@ -172,8 +172,8 @@ class DrsCracknamesTestCase(drs_base.DrsBaseTestCase): > drsuapi.DRSUAPI_DS_NAME_FORMAT_FQDN_1779, > drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID) > >- self.assertEquals(ctr.count, 1) >- self.assertEquals(ctr.array[0].status, >+ self.assertEqual(ctr.count, 1) >+ self.assertEqual(ctr.array[0].status, > drsuapi.DRSUAPI_DS_NAME_STATUS_OK) > > user_guid = ctr.array[0].result_name >@@ -182,8 +182,8 @@ class DrsCracknamesTestCase(drs_base.DrsBaseTestCase): > drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID, > drsuapi.DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) > >- self.assertEquals(ctr.count, 1) >- self.assertEquals(ctr.array[0].status, >+ self.assertEqual(ctr.count, 1) >+ self.assertEqual(ctr.array[0].status, > drsuapi.DRSUAPI_DS_NAME_STATUS_NOT_FOUND) > > self.ldb_dc1.delete(user) >diff --git a/source4/torture/drs/python/delete_object.py b/source4/torture/drs/python/delete_object.py >index 1022489a767..395877ad76a 100644 >--- a/source4/torture/drs/python/delete_object.py >+++ b/source4/torture/drs/python/delete_object.py >@@ -65,7 +65,7 @@ class DrsDeleteObjectTestCase(drs_base.DrsBaseTestCase): > res = sam_ldb.search(base=self.domain_dn, > expression=expression, > controls=["show_deleted:1"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > user_cur = res[0] > # Deleted Object base DN > dodn = self._deleted_objects_dn(sam_ldb) >@@ -75,7 +75,7 @@ class DrsDeleteObjectTestCase(drs_base.DrsBaseTestCase): > name_orig = str(obj_orig["name"][0]) > name_cur = str(user_cur["name"][0]) > if is_deleted: >- self.assertEquals(str(user_cur["isDeleted"][0]), "TRUE") >+ self.assertEqual(str(user_cur["isDeleted"][0]), "TRUE") > self.assertFalse("objectCategory" in user_cur) > self.assertFalse("sAMAccountType" in user_cur) > self.assertFalse("description" in user_cur) >@@ -83,17 +83,17 @@ class DrsDeleteObjectTestCase(drs_base.DrsBaseTestCase): > self.assertFalse("member" in user_cur) > self.assertTrue(dodn in str(user_cur["dn"]), > "User %s is deleted but it is not located under %s (found at %s)!" % (name_orig, dodn, user_cur["dn"])) >- self.assertEquals(name_cur, name_orig + "\nDEL:" + guid_str) >- self.assertEquals(name_cur, user_cur.dn.get_rdn_value()) >- self.assertEquals(cn_cur, cn_orig + "\nDEL:" + guid_str) >- self.assertEquals(name_cur, cn_cur) >+ self.assertEqual(name_cur, name_orig + "\nDEL:" + guid_str) >+ self.assertEqual(name_cur, user_cur.dn.get_rdn_value()) >+ self.assertEqual(cn_cur, cn_orig + "\nDEL:" + guid_str) >+ self.assertEqual(name_cur, cn_cur) > else: > self.assertFalse("isDeleted" in user_cur) >- self.assertEquals(name_cur, name_orig) >- self.assertEquals(name_cur, user_cur.dn.get_rdn_value()) >- self.assertEquals(cn_cur, cn_orig) >- self.assertEquals(name_cur, cn_cur) >- self.assertEquals(obj_orig["dn"], user_cur["dn"]) >+ self.assertEqual(name_cur, name_orig) >+ self.assertEqual(name_cur, user_cur.dn.get_rdn_value()) >+ self.assertEqual(cn_cur, cn_orig) >+ self.assertEqual(name_cur, cn_cur) >+ self.assertEqual(obj_orig["dn"], user_cur["dn"]) > self.assertTrue(dodn not in str(user_cur["dn"])) > return user_cur > >@@ -118,7 +118,7 @@ class DrsDeleteObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.domain_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -274,7 +274,7 @@ class DrsDeleteObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.domain_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >diff --git a/source4/torture/drs/python/drs_base.py b/source4/torture/drs/python/drs_base.py >index 5eaad9edc1c..9c8e825a737 100644 >--- a/source4/torture/drs/python/drs_base.py >+++ b/source4/torture/drs/python/drs_base.py >@@ -98,14 +98,14 @@ class DrsBaseTestCase(SambaToolCmdTest): > res = sam_ldb.search(base=wkdn, > scope=SCOPE_BASE, > controls=["show_deleted:1"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > return str(res[0]["dn"]) > > def _lost_and_found_dn(self, sam_ldb, nc): > wkdn = "<WKGUID=%s,%s>" % (dsdb.DS_GUID_LOSTANDFOUND_CONTAINER, nc) > res = sam_ldb.search(base=wkdn, > scope=SCOPE_BASE) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > return str(res[0]["dn"]) > > def _make_obj_name(self, prefix): >@@ -143,7 +143,7 @@ class DrsBaseTestCase(SambaToolCmdTest): > > (result, out, err) = self.runsubcmd(*samba_tool_cmdline) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > > def _enable_inbound_repl(self, DC): > # make base command line >@@ -152,7 +152,7 @@ class DrsBaseTestCase(SambaToolCmdTest): > samba_tool_cmd += [DC, "--dsa-option=-DISABLE_INBOUND_REPL"] > (result, out, err) = self.runsubcmd(*samba_tool_cmd) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > > def _disable_inbound_repl(self, DC): > # make base command line >@@ -161,7 +161,7 @@ class DrsBaseTestCase(SambaToolCmdTest): > samba_tool_cmd += [DC, "--dsa-option=+DISABLE_INBOUND_REPL"] > (result, out, err) = self.runsubcmd(*samba_tool_cmd) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > > def _enable_all_repl(self, DC): > self._enable_inbound_repl(DC) >@@ -171,7 +171,7 @@ class DrsBaseTestCase(SambaToolCmdTest): > samba_tool_cmd += [DC, "--dsa-option=-DISABLE_OUTBOUND_REPL"] > (result, out, err) = self.runsubcmd(*samba_tool_cmd) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > > def _disable_all_repl(self, DC): > self._disable_inbound_repl(DC) >@@ -181,7 +181,7 @@ class DrsBaseTestCase(SambaToolCmdTest): > samba_tool_cmd += [DC, "--dsa-option=+DISABLE_OUTBOUND_REPL"] > (result, out, err) = self.runsubcmd(*samba_tool_cmd) > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > > def _get_highest_hwm_utdv(self, ldb_conn): > res = ldb_conn.search("", scope=ldb.SCOPE_BASE, attrs=["highestCommittedUSN"]) >diff --git a/source4/torture/drs/python/fsmo.py b/source4/torture/drs/python/fsmo.py >index f846ca71611..b548fbca26a 100644 >--- a/source4/torture/drs/python/fsmo.py >+++ b/source4/torture/drs/python/fsmo.py >@@ -70,7 +70,7 @@ class DrsFsmoTestCase(drs_base.DrsBaseTestCase): > cmd_line_auth) > > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > if not noop: > self.assertTrue("FSMO transfer of '%s' role successful" % role in out) > else: >diff --git a/source4/torture/drs/python/getnc_exop.py b/source4/torture/drs/python/getnc_exop.py >index 6d60d977ea5..87571ca252b 100644 >--- a/source4/torture/drs/python/getnc_exop.py >+++ b/source4/torture/drs/python/getnc_exop.py >@@ -238,7 +238,7 @@ class DrsReplicaSyncTestCase(drs_base.DrsBaseTestCase): > self.fail("Expected DsGetNCChanges to fail with WERR_DS_CANT_FIND_EXPECTED_NC") > except WERRORError as e1: > (enum, estr) = e1.args >- self.assertEquals(enum, werror.WERR_DS_CANT_FIND_EXPECTED_NC) >+ self.assertEqual(enum, werror.WERR_DS_CANT_FIND_EXPECTED_NC) > > def test_link_utdv_hwm(self): > """Test verify the DRS_GET_ANC behavior.""" >diff --git a/source4/torture/drs/python/getncchanges.py b/source4/torture/drs/python/getncchanges.py >index 023cb8a394c..3db76a5213f 100644 >--- a/source4/torture/drs/python/getncchanges.py >+++ b/source4/torture/drs/python/getncchanges.py >@@ -83,7 +83,7 @@ class DrsReplicaSyncIntegrityTestCase(drs_base.DrsBaseTestCase): > """Adds an OU object""" > self.test_ldb_dc.add({"dn": dn, "objectclass": objectclass}) > res = self.test_ldb_dc.search(base=dn, scope=SCOPE_BASE) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > def modify_object(self, dn, attr, value): > """Modifies an object's USN by adding an attribute value to it""" >diff --git a/source4/torture/drs/python/repl_move.py b/source4/torture/drs/python/repl_move.py >index 624c95e40fc..31dec3849a7 100644 >--- a/source4/torture/drs/python/repl_move.py >+++ b/source4/torture/drs/python/repl_move.py >@@ -117,11 +117,11 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > for o in repl.ctr.array: > e = expected[i] > (attid, orig_dsa, version) = e >- self.assertEquals(attid, o.attid, >+ self.assertEqual(attid, o.attid, > "(LDAP) Wrong attid " > "for expected value %d, wanted 0x%08x got 0x%08x" > % (i, attid, o.attid)) >- self.assertEquals(o.originating_invocation_id, >+ self.assertEqual(o.originating_invocation_id, > misc.GUID(orig_dsa), > "(LDAP) Wrong originating_invocation_id " > "for expected value %d, attid 0x%08x, wanted %s got %s" >@@ -130,7 +130,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > o.originating_invocation_id)) > # Allow version to be skipped when it does not matter > if version is not None: >- self.assertEquals(o.version, version, >+ self.assertEqual(o.version, version, > "(LDAP) Wrong version for expected value %d, " > "attid 0x%08x, " > "wanted %d got %d" >@@ -184,12 +184,12 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > e = expected[i] > (attid, orig_dsa, version) = e > >- self.assertEquals(attid, drs_attid.attid, >+ self.assertEqual(attid, drs_attid.attid, > "(DRS) Wrong attid " > "for expected value %d, wanted 0x%08x got 0x%08x" > % (i, attid, drs_attid.attid)) > >- self.assertEquals(o.originating_invocation_id, >+ self.assertEqual(o.originating_invocation_id, > misc.GUID(orig_dsa), > "(DRS) Wrong originating_invocation_id " > "for expected value %d, attid 0x%08x, wanted %s got %s" >@@ -198,7 +198,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > o.originating_invocation_id)) > # Allow version to be skipped when it does not matter > if version is not None: >- self.assertEquals(o.version, version, >+ self.assertEqual(o.version, version, > "(DRS) Wrong version for expected value %d, " > "attid 0x%08x, " > "wanted %d got %d" >@@ -215,7 +215,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > controls=["show_deleted:1"], > attrs=["*", "parentGUID", > "replPropertyMetaData"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > user_cur = res[0] > rdn_orig = str(obj_orig[user_cur.dn.get_rdn_name()][0]) > rdn_cur = str(user_cur[user_cur.dn.get_rdn_name()][0]) >@@ -226,16 +226,16 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > # now check properties of the user > if is_deleted: > self.assertTrue("isDeleted" in user_cur) >- self.assertEquals(rdn_cur.split('\n')[0], rdn_orig) >- self.assertEquals(name_cur.split('\n')[0], name_orig) >- self.assertEquals(dn_cur.get_rdn_value().split('\n')[0], >+ self.assertEqual(rdn_cur.split('\n')[0], rdn_orig) >+ self.assertEqual(name_cur.split('\n')[0], name_orig) >+ self.assertEqual(dn_cur.get_rdn_value().split('\n')[0], > dn_orig.get_rdn_value()) > self.assertEqual(name_cur, rdn_cur) > else: > self.assertFalse("isDeleted" in user_cur) >- self.assertEquals(rdn_cur, rdn_orig) >- self.assertEquals(name_cur, name_orig) >- self.assertEquals(dn_cur, dn_orig) >+ self.assertEqual(rdn_cur, rdn_orig) >+ self.assertEqual(name_cur, name_orig) >+ self.assertEqual(dn_cur, dn_orig) > self.assertEqual(name_cur, rdn_cur) > parent_cur = user_cur["parentGUID"][0] > try: >@@ -277,7 +277,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -318,7 +318,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -550,7 +550,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -591,7 +591,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_moved_orig = ldb_res[0] > > moved_metadata = [ >@@ -629,7 +629,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 0) >+ self.assertEqual(len(ldb_res), 0) > > # delete user on DC1 > self.ldb_dc1.delete('<GUID=%s>' % self._GUID_string(user_orig["objectGUID"][0])) >@@ -733,7 +733,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -774,7 +774,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -913,7 +913,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -954,7 +954,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -1094,7 +1094,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -1167,7 +1167,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -1418,7 +1418,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -1438,7 +1438,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -1483,7 +1483,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_BASE, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > ou_orig = ldb_res[0] > ou_dn = ldb_res[0]["dn"] > >@@ -1502,7 +1502,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=new_dn, > scope=SCOPE_BASE, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > ou_moved_orig = ldb_res[0] > ou_moved_dn = ldb_res[0]["dn"] >@@ -1548,7 +1548,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_BASE, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > ou_orig = ldb_res[0] > ou_dn = ldb_res[0]["dn"] > >@@ -1567,7 +1567,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=new_dn, > scope=SCOPE_BASE, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > ou_moved_orig = ldb_res[0] > ou_moved_dn = ldb_res[0]["dn"] >@@ -1613,7 +1613,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_BASE, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > ou_orig = ldb_res[0] > ou_dn = ldb_res[0]["dn"] > >@@ -1632,7 +1632,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=new_dn, > scope=SCOPE_BASE, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > ou_moved_orig = ldb_res[0] > ou_moved_dn = ldb_res[0]["dn"] >@@ -1679,7 +1679,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_BASE, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > ou_orig = ldb_res[0] > ou_dn = ldb_res[0]["dn"] > >@@ -1698,7 +1698,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=new_dn, > scope=SCOPE_BASE, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > ou_moved_orig = ldb_res[0] > ou_moved_dn = ldb_res[0]["dn"] >@@ -1744,7 +1744,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_BASE, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > ou_orig = ldb_res[0] > ou_dn = ldb_res[0]["dn"] > >@@ -1792,7 +1792,7 @@ class DrsMoveObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_BASE, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > ou_orig = ldb_res[0] > ou_dn = ldb_res[0]["dn"] > >@@ -1911,7 +1911,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > res = sam_ldb.search(base='<GUID=%s>' % guid_str, > controls=["show_deleted:1"], > attrs=["*", "parentGUID"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > user_cur = res[0] > cn_orig = str(obj_orig["cn"][0]) > cn_cur = str(user_cur["cn"][0]) >@@ -1922,16 +1922,16 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > # now check properties of the user > if is_deleted: > self.assertTrue("isDeleted" in user_cur) >- self.assertEquals(cn_cur.split('\n')[0], cn_orig) >- self.assertEquals(name_cur.split('\n')[0], name_orig) >- self.assertEquals(dn_cur.get_rdn_value().split('\n')[0], >+ self.assertEqual(cn_cur.split('\n')[0], cn_orig) >+ self.assertEqual(name_cur.split('\n')[0], name_orig) >+ self.assertEqual(dn_cur.get_rdn_value().split('\n')[0], > dn_orig.get_rdn_value()) > self.assertEqual(name_cur, cn_cur) > else: > self.assertFalse("isDeleted" in user_cur) >- self.assertEquals(cn_cur, cn_orig) >- self.assertEquals(name_cur, name_orig) >- self.assertEquals(dn_cur, dn_orig) >+ self.assertEqual(cn_cur, cn_orig) >+ self.assertEqual(name_cur, name_orig) >+ self.assertEqual(dn_cur, dn_orig) > self.assertEqual(name_cur, cn_cur) > self.assertEqual(name_cur, user_cur.dn.get_rdn_value()) > >@@ -1958,7 +1958,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -1977,7 +1977,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou2_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -2015,7 +2015,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -2038,7 +2038,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=new_dn3, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -2062,7 +2062,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -2110,7 +2110,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -2133,7 +2133,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=new_dn3, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -2155,7 +2155,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -2165,7 +2165,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > # check user info on DC2 - should be valid user > user_cur = self._check_obj(sam_ldb=self.ldb_dc2, obj_orig=user_moved_orig, is_deleted=False) > >- self.assertEquals(user_cur["parentGUID"], user_moved_orig["parentGUID"]) >+ self.assertEqual(user_cur["parentGUID"], user_moved_orig["parentGUID"]) > > # delete user on DC1 > self.ldb_dc1.delete('<GUID=%s>' % self._GUID_string(user_orig["objectGUID"][0])) >@@ -2200,7 +2200,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -2219,7 +2219,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou2_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -2261,7 +2261,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -2270,7 +2270,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > self._net_drs_replicate(DC=self.dnsname_dc2, fromDC=self.dnsname_dc1, forced=True) > # check user info on DC2 - should be valid user > user_cur = self._check_obj(sam_ldb=self.ldb_dc2, obj_orig=user_moved_orig, is_deleted=False) >- self.assertEquals(user_cur["parentGUID"][0], user_moved_orig["parentGUID"][0]) >+ self.assertEqual(user_cur["parentGUID"][0], user_moved_orig["parentGUID"][0]) > > # delete user on DC1 > self.ldb_dc1.delete('<GUID=%s>' % self._GUID_string(user_orig["objectGUID"][0])) >@@ -2301,7 +2301,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou1_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -2323,7 +2323,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > ldb_res = self.ldb_dc1.search(base=self.ou2_dn, > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > > user_moved_orig = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] >@@ -2363,7 +2363,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -2377,7 +2377,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > # check user info on DC2 - should be valid user > user_cur = self._check_obj(sam_ldb=self.ldb_dc2, obj_orig=user_orig, is_deleted=False) > >- self.assertEquals(user_cur["parentGUID"], user_orig["parentGUID"]) >+ self.assertEqual(user_cur["parentGUID"], user_orig["parentGUID"]) > > # delete user on DC1 > self.ldb_dc1.delete('<GUID=%s>' % self._GUID_string(user_orig["objectGUID"][0])) >@@ -2410,7 +2410,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -2424,7 +2424,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_moved = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] > >@@ -2433,7 +2433,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > # check user info on DC2 - should be valid user > user_cur = self._check_obj(sam_ldb=self.ldb_dc2, obj_orig=user_moved, is_deleted=False) > >- self.assertEquals(user_cur["parentGUID"], user_moved["parentGUID"]) >+ self.assertEqual(user_cur["parentGUID"], user_moved["parentGUID"]) > > # delete user on DC1 > self.ldb_dc1.delete('<GUID=%s>' % self._GUID_string(user_orig["objectGUID"][0])) >@@ -2466,7 +2466,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -2505,7 +2505,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_moved = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] > >@@ -2514,7 +2514,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > # check user info on DC2 - should be under the OU2 from DC1 > user_cur = self._check_obj(sam_ldb=self.ldb_dc2, obj_orig=user_moved, is_deleted=False) > >- self.assertEquals(user_cur["parentGUID"], user_moved["parentGUID"]) >+ self.assertEqual(user_cur["parentGUID"], user_moved["parentGUID"]) > > # delete user on DC1 > self.ldb_dc1.delete('<GUID=%s>' % self._GUID_string(user_orig["objectGUID"][0])) >@@ -2546,7 +2546,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_orig = ldb_res[0] > user_dn = ldb_res[0]["dn"] > >@@ -2583,7 +2583,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > scope=SCOPE_SUBTREE, > expression="(samAccountName=%s)" % username, > attrs=["*", "parentGUID"]) >- self.assertEquals(len(ldb_res), 1) >+ self.assertEqual(len(ldb_res), 1) > user_moved = ldb_res[0] > user_moved_dn = ldb_res[0]["dn"] > >@@ -2592,7 +2592,7 @@ class DrsMoveBetweenTreeOfObjectTestCase(drs_base.DrsBaseTestCase): > # check user info on DC2 - should be under the OU2 from DC1 > user_cur = self._check_obj(sam_ldb=self.ldb_dc2, obj_orig=user_moved, is_deleted=False) > >- self.assertEquals(user_cur["parentGUID"], user_moved["parentGUID"]) >+ self.assertEqual(user_cur["parentGUID"], user_moved["parentGUID"]) > > # delete user on DC1 > self.ldb_dc1.delete('<GUID=%s>' % self._GUID_string(user_orig["objectGUID"][0])) >diff --git a/source4/torture/drs/python/repl_rodc.py b/source4/torture/drs/python/repl_rodc.py >index f27f02814af..21e70b8bc6f 100644 >--- a/source4/torture/drs/python/repl_rodc.py >+++ b/source4/torture/drs/python/repl_rodc.py >@@ -199,7 +199,7 @@ class DrsRodcTestCase(drs_base.DrsBaseTestCase): > self.fail("Successfully replicated secrets to an RODC that shouldn't have been replicated.") > except WERRORError as e: > (enum, estr) = e.args >- self.assertEquals(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED >+ self.assertEqual(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED > > # send the same request again and we should get the same response > try: >@@ -207,7 +207,7 @@ class DrsRodcTestCase(drs_base.DrsBaseTestCase): > self.fail("Successfully replicated secrets to an RODC that shouldn't have been replicated.") > except WERRORError as e1: > (enum, estr) = e1.args >- self.assertEquals(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED >+ self.assertEqual(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED > > # Retry with Administrator credentials, ignores password replication groups > (level, ctr) = self.drs.DsGetNCChanges(self.drs_handle, 10, req10) >@@ -512,7 +512,7 @@ class DrsRodcTestCase(drs_base.DrsBaseTestCase): > self.fail("Successfully replicated secrets to an RODC that shouldn't have been replicated.") > except WERRORError as e3: > (enum, estr) = e3.args >- self.assertEquals(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED >+ self.assertEqual(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED > > req10 = self._getnc_req10(dest_dsa=str(self.rodc_ctx.ntds_guid), > invocation_id=self.ldb_dc1.get_invocation_id(), >@@ -527,7 +527,7 @@ class DrsRodcTestCase(drs_base.DrsBaseTestCase): > self.fail("Successfully replicated secrets to an RODC that shouldn't have been replicated.") > except WERRORError as e4: > (enum, estr) = e4.args >- self.assertEquals(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED >+ self.assertEqual(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED > > def test_msDSRevealedUsers_local_deny_allow(self): > """ >@@ -597,7 +597,7 @@ class DrsRodcTestCase(drs_base.DrsBaseTestCase): > self.fail("Successfully replicated secrets to an RODC that shouldn't have been replicated.") > except WERRORError as e5: > (enum, estr) = e5.args >- self.assertEquals(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED >+ self.assertEqual(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED > > m = ldb.Message() > m.dn = ldb.Dn(self.ldb_dc1, self.computer_dn) >@@ -614,7 +614,7 @@ class DrsRodcTestCase(drs_base.DrsBaseTestCase): > self.fail("Successfully replicated secrets to an RODC that shouldn't have been replicated.") > except WERRORError as e6: > (enum, estr) = e6.args >- self.assertEquals(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED >+ self.assertEqual(enum, 8630) # ERROR_DS_DRA_SECRETS_DENIED > > def _assert_in_revealed_users(self, user_dn, attrlist): > res = self.ldb_dc1.search(scope=ldb.SCOPE_BASE, base=self.computer_dn, >@@ -632,7 +632,7 @@ class DrsRodcTestCase(drs_base.DrsBaseTestCase): > packed_attrs.append(dsdb_dn.get_bytes()) > actual_attrids.append(metadata.attid) > >- self.assertEquals(sorted(actual_attrids), sorted(attrlist)) >+ self.assertEqual(sorted(actual_attrids), sorted(attrlist)) > > return (packed_attrs, unpacked_attrs) > >@@ -641,16 +641,16 @@ class DrsRodcTestCase(drs_base.DrsBaseTestCase): > > def _assert_attrlist_changed(self, list_1, list_2, changed_attributes, num_changes=1, expected_new_usn=True): > for i in range(len(list_2)): >- self.assertEquals(list_1[i].attid, list_2[i].attid) >- self.assertEquals(list_1[i].originating_invocation_id, list_2[i].originating_invocation_id) >- self.assertEquals(list_1[i].version + num_changes, list_2[i].version) >+ self.assertEqual(list_1[i].attid, list_2[i].attid) >+ self.assertEqual(list_1[i].originating_invocation_id, list_2[i].originating_invocation_id) >+ self.assertEqual(list_1[i].version + num_changes, list_2[i].version) > > if expected_new_usn: > self.assertTrue(list_1[i].originating_usn < list_2[i].originating_usn) > self.assertTrue(list_1[i].local_usn < list_2[i].local_usn) > else: >- self.assertEquals(list_1[i].originating_usn, list_2[i].originating_usn) >- self.assertEquals(list_1[i].local_usn, list_2[i].local_usn) >+ self.assertEqual(list_1[i].originating_usn, list_2[i].originating_usn) >+ self.assertEqual(list_1[i].local_usn, list_2[i].local_usn) > > if list_1[i].attid in changed_attributes: > # We do the changes too quickly, so unless we put sleeps >@@ -659,7 +659,7 @@ class DrsRodcTestCase(drs_base.DrsBaseTestCase): > pass > #self.assertTrue(list_1[i].originating_change_time < list_2[i].originating_change_time) > else: >- self.assertEquals(list_1[i].originating_change_time, list_2[i].originating_change_time) >+ self.assertEqual(list_1[i].originating_change_time, list_2[i].originating_change_time) > > def _create_rodc(self, ctx): > ctx.nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn] >diff --git a/source4/torture/drs/python/repl_schema.py b/source4/torture/drs/python/repl_schema.py >index ee42fd1da10..b46a87af51e 100644 >--- a/source4/torture/drs/python/repl_schema.py >+++ b/source4/torture/drs/python/repl_schema.py >@@ -166,7 +166,7 @@ class DrsReplSchemaTestCase(drs_base.DrsBaseTestCase): > res_dc1 = self.ldb_dc1.search(base=obj_dn, > scope=SCOPE_BASE, > attrs=["*"]) >- self.assertEquals(len(res_dc1), 1, >+ self.assertEqual(len(res_dc1), 1, > "%s doesn't exists on %s" % (obj_dn, self.dnsname_dc1)) > try: > res_dc2 = self.ldb_dc2.search(base=obj_dn, >@@ -177,7 +177,7 @@ class DrsReplSchemaTestCase(drs_base.DrsBaseTestCase): > if enum == ERR_NO_SUCH_OBJECT: > self.fail("%s doesn't exists on %s" % (obj_dn, self.dnsname_dc2)) > raise >- self.assertEquals(len(res_dc2), 1, >+ self.assertEqual(len(res_dc2), 1, > "%s doesn't exists on %s" % (obj_dn, self.dnsname_dc2)) > > def test_class(self): >diff --git a/source4/torture/drs/python/repl_secdesc.py b/source4/torture/drs/python/repl_secdesc.py >index 58212907e23..3c36ba68910 100644 >--- a/source4/torture/drs/python/repl_secdesc.py >+++ b/source4/torture/drs/python/repl_secdesc.py >@@ -80,7 +80,7 @@ class ReplAclTestCase(drs_base.DrsBaseTestCase): > > self.assertIn(self.mod_inherits_as, > self.sd_utils_dc1.get_sd_as_sddl(dn)) >- self.assertEquals(self.sd_utils_dc1.get_sd_as_sddl(dn), >+ self.assertEqual(self.sd_utils_dc1.get_sd_as_sddl(dn), > self.sd_utils_dc2.get_sd_as_sddl(dn)) > > def test_acl_inheirt_new_object(self): >@@ -113,7 +113,7 @@ class ReplAclTestCase(drs_base.DrsBaseTestCase): > > self.assertIn(self.mod_inherits_as, > self.sd_utils_dc1.get_sd_as_sddl(dn)) >- self.assertEquals(self.sd_utils_dc1.get_sd_as_sddl(dn), >+ self.assertEqual(self.sd_utils_dc1.get_sd_as_sddl(dn), > self.sd_utils_dc2.get_sd_as_sddl(dn)) > > def test_acl_inherit_existing_object(self): >@@ -160,7 +160,7 @@ class ReplAclTestCase(drs_base.DrsBaseTestCase): > > self.assertIn(self.mod_inherits_as, > self.sd_utils_dc1.get_sd_as_sddl(dn)) >- self.assertEquals(self.sd_utils_dc1.get_sd_as_sddl(dn), >+ self.assertEqual(self.sd_utils_dc1.get_sd_as_sddl(dn), > self.sd_utils_dc2.get_sd_as_sddl(dn)) > > def test_acl_inheirt_existing_object_1_pass(self): >@@ -198,7 +198,7 @@ class ReplAclTestCase(drs_base.DrsBaseTestCase): > > self.assertIn(self.mod_inherits_as, > self.sd_utils_dc1.get_sd_as_sddl(dn)) >- self.assertEquals(self.sd_utils_dc1.get_sd_as_sddl(dn), >+ self.assertEqual(self.sd_utils_dc1.get_sd_as_sddl(dn), > self.sd_utils_dc2.get_sd_as_sddl(dn)) > > def test_acl_inheirt_renamed_object(self): >@@ -256,7 +256,7 @@ class ReplAclTestCase(drs_base.DrsBaseTestCase): > # Confirm inherited ACLs are identical and were inherited > self.assertIn(self.mod_inherits_as, > self.sd_utils_dc1.get_sd_as_sddl(sub_ou_dn)) >- self.assertEquals(self.sd_utils_dc1.get_sd_as_sddl(sub_ou_dn), >+ self.assertEqual(self.sd_utils_dc1.get_sd_as_sddl(sub_ou_dn), > self.sd_utils_dc2.get_sd_as_sddl(sub_ou_dn)) > > >@@ -330,14 +330,14 @@ class ReplAclTestCase(drs_base.DrsBaseTestCase): > # Confirm set ACLs (on l3 ) are identical and were inherited > self.assertIn(self.mod_becomes, > self.sd_utils_dc2.get_sd_as_sddl(sub3_ou_dn_final)) >- self.assertEquals(self.sd_utils_dc1.get_sd_as_sddl(sub3_ou_dn_final), >+ self.assertEqual(self.sd_utils_dc1.get_sd_as_sddl(sub3_ou_dn_final), > self.sd_utils_dc2.get_sd_as_sddl(sub3_ou_dn_final)) > > # Confirm inherited ACLs (from l3 to l4) are identical > # and where inherited > self.assertIn(self.mod_inherits_as, > self.sd_utils_dc1.get_sd_as_sddl(sub4_ou_dn_final)) >- self.assertEquals(self.sd_utils_dc1.get_sd_as_sddl(sub4_ou_dn_final), >+ self.assertEqual(self.sd_utils_dc1.get_sd_as_sddl(sub4_ou_dn_final), > self.sd_utils_dc2.get_sd_as_sddl(sub4_ou_dn_final)) > > >@@ -382,7 +382,7 @@ class ReplAclTestCase(drs_base.DrsBaseTestCase): > for child in children: > self.assertIn(self.mod_inherits_as, > self.sd_utils_dc2.get_sd_as_sddl(child.dn)) >- self.assertEquals(self.sd_utils_dc1.get_sd_as_sddl(sub_ou_dn), >+ self.assertEqual(self.sd_utils_dc1.get_sd_as_sddl(sub_ou_dn), > self.sd_utils_dc2.get_sd_as_sddl(child.dn)) > > # Replicate back >@@ -396,5 +396,5 @@ class ReplAclTestCase(drs_base.DrsBaseTestCase): > for child in children: > self.assertIn(self.mod_inherits_as, > self.sd_utils_dc1.get_sd_as_sddl(child.dn)) >- self.assertEquals(self.sd_utils_dc1.get_sd_as_sddl(child.dn), >+ self.assertEqual(self.sd_utils_dc1.get_sd_as_sddl(child.dn), > self.sd_utils_dc2.get_sd_as_sddl(child.dn)) >diff --git a/source4/torture/drs/python/replica_sync.py b/source4/torture/drs/python/replica_sync.py >index f787c8f0f11..62545be6fee 100644 >--- a/source4/torture/drs/python/replica_sync.py >+++ b/source4/torture/drs/python/replica_sync.py >@@ -70,12 +70,12 @@ class DrsReplicaSyncTestCase(drs_base.DrsBaseTestCase): > self.ldb_dc2.delete(dn, ["tree_delete:1"]) > except LdbError as e: > (num, _) = e.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > try: > self.ldb_dc1.delete(dn, ["tree_delete:1"]) > except LdbError as e1: > (num, _) = e1.args >- self.assertEquals(num, ERR_NO_SUCH_OBJECT) >+ self.assertEqual(num, ERR_NO_SUCH_OBJECT) > > def _cleanup_object(self, guid): > """Cleans up a test object, if it still exists""" >@@ -133,13 +133,13 @@ objectClass: organizationalUnit > res = sam_ldb.search(base='<GUID=%s>' % guid, > controls=["show_deleted:1"], > attrs=["isDeleted", "objectCategory", "ou"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > ou_cur = res[0] > # Deleted Object base DN > dodn = self._deleted_objects_dn(sam_ldb) > # now check properties of the user > name_cur = ou_cur["ou"][0] >- self.assertEquals(ou_cur["isDeleted"][0], b"TRUE") >+ self.assertEqual(ou_cur["isDeleted"][0], b"TRUE") > self.assertTrue(not("objectCategory" in ou_cur)) > self.assertTrue(dodn in str(ou_cur["dn"]), > "OU %s is deleted but it is not located under %s!" % (name_cur, dodn)) >diff --git a/source4/torture/drs/python/replica_sync_rodc.py b/source4/torture/drs/python/replica_sync_rodc.py >index 8dc48a9b916..b904e17575c 100644 >--- a/source4/torture/drs/python/replica_sync_rodc.py >+++ b/source4/torture/drs/python/replica_sync_rodc.py >@@ -70,13 +70,13 @@ objectClass: organizationalUnit > res = sam_ldb.search(base='<GUID=%s>' % guid, > controls=["show_deleted:1"], > attrs=["isDeleted", "objectCategory", "ou"]) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > ou_cur = res[0] > # Deleted Object base DN > dodn = self._deleted_objects_dn(sam_ldb) > # now check properties of the user > name_cur = ou_cur["ou"][0] >- self.assertEquals(ou_cur["isDeleted"][0], "TRUE") >+ self.assertEqual(ou_cur["isDeleted"][0], "TRUE") > self.assertTrue(not("objectCategory" in ou_cur)) > self.assertTrue(dodn in str(ou_cur["dn"]), > "OU %s is deleted but it is not located under %s!" % (name_cur, dodn)) >diff --git a/source4/torture/drs/python/ridalloc_exop.py b/source4/torture/drs/python/ridalloc_exop.py >index f02ae11072a..3c7b39b280a 100644 >--- a/source4/torture/drs/python/ridalloc_exop.py >+++ b/source4/torture/drs/python/ridalloc_exop.py >@@ -295,7 +295,7 @@ class DrsReplicaSyncTestCase(drs_base.DrsBaseTestCase): > > (result, out, err) = self.runsubcmd("fsmo", "seize", "--role", "rid", "-H", ldb_url, "-s", smbconf, "--force") > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > > # 3. Assert we get the RID Set > res = new_ldb.search(base=server_ref_dn, >@@ -580,7 +580,7 @@ class DrsReplicaSyncTestCase(drs_base.DrsBaseTestCase): > scope=ldb.SCOPE_BASE, attrs=['rIDNextRid', > 'rIDAllocationPool']) > last_allocated_rid = int(rid_set_res[0]["rIDNextRid"][0]) >- self.assertEquals(last_allocated_rid, last_rid - 10) >+ self.assertEqual(last_allocated_rid, last_rid - 10) > > # 9. Assert that the range wasn't thrown away > >@@ -623,7 +623,7 @@ class DrsReplicaSyncTestCase(drs_base.DrsBaseTestCase): > # 4. Seize the RID Manager role > (result, out, err) = self.runsubcmd("fsmo", "seize", "--role", "rid", "-H", ldb_url, "-s", smbconf, "--force") > self.assertCmdSuccess(result, out, err) >- self.assertEquals(err, "", "Shouldn't be any error messages") >+ self.assertEqual(err, "", "Shouldn't be any error messages") > > # 5. Add a new user (triggers RID set work) > new_ldb.newuser("ridalloctestuser", "P@ssword!") >diff --git a/source4/torture/drs/python/samba_tool_drs_no_dns.py b/source4/torture/drs/python/samba_tool_drs_no_dns.py >index b9cab49e82b..326181a7fd7 100644 >--- a/source4/torture/drs/python/samba_tool_drs_no_dns.py >+++ b/source4/torture/drs/python/samba_tool_drs_no_dns.py >@@ -117,29 +117,29 @@ class SambaToolDrsNoDnsTests(drs_base.DrsBaseTestCase): > # Show that Has-Master-NCs is fixed by samba_upgradedns > res = samdb.search(base=server_ds_name, > expression="(msds-hasmasterncs=%s)" % forestdns_dn) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > res = samdb.search(base=server_ds_name, > expression="(msds-hasmasterncs=%s)" % domaindns_dn) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > self.check_output("samba_upgradedns -s %s" % (new_dc_config_file)) > > res = samdb.search(base=server_ds_name, > expression="(msds-hasmasterncs=%s)" % forestdns_dn) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > res = samdb.search(base=server_ds_name, > expression="(msds-hasmasterncs=%s)" % domaindns_dn) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > # Show that replica locations is fixed by dbcheck > res = samdb.search(controls=["search_options:1:2"], > expression="(&(msds-nc-replica-locations=%s)(ncname=%s))" > % (server_ds_name, forestdns_dn)) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > res = samdb.search(controls=["search_options:1:2"], > expression="(&(msds-nc-replica-locations=%s)(ncname=%s))" > % (server_ds_name, domaindns_dn)) >- self.assertEquals(len(res), 0) >+ self.assertEqual(len(res), 0) > > try: > # This fixes any forward-link-backward-link issues with the tools >@@ -157,26 +157,26 @@ class SambaToolDrsNoDnsTests(drs_base.DrsBaseTestCase): > # Check all ForestDNS connections and backlinks > res = samdb.search(base=server_ds_name, > expression="(msds-hasmasterncs=%s)" % forestdns_dn) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > res = samdb.search(base=forestdns_dn, > expression="(msds-masteredby=%s)" % server_ds_name) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > res = samdb.search(controls=["search_options:1:2"], > expression="(&(msds-nc-replica-locations=%s)(ncname=%s))" > % (server_ds_name, forestdns_dn)) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > # Check all DomainDNS connections and backlinks > res = samdb.search(base=server_ds_name, > expression="(msds-hasmasterncs=%s)" % domaindns_dn) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > res = samdb.search(base=domaindns_dn, > expression="(msds-masteredby=%s)" % server_ds_name) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > res = samdb.search(controls=["search_options:1:2"], > expression="(&(msds-nc-replica-locations=%s)(ncname=%s))" > % (server_ds_name, domaindns_dn)) >- self.assertEquals(len(res), 1) >+ self.assertEqual(len(res), 1) > > # Demote the DC we created in the test > self.check_output("samba-tool domain demote --remove-other-dead-server=%s -H ldap://%s %s -s %s" >-- >2.25.1 > > >From a35627c38c65a12afbd7832149f01f9836eeb002 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Sat, 18 Jan 2020 08:06:45 +0100 >Subject: [PATCH 383/686] s3/auth: use set_current_user_info() in > auth3_generate_session_info_pac() > >This delays reloading config slightly, but I don't see how could affect >observable behaviour other then log messages coming from the functions in >between the different locations for lp_load_with_shares() like >make_session_info_krb5() are sent to a different logfile if "log file" uses %U. > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit dc4b1e39ce1f2201a2d6ae2d4cffef2448f69a62) >--- > source3/auth/auth_generic.c | 14 ++++++++------ > 1 file changed, 8 insertions(+), 6 deletions(-) > >diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c >index 167d4e00367..0e9c423efef 100644 >--- a/source3/auth/auth_generic.c >+++ b/source3/auth/auth_generic.c >@@ -159,12 +159,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > } > } > >- /* setup the string used by %U */ >- sub_set_smb_name(username); >- >- /* reload services so that the new %U is taken into account */ >- lp_load_with_shares(get_dyn_CONFIGFILE()); >- > status = make_session_info_krb5(mem_ctx, > ntuser, ntdomain, username, pw, > info3_copy, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */, >@@ -176,6 +170,14 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > goto done; > } > >+ /* setup the string used by %U */ >+ set_current_user_info((*session_info)->unix_info->sanitized_username, >+ (*session_info)->unix_info->unix_name, >+ (*session_info)->info->domain_name); >+ >+ /* reload services so that the new %U is taken into account */ >+ lp_load_with_shares(get_dyn_CONFIGFILE()); >+ > DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n", > ntuser, ntdomain, rhost)); > >-- >2.25.1 > > >From 20b1b14dc695cb920466ad2db12dd312a17c33f3 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Tue, 8 Dec 2020 22:00:55 +1300 >Subject: [PATCH 384/686] CVE-2020-25718 ldb/attrib_handler casefold: simplify > space dropping > >As seen in CVE-2021-20277, ldb_handler_fold() has been making mistakes >when collapsing spaces down to a single space. > >This patch fixes the way it handles internal spaces (CVE-2021-20277 >was about leading spaces), and involves a rewrite of the parsing loop. > >The bug has a detailed description of the problem. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14656 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Wed Apr 7 03:16:39 UTC 2021 on sn-devel-184 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit 24ddc1ca9cad95673bdd8023d99867707b37085f) >--- > lib/ldb/common/attrib_handlers.c | 53 +++++++++++++++----------------- > lib/ldb/tests/ldb_match_test.c | 2 ++ > 2 files changed, 27 insertions(+), 28 deletions(-) > >diff --git a/lib/ldb/common/attrib_handlers.c b/lib/ldb/common/attrib_handlers.c >index 409b8c62025..a794adcb796 100644 >--- a/lib/ldb/common/attrib_handlers.c >+++ b/lib/ldb/common/attrib_handlers.c >@@ -54,8 +54,8 @@ int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx, > int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, > const struct ldb_val *in, struct ldb_val *out) > { >- char *s, *t; >- size_t l; >+ char *s, *t, *start; >+ bool in_space; > > if (!in || !out || !(in->data)) { > return -1; >@@ -67,36 +67,33 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, > return -1; > } > >- s = (char *)(out->data); >- >- /* remove trailing spaces if any */ >- l = strlen(s); >- while (l > 0 && s[l - 1] == ' ') l--; >- s[l] = '\0'; >- >- /* remove leading spaces if any */ >- if (*s == ' ') { >- for (t = s; *s == ' '; s++, l--) ; >- >- /* remove leading spaces by moving down the string */ >- memmove(t, s, l); >- >- s = t; >+ start = (char *)(out->data); >+ in_space = true; >+ t = start; >+ for (s = start; *s != '\0'; s++) { >+ if (*s == ' ') { >+ if (in_space) { >+ /* >+ * We already have one (or this is the start) >+ * and we don't want to add more >+ */ >+ continue; >+ } >+ in_space = true; >+ } else { >+ in_space = false; >+ } >+ *t = *s; >+ t++; > } > >- /* check middle spaces */ >- while ((t = strchr(s, ' ')) != NULL) { >- for (s = t; *s == ' '; s++) ; >- >- if ((s - t) > 1) { >- l = strlen(s); >- >- /* remove all spaces but one by moving down the string */ >- memmove(t + 1, s, l); >- } >+ if (in_space && t != start) { >+ /* the loop will have left a single trailing space */ >+ t--; > } >+ *t = '\0'; > >- out->length = strlen((char *)out->data); >+ out->length = t - start; > return 0; > } > >diff --git a/lib/ldb/tests/ldb_match_test.c b/lib/ldb/tests/ldb_match_test.c >index ba6ea56be15..1bb56d072d9 100644 >--- a/lib/ldb/tests/ldb_match_test.c >+++ b/lib/ldb/tests/ldb_match_test.c >@@ -183,6 +183,8 @@ static void test_wildcard_match(void **state) > struct wildcard_test tests[] = { > TEST_ENTRY(" 1 0", "1*0*", true, true), > TEST_ENTRY(" 1 0", "1 *0", true, true), >+ TEST_ENTRY(" 1 0", "*1 0", true, true), >+ TEST_ENTRY("1 0", "*1 0", true, true), > TEST_ENTRY("The value.......end", "*end", true, true), > TEST_ENTRY("The value.......end", "*fend", false, true), > TEST_ENTRY("The value.......end", "*eel", false, true), >-- >2.25.1 > > >From d63a22ad6504163cf93a198f339f302fc465a635 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 3 Mar 2021 19:17:36 +1300 >Subject: [PATCH 385/686] CVE-2020-25718 ldb_match: trailing chunk must match > end of string >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >A wildcard search is divided into chunks by the asterisks. While most >chunks match the first suitable string, the last chunk matches the >last possible string (unless there is a trailing asterisk, in which >case this distinction is moot). > >We always knew this in our hearts, but we tried to do it in a funny >complicated way that stepped through the string, comparing here and >there, leading to CVE-2019-3824 and missed matches (bug 14044). > >With this patch, we just jump to the end of the string and compare it. >As well as being correct, this should also improve performance, as the >previous algorithm involved a quadratic loop of erroneous memmem()s. > >See https://tools.ietf.org/html/rfc4517 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14044 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Björn Jacke <bjacke@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit cc098f1cad04b2cfec4ddd6b2511cd5a600f31c6) >--- > lib/ldb/common/ldb_match.c | 80 +++++++++++++++++--------------------- > 1 file changed, 35 insertions(+), 45 deletions(-) > >diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c >index 829afa77e71..da595615bd9 100644 >--- a/lib/ldb/common/ldb_match.c >+++ b/lib/ldb/common/ldb_match.c >@@ -295,8 +295,9 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, > uint8_t *p; > > chunk = tree->u.substring.chunks[c]; >- if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; >- >+ if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) { >+ goto mismatch; >+ } > /* > * Empty strings are returned as length 0. Ensure > * we can cope with this. >@@ -304,52 +305,41 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, > if (cnk.length == 0) { > goto mismatch; > } >- /* >- * Values might be binary blobs. Don't use string >- * search, but memory search instead. >- */ >- p = memmem((const void *)val.data,val.length, >- (const void *)cnk.data, cnk.length); >- if (p == NULL) goto mismatch; >- >- /* >- * At this point we know cnk.length <= val.length as >- * otherwise there could be no match >- */ >+ if (cnk.length > val.length) { >+ goto mismatch; >+ } > >- if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) { >- uint8_t *g; >- uint8_t *end = val.data + val.length; >- do { /* greedy */ >- >- /* >- * haystack is a valid pointer in val >- * because the memmem() can only >- * succeed if the needle (cnk.length) >- * is <= haystacklen >- * >- * p will be a pointer at least >- * cnk.length from the end of haystack >- */ >- uint8_t *haystack >- = p + cnk.length; >- size_t haystacklen >- = end - (haystack); >- >- g = memmem(haystack, >- haystacklen, >- (const uint8_t *)cnk.data, >- cnk.length); >- if (g) { >- p = g; >- } >- } while(g); >+ if ( (tree->u.substring.chunks[c + 1]) == NULL && >+ (! tree->u.substring.end_with_wildcard) ) { >+ /* >+ * The last bit, after all the asterisks, must match >+ * exactly the last bit of the string. >+ */ >+ int cmp; >+ p = val.data + val.length - cnk.length; >+ cmp = memcmp(p, >+ cnk.data, >+ cnk.length); >+ if (cmp != 0) { >+ goto mismatch; >+ } >+ } else { >+ /* >+ * Values might be binary blobs. Don't use string >+ * search, but memory search instead. >+ */ >+ p = memmem((const void *)val.data, val.length, >+ (const void *)cnk.data, cnk.length); >+ if (p == NULL) { >+ goto mismatch; >+ } >+ /* move val to the end of the match */ >+ p += cnk.length; >+ val.length -= (p - val.data); >+ val.data = p; > } >- val.length = val.length - (p - (uint8_t *)(val.data)) - cnk.length; >- val.data = (uint8_t *)(p + cnk.length); > c++; >- talloc_free(cnk.data); >- cnk.data = NULL; >+ TALLOC_FREE(cnk.data); > } > > /* last chunk may not have reached end of string */ >-- >2.25.1 > > >From e6ed03578fd7768ad85b7ab7f21f14fb89dd0c0a Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Sat, 6 Mar 2021 16:05:15 +1300 >Subject: [PATCH 386/686] CVE-2020-25718 ldb: fix ldb_comparison_fold > off-by-one overrun > >We run one character over in comparing all the bytes in two ldb_vals. > >In almost all circumstances both ldb_vals would have an allocated '\0' >in the overrun position, but it is best not to rely on that. > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit 2b2f4f519454beb6f2a46705675a62274019fc09) >--- > lib/ldb/common/attrib_handlers.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/lib/ldb/common/attrib_handlers.c b/lib/ldb/common/attrib_handlers.c >index a794adcb796..166d6d49e66 100644 >--- a/lib/ldb/common/attrib_handlers.c >+++ b/lib/ldb/common/attrib_handlers.c >@@ -227,8 +227,8 @@ int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, > if (toupper((unsigned char)*s1) != toupper((unsigned char)*s2)) > break; > if (*s1 == ' ') { >- while (n1 && s1[0] == s1[1]) { s1++; n1--; } >- while (n2 && s2[0] == s2[1]) { s2++; n2--; } >+ while (n1 > 1 && s1[0] == s1[1]) { s1++; n1--; } >+ while (n2 > 1 && s2[0] == s2[1]) { s2++; n2--; } > } > s1++; s2++; > n1--; n2--; >-- >2.25.1 > > >From 607fa62b397e0de38eac17283c04e293685d28b6 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 19 Jan 2021 16:53:55 +0100 >Subject: [PATCH 387/686] CVE-2020-25718 pyldb: catch potential overflow error > in py_timestring >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Pair-Programmed-With: Björn Baumbach <bb@sernet.de> > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Signed-off-by: Björn Baumbach <bb@sernet.de> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit 71e8b24b8a031de26b21539e36a60f459257d2fd) > >[jsutton@samba.org Adapted to fix conflict] >--- > lib/ldb/common/ldb_msg.c | 1 + > lib/ldb/pyldb.c | 7 +++++++ > lib/ldb/tests/python/api.py | 19 +++++++++++++++++++ > 3 files changed, 27 insertions(+) > >diff --git a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c >index e21dac81b6a..2b5c3fc9348 100644 >--- a/lib/ldb/common/ldb_msg.c >+++ b/lib/ldb/common/ldb_msg.c >@@ -1272,6 +1272,7 @@ char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t) > > if (r != 17) { > talloc_free(ts); >+ errno = EOVERFLOW; > return NULL; > } > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index 6423db22e49..7a2aaf56cbb 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -4203,6 +4203,13 @@ static PyObject *py_timestring(PyObject *module, PyObject *args) > if (!PyArg_ParseTuple(args, "l", &t_val)) > return NULL; > tresult = ldb_timestring(NULL, (time_t) t_val); >+ if (tresult == NULL) { >+ /* >+ * Most likely EOVERFLOW from gmtime() >+ */ >+ PyErr_SetFromErrno(PyExc_OSError); >+ return NULL; >+ } > ret = PyStr_FromString(tresult); > talloc_free(tresult); > return ret; >diff --git a/lib/ldb/tests/python/api.py b/lib/ldb/tests/python/api.py >index 40f7b1ceb66..617aefae7ee 100755 >--- a/lib/ldb/tests/python/api.py >+++ b/lib/ldb/tests/python/api.py >@@ -5,10 +5,12 @@ > import os > from unittest import TestCase > import sys >+sys.path.insert(0, "bin/python") > import gc > import time > import ldb > import shutil >+import errno > > PY3 = sys.version_info > (3, 0) > >@@ -42,10 +44,27 @@ class NoContextTests(TestCase): > self.assertEqual("19700101000000.0Z", ldb.timestring(0)) > self.assertEqual("20071119191012.0Z", ldb.timestring(1195499412)) > >+ self.assertEqual("00000101000000.0Z", ldb.timestring(-62167219200)) >+ self.assertEqual("99991231235959.0Z", ldb.timestring(253402300799)) >+ >+ # should result with OSError EOVERFLOW from gmtime() >+ with self.assertRaises(OSError) as err: >+ ldb.timestring(-62167219201) >+ self.assertEqual(err.exception.errno, errno.EOVERFLOW) >+ with self.assertRaises(OSError) as err: >+ ldb.timestring(253402300800) >+ self.assertEqual(err.exception.errno, errno.EOVERFLOW) >+ with self.assertRaises(OSError) as err: >+ ldb.timestring(0x7fffffffffffffff) >+ self.assertEqual(err.exception.errno, errno.EOVERFLOW) >+ > def test_string_to_time(self): > self.assertEqual(0, ldb.string_to_time("19700101000000.0Z")) > self.assertEqual(1195499412, ldb.string_to_time("20071119191012.0Z")) > >+ self.assertEqual(-62167219200, ldb.string_to_time("00000101000000.0Z")) >+ self.assertEqual(253402300799, ldb.string_to_time("99991231235959.0Z")) >+ > def test_binary_encode(self): > encoded = ldb.binary_encode(b'test\\x') > decoded = ldb.binary_decode(encoded) >-- >2.25.1 > > >From 3f37fec32448eb4490dfa6716224f1e2faeea2d0 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 3 Mar 2021 19:54:37 +1300 >Subject: [PATCH 388/686] CVE-2020-25718 ldb_match: remove redundant check >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >We already ensure the no-trailing-asterisk case ends at the end of the >string. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14044 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Björn Jacke <bjacke@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit fa93339978040eab52b2722c1716028b48d8d084) >--- > lib/ldb/common/ldb_match.c | 2 -- > 1 file changed, 2 deletions(-) > >diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c >index da595615bd9..2f4d41f3441 100644 >--- a/lib/ldb/common/ldb_match.c >+++ b/lib/ldb/common/ldb_match.c >@@ -342,8 +342,6 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, > TALLOC_FREE(cnk.data); > } > >- /* last chunk may not have reached end of string */ >- if ( (! tree->u.substring.end_with_wildcard) && (val.length != 0) ) goto mismatch; > talloc_free(save_p); > *matched = true; > return LDB_SUCCESS; >-- >2.25.1 > > >From 5307ba7005e5ee23620251bebd33884526e640f4 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 28 May 2021 14:15:43 +1200 >Subject: [PATCH 389/686] CVE-2020-25718 pyldb: Fix Message.items() for a > message containing elements > >Previously, message elements were being freed before the call to >Py_BuildValue(), resulting in an exception being raised. Additionally, >only the first element of the returned list was ever assigned to. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit 3e4ec0a90a222c1cff4a91912afc703ca4cbbb0e) >--- > lib/ldb/pyldb.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index 7a2aaf56cbb..c343e661ef0 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -3526,13 +3526,13 @@ static PyObject *py_ldb_msg_items(PyLdbMessageObject *self, > PyObject *value = NULL; > PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements); > int res = 0; >- Py_CLEAR(py_el); > value = Py_BuildValue("(sO)", msg->elements[i].name, py_el); >+ Py_CLEAR(py_el); > if (value == NULL ) { > Py_CLEAR(l); > return NULL; > } >- res = PyList_SetItem(l, 0, value); >+ res = PyList_SetItem(l, j, value); > if (res == -1) { > Py_CLEAR(l); > return NULL; >-- >2.25.1 > > >From d526d04fa25ba6ef037a2cc8697264d3fb05894e Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 1 Feb 2021 14:21:21 +0100 >Subject: [PATCH 390/686] CVE-2020-25718 lib:ldb: Add missing break in switch > statement > >error: unannotated fall-through between switch labels [-Werror,-Wimplicit-fallthrough] > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit 1ffacac547a8ce29c6696dda73991a8db7e34dfd) >--- > lib/ldb/ldb_map/ldb_map_inbound.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/lib/ldb/ldb_map/ldb_map_inbound.c b/lib/ldb/ldb_map/ldb_map_inbound.c >index 861c4c1622d..324295737da 100644 >--- a/lib/ldb/ldb_map/ldb_map_inbound.c >+++ b/lib/ldb/ldb_map/ldb_map_inbound.c >@@ -262,6 +262,7 @@ static int map_search_self_callback(struct ldb_request *req, struct ldb_reply *a > LDB_ERR_OPERATIONS_ERROR); > } > >+ break; > default: > /* ignore referrals */ > break; >-- >2.25.1 > > >From a5c018963e359e6585569d0a7bb7f67ab67e98eb Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Sat, 19 Dec 2020 11:43:56 +1300 >Subject: [PATCH 391/686] CVE-2020-25718 ldb.h: remove undefined async_ctx > function signatures > >These functions do not exist. > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Jeremy Allison <jra@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit 1a05b58edaf96e7da707f9ad0a237551dbe13eb5) >--- > lib/ldb/include/ldb.h | 12 ------------ > 1 file changed, 12 deletions(-) > >diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h >index 81bee934da5..a9120ebc405 100644 >--- a/lib/ldb/include/ldb.h >+++ b/lib/ldb/include/ldb.h >@@ -1070,18 +1070,6 @@ int ldb_global_init(void); > */ > struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx); > >-typedef void (*ldb_async_timeout_fn) (void *); >-typedef bool (*ldb_async_callback_fn) (void *); >-typedef int (*ldb_async_ctx_add_op_fn)(void *, time_t, void *, ldb_async_timeout_fn, ldb_async_callback_fn); >-typedef int (*ldb_async_ctx_wait_op_fn)(void *); >- >-void ldb_async_ctx_set_private_data(struct ldb_context *ldb, >- void *private_data); >-void ldb_async_ctx_set_add_op(struct ldb_context *ldb, >- ldb_async_ctx_add_op_fn add_op); >-void ldb_async_ctx_set_wait_op(struct ldb_context *ldb, >- ldb_async_ctx_wait_op_fn wait_op); >- > /** > Connect to a database. > >-- >2.25.1 > > >From 46b3493fdae2df2b20f490f229deecd856b1d0c0 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Sat, 6 Mar 2021 09:57:44 +1300 >Subject: [PATCH 392/686] CVE-2020-25718 ldb: correct comments in > attrib_handers val_to_int64 > >c.f. the identical static function in lib/ldb-samba/ldif_handlers.c > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Jeremy Allison <jra@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit 46e6f6ef8436df7e083f34556c25f66f65ea1ce5) >--- > lib/ldb/common/attrib_handlers.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > >diff --git a/lib/ldb/common/attrib_handlers.c b/lib/ldb/common/attrib_handlers.c >index 166d6d49e66..6259c9d809a 100644 >--- a/lib/ldb/common/attrib_handlers.c >+++ b/lib/ldb/common/attrib_handlers.c >@@ -97,7 +97,7 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, > return 0; > } > >-/* length limited conversion of a ldb_val to a int32_t */ >+/* length limited conversion of a ldb_val to an int64_t */ > static int val_to_int64(const struct ldb_val *in, int64_t *v) > { > char *end; >@@ -110,8 +110,6 @@ static int val_to_int64(const struct ldb_val *in, int64_t *v) > strncpy(buf, (char *)in->data, in->length); > buf[in->length] = 0; > >- /* We've to use "strtoll" here to have the intended overflows. >- * Otherwise we may get "LONG_MAX" and the conversion is wrong. */ > *v = (int64_t) strtoll(buf, &end, 0); > if (*end != 0) { > return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; >-- >2.25.1 > > >From 8f485329fa2b2c9b41c06fa279b63258dba83687 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 29 Jan 2021 13:49:02 +1300 >Subject: [PATCH 393/686] CVE-2020-25718 ldb: improve comments for > ldb_module_connect_backend() > >There is no flags argument. >There are more URI forms. > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Jeremy Allison <jra@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit 48068a58df0313cd904f27e2c918ee10275ae373) >--- > lib/ldb/common/ldb_modules.c | 14 +++++++++----- > 1 file changed, 9 insertions(+), 5 deletions(-) > >diff --git a/lib/ldb/common/ldb_modules.c b/lib/ldb/common/ldb_modules.c >index cc067abdfe0..4366f05e066 100644 >--- a/lib/ldb/common/ldb_modules.c >+++ b/lib/ldb/common/ldb_modules.c >@@ -173,11 +173,15 @@ int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn, bool > > /* > Return the ldb module form of a database. >- The URL can either be one of the following forms >- ldb://path >- ldapi://path >- >- flags is made up of LDB_FLG_* >+ The URL looks something like this: >+ tdb://PATH >+ ldb://PATH >+ mdb://PATH >+ ldapi://PATH >+ PATH (unadorned PATH defaults to tdb://) >+ >+ for a complete list of backends (including possibly unmaintained ones) grep >+ for calls to ldb_register_backend(). > > the options are passed uninterpreted to the backend, and are > backend specific. >-- >2.25.1 > > >From 807b922db1c55134c913a6b6868acf5d216c1d3b Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Bj=C3=B6rn=20Baumbach?= <bb@sernet.de> >Date: Mon, 18 Jan 2021 16:48:21 +0100 >Subject: [PATCH 394/686] CVE-2020-25718 pyldb: fix a typo >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Signed-off-by: Björn Baumbach <bb@sernet.de> >Reviewed-by: Rowland penny <rpenny@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit 6fcde09f093db5d26c582a3c28531265f06b9fde) >--- > lib/ldb/pyldb.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c >index c343e661ef0..15edaee213d 100644 >--- a/lib/ldb/pyldb.c >+++ b/lib/ldb/pyldb.c >@@ -4290,7 +4290,7 @@ static PyMethodDef py_ldb_global_methods[] = { > "S.string_to_time(string) -> int\n\n" > "Parse a LDAP time string into a UNIX timestamp." }, > { "valid_attr_name", py_valid_attr_name, METH_VARARGS, >- "S.valid_attr_name(name) -> bool\n\nn" >+ "S.valid_attr_name(name) -> bool\n\n" > "Check whether the supplied name is a valid attribute name." }, > { "open", PY_DISCARD_FUNC_SIG(PyCFunction,py_ldb_new), > METH_VARARGS|METH_KEYWORDS, >-- >2.25.1 > > >From 98c3260241aafb7818ec98ba7e5d5bd53f4c54b7 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Thu, 17 Dec 2020 11:56:08 +0100 >Subject: [PATCH 395/686] CVE-2020-25718 lib:ldb: Use C99 initializers for > builtin_popt_options[] > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit a593065c7f22e17434f33d0132cc6a7073acf414) >--- > lib/ldb/tools/cmdline.c | 250 ++++++++++++++++++++++++++++++++++++---- > 1 file changed, 225 insertions(+), 25 deletions(-) > >diff --git a/lib/ldb/tools/cmdline.c b/lib/ldb/tools/cmdline.c >index b0f4c5c2141..b2fbb854910 100644 >--- a/lib/ldb/tools/cmdline.c >+++ b/lib/ldb/tools/cmdline.c >@@ -34,31 +34,231 @@ enum ldb_cmdline_options { CMDLINE_RELAX=1 }; > > static struct poptOption builtin_popt_options[] = { > POPT_AUTOHELP >- { "url", 'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" }, >- { "basedn", 'b', POPT_ARG_STRING, &options.basedn, 0, "base DN", "DN" }, >- { "editor", 'e', POPT_ARG_STRING, &options.editor, 0, "external editor", "PROGRAM" }, >- { "scope", 's', POPT_ARG_STRING, NULL, 's', "search scope", "SCOPE" }, >- { "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "increase verbosity", NULL }, >- { "trace", 0, POPT_ARG_NONE, &options.tracing, 0, "enable tracing", NULL }, >- { "interactive", 'i', POPT_ARG_NONE, &options.interactive, 0, "input from stdin", NULL }, >- { "recursive", 'r', POPT_ARG_NONE, &options.recursive, 0, "recursive delete", NULL }, >- { "modules-path", 0, POPT_ARG_STRING, &options.modules_path, 0, "modules path", "PATH" }, >- { "num-searches", 0, POPT_ARG_INT, &options.num_searches, 0, "number of test searches", NULL }, >- { "num-records", 0, POPT_ARG_INT, &options.num_records, 0, "number of test records", NULL }, >- { "all", 'a', POPT_ARG_NONE, &options.all_records, 0, "(|(objectClass=*)(distinguishedName=*))", NULL }, >- { "nosync", 0, POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL }, >- { "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL }, >- { NULL, 'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" }, >- { "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL }, >- { "show-binary", 0, POPT_ARG_NONE, &options.show_binary, 0, "display binary LDIF", NULL }, >- { "paged", 0, POPT_ARG_NONE, NULL, 'P', "use a paged search", NULL }, >- { "show-deleted", 0, POPT_ARG_NONE, NULL, 'D', "show deleted objects", NULL }, >- { "show-recycled", 0, POPT_ARG_NONE, NULL, 'R', "show recycled objects", NULL }, >- { "show-deactivated-link", 0, POPT_ARG_NONE, NULL, 'd', "show deactivated links", NULL }, >- { "reveal", 0, POPT_ARG_NONE, NULL, 'r', "reveal ldb internals", NULL }, >- { "relax", 0, POPT_ARG_NONE, NULL, CMDLINE_RELAX, "pass relax control", NULL }, >- { "cross-ncs", 0, POPT_ARG_NONE, NULL, 'N', "search across NC boundaries", NULL }, >- { "extended-dn", 0, POPT_ARG_NONE, NULL, 'E', "show extended DNs", NULL }, >+ { >+ .longName = "url", >+ .shortName = 'H', >+ .argInfo = POPT_ARG_STRING, >+ .arg = &options.url, >+ .val = 0, >+ .descrip = "database URL", >+ .argDescrip = "URL" >+ }, >+ { >+ .longName = "basedn", >+ .shortName = 'b', >+ .argInfo = POPT_ARG_STRING, >+ .arg = &options.basedn, >+ .val = 0, >+ .descrip = "base DN", >+ .argDescrip = "DN" >+ }, >+ { >+ .longName = "editor", >+ .shortName = 'e', >+ .argInfo = POPT_ARG_STRING, >+ .arg = &options.editor, >+ .val = 0, >+ .descrip = "external editor", >+ .argDescrip = "PROGRAM" >+ }, >+ { >+ .longName = "scope", >+ .shortName = 's', >+ .argInfo = POPT_ARG_STRING, >+ .arg = NULL, >+ .val = 's', >+ .descrip = "search scope", >+ .argDescrip = "SCOPE" >+ }, >+ { >+ .longName = "verbose", >+ .shortName = 'v', >+ .argInfo = POPT_ARG_NONE, >+ .arg = NULL, >+ .val = 'v', >+ .descrip = "increase verbosity", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "trace", >+ .shortName = 0, >+ .argInfo = POPT_ARG_NONE, >+ .arg = &options.tracing, >+ .val = 0, >+ .descrip = "enable tracing", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "interactive", >+ .shortName = 'i', >+ .argInfo = POPT_ARG_NONE, >+ .arg = &options.interactive, >+ .val = 0, >+ .descrip = "input from stdin", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "recursive", >+ .shortName = 'r', >+ .argInfo = POPT_ARG_NONE, >+ .arg = &options.recursive, >+ .val = 0, >+ .descrip = "recursive delete", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "modules-path", >+ .shortName = 0, >+ .argInfo = POPT_ARG_STRING, >+ .arg = &options.modules_path, >+ .val = 0, >+ .descrip = "modules path", >+ .argDescrip = "PATH" >+ }, >+ { >+ .longName = "num-searches", >+ .shortName = 0, >+ .argInfo = POPT_ARG_INT, >+ .arg = &options.num_searches, >+ .val = 0, >+ .descrip = "number of test searches", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "num-records", >+ .shortName = 0, >+ .argInfo = POPT_ARG_INT, >+ .arg = &options.num_records, >+ .val = 0, >+ .descrip = "number of test records", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "all", >+ .shortName = 'a', >+ .argInfo = POPT_ARG_NONE, >+ .arg = &options.all_records, >+ .val = 0, >+ .descrip = "(|(objectClass=*)(distinguishedName=*))", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "nosync", >+ .shortName = 0, >+ .argInfo = POPT_ARG_NONE, >+ .arg = &options.nosync, >+ .val = 0, >+ .descrip = "non-synchronous transactions", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "sorted", >+ .shortName = 'S', >+ .argInfo = POPT_ARG_NONE, >+ .arg = &options.sorted, >+ .val = 0, >+ .descrip = "sort attributes", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = NULL, >+ .shortName = 'o', >+ .argInfo = POPT_ARG_STRING, >+ .arg = NULL, >+ .val = 'o', >+ .descrip = "ldb_connect option", >+ .argDescrip = "OPTION" >+ }, >+ { >+ .longName = "controls", >+ .shortName = 0, >+ .argInfo = POPT_ARG_STRING, >+ .arg = NULL, >+ .val = 'c', >+ .descrip = "controls", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "show-binary", >+ .shortName = 0, >+ .argInfo = POPT_ARG_NONE, >+ .arg = &options.show_binary, >+ .val = 0, >+ .descrip = "display binary LDIF", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "paged", >+ .shortName = 0, >+ .argInfo = POPT_ARG_NONE, >+ .arg = NULL, >+ .val = 'P', >+ .descrip = "use a paged search", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "show-deleted", >+ .shortName = 0, >+ .argInfo = POPT_ARG_NONE, >+ .arg = NULL, >+ .val = 'D', >+ .descrip = "show deleted objects", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "show-recycled", >+ .shortName = 0, >+ .argInfo = POPT_ARG_NONE, >+ .arg = NULL, >+ .val = 'R', >+ .descrip = "show recycled objects", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "show-deactivated-link", >+ .shortName = 0, >+ .argInfo = POPT_ARG_NONE, >+ .arg = NULL, >+ .val = 'd', >+ .descrip = "show deactivated links", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "reveal", >+ .shortName = 0, >+ .argInfo = POPT_ARG_NONE, >+ .arg = NULL, >+ .val = 'r', >+ .descrip = "reveal ldb internals", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "relax", >+ .shortName = 0, >+ .argInfo = POPT_ARG_NONE, >+ .arg = NULL, >+ .val = CMDLINE_RELAX, >+ .descrip = "pass relax control", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "cross-ncs", >+ .shortName = 0, >+ .argInfo = POPT_ARG_NONE, >+ .arg = NULL, >+ .val = 'N', >+ .descrip = "search across NC boundaries", >+ .argDescrip = NULL >+ }, >+ { >+ .longName = "extended-dn", >+ .shortName = 0, >+ .argInfo = POPT_ARG_NONE, >+ .arg = NULL, >+ .val = 'E', >+ .descrip = "show extended DNs", >+ .argDescrip = NULL >+ }, > {0} > }; > >-- >2.25.1 > > >From 69feffba2051e0725fc825d8e788c5402f9dac43 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Thu, 17 Dec 2020 19:16:13 +0100 >Subject: [PATCH 396/686] CVE-2020-25718 lib:ldb-samba: Improve > calculate_popt_array_length() > >Note that memcmp() doesn't work well with padding bytes. So avoid it! > >(gdb) ptype/o struct poptOption >/* offset | size */ type = struct poptOption { >/* 0 | 8 */ const char *longName; >/* 8 | 1 */ char shortName; >/* XXX 3-byte hole */ >/* 12 | 4 */ unsigned int argInfo; >/* 16 | 8 */ void *arg; >/* 24 | 4 */ int val; >/* XXX 4-byte hole */ >/* 32 | 8 */ const char *descrip; >/* 40 | 8 */ const char *argDescrip; > > /* total size (bytes): 48 */ > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit c2c7c1f50a8acb3169e19ba4329aa78839b66def) >--- > lib/ldb-samba/samba_extensions.c | 27 ++++++++++++++++++++++----- > lib/ldb/tools/cmdline.c | 2 +- > 2 files changed, 23 insertions(+), 6 deletions(-) > >diff --git a/lib/ldb-samba/samba_extensions.c b/lib/ldb-samba/samba_extensions.c >index 65a4079ec97..60aa1a332b5 100644 >--- a/lib/ldb-samba/samba_extensions.c >+++ b/lib/ldb-samba/samba_extensions.c >@@ -34,15 +34,32 @@ > #include "popt.h" > > >+static bool is_popt_table_end(const struct poptOption *o) >+{ >+ if (o->longName == NULL && >+ o->shortName =='\0' && >+ o->arg == NULL) { >+ return true; >+ } >+ >+ return false; >+} > > /* > work out the length of a popt array > */ >-static unsigned calculate_popt_array_length(struct poptOption *opts) >+static size_t calculate_popt_array_length(struct poptOption *opts) > { >- unsigned i; >- struct poptOption zero_opt = { 0 }; >- for (i=0; memcmp(&zero_opt, &opts[i], sizeof(zero_opt)) != 0; i++) ; >+ size_t i = 0; >+ >+ for (i = 0; i < UINT32_MAX; i++) { >+ struct poptOption *o = &(opts[i]); >+ >+ if (is_popt_table_end(o)) { >+ break; >+ } >+ } >+ > return i; > } > >@@ -61,7 +78,7 @@ static int extensions_hook(struct ldb_context *ldb, enum ldb_module_hook_type t) > { > switch (t) { > case LDB_MODULE_HOOK_CMDLINE_OPTIONS: { >- unsigned len1, len2; >+ size_t len1, len2; > struct poptOption **popt_options = ldb_module_popt_options(ldb); > struct poptOption *new_array; > >diff --git a/lib/ldb/tools/cmdline.c b/lib/ldb/tools/cmdline.c >index b2fbb854910..306bca6555a 100644 >--- a/lib/ldb/tools/cmdline.c >+++ b/lib/ldb/tools/cmdline.c >@@ -259,7 +259,7 @@ static struct poptOption builtin_popt_options[] = { > .descrip = "show extended DNs", > .argDescrip = NULL > }, >- {0} >+ POPT_TABLEEND > }; > > void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f) >-- >2.25.1 > > >From 07de39f6ff3a5625334bdb33687a3b2a4cb4ad36 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 24 Jul 2020 12:41:29 +1200 >Subject: [PATCH 397/686] CVE-2020-25718 ldb_controls: control_to_string avoids > crash > >Otherwise a malformed control with unexpected NULL data will segfault >ldb_control_to_string(), though this is not very likely to affect >anyone in practice as converting controls to strings is rarely >necessary. If it happens at all in Samba it is in Python code. > >Found by Honggfuzz using fuzz_ldb_parse_control. > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@samba.org> > >Autobuild-User(master): Douglas Bagnall <dbagnall@samba.org> >Autobuild-Date(master): Wed Jul 29 04:43:23 UTC 2020 on sn-devel-184 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit 2aace18f170644da9c293342a6df5e5b2ae8da25) >--- > lib/ldb/common/ldb_controls.c | 22 ++++++++++++++++++++++ > 1 file changed, 22 insertions(+) > >diff --git a/lib/ldb/common/ldb_controls.c b/lib/ldb/common/ldb_controls.c >index e0f0eb48f3a..e6c3cf072b7 100644 >--- a/lib/ldb/common/ldb_controls.c >+++ b/lib/ldb/common/ldb_controls.c >@@ -286,6 +286,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr > if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) { > struct ldb_paged_control *rep_control = talloc_get_type(control->data, struct ldb_paged_control); > char *cookie; >+ if (rep_control == NULL) { >+ return NULL; >+ } > > cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len); > if (cookie == NULL) { >@@ -312,6 +315,10 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr > > char *cookie; > >+ if (rep_control == NULL) { >+ return NULL; >+ } >+ > cookie = ldb_base64_encode(mem_ctx, > (char *)rep_control->contextId, > rep_control->ctxid_len); >@@ -334,6 +341,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr > struct ldb_sort_resp_control *rep_control = talloc_get_type(control->data, > struct ldb_sort_resp_control); > >+ if (rep_control == NULL) { >+ return NULL; >+ } > res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s", > LDB_CONTROL_SORT_RESP_NAME, > control->critical, >@@ -347,6 +357,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr > struct ldb_asq_control *rep_control = talloc_get_type(control->data, > struct ldb_asq_control); > >+ if (rep_control == NULL) { >+ return NULL; >+ } > res = talloc_asprintf(mem_ctx, "%s:%d:%d", > LDB_CONTROL_SORT_RESP_NAME, > control->critical, >@@ -360,6 +373,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr > struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, > struct ldb_dirsync_control); > >+ if (rep_control == NULL) { >+ return NULL; >+ } > cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, > rep_control->cookie_len); > if (cookie == NULL) { >@@ -380,6 +396,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr > struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, > struct ldb_dirsync_control); > >+ if (rep_control == NULL) { >+ return NULL; >+ } > cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, > rep_control->cookie_len); > if (cookie == NULL) { >@@ -399,6 +418,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr > if (strcmp(control->oid, LDB_CONTROL_VERIFY_NAME_OID) == 0) { > struct ldb_verify_name_control *rep_control = talloc_get_type(control->data, struct ldb_verify_name_control); > >+ if (rep_control == NULL) { >+ return NULL; >+ } > if (rep_control->gc != NULL) { > res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s", > LDB_CONTROL_VERIFY_NAME_NAME, >-- >2.25.1 > > >From d6766e7fa84f3ba457f9ed9d89a0b9c4b8ef5716 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 4 Jan 2021 13:12:30 +0100 >Subject: [PATCH 398/686] CVE-2020-25718 lib: Add "hex_byte()" to replace.h > >This is required in quite a few places, and replace.h has things like >ZERO_STRUCT already, so this is not completely outplaced. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit c8d9ce3f7c8c486ab21e320a0adcb71311dcb453) >--- > lib/replace/replace.h | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > >diff --git a/lib/replace/replace.h b/lib/replace/replace.h >index 76898f013f8..0d07efc8c2e 100644 >--- a/lib/replace/replace.h >+++ b/lib/replace/replace.h >@@ -957,6 +957,22 @@ bool nss_wrapper_hosts_enabled(void); > bool socket_wrapper_enabled(void); > bool uid_wrapper_enabled(void); > >+static inline bool _hexcharval(char c, uint8_t *val) >+{ >+ if ((c >= '0') && (c <= '9')) { *val = c - '0'; return true; } >+ if ((c >= 'a') && (c <= 'f')) { *val = c - 'a' + 10; return true; } >+ if ((c >= 'A') && (c <= 'F')) { *val = c - 'A' + 10; return true; } >+ return false; >+} >+ >+static inline bool hex_byte(const char *in, uint8_t *out) >+{ >+ uint8_t hi=0, lo=0; >+ bool ok = _hexcharval(in[0], &hi) && _hexcharval(in[1], &lo); >+ *out = (hi<<4)+lo; >+ return ok; >+} >+ > /* Needed for Solaris atomic_add_XX functions. */ > #if defined(HAVE_SYS_ATOMIC_H) > #include <sys/atomic.h> >-- >2.25.1 > > >From f50f57d9fc1f23ef068946f93bf8b5a5768cccdd Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 4 Jan 2021 13:55:01 +0100 >Subject: [PATCH 399/686] CVE-2020-25718 ldb: Use hex_byte() in > ldb_binary_decode() > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit b6a57c49c00a778f954aaf10db6ebe6dca8f5ae2) >--- > lib/ldb/common/ldb_parse.c | 27 ++++----------------------- > 1 file changed, 4 insertions(+), 23 deletions(-) > >diff --git a/lib/ldb/common/ldb_parse.c b/lib/ldb/common/ldb_parse.c >index 7e15206b168..f0045ad2093 100644 >--- a/lib/ldb/common/ldb_parse.c >+++ b/lib/ldb/common/ldb_parse.c >@@ -53,26 +53,6 @@ > */ > #define LDB_MAX_PARSE_TREE_DEPTH 128 > >-static int ldb_parse_hex2char(const char *x) >-{ >- if (isxdigit(x[0]) && isxdigit(x[1])) { >- const char h1 = x[0], h2 = x[1]; >- int c = 0; >- >- if (h1 >= 'a') c = h1 - (int)'a' + 10; >- else if (h1 >= 'A') c = h1 - (int)'A' + 10; >- else if (h1 >= '0') c = h1 - (int)'0'; >- c = c << 4; >- if (h2 >= 'a') c += h2 - (int)'a' + 10; >- else if (h2 >= 'A') c += h2 - (int)'A' + 10; >- else if (h2 >= '0') c += h2 - (int)'0'; >- >- return c; >- } >- >- return -1; >-} >- > /* > a filter is defined by: > <filter> ::= '(' <filtercomp> ')' >@@ -101,10 +81,11 @@ struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str) > > for (i=j=0;i<slen;i++) { > if (str[i] == '\\') { >- int c; >+ uint8_t c; >+ bool ok; > >- c = ldb_parse_hex2char(&str[i+1]); >- if (c == -1) { >+ ok = hex_byte(&str[i+1], &c); >+ if (!ok) { > talloc_free(ret.data); > memset(&ret, 0, sizeof(ret)); > return ret; >-- >2.25.1 > > >From 0644d5a6c4eebbace6a773819be19063918c6544 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de> >Date: Mon, 19 Oct 2020 02:39:46 +0200 >Subject: [PATCH 400/686] CVE-2020-25718 ldb_kv_index: fix empty initializer > compile warning > >Signed-off-by: Bjoern Jacke <bjacke@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >(cherry picked from commit c862ad64aea31d1d5ec66385bb50d9b97e609071) >--- > lib/ldb/ldb_key_value/ldb_kv_index.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/ldb/ldb_key_value/ldb_kv_index.c b/lib/ldb/ldb_key_value/ldb_kv_index.c >index af02107b5d2..3ec6a9de8c6 100644 >--- a/lib/ldb/ldb_key_value/ldb_kv_index.c >+++ b/lib/ldb/ldb_key_value/ldb_kv_index.c >@@ -1785,7 +1785,7 @@ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv, > struct ldb_message *filtered_msg; > unsigned int i; > unsigned int num_keys = 0; >- uint8_t previous_guid_key[LDB_KV_GUID_KEY_SIZE] = {}; >+ uint8_t previous_guid_key[LDB_KV_GUID_KEY_SIZE] = {0}; > struct ldb_val *keys = NULL; > > /* >-- >2.25.1 > > >From f6b74ef7c8792c5d6923e2b296abbc3c9bb21294 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 15 Sep 2020 16:01:04 +0200 >Subject: [PATCH 401/686] CVE-2020-25717 winbind.idl: rename wbint_TransID.type > to wbint_TransID.type_hint > >This makes it clear that it's a hint from the parent to the >child. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 1576421dbdd2cfe9a47516224cb54bf15ba51132) >--- > librpc/idl/winbind.idl | 2 +- > source3/winbindd/wb_sids2xids.c | 5 ++--- > source3/winbindd/winbindd_dual_srv.c | 2 +- > 3 files changed, 4 insertions(+), 5 deletions(-) > >diff --git a/librpc/idl/winbind.idl b/librpc/idl/winbind.idl >index 258dd284ad5..a2bc81a9333 100644 >--- a/librpc/idl/winbind.idl >+++ b/librpc/idl/winbind.idl >@@ -40,7 +40,7 @@ interface winbind > ); > > typedef struct { >- id_type type; >+ id_type type_hint; > uint32 domain_index; > uint32 rid; > unixid xid; >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index e6698f94789..ff2135b4b50 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -222,7 +222,7 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > > sid_copy(&dom_sid, sid); > sid_split_rid(&dom_sid, &t->rid); >- t->type = lsa_SidType_to_id_type(n->sid_type); >+ t->type_hint = lsa_SidType_to_id_type(n->sid_type); > domain_index = init_lsa_ref_domain_list( > state, &state->idmap_doms, domain_name, &dom_sid); > if (domain_index == -1) { >@@ -232,7 +232,7 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > t->domain_index = domain_index; > > t->xid.id = UINT32_MAX; >- t->xid.type = t->type; >+ t->xid.type = ID_TYPE_NOT_SPECIFIED; > } > > TALLOC_FREE(names); >@@ -337,7 +337,6 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > > for (i=0; i<dst->num_ids; i++) { > if (dst->ids[i].domain_index == state->dom_index) { >- dst->ids[i].type = src->ids[src_idx].type; > dst->ids[i].xid = src->ids[src_idx].xid; > src_idx += 1; > } >diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c >index ab14f5d51a0..b83a313ea45 100644 >--- a/source3/winbindd/winbindd_dual_srv.c >+++ b/source3/winbindd/winbindd_dual_srv.c >@@ -199,7 +199,7 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p, > > sid_compose(m->sid, d->sid, ids[i].rid); > m->status = ID_UNKNOWN; >- m->xid = (struct unixid) { .type = ids[i].type }; >+ m->xid = (struct unixid) { .type = ids[i].type_hint }; > } > > status = dom->methods->sids_to_unixids(dom, id_map_ptrs); >-- >2.25.1 > > >From 088ebe421905806924910cdd3dd793704beadf55 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 15 Sep 2020 16:46:44 +0200 >Subject: [PATCH 402/686] CVE-2020-25717 s3:passdb: use ID_TYPE_* instead of > WBC_ID_TYPE_* > >Currently these enums have the same values, but that will >change in future. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 58e9b62222ad62c81cdf11d704859a227cb2902b) > >[jsutton@samba.org Fixed conflict] >--- > source3/passdb/lookup_sid.c | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > >diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c >index 1bb15ccb8b4..a7a1d5faa8e 100644 >--- a/source3/passdb/lookup_sid.c >+++ b/source3/passdb/lookup_sid.c >@@ -1339,14 +1339,14 @@ bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids, > done: > for (i=0; i<num_sids; i++) { > switch(ids[i].type) { >- case WBC_ID_TYPE_GID: >- case WBC_ID_TYPE_UID: >- case WBC_ID_TYPE_BOTH: >- if (ids[i].id == -1) { >+ case ID_TYPE_GID: >+ case ID_TYPE_UID: >+ case ID_TYPE_BOTH: >+ if (ids[i].id == (uint32_t)-1) { > ids[i].type = ID_TYPE_NOT_SPECIFIED; > } > break; >- case WBC_ID_TYPE_NOT_SPECIFIED: >+ case ID_TYPE_NOT_SPECIFIED: > break; > } > } >-- >2.25.1 > > >From 5bfa474c7776cb485edea09a1f73eb756c7bf273 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 Mar 2019 12:29:00 +0100 >Subject: [PATCH 403/686] CVE-2020-25717 test_idmap_tdb_common: correctly > initialize the idmap domain with an init function > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit f5eec89011cf7b577375d83247524587f170b592) >--- > source3/torture/test_idmap_tdb_common.c | 50 ++++++++++++++++--------- > 1 file changed, 33 insertions(+), 17 deletions(-) > >diff --git a/source3/torture/test_idmap_tdb_common.c b/source3/torture/test_idmap_tdb_common.c >index 5ecb978990d..f881babcc52 100644 >--- a/source3/torture/test_idmap_tdb_common.c >+++ b/source3/torture/test_idmap_tdb_common.c >@@ -110,12 +110,21 @@ static bool open_db(struct idmap_tdb_common_context *ctx) > return true; > } > >-static struct idmap_tdb_common_context *createcontext(TALLOC_CTX *memctx) >+static NTSTATUS idmap_test_tdb_db_init(struct idmap_domain *dom) > { > struct idmap_tdb_common_context *ret; > >- ret = talloc_zero(memctx, struct idmap_tdb_common_context); >+ DBG_DEBUG("called for domain '%s'\n", dom->name); >+ >+ ret = talloc_zero(dom, struct idmap_tdb_common_context); >+ if (ret == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } > ret->rw_ops = talloc_zero(ret, struct idmap_rw_ops); >+ if (ret->rw_ops == NULL) { >+ TALLOC_FREE(ret); >+ return NT_STATUS_NO_MEMORY; >+ } > > ret->max_id = HIGH_ID; > ret->hwmkey_uid = HWM_USER; >@@ -125,25 +134,33 @@ static struct idmap_tdb_common_context *createcontext(TALLOC_CTX *memctx) > ret->rw_ops->set_mapping = idmap_tdb_common_set_mapping; > > if (!open_db(ret)) { >- return NULL; >+ TALLOC_FREE(ret); >+ return NT_STATUS_INTERNAL_ERROR; > }; > >- return ret; >+ dom->private_data = ret; >+ >+ return NT_STATUS_OK; > } > > static struct idmap_domain *createdomain(TALLOC_CTX *memctx) > { > struct idmap_domain *dom; >+ struct idmap_methods *m; > > dom = talloc_zero(memctx, struct idmap_domain); > dom->name = "*"; > dom->low_id = LOW_ID; > dom->high_id = HIGH_ID; > dom->read_only = false; >- dom->methods = talloc_zero(dom, struct idmap_methods); >- dom->methods->sids_to_unixids = idmap_tdb_common_sids_to_unixids; >- dom->methods->unixids_to_sids = idmap_tdb_common_unixids_to_sids; >- dom->methods->allocate_id = idmap_tdb_common_get_new_id; >+ m = talloc_zero(dom, struct idmap_methods); >+ *m = (struct idmap_methods) { >+ .init = idmap_test_tdb_db_init, >+ .sids_to_unixids = idmap_tdb_common_sids_to_unixids, >+ .unixids_to_sids = idmap_tdb_common_unixids_to_sids, >+ .allocate_id = idmap_tdb_common_get_new_id, >+ }; >+ dom->methods = m; > > return dom; > } >@@ -965,20 +982,20 @@ out: > bool run_idmap_tdb_common_test(int dummy) > { > bool result; >- struct idmap_tdb_common_context *ctx; > struct idmap_domain *dom; >- >- TALLOC_CTX *memctx = talloc_new(NULL); > TALLOC_CTX *stack = talloc_stackframe(); >+ TALLOC_CTX *memctx = talloc_new(stack); >+ NTSTATUS status; > >- ctx = createcontext(memctx); >- if(!ctx) { >+ dom = createdomain(memctx); >+ if (dom == NULL) { > return false; > } > >- dom = createdomain(memctx); >- >- dom->private_data = ctx; >+ status = dom->methods->init(dom); >+ if (!NT_STATUS_IS_OK(status)) { >+ return false; >+ } > > /* test a single allocation from pool (no mapping) */ > result = test_getnewid1(memctx, dom); >@@ -1022,7 +1039,6 @@ bool run_idmap_tdb_common_test(int dummy) > result = test_getnewid2(memctx, dom); > CHECKRESULT(result); > >- talloc_free(memctx); > talloc_free(stack); > > return true; >-- >2.25.1 > > >From ea73b3e5e7064f7c2717c0474e0da753fd3206fa Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 Mar 2019 12:30:37 +0100 >Subject: [PATCH 404/686] CVE-2020-25717 winbindd/idmap: apply const to struct > idmap_methods pointers > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 95b0dac0af5bc7ee85c6c8099dda135c36c9684b) >--- > source3/include/idmap.h | 2 +- > source3/winbindd/idmap.c | 6 +++--- > source3/winbindd/idmap_ad.c | 2 +- > source3/winbindd/idmap_autorid.c | 2 +- > source3/winbindd/idmap_hash/idmap_hash.c | 2 +- > source3/winbindd/idmap_ldap.c | 2 +- > source3/winbindd/idmap_nss.c | 3 +-- > source3/winbindd/idmap_passdb.c | 7 +------ > source3/winbindd/idmap_proto.h | 2 +- > source3/winbindd/idmap_rfc2307.c | 2 +- > source3/winbindd/idmap_rid.c | 2 +- > source3/winbindd/idmap_script.c | 2 +- > source3/winbindd/idmap_tdb.c | 2 +- > source3/winbindd/idmap_tdb2.c | 2 +- > 14 files changed, 16 insertions(+), 22 deletions(-) > >diff --git a/source3/include/idmap.h b/source3/include/idmap.h >index 8d80643e6e9..dce60f1f76d 100644 >--- a/source3/include/idmap.h >+++ b/source3/include/idmap.h >@@ -42,7 +42,7 @@ struct idmap_domain { > * so don't rely on this being filled out everywhere! > */ > struct dom_sid dom_sid; >- struct idmap_methods *methods; >+ const struct idmap_methods *methods; > NTSTATUS (*query_user)(struct idmap_domain *domain, > struct wbint_userinfo *info); > uint32_t low_id; >diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c >index bfac7f86432..eee28992929 100644 >--- a/source3/winbindd/idmap.c >+++ b/source3/winbindd/idmap.c >@@ -40,7 +40,7 @@ static_decl_idmap; > > struct idmap_backend { > const char *name; >- struct idmap_methods *methods; >+ const struct idmap_methods *methods; > struct idmap_backend *prev, *next; > }; > static struct idmap_backend *backends = NULL; >@@ -285,7 +285,7 @@ static bool idmap_found_domain_backend(const char *domname, > return false; > } > >-static struct idmap_methods *get_methods(const char *name) >+static const struct idmap_methods *get_methods(const char *name) > { > struct idmap_backend *b; > >@@ -309,7 +309,7 @@ bool idmap_is_offline(void) > **********************************************************************/ > > NTSTATUS smb_register_idmap(int version, const char *name, >- struct idmap_methods *methods) >+ const struct idmap_methods *methods) > { > struct idmap_backend *entry; > >diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c >index a93c61f54d1..cf1bfafbd09 100644 >--- a/source3/winbindd/idmap_ad.c >+++ b/source3/winbindd/idmap_ad.c >@@ -959,7 +959,7 @@ static NTSTATUS idmap_ad_sids_to_unixids_retry(struct idmap_domain *dom, > return status; > } > >-static struct idmap_methods ad_methods = { >+static const struct idmap_methods ad_methods = { > .init = idmap_ad_initialize, > .unixids_to_sids = idmap_ad_unixids_to_sids_retry, > .sids_to_unixids = idmap_ad_sids_to_unixids_retry, >diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c >index 1d0f0fafb82..636852119b2 100644 >--- a/source3/winbindd/idmap_autorid.c >+++ b/source3/winbindd/idmap_autorid.c >@@ -919,7 +919,7 @@ done: > return status; > } > >-static struct idmap_methods autorid_methods = { >+static const struct idmap_methods autorid_methods = { > .init = idmap_autorid_initialize, > .unixids_to_sids = idmap_autorid_unixids_to_sids, > .sids_to_unixids = idmap_autorid_sids_to_unixids, >diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c >index 1747b7c56c1..267ff3e5edc 100644 >--- a/source3/winbindd/idmap_hash/idmap_hash.c >+++ b/source3/winbindd/idmap_hash/idmap_hash.c >@@ -331,7 +331,7 @@ static NTSTATUS nss_hash_close(void) > Dispatch Tables for IDMap and NssInfo Methods > ********************************************************************/ > >-static struct idmap_methods hash_idmap_methods = { >+static const struct idmap_methods hash_idmap_methods = { > .init = idmap_hash_initialize, > .unixids_to_sids = unixids_to_sids, > .sids_to_unixids = sids_to_unixids, >diff --git a/source3/winbindd/idmap_ldap.c b/source3/winbindd/idmap_ldap.c >index 17cc7404f12..327b8119331 100644 >--- a/source3/winbindd/idmap_ldap.c >+++ b/source3/winbindd/idmap_ldap.c >@@ -1072,7 +1072,7 @@ done: > Close the idmap ldap instance > **********************************/ > >-static struct idmap_methods idmap_ldap_methods = { >+static const struct idmap_methods idmap_ldap_methods = { > > .init = idmap_ldap_db_init, > .unixids_to_sids = idmap_ldap_unixids_to_sids, >diff --git a/source3/winbindd/idmap_nss.c b/source3/winbindd/idmap_nss.c >index 3fe98cbc729..9e1efefeb24 100644 >--- a/source3/winbindd/idmap_nss.c >+++ b/source3/winbindd/idmap_nss.c >@@ -195,8 +195,7 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma > Close the idmap tdb instance > **********************************/ > >-static struct idmap_methods nss_methods = { >- >+static const struct idmap_methods nss_methods = { > .init = idmap_nss_int_init, > .unixids_to_sids = idmap_nss_unixids_to_sids, > .sids_to_unixids = idmap_nss_sids_to_unixids, >diff --git a/source3/winbindd/idmap_passdb.c b/source3/winbindd/idmap_passdb.c >index 75fc732cca0..758f31a2c9d 100644 >--- a/source3/winbindd/idmap_passdb.c >+++ b/source3/winbindd/idmap_passdb.c >@@ -75,12 +75,7 @@ static NTSTATUS idmap_pdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma > return NT_STATUS_OK; > } > >-/********************************** >- Close the idmap tdb instance >-**********************************/ >- >-static struct idmap_methods passdb_methods = { >- >+static const struct idmap_methods passdb_methods = { > .init = idmap_pdb_init, > .unixids_to_sids = idmap_pdb_unixids_to_sids, > .sids_to_unixids = idmap_pdb_sids_to_unixids, >diff --git a/source3/winbindd/idmap_proto.h b/source3/winbindd/idmap_proto.h >index a36d6c2f5bb..adc04430a67 100644 >--- a/source3/winbindd/idmap_proto.h >+++ b/source3/winbindd/idmap_proto.h >@@ -29,7 +29,7 @@ > > bool idmap_is_offline(void); > NTSTATUS smb_register_idmap(int version, const char *name, >- struct idmap_methods *methods); >+ const struct idmap_methods *methods); > void idmap_close(void); > NTSTATUS idmap_allocate_uid(struct unixid *id); > NTSTATUS idmap_allocate_gid(struct unixid *id); >diff --git a/source3/winbindd/idmap_rfc2307.c b/source3/winbindd/idmap_rfc2307.c >index e3bf58d8165..a747ff1f3bf 100644 >--- a/source3/winbindd/idmap_rfc2307.c >+++ b/source3/winbindd/idmap_rfc2307.c >@@ -836,7 +836,7 @@ err: > return status; > } > >-static struct idmap_methods rfc2307_methods = { >+static const struct idmap_methods rfc2307_methods = { > .init = idmap_rfc2307_initialize, > .unixids_to_sids = idmap_rfc2307_unixids_to_sids, > .sids_to_unixids = idmap_rfc2307_sids_to_unixids, >diff --git a/source3/winbindd/idmap_rid.c b/source3/winbindd/idmap_rid.c >index e5bb1fa856c..33f049695f4 100644 >--- a/source3/winbindd/idmap_rid.c >+++ b/source3/winbindd/idmap_rid.c >@@ -168,7 +168,7 @@ static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_ma > return NT_STATUS_OK; > } > >-static struct idmap_methods rid_methods = { >+static const struct idmap_methods rid_methods = { > .init = idmap_rid_initialize, > .unixids_to_sids = idmap_rid_unixids_to_sids, > .sids_to_unixids = idmap_rid_sids_to_unixids, >diff --git a/source3/winbindd/idmap_script.c b/source3/winbindd/idmap_script.c >index f382f896b35..a56ad7b93fb 100644 >--- a/source3/winbindd/idmap_script.c >+++ b/source3/winbindd/idmap_script.c >@@ -665,7 +665,7 @@ failed: > return ret; > } > >-static struct idmap_methods db_methods = { >+static const struct idmap_methods db_methods = { > .init = idmap_script_db_init, > .unixids_to_sids = idmap_script_unixids_to_sids, > .sids_to_unixids = idmap_script_sids_to_unixids, >diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c >index c3215c4dd9b..1ec2be0d789 100644 >--- a/source3/winbindd/idmap_tdb.c >+++ b/source3/winbindd/idmap_tdb.c >@@ -426,7 +426,7 @@ failed: > return ret; > } > >-static struct idmap_methods db_methods = { >+static const struct idmap_methods db_methods = { > .init = idmap_tdb_db_init, > .unixids_to_sids = idmap_tdb_common_unixids_to_sids, > .sids_to_unixids = idmap_tdb_common_sids_to_unixids, >diff --git a/source3/winbindd/idmap_tdb2.c b/source3/winbindd/idmap_tdb2.c >index eceab9c0784..f2731f9a04a 100644 >--- a/source3/winbindd/idmap_tdb2.c >+++ b/source3/winbindd/idmap_tdb2.c >@@ -598,7 +598,7 @@ failed: > } > > >-static struct idmap_methods db_methods = { >+static const struct idmap_methods db_methods = { > .init = idmap_tdb2_db_init, > .unixids_to_sids = idmap_tdb_common_unixids_to_sids, > .sids_to_unixids = idmap_tdb_common_sids_to_unixids, >-- >2.25.1 > > >From 111932d3566556af47f43a1a6a55fd245da2f610 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 Mar 2019 12:30:37 +0100 >Subject: [PATCH 405/686] CVE-2020-25717 winbindd/idmap: apply const to struct > nss_info_methods pointers > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 7518a0ca32cade2b8b9eac0e2b5416ae685ffcff) >--- > source3/include/nss_info.h | 6 +++--- > source3/winbindd/idmap_ad_nss.c | 6 +++--- > source3/winbindd/idmap_hash/idmap_hash.c | 2 +- > source3/winbindd/nss_info.c | 7 ++++--- > 4 files changed, 11 insertions(+), 10 deletions(-) > >diff --git a/source3/include/nss_info.h b/source3/include/nss_info.h >index 448f8847be9..94df56ee7db 100644 >--- a/source3/include/nss_info.h >+++ b/source3/include/nss_info.h >@@ -38,7 +38,7 @@ struct nss_function_entry { > struct nss_function_entry *prev, *next; > > const char *name; >- struct nss_info_methods *methods; >+ const struct nss_info_methods *methods; > }; > > /* List of configured domains. Each domain points >@@ -50,7 +50,7 @@ struct nss_domain_entry { > const char *domain; > > NTSTATUS init_status; >- struct nss_function_entry *backend; >+ const struct nss_function_entry *backend; > > /* hold state on a per domain basis */ > >@@ -75,7 +75,7 @@ struct nss_info_methods { > > NTSTATUS smb_register_idmap_nss(int version, > const char *name, >- struct nss_info_methods *methods); >+ const struct nss_info_methods *methods); > > NTSTATUS nss_map_to_alias( TALLOC_CTX *mem_ctx, const char *domain, > const char *name, char **alias ); >diff --git a/source3/winbindd/idmap_ad_nss.c b/source3/winbindd/idmap_ad_nss.c >index 0fd2b51e156..96fee84997f 100644 >--- a/source3/winbindd/idmap_ad_nss.c >+++ b/source3/winbindd/idmap_ad_nss.c >@@ -370,19 +370,19 @@ done: > /* The SFU and RFC2307 NSS plugins share everything but the init > function which sets the intended schema model to use */ > >-static struct nss_info_methods nss_rfc2307_methods = { >+static const struct nss_info_methods nss_rfc2307_methods = { > .init = nss_rfc2307_init, > .map_to_alias = nss_ad_map_to_alias, > .map_from_alias = nss_ad_map_from_alias, > }; > >-static struct nss_info_methods nss_sfu_methods = { >+static const struct nss_info_methods nss_sfu_methods = { > .init = nss_sfu_init, > .map_to_alias = nss_ad_map_to_alias, > .map_from_alias = nss_ad_map_from_alias, > }; > >-static struct nss_info_methods nss_sfu20_methods = { >+static const struct nss_info_methods nss_sfu20_methods = { > .init = nss_sfu20_init, > .map_to_alias = nss_ad_map_to_alias, > .map_from_alias = nss_ad_map_from_alias, >diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c >index 267ff3e5edc..be0ba45a044 100644 >--- a/source3/winbindd/idmap_hash/idmap_hash.c >+++ b/source3/winbindd/idmap_hash/idmap_hash.c >@@ -337,7 +337,7 @@ static const struct idmap_methods hash_idmap_methods = { > .sids_to_unixids = sids_to_unixids, > }; > >-static struct nss_info_methods hash_nss_methods = { >+static const struct nss_info_methods hash_nss_methods = { > .init = nss_hash_init, > .map_to_alias = nss_hash_map_to_alias, > .map_from_alias = nss_hash_map_from_alias, >diff --git a/source3/winbindd/nss_info.c b/source3/winbindd/nss_info.c >index 1a8325ce7dc..9c502e84ef0 100644 >--- a/source3/winbindd/nss_info.c >+++ b/source3/winbindd/nss_info.c >@@ -46,7 +46,8 @@ static struct nss_function_entry *nss_get_backend(const char *name ) > Allow a module to register itself as a backend. > **********************************************************************/ > >- NTSTATUS smb_register_idmap_nss(int version, const char *name, struct nss_info_methods *methods) >+ NTSTATUS smb_register_idmap_nss(int version, const char *name, >+ const struct nss_info_methods *methods) > { > struct nss_function_entry *entry; > >@@ -319,7 +320,7 @@ static struct nss_domain_entry *find_nss_domain( const char *domain ) > const char *name, char **alias ) > { > struct nss_domain_entry *p; >- struct nss_info_methods *m; >+ const struct nss_info_methods *m; > > if ( (p = find_nss_domain( domain )) == NULL ) { > DEBUG(4,("nss_map_to_alias: Failed to find nss domain pointer for %s\n", >@@ -340,7 +341,7 @@ static struct nss_domain_entry *find_nss_domain( const char *domain ) > const char *alias, char **name ) > { > struct nss_domain_entry *p; >- struct nss_info_methods *m; >+ const struct nss_info_methods *m; > > if ( (p = find_nss_domain( domain )) == NULL ) { > DEBUG(4,("nss_map_from_alias: Failed to find nss domain pointer for %s\n", >-- >2.25.1 > > >From 0e06d59ed2c336fede59cf6cf1e79a277575aac4 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Sep 2020 13:52:17 +0200 >Subject: [PATCH 406/686] CVE-2020-25717 wb_queryuser: avoid idmap_child() and > use idmap_child_handle() instead > >This is the only aspect we need here. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 7dbe5b4897448aa71b5a8a2175850b4010316b88) >--- > source3/winbindd/wb_queryuser.c | 21 +++++++++------------ > 1 file changed, 9 insertions(+), 12 deletions(-) > >diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c >index 2eb61406fc5..2e36643454b 100644 >--- a/source3/winbindd/wb_queryuser.c >+++ b/source3/winbindd/wb_queryuser.c >@@ -77,7 +77,7 @@ static void wb_queryuser_got_uid(struct tevent_req *subreq) > req, struct wb_queryuser_state); > struct wbint_userinfo *info = state->info; > struct netr_SamInfo3 *info3; >- struct winbindd_child *child; >+ struct dcerpc_binding_handle *child_binding_handle = NULL; > struct unixid xid; > NTSTATUS status; > >@@ -138,10 +138,9 @@ static void wb_queryuser_got_uid(struct tevent_req *subreq) > return; > } > >- child = idmap_child(); >- >+ child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_GetNssInfo_send( >- state, state->ev, child->binding_handle, info); >+ state, state->ev, child_binding_handle, info); > if (tevent_req_nomem(subreq, req)) { > return; > } >@@ -156,7 +155,7 @@ static void wb_queryuser_got_domain(struct tevent_req *subreq) > req, struct wb_queryuser_state); > struct wbint_userinfo *info = state->info; > enum lsa_SidType type; >- struct winbindd_child *child; >+ struct dcerpc_binding_handle *child_binding_handle = NULL; > NTSTATUS status; > > status = wb_lookupsid_recv(subreq, state, &type, >@@ -186,10 +185,9 @@ static void wb_queryuser_got_domain(struct tevent_req *subreq) > return; > } > >- child = idmap_child(); >- >+ child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_GetNssInfo_send( >- state, state->ev, child->binding_handle, info); >+ state, state->ev, child_binding_handle, info); > if (tevent_req_nomem(subreq, req)) { > return; > } >@@ -270,7 +268,7 @@ static void wb_queryuser_got_dc(struct tevent_req *subreq) > req, struct wb_queryuser_state); > struct wbint_userinfo *info = state->info; > struct netr_DsRGetDCNameInfo *dcinfo; >- struct winbindd_child *child; >+ struct dcerpc_binding_handle *child_binding_handle = NULL; > NTSTATUS status; > > status = wb_dsgetdcname_recv(subreq, state, &dcinfo); >@@ -286,10 +284,9 @@ static void wb_queryuser_got_dc(struct tevent_req *subreq) > return; > } > >- child = idmap_child(); >- >+ child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_GetNssInfo_send( >- state, state->ev, child->binding_handle, info); >+ state, state->ev, child_binding_handle, info); > if (tevent_req_nomem(subreq, req)) { > return; > } >-- >2.25.1 > > >From 66df7b79045136601564e05822dc4b2d5d35562a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Sep 2020 12:35:09 +0200 >Subject: [PATCH 407/686] CVE-2020-25717 wb_xids2sids: avoid idmap_child() and > use idmap_child_handle() instead > >This is the only aspect we need here. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 5cc21a9d319e00397ad98900d81ffb9d1d70514f) >--- > source3/winbindd/wb_xids2sids.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > >diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c >index 9ddc71f3796..c332823dd1d 100644 >--- a/source3/winbindd/wb_xids2sids.c >+++ b/source3/winbindd/wb_xids2sids.c >@@ -270,7 +270,7 @@ static struct tevent_req *wb_xids2sids_dom_send( > { > struct tevent_req *req, *subreq; > struct wb_xids2sids_dom_state *state; >- struct winbindd_child *child; >+ struct dcerpc_binding_handle *child_binding_handle = NULL; > size_t i; > > req = tevent_req_create(mem_ctx, &state, >@@ -317,9 +317,9 @@ static struct tevent_req *wb_xids2sids_dom_send( > return tevent_req_post(req, ev); > } > >- child = idmap_child(); >+ child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_UnixIDs2Sids_send( >- state, ev, child->binding_handle, dom_map->name, dom_map->sid, >+ state, ev, child_binding_handle, dom_map->name, dom_map->sid, > state->num_dom_xids, state->dom_xids, state->dom_sids); > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); >@@ -396,7 +396,7 @@ static void wb_xids2sids_dom_gotdc(struct tevent_req *subreq) > subreq, struct tevent_req); > struct wb_xids2sids_dom_state *state = tevent_req_data( > req, struct wb_xids2sids_dom_state); >- struct winbindd_child *child = idmap_child(); >+ struct dcerpc_binding_handle *child_binding_handle = NULL; > struct netr_DsRGetDCNameInfo *dcinfo; > NTSTATUS status; > >@@ -413,9 +413,9 @@ static void wb_xids2sids_dom_gotdc(struct tevent_req *subreq) > return; > } > >- child = idmap_child(); >+ child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_UnixIDs2Sids_send( >- state, state->ev, child->binding_handle, state->dom_map->name, >+ state, state->ev, child_binding_handle, state->dom_map->name, > state->dom_map->sid, state->num_dom_xids, > state->dom_xids, state->dom_sids); > if (tevent_req_nomem(subreq, req)) { >-- >2.25.1 > > >From dfd2aa1cef1cbead7aba8582db2e5943484967ef Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Sep 2020 15:49:34 +0200 >Subject: [PATCH 408/686] CVE-2020-25717 wb_sids2xids: avoid idmap_child() and > use idmap_child_handle() instead > >This is the only aspect we need here. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 1694de1ae6ce63377d0afc47e84e55e4745905d7) >--- > source3/winbindd/wb_sids2xids.c | 16 +++++++--------- > 1 file changed, 7 insertions(+), 9 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index ff2135b4b50..b47856520ea 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -238,8 +238,6 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > TALLOC_FREE(names); > TALLOC_FREE(domains); > >- child_binding_handle = idmap_child_handle(); >- > state->dom_ids = wb_sids2xids_extract_for_domain_index( > state, &state->ids, state->dom_index); > if (tevent_req_nomem(state->dom_ids, req)) { >@@ -252,6 +250,7 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > .max_size = 1 > }; > >+ child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_Sids2UnixIDs_send( > state, state->ev, child_binding_handle, &state->idmap_dom, > state->dom_ids); >@@ -290,8 +289,7 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > struct wb_sids2xids_state *state = tevent_req_data( > req, struct wb_sids2xids_state); > NTSTATUS status, result; >- struct winbindd_child *child; >- >+ struct dcerpc_binding_handle *child_binding_handle = NULL; > struct wbint_TransIDArray *src, *dst; > uint32_t i, src_idx; > >@@ -352,8 +350,6 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > return; > } > >- child = idmap_child(); >- > state->dom_ids = wb_sids2xids_extract_for_domain_index( > state, &state->ids, state->dom_index); > if (tevent_req_nomem(state->dom_ids, req)) { >@@ -366,8 +362,9 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > .max_size = 1 > }; > >+ child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_Sids2UnixIDs_send( >- state, state->ev, child->binding_handle, &state->idmap_dom, >+ state, state->ev, child_binding_handle, &state->idmap_dom, > state->dom_ids); > if (tevent_req_nomem(subreq, req)) { > return; >@@ -381,7 +378,7 @@ static void wb_sids2xids_gotdc(struct tevent_req *subreq) > subreq, struct tevent_req); > struct wb_sids2xids_state *state = tevent_req_data( > req, struct wb_sids2xids_state); >- struct winbindd_child *child = idmap_child(); >+ struct dcerpc_binding_handle *child_binding_handle = NULL; > struct netr_DsRGetDCNameInfo *dcinfo; > NTSTATUS status; > >@@ -404,8 +401,9 @@ static void wb_sids2xids_gotdc(struct tevent_req *subreq) > } > } > >+ child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_Sids2UnixIDs_send( >- state, state->ev, child->binding_handle, &state->idmap_dom, >+ state, state->ev, child_binding_handle, &state->idmap_dom, > state->dom_ids); > if (tevent_req_nomem(subreq, req)) { > return; >-- >2.25.1 > > >From 936cc19cada5bb64dacb2c5442b72101e96f4075 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Sep 2020 14:06:04 +0200 >Subject: [PATCH 409/686] CVE-2020-25717 winbindd: add and use > idmap_child_pid() > >We should avoid calling idmap_child() as much as possible. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 2103543629004a3a22e7bf60305bb15bf3b316be) >--- > source3/winbindd/winbindd_cm.c | 12 ++++++------ > source3/winbindd/winbindd_dual.c | 6 +++--- > source3/winbindd/winbindd_idmap.c | 5 +++++ > source3/winbindd/winbindd_proto.h | 1 + > 4 files changed, 15 insertions(+), 9 deletions(-) > >diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c >index 4bd03ed8b7a..89249bdaf81 100644 >--- a/source3/winbindd/winbindd_cm.c >+++ b/source3/winbindd/winbindd_cm.c >@@ -463,11 +463,11 @@ void set_domain_offline(struct winbindd_domain *domain) > primary domain goes offline */ > > if ( domain->primary ) { >- struct winbindd_child *idmap = idmap_child(); >+ pid_t idmap_pid = idmap_child_pid(); > >- if ( idmap->pid != 0 ) { >+ if (idmap_pid != 0) { > messaging_send_buf(global_messaging_context(), >- pid_to_procid(idmap->pid), >+ pid_to_procid(idmap_pid), > MSG_WINBIND_OFFLINE, > (const uint8_t *)domain->name, > strlen(domain->name)+1); >@@ -549,11 +549,11 @@ static void set_domain_online(struct winbindd_domain *domain) > primary domain comes online */ > > if ( domain->primary ) { >- struct winbindd_child *idmap = idmap_child(); >+ pid_t idmap_pid = idmap_child_pid(); > >- if ( idmap->pid != 0 ) { >+ if (idmap_pid != 0) { > messaging_send_buf(global_messaging_context(), >- pid_to_procid(idmap->pid), >+ pid_to_procid(idmap_pid), > MSG_WINBIND_ONLINE, > (const uint8_t *)domain->name, > strlen(domain->name)+1); >diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c >index 6e3277e5529..cb93057b53a 100644 >--- a/source3/winbindd/winbindd_dual.c >+++ b/source3/winbindd/winbindd_dual.c >@@ -1009,11 +1009,11 @@ void winbind_msg_online(struct messaging_context *msg_ctx, > primary domain comes back online */ > > if ( domain->primary ) { >- struct winbindd_child *idmap = idmap_child(); >+ pid_t idmap_pid = idmap_child_pid(); > >- if ( idmap->pid != 0 ) { >+ if (idmap_pid != 0) { > messaging_send_buf(msg_ctx, >- pid_to_procid(idmap->pid), >+ pid_to_procid(idmap_pid), > MSG_WINBIND_ONLINE, > (const uint8_t *)domain->name, > strlen(domain->name)+1); >diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c >index 2ee436bc7dc..965a7839f17 100644 >--- a/source3/winbindd/winbindd_idmap.c >+++ b/source3/winbindd/winbindd_idmap.c >@@ -34,6 +34,11 @@ struct winbindd_child *idmap_child(void) > return &static_idmap_child; > } > >+pid_t idmap_child_pid(void) >+{ >+ return static_idmap_child.pid; >+} >+ > struct dcerpc_binding_handle *idmap_child_handle(void) > { > return static_idmap_child.binding_handle; >diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h >index ae8f555ec45..95d7376f93c 100644 >--- a/source3/winbindd/winbindd_proto.h >+++ b/source3/winbindd/winbindd_proto.h >@@ -359,6 +359,7 @@ NTSTATUS winbindd_print_groupmembers(struct db_context *members, > > void init_idmap_child(void); > struct winbindd_child *idmap_child(void); >+pid_t idmap_child_pid(void); > struct dcerpc_binding_handle *idmap_child_handle(void); > struct idmap_domain *idmap_find_domain_with_sid(const char *domname, > const struct dom_sid *sid); >-- >2.25.1 > > >From a8cd80d680350df10a3293d820e51ef957414711 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Sep 2020 14:06:04 +0200 >Subject: [PATCH 410/686] CVE-2020-25717 winbindd: add and use is_idmap_child() > >We should avoid calling idmap_child() as much as possible. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit cd9a9702c1f97c47bd3447e2014eeff3e56268cf) >--- > source3/winbindd/winbindd_dual.c | 4 ++-- > source3/winbindd/winbindd_idmap.c | 9 +++++++++ > source3/winbindd/winbindd_proto.h | 1 + > 3 files changed, 12 insertions(+), 2 deletions(-) > >diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c >index cb93057b53a..6996cd635c0 100644 >--- a/source3/winbindd/winbindd_dual.c >+++ b/source3/winbindd/winbindd_dual.c >@@ -1713,7 +1713,7 @@ static bool fork_domain_child(struct winbindd_child *child) > > if (child_domain != NULL) { > setproctitle("domain child [%s]", child_domain->name); >- } else if (child == idmap_child()) { >+ } else if (is_idmap_child(child)) { > setproctitle("idmap child"); > } > >@@ -1759,7 +1759,7 @@ static bool fork_domain_child(struct winbindd_child *child) > * We are in idmap child, make sure that we set the > * check_online_event to bring primary domain online. > */ >- if (child == idmap_child()) { >+ if (is_idmap_child(child)) { > set_domain_online_request(primary_domain); > } > >diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c >index 965a7839f17..bd5f3a67aad 100644 >--- a/source3/winbindd/winbindd_idmap.c >+++ b/source3/winbindd/winbindd_idmap.c >@@ -34,6 +34,15 @@ struct winbindd_child *idmap_child(void) > return &static_idmap_child; > } > >+bool is_idmap_child(const struct winbindd_child *child) >+{ >+ if (child == &static_idmap_child) { >+ return true; >+ } >+ >+ return false; >+} >+ > pid_t idmap_child_pid(void) > { > return static_idmap_child.pid; >diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h >index 95d7376f93c..ed2a9dc652b 100644 >--- a/source3/winbindd/winbindd_proto.h >+++ b/source3/winbindd/winbindd_proto.h >@@ -359,6 +359,7 @@ NTSTATUS winbindd_print_groupmembers(struct db_context *members, > > void init_idmap_child(void); > struct winbindd_child *idmap_child(void); >+bool is_idmap_child(const struct winbindd_child *child); > pid_t idmap_child_pid(void); > struct dcerpc_binding_handle *idmap_child_handle(void); > struct idmap_domain *idmap_find_domain_with_sid(const char *domname, >-- >2.25.1 > > >From f3e3711b72150c0391b20f6ec3aacb621c6d0b29 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Sep 2020 12:16:00 +0200 >Subject: [PATCH 411/686] CVE-2020-25717 winbindd: add generic > wb_parent_idmap_setup_send/recv() helpers > >This is more or less a copy of wb_xids2sids_init_dom_maps_send/recv, >but it's more generic and doesn't imply global state. > >It also closes a initialization race by using a tevent_queue to >serialize the calls. > >In the next commits we'll replace wb_xids2sids_init_dom_maps_send/recv. > >We'll also use the new function in the wb_sids2xids code. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 209e81a2ea8c972ee57e2f0c9579da843c0e2ac7) >--- > source3/winbindd/winbindd.h | 13 ++ > source3/winbindd/winbindd_idmap.c | 314 ++++++++++++++++++++++++++++++ > source3/winbindd/winbindd_proto.h | 5 + > 3 files changed, 332 insertions(+) > >diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h >index a72d6aa7830..480ba4f1282 100644 >--- a/source3/winbindd/winbindd.h >+++ b/source3/winbindd/winbindd.h >@@ -189,6 +189,19 @@ struct winbindd_domain { > struct winbindd_domain *prev, *next; > }; > >+struct wb_parent_idmap_config_dom { >+ unsigned low_id; >+ unsigned high_id; >+ const char *name; >+ struct dom_sid sid; >+}; >+ >+struct wb_parent_idmap_config { >+ struct tevent_queue *queue; >+ uint32_t num_doms; >+ struct wb_parent_idmap_config_dom *doms; >+}; >+ > struct wb_acct_info { > const char *acct_name; /* account name */ > const char *acct_desc; /* account name */ >diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c >index bd5f3a67aad..487f27fd94d 100644 >--- a/source3/winbindd/winbindd_idmap.c >+++ b/source3/winbindd/winbindd_idmap.c >@@ -23,12 +23,21 @@ > > #include "includes.h" > #include "winbindd.h" >+#include "../libcli/security/security.h" >+#include "passdb/lookup_sid.h" > > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_WINBIND > > static struct winbindd_child static_idmap_child; > >+/* >+ * Map idmap ranges to domain names, taken from smb.conf. This is >+ * stored in the parent winbind and used to assemble xids2sids/sids2xids calls >+ * into per-idmap-domain chunks. >+ */ >+static struct wb_parent_idmap_config static_parent_idmap_config; >+ > struct winbindd_child *idmap_child(void) > { > return &static_idmap_child; >@@ -73,3 +82,308 @@ void init_idmap_child(void) > idmap_dispatch_table, > "log.winbindd", "idmap"); > } >+ >+struct wb_parent_idmap_setup_state { >+ struct tevent_context *ev; >+ struct wb_parent_idmap_config *cfg; >+ size_t dom_idx; >+}; >+ >+static void wb_parent_idmap_setup_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state) >+{ >+ struct wb_parent_idmap_setup_state *state = >+ tevent_req_data(req, >+ struct wb_parent_idmap_setup_state); >+ >+ if (req_state == TEVENT_REQ_DONE) { >+ state->cfg = NULL; >+ return; >+ } >+ >+ if (state->cfg == NULL) { >+ return; >+ } >+ >+ state->cfg->num_doms = 0; >+ TALLOC_FREE(state->cfg->doms); >+ state->cfg = NULL; >+} >+ >+static void wb_parent_idmap_setup_queue_wait_done(struct tevent_req *subreq); >+static bool wb_parent_idmap_setup_scan_config(const char *domname, >+ void *private_data); >+static void wb_parent_idmap_setup_lookupname_next(struct tevent_req *req); >+static void wb_parent_idmap_setup_lookupname_done(struct tevent_req *subreq); >+ >+struct tevent_req *wb_parent_idmap_setup_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev) >+{ >+ struct tevent_req *req = NULL; >+ struct wb_parent_idmap_setup_state *state = NULL; >+ struct tevent_req *subreq = NULL; >+ >+ req = tevent_req_create(mem_ctx, &state, >+ struct wb_parent_idmap_setup_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ *state = (struct wb_parent_idmap_setup_state) { >+ .ev = ev, >+ .cfg = &static_parent_idmap_config, >+ .dom_idx = 0, >+ }; >+ >+ if (state->cfg->queue == NULL) { >+ state->cfg->queue = tevent_queue_create(NULL, >+ "wb_parent_idmap_config_queue"); >+ if (tevent_req_nomem(state->cfg->queue, req)) { >+ return tevent_req_post(req, ev); >+ } >+ } >+ >+ subreq = tevent_queue_wait_send(state, state->ev, state->cfg->queue); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, >+ wb_parent_idmap_setup_queue_wait_done, >+ req); >+ >+ return req; >+} >+ >+static void wb_parent_idmap_setup_queue_wait_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = >+ tevent_req_callback_data(subreq, >+ struct tevent_req); >+ struct wb_parent_idmap_setup_state *state = >+ tevent_req_data(req, >+ struct wb_parent_idmap_setup_state); >+ bool ok; >+ >+ /* >+ * Note we don't call TALLOC_FREE(subreq) here in order to block the >+ * queue until tevent_req_received() in wb_parent_idmap_setup_recv() >+ * will destroy it implicitly. >+ */ >+ ok = tevent_queue_wait_recv(subreq); >+ if (!ok) { >+ DBG_ERR("tevent_queue_wait_recv() failed\n"); >+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >+ return; >+ } >+ >+ if (state->cfg->num_doms != 0) { >+ /* >+ * If we're not the first one we're done. >+ */ >+ tevent_req_done(req); >+ return; >+ } >+ >+ /* >+ * From this point we start changing state->cfg, >+ * which is &static_parent_idmap_config, >+ * so we better setup a cleanup function >+ * to undo the changes on failure. >+ */ >+ tevent_req_set_cleanup_fn(req, wb_parent_idmap_setup_cleanup); >+ >+ /* >+ * Put the passdb idmap domain first. We always need to try >+ * there first. >+ */ >+ state->cfg->doms = talloc_zero_array(NULL, >+ struct wb_parent_idmap_config_dom, >+ 1); >+ if (tevent_req_nomem(state->cfg->doms, req)) { >+ return; >+ } >+ state->cfg->doms[0].low_id = 0; >+ state->cfg->doms[0].high_id = UINT_MAX; >+ state->cfg->doms[0].name = talloc_strdup(state->cfg->doms, >+ get_global_sam_name()); >+ if (tevent_req_nomem(state->cfg->doms[0].name, req)) { >+ return; >+ } >+ state->cfg->num_doms += 1; >+ >+ lp_scan_idmap_domains(wb_parent_idmap_setup_scan_config, req); >+ if (!tevent_req_is_in_progress(req)) { >+ return; >+ } >+ >+ wb_parent_idmap_setup_lookupname_next(req); >+} >+ >+static bool wb_parent_idmap_setup_scan_config(const char *domname, >+ void *private_data) >+{ >+ struct tevent_req *req = >+ talloc_get_type_abort(private_data, >+ struct tevent_req); >+ struct wb_parent_idmap_setup_state *state = >+ tevent_req_data(req, >+ struct wb_parent_idmap_setup_state); >+ struct wb_parent_idmap_config_dom *map = NULL; >+ size_t i; >+ const char *range; >+ unsigned low_id, high_id; >+ int ret; >+ >+ range = idmap_config_const_string(domname, "range", NULL); >+ if (range == NULL) { >+ DBG_DEBUG("No range for domain %s found\n", domname); >+ return false; >+ } >+ >+ ret = sscanf(range, "%u - %u", &low_id, &high_id); >+ if (ret != 2) { >+ DBG_DEBUG("Invalid range spec \"%s\" for domain %s\n", >+ range, domname); >+ return false; >+ } >+ >+ if (low_id > high_id) { >+ DBG_DEBUG("Invalid range %u - %u for domain %s\n", >+ low_id, high_id, domname); >+ return false; >+ } >+ >+ for (i=0; i<state->cfg->num_doms; i++) { >+ if (strequal(domname, state->cfg->doms[i].name)) { >+ map = &state->cfg->doms[i]; >+ break; >+ } >+ } >+ >+ if (map == NULL) { >+ struct wb_parent_idmap_config_dom *tmp; >+ char *name; >+ >+ name = talloc_strdup(state, domname); >+ if (name == NULL) { >+ DBG_ERR("talloc failed\n"); >+ return false; >+ } >+ >+ tmp = talloc_realloc( >+ NULL, state->cfg->doms, struct wb_parent_idmap_config_dom, >+ state->cfg->num_doms+1); >+ if (tmp == NULL) { >+ DBG_ERR("talloc failed\n"); >+ return false; >+ } >+ state->cfg->doms = tmp; >+ >+ map = &state->cfg->doms[state->cfg->num_doms]; >+ state->cfg->num_doms += 1; >+ ZERO_STRUCTP(map); >+ map->name = talloc_move(state->cfg->doms, &name); >+ } >+ >+ map->low_id = low_id; >+ map->high_id = high_id; >+ >+ return false; >+} >+ >+static void wb_parent_idmap_setup_lookupname_next(struct tevent_req *req) >+{ >+ struct wb_parent_idmap_setup_state *state = >+ tevent_req_data(req, >+ struct wb_parent_idmap_setup_state); >+ struct wb_parent_idmap_config_dom *dom = >+ &state->cfg->doms[state->dom_idx]; >+ struct tevent_req *subreq = NULL; >+ >+ next_domain: >+ if (state->dom_idx == state->cfg->num_doms) { >+ tevent_req_done(req); >+ return; >+ } >+ >+ if (strequal(dom->name, "*")) { >+ state->dom_idx++; >+ goto next_domain; >+ } >+ >+ subreq = wb_lookupname_send(state, >+ state->ev, >+ dom->name, >+ dom->name, >+ "", >+ LOOKUP_NAME_NO_NSS); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, >+ wb_parent_idmap_setup_lookupname_done, >+ req); >+} >+ >+static void wb_parent_idmap_setup_lookupname_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = >+ tevent_req_callback_data(subreq, >+ struct tevent_req); >+ struct wb_parent_idmap_setup_state *state = >+ tevent_req_data(req, >+ struct wb_parent_idmap_setup_state); >+ struct wb_parent_idmap_config_dom *dom = >+ &state->cfg->doms[state->dom_idx]; >+ enum lsa_SidType type; >+ NTSTATUS status; >+ >+ status = wb_lookupname_recv(subreq, &dom->sid, &type); >+ TALLOC_FREE(subreq); >+ if (!NT_STATUS_IS_OK(status)) { >+ DBG_ERR("Lookup domain name '%s' failed '%s'\n", >+ dom->name, >+ nt_errstr(status)); >+ >+ state->dom_idx++; >+ wb_parent_idmap_setup_lookupname_next(req); >+ return; >+ } >+ >+ if (type != SID_NAME_DOMAIN) { >+ struct dom_sid_buf buf; >+ >+ DBG_ERR("SID %s for idmap domain name '%s' " >+ "not a domain SID\n", >+ dom_sid_str_buf(&dom->sid, &buf), >+ dom->name); >+ >+ ZERO_STRUCT(dom->sid); >+ } >+ >+ state->dom_idx++; >+ wb_parent_idmap_setup_lookupname_next(req); >+ >+ return; >+} >+ >+NTSTATUS wb_parent_idmap_setup_recv(struct tevent_req *req, >+ const struct wb_parent_idmap_config **_cfg) >+{ >+ const struct wb_parent_idmap_config *cfg = &static_parent_idmap_config; >+ NTSTATUS status; >+ >+ *_cfg = NULL; >+ >+ if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); >+ return status; >+ } >+ >+ /* >+ * Note state->cfg is already set to NULL by >+ * wb_parent_idmap_setup_cleanup() >+ */ >+ *_cfg = cfg; >+ tevent_req_received(req); >+ return NT_STATUS_OK; >+} >diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h >index ed2a9dc652b..5673bf5bfce 100644 >--- a/source3/winbindd/winbindd_proto.h >+++ b/source3/winbindd/winbindd_proto.h >@@ -357,6 +357,11 @@ NTSTATUS winbindd_print_groupmembers(struct db_context *members, > > /* The following definitions come from winbindd/winbindd_idmap.c */ > >+struct tevent_req *wb_parent_idmap_setup_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev); >+NTSTATUS wb_parent_idmap_setup_recv(struct tevent_req *req, >+ const struct wb_parent_idmap_config **_cfg); >+ > void init_idmap_child(void); > struct winbindd_child *idmap_child(void); > bool is_idmap_child(const struct winbindd_child *child); >-- >2.25.1 > > >From 73cc90d9a4894935d998e98eea4e1ef066e91fba Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Sep 2020 12:31:13 +0200 >Subject: [PATCH 412/686] CVE-2020-25717 wb_xids2sids: make use of the new > wb_parent_idmap_setup_send/recv() helpers > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit a8f57c94fc2294c309ecb18ea79d0acac86c495b) >--- > source3/winbindd/wb_xids2sids.c | 255 +++----------------------------- > 1 file changed, 17 insertions(+), 238 deletions(-) > >diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c >index c332823dd1d..fc5d363dac2 100644 >--- a/source3/winbindd/wb_xids2sids.c >+++ b/source3/winbindd/wb_xids2sids.c >@@ -25,231 +25,13 @@ > #include "librpc/gen_ndr/ndr_netlogon.h" > #include "passdb/lookup_sid.h" > >-struct wb_xids2sids_dom_map { >- unsigned low_id; >- unsigned high_id; >- const char *name; >- struct dom_sid sid; >-}; >- >-/* >- * Map idmap ranges to domain names, taken from smb.conf. This is >- * stored in the parent winbind and used to assemble xid2sid calls >- * into per-idmap-domain chunks. >- */ >-static struct wb_xids2sids_dom_map *dom_maps; >- >-static bool wb_xids2sids_add_dom(const char *domname, >- void *private_data) >-{ >- struct wb_xids2sids_dom_map *map = NULL; >- size_t num_maps = talloc_array_length(dom_maps); >- size_t i; >- const char *range; >- unsigned low_id, high_id; >- int ret; >- >- range = idmap_config_const_string(domname, "range", NULL); >- if (range == NULL) { >- DBG_DEBUG("No range for domain %s found\n", domname); >- return false; >- } >- >- ret = sscanf(range, "%u - %u", &low_id, &high_id); >- if (ret != 2) { >- DBG_DEBUG("Invalid range spec \"%s\" for domain %s\n", >- range, domname); >- return false; >- } >- >- if (low_id > high_id) { >- DBG_DEBUG("Invalid range %u - %u for domain %s\n", >- low_id, high_id, domname); >- return false; >- } >- >- for (i=0; i<num_maps; i++) { >- if (strequal(domname, dom_maps[i].name)) { >- map = &dom_maps[i]; >- break; >- } >- } >- >- if (map == NULL) { >- struct wb_xids2sids_dom_map *tmp; >- char *name; >- >- name = talloc_strdup(talloc_tos(), domname); >- if (name == NULL) { >- DBG_DEBUG("talloc failed\n"); >- return false; >- } >- >- tmp = talloc_realloc( >- NULL, dom_maps, struct wb_xids2sids_dom_map, >- num_maps+1); >- if (tmp == NULL) { >- TALLOC_FREE(name); >- return false; >- } >- dom_maps = tmp; >- >- map = &dom_maps[num_maps]; >- ZERO_STRUCTP(map); >- map->name = talloc_move(dom_maps, &name); >- } >- >- map->low_id = low_id; >- map->high_id = high_id; >- >- return false; >-} >- >-struct wb_xids2sids_init_dom_maps_state { >- struct tevent_context *ev; >- struct tevent_req *req; >- size_t dom_idx; >-}; >- >-static void wb_xids2sids_init_dom_maps_lookupname_next( >- struct wb_xids2sids_init_dom_maps_state *state); >- >-static void wb_xids2sids_init_dom_maps_lookupname_done( >- struct tevent_req *subreq); >- >-static struct tevent_req *wb_xids2sids_init_dom_maps_send( >- TALLOC_CTX *mem_ctx, struct tevent_context *ev) >-{ >- struct tevent_req *req = NULL; >- struct wb_xids2sids_init_dom_maps_state *state = NULL; >- >- req = tevent_req_create(mem_ctx, &state, >- struct wb_xids2sids_init_dom_maps_state); >- if (req == NULL) { >- return NULL; >- } >- *state = (struct wb_xids2sids_init_dom_maps_state) { >- .ev = ev, >- .req = req, >- .dom_idx = 0, >- }; >- >- if (dom_maps != NULL) { >- tevent_req_done(req); >- return tevent_req_post(req, ev); >- } >- /* >- * Put the passdb idmap domain first. We always need to try >- * there first. >- */ >- >- dom_maps = talloc_zero_array(NULL, struct wb_xids2sids_dom_map, 1); >- if (tevent_req_nomem(dom_maps, req)) { >- return tevent_req_post(req, ev); >- } >- dom_maps[0].low_id = 0; >- dom_maps[0].high_id = UINT_MAX; >- dom_maps[0].name = talloc_strdup(dom_maps, get_global_sam_name()); >- if (tevent_req_nomem(dom_maps[0].name, req)) { >- TALLOC_FREE(dom_maps); >- return tevent_req_post(req, ev); >- } >- >- lp_scan_idmap_domains(wb_xids2sids_add_dom, NULL); >- >- wb_xids2sids_init_dom_maps_lookupname_next(state); >- if (!tevent_req_is_in_progress(req)) { >- tevent_req_post(req, ev); >- } >- return req; >-} >- >-static void wb_xids2sids_init_dom_maps_lookupname_next( >- struct wb_xids2sids_init_dom_maps_state *state) >-{ >- struct tevent_req *subreq = NULL; >- >- if (state->dom_idx == talloc_array_length(dom_maps)) { >- tevent_req_done(state->req); >- return; >- } >- >- if (strequal(dom_maps[state->dom_idx].name, "*")) { >- state->dom_idx++; >- if (state->dom_idx == talloc_array_length(dom_maps)) { >- tevent_req_done(state->req); >- return; >- } >- } >- >- subreq = wb_lookupname_send(state, >- state->ev, >- dom_maps[state->dom_idx].name, >- dom_maps[state->dom_idx].name, >- "", >- LOOKUP_NAME_NO_NSS); >- if (tevent_req_nomem(subreq, state->req)) { >- return; >- } >- tevent_req_set_callback(subreq, >- wb_xids2sids_init_dom_maps_lookupname_done, >- state->req); >-} >- >-static void wb_xids2sids_init_dom_maps_lookupname_done( >- struct tevent_req *subreq) >-{ >- struct tevent_req *req = tevent_req_callback_data( >- subreq, struct tevent_req); >- struct wb_xids2sids_init_dom_maps_state *state = tevent_req_data( >- req, struct wb_xids2sids_init_dom_maps_state); >- enum lsa_SidType type; >- NTSTATUS status; >- >- status = wb_lookupname_recv(subreq, >- &dom_maps[state->dom_idx].sid, >- &type); >- TALLOC_FREE(subreq); >- if (!NT_STATUS_IS_OK(status)) { >- DBG_WARNING("Lookup domain name '%s' failed '%s'\n", >- dom_maps[state->dom_idx].name, >- nt_errstr(status)); >- >- state->dom_idx++; >- wb_xids2sids_init_dom_maps_lookupname_next(state); >- return; >- } >- >- if (type != SID_NAME_DOMAIN) { >- struct dom_sid_buf buf; >- >- DBG_WARNING("SID %s for idmap domain name '%s' " >- "not a domain SID\n", >- dom_sid_str_buf(&dom_maps[state->dom_idx].sid, >- &buf), >- dom_maps[state->dom_idx].name); >- >- ZERO_STRUCT(dom_maps[state->dom_idx].sid); >- } >- >- state->dom_idx++; >- wb_xids2sids_init_dom_maps_lookupname_next(state); >- >- return; >-} >- >-static NTSTATUS wb_xids2sids_init_dom_maps_recv(struct tevent_req *req) >-{ >- return tevent_req_simple_recv_ntstatus(req); >-} >- > struct wb_xids2sids_dom_state { > struct tevent_context *ev; > struct unixid *all_xids; > const bool *cached; > size_t num_all_xids; > struct dom_sid *all_sids; >- struct wb_xids2sids_dom_map *dom_map; >+ const struct wb_parent_idmap_config_dom *dom_map; > bool tried_dclookup; > > size_t num_dom_xids; >@@ -262,7 +44,7 @@ static void wb_xids2sids_dom_gotdc(struct tevent_req *subreq); > > static struct tevent_req *wb_xids2sids_dom_send( > TALLOC_CTX *mem_ctx, struct tevent_context *ev, >- struct wb_xids2sids_dom_map *dom_map, >+ const struct wb_parent_idmap_config_dom *dom_map, > struct unixid *xids, > const bool *cached, > size_t num_xids, >@@ -334,7 +116,7 @@ static void wb_xids2sids_dom_done(struct tevent_req *subreq) > subreq, struct tevent_req); > struct wb_xids2sids_dom_state *state = tevent_req_data( > req, struct wb_xids2sids_dom_state); >- struct wb_xids2sids_dom_map *dom_map = state->dom_map; >+ const struct wb_parent_idmap_config_dom *dom_map = state->dom_map; > NTSTATUS status, result; > size_t i; > size_t dom_sid_idx; >@@ -437,10 +219,11 @@ struct wb_xids2sids_state { > bool *cached; > > size_t dom_idx; >+ const struct wb_parent_idmap_config *cfg; > }; > >+static void wb_xids2sids_idmap_setup_done(struct tevent_req *subreq); > static void wb_xids2sids_done(struct tevent_req *subreq); >-static void wb_xids2sids_init_dom_maps_done(struct tevent_req *subreq); > > struct tevent_req *wb_xids2sids_send(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >@@ -490,38 +273,32 @@ struct tevent_req *wb_xids2sids_send(TALLOC_CTX *mem_ctx, > } > } > >- subreq = wb_xids2sids_init_dom_maps_send( >- state, state->ev); >+ subreq = wb_parent_idmap_setup_send(state, state->ev); > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, wb_xids2sids_init_dom_maps_done, req); >+ tevent_req_set_callback(subreq, wb_xids2sids_idmap_setup_done, req); > return req; > } > >-static void wb_xids2sids_init_dom_maps_done(struct tevent_req *subreq) >+static void wb_xids2sids_idmap_setup_done(struct tevent_req *subreq) > { > struct tevent_req *req = tevent_req_callback_data( > subreq, struct tevent_req); > struct wb_xids2sids_state *state = tevent_req_data( > req, struct wb_xids2sids_state); >- size_t num_domains; > NTSTATUS status; > >- status = wb_xids2sids_init_dom_maps_recv(subreq); >+ status = wb_parent_idmap_setup_recv(subreq, &state->cfg); > TALLOC_FREE(subreq); > if (tevent_req_nterror(req, status)) { > return; > } >- >- num_domains = talloc_array_length(dom_maps); >- if (num_domains == 0) { >- tevent_req_done(req); >- return; >- } >+ SMB_ASSERT(state->cfg->num_doms > 0); > > subreq = wb_xids2sids_dom_send( >- state, state->ev, &dom_maps[state->dom_idx], >+ state, state->ev, >+ &state->cfg->doms[state->dom_idx], > state->xids, state->cached, state->num_xids, state->sids); > if (tevent_req_nomem(subreq, req)) { > return; >@@ -536,7 +313,6 @@ static void wb_xids2sids_done(struct tevent_req *subreq) > subreq, struct tevent_req); > struct wb_xids2sids_state *state = tevent_req_data( > req, struct wb_xids2sids_state); >- size_t num_domains = talloc_array_length(dom_maps); > size_t i; > NTSTATUS status; > >@@ -548,10 +324,13 @@ static void wb_xids2sids_done(struct tevent_req *subreq) > > state->dom_idx += 1; > >- if (state->dom_idx < num_domains) { >+ if (state->dom_idx < state->cfg->num_doms) { >+ const struct wb_parent_idmap_config_dom *dom_map = >+ &state->cfg->doms[state->dom_idx]; >+ > subreq = wb_xids2sids_dom_send(state, > state->ev, >- &dom_maps[state->dom_idx], >+ dom_map, > state->xids, > state->cached, > state->num_xids, >-- >2.25.1 > > >From f948830a72d6b846cca25bb3d46757b05e60057e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Sep 2020 12:52:40 +0200 >Subject: [PATCH 413/686] CVE-2020-25717 wb_sids2xids: call > wb_parent_idmap_setup_send/recv as the first step > >This isn't really used yet, but it will in the next commits. > >Also idmap_child_handle() will soon assert that >wb_parent_idmap_setup_send/recv() was called before it's used. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit d42aaeba6e0820acd17f204ff7ab6d1aede1b303) >--- > source3/winbindd/wb_sids2xids.c | 34 +++++++++++++++++++++++++++++---- > 1 file changed, 30 insertions(+), 4 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index b47856520ea..59f6ba5891e 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -29,6 +29,8 @@ > struct wb_sids2xids_state { > struct tevent_context *ev; > >+ const struct wb_parent_idmap_config *cfg; >+ > struct dom_sid *sids; > uint32_t num_sids; > >@@ -58,7 +60,7 @@ struct wb_sids2xids_state { > struct wbint_TransIDArray ids; > }; > >- >+static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq); > static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map); > static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq); > static void wb_sids2xids_done(struct tevent_req *subreq); >@@ -126,15 +128,39 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- subreq = wb_lookupsids_send(state, ev, state->non_cached, >- state->num_non_cached); >+ subreq = wb_parent_idmap_setup_send(state, state->ev); > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, wb_sids2xids_lookupsids_done, req); >+ tevent_req_set_callback(subreq, wb_sids2xids_idmap_setup_done, req); > return req; > } > >+static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct wb_sids2xids_state *state = tevent_req_data( >+ req, struct wb_sids2xids_state); >+ NTSTATUS status; >+ >+ status = wb_parent_idmap_setup_recv(subreq, &state->cfg); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ SMB_ASSERT(state->cfg->num_doms > 0); >+ >+ subreq = wb_lookupsids_send(state, >+ state->ev, >+ state->non_cached, >+ state->num_non_cached); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, wb_sids2xids_lookupsids_done, req); >+} >+ > static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map) > { > struct unixid id; >-- >2.25.1 > > >From 98694cdc7431e3ae6286fc31fb4758e74d16c4dd Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Sep 2020 13:52:17 +0200 >Subject: [PATCH 414/686] CVE-2020-25717 wb_queryuser: explain why > wb_parent_idmap_setup_send/recv is not needed > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 82fd07793f065e150729848566e7c30f4f4d472e) >--- > source3/winbindd/wb_queryuser.c | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > >diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c >index 2e36643454b..9db51909c02 100644 >--- a/source3/winbindd/wb_queryuser.c >+++ b/source3/winbindd/wb_queryuser.c >@@ -138,6 +138,11 @@ static void wb_queryuser_got_uid(struct tevent_req *subreq) > return; > } > >+ /* >+ * Note wb_sids2xids_send/recv was called before, >+ * so we're sure that wb_parent_idmap_setup_send/recv >+ * was already called. >+ */ > child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_GetNssInfo_send( > state, state->ev, child_binding_handle, info); >@@ -185,6 +190,11 @@ static void wb_queryuser_got_domain(struct tevent_req *subreq) > return; > } > >+ /* >+ * Note wb_sids2xids_send/recv was called before, >+ * so we're sure that wb_parent_idmap_setup_send/recv >+ * was already called. >+ */ > child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_GetNssInfo_send( > state, state->ev, child_binding_handle, info); >@@ -284,6 +294,11 @@ static void wb_queryuser_got_dc(struct tevent_req *subreq) > return; > } > >+ /* >+ * Note wb_sids2xids_send/recv was called before, >+ * so we're sure that wb_parent_idmap_setup_send/recv >+ * was already called. >+ */ > child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_GetNssInfo_send( > state, state->ev, child_binding_handle, info); >-- >2.25.1 > > >From 51f319ca03176613140c0344b60944b9ee69a879 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Sep 2020 14:12:17 +0200 >Subject: [PATCH 415/686] CVE-2020-25717 winbindd: assert > wb_parent_idmap_setup_send/recv() was called before idmap_child_handle() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit b8c74b7b46d1c7f6b66e565ee08f8c88d6dc2cc4) >--- > source3/winbindd/winbindd_idmap.c | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c >index 487f27fd94d..14836e3b8a0 100644 >--- a/source3/winbindd/winbindd_idmap.c >+++ b/source3/winbindd/winbindd_idmap.c >@@ -59,6 +59,11 @@ pid_t idmap_child_pid(void) > > struct dcerpc_binding_handle *idmap_child_handle(void) > { >+ /* >+ * The caller needs to use wb_parent_idmap_setup_send/recv >+ * before talking to the idmap child! >+ */ >+ SMB_ASSERT(static_parent_idmap_config.num_doms > 0); > return static_idmap_child.binding_handle; > } > >-- >2.25.1 > > >From 4ac6d83081a834a823a331848d93ce2096977ff7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Sep 2020 15:42:42 +0200 >Subject: [PATCH 416/686] CVE-2020-25717 winbindd: defer the setup_child() from > init_idmap_child() > >At startup we trigger a wb_parent_idmap_setup_send() and make >sure setup_child() is called just before wb_parent_idmap_setup_recv() >finished. > >This makes sure our view of the idmap config in the parent matches >what we have in the child. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 28e020c0a863411cfa95e3b1ed943d922b8635bd) >--- > source3/winbindd/winbindd_idmap.c | 45 ++++++++++++++++++++++++++++--- > 1 file changed, 42 insertions(+), 3 deletions(-) > >diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c >index 14836e3b8a0..3e2461478a9 100644 >--- a/source3/winbindd/winbindd_idmap.c >+++ b/source3/winbindd/winbindd_idmap.c >@@ -81,11 +81,44 @@ static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = { > } > }; > >+static void init_idmap_child_done(struct tevent_req *subreq); >+ > void init_idmap_child(void) > { >- setup_child(NULL, &static_idmap_child, >- idmap_dispatch_table, >- "log.winbindd", "idmap"); >+ struct tevent_req *subreq = NULL; >+ >+ subreq = wb_parent_idmap_setup_send(global_event_context(), >+ global_event_context()); >+ if (subreq == NULL) { >+ /* >+ * This is only an optimization, so we're free to >+ * to ignore errors >+ */ >+ DBG_ERR("wb_parent_idmap_setup_send() failed\n"); >+ return; >+ } >+ tevent_req_set_callback(subreq, init_idmap_child_done, NULL); >+ DBG_DEBUG("wb_parent_idmap_setup_send() started\n"); >+} >+ >+static void init_idmap_child_done(struct tevent_req *subreq) >+{ >+ const struct wb_parent_idmap_config *cfg = NULL; >+ NTSTATUS status; >+ >+ status = wb_parent_idmap_setup_recv(subreq, &cfg); >+ TALLOC_FREE(subreq); >+ if (!NT_STATUS_IS_OK(status)) { >+ /* >+ * This is only an optimization, so we're free to >+ * to ignore errors >+ */ >+ DBG_ERR("wb_parent_idmap_setup_recv() failed %s\n", >+ nt_errstr(status)); >+ return; >+ } >+ >+ DBG_DEBUG("wb_parent_idmap_setup_recv() finished\n"); > } > > struct wb_parent_idmap_setup_state { >@@ -306,6 +339,12 @@ static void wb_parent_idmap_setup_lookupname_next(struct tevent_req *req) > > next_domain: > if (state->dom_idx == state->cfg->num_doms) { >+ /* >+ * We're done, so start the idmap child >+ */ >+ setup_child(NULL, &static_idmap_child, >+ idmap_dispatch_table, >+ "log.winbindd", "idmap"); > tevent_req_done(req); > return; > } >-- >2.25.1 > > >From d90c2c76b640b0cd1c7d54a9aac1256efbc7972c Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 3 Jul 2020 16:39:26 +0200 >Subject: [PATCH 417/686] CVE-2020-25717 wb_sids2xids: split out > wb_sids2xids_next_sids2unix() > >Put the code that calls the per-domain idmap backend >in its own function. > >This makes further reconstruction easier. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Ralph Boehme <slow@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 79c1d3aaf6d465a8edd1871edb85211f8715fea1) >--- > source3/winbindd/wb_sids2xids.c | 34 ++++++++++++--------------------- > 1 file changed, 12 insertions(+), 22 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index 59f6ba5891e..725fd857ef5 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -65,6 +65,7 @@ static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map); > static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq); > static void wb_sids2xids_done(struct tevent_req *subreq); > static void wb_sids2xids_gotdc(struct tevent_req *subreq); >+static void wb_sids2xids_next_sids2unix(struct tevent_req *req); > > struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >@@ -194,7 +195,6 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > req, struct wb_sids2xids_state); > struct lsa_RefDomainList *domains = NULL; > struct lsa_TransNameArray *names = NULL; >- struct dcerpc_binding_handle *child_binding_handle = NULL; > NTSTATUS status; > uint32_t i; > >@@ -264,6 +264,16 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > TALLOC_FREE(names); > TALLOC_FREE(domains); > >+ wb_sids2xids_next_sids2unix(req); >+} >+ >+static void wb_sids2xids_next_sids2unix(struct tevent_req *req) >+{ >+ struct wb_sids2xids_state *state = tevent_req_data( >+ req, struct wb_sids2xids_state); >+ struct tevent_req *subreq = NULL; >+ struct dcerpc_binding_handle *child_binding_handle = NULL; >+ > state->dom_ids = wb_sids2xids_extract_for_domain_index( > state, &state->ids, state->dom_index); > if (tevent_req_nomem(state->dom_ids, req)) { >@@ -315,7 +325,6 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > struct wb_sids2xids_state *state = tevent_req_data( > req, struct wb_sids2xids_state); > NTSTATUS status, result; >- struct dcerpc_binding_handle *child_binding_handle = NULL; > struct wbint_TransIDArray *src, *dst; > uint32_t i, src_idx; > >@@ -376,26 +385,7 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > return; > } > >- state->dom_ids = wb_sids2xids_extract_for_domain_index( >- state, &state->ids, state->dom_index); >- if (tevent_req_nomem(state->dom_ids, req)) { >- return; >- } >- >- state->idmap_dom = (struct lsa_RefDomainList) { >- .count = 1, >- .domains = &state->idmap_doms.domains[state->dom_index], >- .max_size = 1 >- }; >- >- child_binding_handle = idmap_child_handle(); >- subreq = dcerpc_wbint_Sids2UnixIDs_send( >- state, state->ev, child_binding_handle, &state->idmap_dom, >- state->dom_ids); >- if (tevent_req_nomem(subreq, req)) { >- return; >- } >- tevent_req_set_callback(subreq, wb_sids2xids_done, req); >+ wb_sids2xids_next_sids2unix(req); > } > > static void wb_sids2xids_gotdc(struct tevent_req *subreq) >-- >2.25.1 > > >From 59e58a1701af0078a1f8ffbcf5a82c58281e7d88 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Sep 2020 16:45:03 +0200 >Subject: [PATCH 418/686] CVE-2020-25717 wb_sids2xids: maintain struct > wbint_TransIDArray all_ids as cache > >Entries with domain_index == UINT32_MAX are valid cache entries. > >In the following commits we'll fill in missing entries step by step >until all entries are marked as filled. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 04956350a5725325954b2caba662ecd6dace7829) >--- > source3/winbindd/wb_sids2xids.c | 49 ++++++++++++++++++++++++++++----- > 1 file changed, 42 insertions(+), 7 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index 725fd857ef5..770a7f0d8b0 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -34,7 +34,7 @@ struct wb_sids2xids_state { > struct dom_sid *sids; > uint32_t num_sids; > >- struct id_map *cached; >+ struct wbint_TransIDArray all_ids; > > struct dom_sid *non_cached; > uint32_t num_non_cached; >@@ -75,6 +75,7 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > struct tevent_req *req, *subreq; > struct wb_sids2xids_state *state; > uint32_t i; >+ uint32_t num_valid = 0; > > req = tevent_req_create(mem_ctx, &state, > struct wb_sids2xids_state); >@@ -95,8 +96,9 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > sid_copy(&state->sids[i], &sids[i]); > } > >- state->cached = talloc_zero_array(state, struct id_map, num_sids); >- if (tevent_req_nomem(state->cached, req)) { >+ state->all_ids.num_ids = num_sids; >+ state->all_ids.ids = talloc_zero_array(state, struct wbint_TransID, num_sids); >+ if (tevent_req_nomem(state->all_ids.ids, req)) { > return tevent_req_post(req, ev); > } > >@@ -111,20 +113,53 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > * the same index. > */ > for (i=0; i<state->num_sids; i++) { >+ struct wbint_TransID *cur_id = &state->all_ids.ids[i]; >+ struct dom_sid domain_sid; > struct dom_sid_buf buf; >+ struct id_map map = { .status = ID_UNMAPPED, }; >+ uint32_t rid = 0; >+ bool in_cache; >+ >+ sid_copy(&domain_sid, &state->sids[i]); >+ sid_split_rid(&domain_sid, &rid); >+ >+ /* >+ * Start with an invalid entry. >+ */ >+ *cur_id = (struct wbint_TransID) { >+ .type_hint = ID_TYPE_NOT_SPECIFIED, >+ .domain_index = UINT32_MAX - 1, /* invalid */ >+ .rid = rid, >+ .xid = { >+ .id = UINT32_MAX, >+ .type = ID_TYPE_NOT_SPECIFIED, >+ }, >+ }; > > DEBUG(10, ("SID %d: %s\n", (int)i, > dom_sid_str_buf(&state->sids[i], &buf))); > >- if (wb_sids2xids_in_cache(&state->sids[i], &state->cached[i])) { >+ in_cache = wb_sids2xids_in_cache(&state->sids[i], &map); >+ if (in_cache) { >+ /* >+ * We used to ignore map.status and just rely >+ * on map.xid.type. >+ * >+ * Lets keep this logic for now... >+ */ >+ >+ cur_id->xid = map.xid; >+ cur_id->domain_index = UINT32_MAX; /* this marks it as filled entry */ >+ num_valid += 1; > continue; > } >+ > sid_copy(&state->non_cached[state->num_non_cached], > &state->sids[i]); > state->num_non_cached += 1; > } > >- if (state->num_non_cached == 0) { >+ if (num_valid == num_sids) { > tevent_req_done(req); > return tevent_req_post(req, ev); > } >@@ -453,8 +488,8 @@ NTSTATUS wb_sids2xids_recv(struct tevent_req *req, > > xid.id = UINT32_MAX; > >- if (state->cached[i].sid != NULL) { >- xid = state->cached[i].xid; >+ if (state->all_ids.ids[i].domain_index == UINT32_MAX) { >+ xid = state->all_ids.ids[i].xid; > } else { > xid = state->ids.ids[num_non_cached].xid; > >-- >2.25.1 > > >From 30c03b95662c27202d45aac3df1f1b090301ae83 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Sep 2020 17:45:24 +0200 >Subject: [PATCH 419/686] CVE-2020-25717 wb_sids2xids: rename 'non_cached' to > 'lookup_sids' > >This array is used to pass to wb_lookupsids_send() >and that will be the only reason to have this in future. > >For now it's used for all non cached sids, but that will >also change in the next commits. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 797b11f198e819300007997ce536bc6d05f19843) >--- > source3/winbindd/wb_sids2xids.c | 34 ++++++++++++++++----------------- > 1 file changed, 16 insertions(+), 18 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index 770a7f0d8b0..2a30eee2c7b 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -36,8 +36,8 @@ struct wb_sids2xids_state { > > struct wbint_TransIDArray all_ids; > >- struct dom_sid *non_cached; >- uint32_t num_non_cached; >+ uint32_t lookup_count; >+ struct dom_sid *lookup_sids; > > /* > * Domain array to use for the idmap call. The output from >@@ -102,8 +102,8 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- state->non_cached = talloc_array(state, struct dom_sid, num_sids); >- if (tevent_req_nomem(state->non_cached, req)) { >+ state->lookup_sids = talloc_zero_array(state, struct dom_sid, num_sids); >+ if (tevent_req_nomem(state->lookup_sids, req)) { > return tevent_req_post(req, ev); > } > >@@ -154,9 +154,9 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > continue; > } > >- sid_copy(&state->non_cached[state->num_non_cached], >+ sid_copy(&state->lookup_sids[state->lookup_count], > &state->sids[i]); >- state->num_non_cached += 1; >+ state->lookup_count += 1; > } > > if (num_valid == num_sids) { >@@ -189,8 +189,8 @@ static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq) > > subreq = wb_lookupsids_send(state, > state->ev, >- state->non_cached, >- state->num_non_cached); >+ state->lookup_sids, >+ state->lookup_count); > if (tevent_req_nomem(subreq, req)) { > return; > } >@@ -239,15 +239,15 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > return; > } > >- state->ids.num_ids = state->num_non_cached; >+ state->ids.num_ids = state->lookup_count; > state->ids.ids = talloc_array(state, struct wbint_TransID, >- state->num_non_cached); >+ state->ids.num_ids); > if (tevent_req_nomem(state->ids.ids, req)) { > return; > } > >- for (i=0; i<state->num_non_cached; i++) { >- const struct dom_sid *sid = &state->non_cached[i]; >+ for (i=0; i<state->lookup_count; i++) { >+ const struct dom_sid *sid = &state->lookup_sids[i]; > struct dom_sid dom_sid; > struct lsa_TranslatedName *n = &names->names[i]; > struct wbint_TransID *t = &state->ids.ids[i]; >@@ -468,7 +468,7 @@ NTSTATUS wb_sids2xids_recv(struct tevent_req *req, > struct wb_sids2xids_state *state = tevent_req_data( > req, struct wb_sids2xids_state); > NTSTATUS status; >- uint32_t i, num_non_cached; >+ uint32_t i, lookup_count = 0; > > if (tevent_req_is_nterror(req, &status)) { > DEBUG(5, ("wb_sids_to_xids failed: %s\n", nt_errstr(status))); >@@ -481,8 +481,6 @@ NTSTATUS wb_sids2xids_recv(struct tevent_req *req, > return NT_STATUS_INTERNAL_ERROR; > } > >- num_non_cached = 0; >- > for (i=0; i<state->num_sids; i++) { > struct unixid xid; > >@@ -491,13 +489,13 @@ NTSTATUS wb_sids2xids_recv(struct tevent_req *req, > if (state->all_ids.ids[i].domain_index == UINT32_MAX) { > xid = state->all_ids.ids[i].xid; > } else { >- xid = state->ids.ids[num_non_cached].xid; >+ xid = state->ids.ids[lookup_count].xid; > > idmap_cache_set_sid2unixid( >- &state->non_cached[num_non_cached], >+ &state->lookup_sids[lookup_count], > &xid); > >- num_non_cached += 1; >+ lookup_count += 1; > } > > xids[i] = xid; >-- >2.25.1 > > >From d09154333a8496b5d5e6834b3e2c738c7c3c38d5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 15 Sep 2020 13:19:14 +0200 >Subject: [PATCH 420/686] CVE-2020-25717 wb_sids2xids: move more checks to > wb_sids2xids_next_sids2unix() > >For the first run this is a no-op, but it simplified the caller. > >We'll call wb_sids2xids_next_sids2unix() in a few more places in future >and it's easier to have this all within wb_sids2xids_next_sids2unix(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 231c8d04b19a1c17937f988d142ca5c0f889d4e0) >--- > source3/winbindd/wb_sids2xids.c | 13 +++++++------ > 1 file changed, 7 insertions(+), 6 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index 2a30eee2c7b..b934425f4fd 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -309,6 +309,13 @@ static void wb_sids2xids_next_sids2unix(struct tevent_req *req) > struct tevent_req *subreq = NULL; > struct dcerpc_binding_handle *child_binding_handle = NULL; > >+ state->tried_dclookup = false; >+ >+ if (state->dom_index == state->idmap_doms.count) { >+ tevent_req_done(req); >+ return; >+ } >+ > state->dom_ids = wb_sids2xids_extract_for_domain_index( > state, &state->ids, state->dom_index); > if (tevent_req_nomem(state->dom_ids, req)) { >@@ -413,12 +420,6 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > TALLOC_FREE(state->dom_ids); > > state->dom_index += 1; >- state->tried_dclookup = false; >- >- if (state->dom_index == state->idmap_doms.count) { >- tevent_req_done(req); >- return; >- } > > wb_sids2xids_next_sids2unix(req); > } >-- >2.25.1 > > >From 45ece1e32618f9274e936d1a4bc7e01491b14fef Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 15 Sep 2020 13:36:43 +0200 >Subject: [PATCH 421/686] CVE-2020-25717 wb_sids2xids: inline > wb_sids2xids_extract_for_domain_index() into wb_sids2xids_next_sids2unix() > >Instead of re-creating the dom_ids element, >we just use a pre-allocated map_ids_in array. > >This is a bit tricky as we need to use map_ids_out as a copy of >map_ids_in, because the _ids argument of dcerpc_wbint_Sids2UnixIDs_send() >in [in,out], which means that _ids->ids is changed between >dcerpc_wbint_Sids2UnixIDs_send() and dcerpc_wbint_Sids2UnixIDs_recv()! > >If the domain doesn't need any mappings, we'll move to the next domain >early, for now this can't happend but it will in future. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit f6bb0ed21f82f2cf1f238f9f00cd049ecf8673af) >--- > source3/winbindd/wb_sids2xids.c | 115 +++++++++++++++++++++----------- > 1 file changed, 75 insertions(+), 40 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index b934425f4fd..aefb9f93ccb 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -39,6 +39,9 @@ struct wb_sids2xids_state { > uint32_t lookup_count; > struct dom_sid *lookup_sids; > >+ struct wbint_TransIDArray map_ids_in; >+ struct wbint_TransIDArray map_ids_out; >+ > /* > * Domain array to use for the idmap call. The output from > * lookupsids cannot be used directly since for migrated >@@ -53,7 +56,6 @@ struct wb_sids2xids_state { > struct lsa_RefDomainList idmap_doms; > > uint32_t dom_index; >- struct wbint_TransIDArray *dom_ids; > struct lsa_RefDomainList idmap_dom; > bool tried_dclookup; > >@@ -107,6 +109,11 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >+ state->map_ids_in.ids = talloc_zero_array(state, struct wbint_TransID, num_sids); >+ if (tevent_req_nomem(state->map_ids_in.ids, req)) { >+ return tevent_req_post(req, ev); >+ } >+ > /* > * Extract those sids that can not be resolved from cache > * into a separate list to be handed to id mapping, keeping >@@ -218,9 +225,6 @@ static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map) > } > > static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type); >-static struct wbint_TransIDArray *wb_sids2xids_extract_for_domain_index( >- TALLOC_CTX *mem_ctx, const struct wbint_TransIDArray *src, >- uint32_t domain_index); > > static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > { >@@ -308,7 +312,11 @@ static void wb_sids2xids_next_sids2unix(struct tevent_req *req) > req, struct wb_sids2xids_state); > struct tevent_req *subreq = NULL; > struct dcerpc_binding_handle *child_binding_handle = NULL; >+ const struct wbint_TransIDArray *src = NULL; >+ struct wbint_TransIDArray *dst = NULL; >+ uint32_t si; > >+ next_domain: > state->tried_dclookup = false; > > if (state->dom_index == state->idmap_doms.count) { >@@ -316,10 +324,23 @@ static void wb_sids2xids_next_sids2unix(struct tevent_req *req) > return; > } > >- state->dom_ids = wb_sids2xids_extract_for_domain_index( >- state, &state->ids, state->dom_index); >- if (tevent_req_nomem(state->dom_ids, req)) { >- return; >+ src = &state->ids; >+ dst = &state->map_ids_in; >+ dst->num_ids = 0; >+ >+ for (si=0; si < src->num_ids; si++) { >+ if (src->ids[si].domain_index != state->dom_index) { >+ continue; >+ } >+ >+ dst->ids[dst->num_ids] = src->ids[si]; >+ dst->ids[dst->num_ids].domain_index = 0; >+ dst->num_ids += 1; >+ } >+ >+ if (dst->num_ids == 0) { >+ state->dom_index += 1; >+ goto next_domain; > } > > state->idmap_dom = (struct lsa_RefDomainList) { >@@ -328,10 +349,23 @@ static void wb_sids2xids_next_sids2unix(struct tevent_req *req) > .max_size = 1 > }; > >+ /* >+ * dcerpc_wbint_Sids2UnixIDs_send/recv will >+ * allocate a new array for the response >+ * and overwrite _ids->ids pointer. >+ * >+ * So we better make a temporary copy >+ * of state->map_ids_in (which contains the request array) >+ * into state->map_ids_out. >+ * >+ * That makes it possible to reuse the pre-allocated >+ * state->map_ids_in.ids array. >+ */ >+ state->map_ids_out = state->map_ids_in; > child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_Sids2UnixIDs_send( > state, state->ev, child_binding_handle, &state->idmap_dom, >- state->dom_ids); >+ &state->map_ids_out); > if (tevent_req_nomem(subreq, req)) { > return; > } >@@ -394,7 +428,7 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > return; > } > >- src = state->dom_ids; >+ src = &state->map_ids_out; > src_idx = 0; > dst = &state->ids; > >@@ -405,11 +439,17 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > /* > * All we can do here is to report "not mapped" > */ >+ src = &state->map_ids_in; > for (i=0; i<src->num_ids; i++) { > src->ids[i].xid.type = ID_TYPE_NOT_SPECIFIED; > } > } > >+ if (src->num_ids != state->map_ids_in.num_ids) { >+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >+ return; >+ } >+ > for (i=0; i<dst->num_ids; i++) { > if (dst->ids[i].domain_index == state->dom_index) { > dst->ids[i].xid = src->ids[src_idx].xid; >@@ -417,7 +457,17 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > } > } > >- TALLOC_FREE(state->dom_ids); >+ state->map_ids_in.num_ids = 0; >+ if (NT_STATUS_IS_OK(status)) { >+ /* >+ * If we got a valid response, we expect >+ * state->map_ids_out.ids to be a new allocated >+ * array, which we want to free early. >+ */ >+ SMB_ASSERT(state->map_ids_out.ids != state->map_ids_in.ids); >+ TALLOC_FREE(state->map_ids_out.ids); >+ } >+ state->map_ids_out = (struct wbint_TransIDArray) { .num_ids = 0, }; > > state->dom_index += 1; > >@@ -453,10 +503,23 @@ static void wb_sids2xids_gotdc(struct tevent_req *subreq) > } > } > >+ /* >+ * dcerpc_wbint_Sids2UnixIDs_send/recv will >+ * allocate a new array for the response >+ * and overwrite _ids->ids pointer. >+ * >+ * So we better make a temporary copy >+ * of state->map_ids_in (which contains the request array) >+ * into state->map_ids_out. >+ * >+ * That makes it possible to reuse the pre-allocated >+ * state->map_ids_in.ids array. >+ */ >+ state->map_ids_out = state->map_ids_in; > child_binding_handle = idmap_child_handle(); > subreq = dcerpc_wbint_Sids2UnixIDs_send( > state, state->ev, child_binding_handle, &state->idmap_dom, >- state->dom_ids); >+ &state->map_ids_out); > if (tevent_req_nomem(subreq, req)) { > return; > } >@@ -504,31 +567,3 @@ NTSTATUS wb_sids2xids_recv(struct tevent_req *req, > > return NT_STATUS_OK; > } >- >-static struct wbint_TransIDArray *wb_sids2xids_extract_for_domain_index( >- TALLOC_CTX *mem_ctx, const struct wbint_TransIDArray *src, >- uint32_t domain_index) >-{ >- struct wbint_TransIDArray *ret; >- uint32_t i; >- >- ret = talloc_zero(mem_ctx, struct wbint_TransIDArray); >- if (ret == NULL) { >- return NULL; >- } >- ret->ids = talloc_array(ret, struct wbint_TransID, src->num_ids); >- if (ret->ids == NULL) { >- TALLOC_FREE(ret); >- return NULL; >- } >- >- for (i=0; i<src->num_ids; i++) { >- if (src->ids[i].domain_index == domain_index) { >- ret->ids[ret->num_ids] = src->ids[i]; >- ret->ids[ret->num_ids].domain_index = 0; >- ret->num_ids += 1; >- } >- } >- >- return ret; >-} >-- >2.25.1 > > >From 198ae3ea3cc7493b8761f8e19dd615813b029e49 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 15 Sep 2020 13:54:24 +0200 >Subject: [PATCH 422/686] CVE-2020-25717 wb_sids2xids: refactor > wb_sids2xids_done() a bit > >Here we don't change the logic. > >It will make the following changes easier. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit cda61f592a0b33d36da8da9b6837312396cceec4) >--- > source3/winbindd/wb_sids2xids.c | 27 ++++++++++++++++++--------- > 1 file changed, 18 insertions(+), 9 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index aefb9f93ccb..d6655402b57 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -401,8 +401,10 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > struct wb_sids2xids_state *state = tevent_req_data( > req, struct wb_sids2xids_state); > NTSTATUS status, result; >- struct wbint_TransIDArray *src, *dst; >- uint32_t i, src_idx; >+ const struct wbint_TransIDArray *src = NULL; >+ struct wbint_TransIDArray *dst = NULL; >+ uint32_t si; >+ uint32_t di; > > status = dcerpc_wbint_Sids2UnixIDs_recv(subreq, state, &result); > TALLOC_FREE(subreq); >@@ -429,7 +431,6 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > } > > src = &state->map_ids_out; >- src_idx = 0; > dst = &state->ids; > > if (any_nt_status_not_ok(status, result, &status)) { >@@ -440,8 +441,8 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > * All we can do here is to report "not mapped" > */ > src = &state->map_ids_in; >- for (i=0; i<src->num_ids; i++) { >- src->ids[i].xid.type = ID_TYPE_NOT_SPECIFIED; >+ for (si=0; si < src->num_ids; si++) { >+ src->ids[si].xid.type = ID_TYPE_NOT_SPECIFIED; > } > } > >@@ -450,11 +451,19 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > return; > } > >- for (i=0; i<dst->num_ids; i++) { >- if (dst->ids[i].domain_index == state->dom_index) { >- dst->ids[i].xid = src->ids[src_idx].xid; >- src_idx += 1; >+ si = 0; >+ for (di=0; di < dst->num_ids; di++) { >+ if (dst->ids[di].domain_index != state->dom_index) { >+ continue; >+ } >+ >+ if (si >= src->num_ids) { >+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >+ return; > } >+ >+ dst->ids[di].xid = src->ids[si].xid; >+ si += 1; > } > > state->map_ids_in.num_ids = 0; >-- >2.25.1 > > >From d22a0e347ca8a8310d6492567e53b90629895c64 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 15 Sep 2020 13:58:26 +0200 >Subject: [PATCH 423/686] CVE-2020-25717 wb_sids2xids: change 'i' to 'li' in > wb_sids2xids_lookupsids_done() > >With all the indexes we have into various array, this makes clear >'li' is the index into the state->lookup_sids array. > >This makes the following changes easier to review. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 19c8b6a8b188e45a6342a3d1308085800388a38e) >--- > source3/winbindd/wb_sids2xids.c | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index d6655402b57..f01e36e6e55 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -235,7 +235,7 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > struct lsa_RefDomainList *domains = NULL; > struct lsa_TransNameArray *names = NULL; > NTSTATUS status; >- uint32_t i; >+ uint32_t li; > > status = wb_lookupsids_recv(subreq, state, &domains, &names); > TALLOC_FREE(subreq); >@@ -250,11 +250,11 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > return; > } > >- for (i=0; i<state->lookup_count; i++) { >- const struct dom_sid *sid = &state->lookup_sids[i]; >+ for (li = 0; li < state->lookup_count; li++) { >+ const struct dom_sid *sid = &state->lookup_sids[li]; > struct dom_sid dom_sid; >- struct lsa_TranslatedName *n = &names->names[i]; >- struct wbint_TransID *t = &state->ids.ids[i]; >+ struct lsa_TranslatedName *n = &names->names[li]; >+ struct wbint_TransID *t = &state->ids.ids[li]; > int domain_index; > const char *domain_name = NULL; > >-- >2.25.1 > > >From f80cd86f18b6521d033794a4b110ae2d728aa06a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 15 Sep 2020 14:17:37 +0200 >Subject: [PATCH 424/686] CVE-2020-25717 wb_sids2xids: directly use > state->all_ids to collect results > >In order to translate the indexes from state->lookup_sids[] >for wb_lookupsids_send/recv() and state->map_ids.ids[] >for dcerpc_wbint_Sids2UnixIDs_send/recv() back to >state->all_ids.ids[] or state->sids[] we have state->tmp_idx[]. > >This simplifies wb_sids2xids_recv() a lot and make further >restructuring much easier. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 374acc2e5fcc3c4b40f41906d0349499e3304841) >--- > source3/winbindd/wb_sids2xids.c | 66 +++++++++++---------------------- > 1 file changed, 22 insertions(+), 44 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index f01e36e6e55..cdbc70a0b49 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -36,6 +36,9 @@ struct wb_sids2xids_state { > > struct wbint_TransIDArray all_ids; > >+ /* Used to translated the idx back into all_ids.ids[idx] */ >+ uint32_t *tmp_idx; >+ > uint32_t lookup_count; > struct dom_sid *lookup_sids; > >@@ -58,8 +61,6 @@ struct wb_sids2xids_state { > uint32_t dom_index; > struct lsa_RefDomainList idmap_dom; > bool tried_dclookup; >- >- struct wbint_TransIDArray ids; > }; > > static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq); >@@ -104,6 +105,11 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >+ state->tmp_idx = talloc_zero_array(state, uint32_t, num_sids); >+ if (tevent_req_nomem(state->tmp_idx, req)) { >+ return tevent_req_post(req, ev); >+ } >+ > state->lookup_sids = talloc_zero_array(state, struct dom_sid, num_sids); > if (tevent_req_nomem(state->lookup_sids, req)) { > return tevent_req_post(req, ev); >@@ -161,6 +167,7 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > continue; > } > >+ state->tmp_idx[state->lookup_count] = i; > sid_copy(&state->lookup_sids[state->lookup_count], > &state->sids[i]); > state->lookup_count += 1; >@@ -243,18 +250,12 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > return; > } > >- state->ids.num_ids = state->lookup_count; >- state->ids.ids = talloc_array(state, struct wbint_TransID, >- state->ids.num_ids); >- if (tevent_req_nomem(state->ids.ids, req)) { >- return; >- } >- > for (li = 0; li < state->lookup_count; li++) { > const struct dom_sid *sid = &state->lookup_sids[li]; > struct dom_sid dom_sid; > struct lsa_TranslatedName *n = &names->names[li]; >- struct wbint_TransID *t = &state->ids.ids[li]; >+ uint32_t ai = state->tmp_idx[li]; >+ struct wbint_TransID *t = &state->all_ids.ids[ai]; > int domain_index; > const char *domain_name = NULL; > >@@ -295,9 +296,6 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > return; > } > t->domain_index = domain_index; >- >- t->xid.id = UINT32_MAX; >- t->xid.type = ID_TYPE_NOT_SPECIFIED; > } > > TALLOC_FREE(names); >@@ -324,7 +322,7 @@ static void wb_sids2xids_next_sids2unix(struct tevent_req *req) > return; > } > >- src = &state->ids; >+ src = &state->all_ids; > dst = &state->map_ids_in; > dst->num_ids = 0; > >@@ -333,6 +331,7 @@ static void wb_sids2xids_next_sids2unix(struct tevent_req *req) > continue; > } > >+ state->tmp_idx[dst->num_ids] = si; > dst->ids[dst->num_ids] = src->ids[si]; > dst->ids[dst->num_ids].domain_index = 0; > dst->num_ids += 1; >@@ -404,7 +403,6 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > const struct wbint_TransIDArray *src = NULL; > struct wbint_TransIDArray *dst = NULL; > uint32_t si; >- uint32_t di; > > status = dcerpc_wbint_Sids2UnixIDs_recv(subreq, state, &result); > TALLOC_FREE(subreq); >@@ -431,7 +429,7 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > } > > src = &state->map_ids_out; >- dst = &state->ids; >+ dst = &state->all_ids; > > if (any_nt_status_not_ok(status, result, &status)) { > DBG_DEBUG("status=%s, result=%s\n", nt_errstr(status), >@@ -451,19 +449,12 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > return; > } > >- si = 0; >- for (di=0; di < dst->num_ids; di++) { >- if (dst->ids[di].domain_index != state->dom_index) { >- continue; >- } >+ for (si=0; si < src->num_ids; si++) { >+ uint32_t di = state->tmp_idx[si]; > >- if (si >= src->num_ids) { >- tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >- return; >+ if (src->ids[si].xid.type != ID_TYPE_NOT_SPECIFIED) { >+ dst->ids[di].xid = src->ids[si].xid; > } >- >- dst->ids[di].xid = src->ids[si].xid; >- si += 1; > } > > state->map_ids_in.num_ids = 0; >@@ -541,7 +532,7 @@ NTSTATUS wb_sids2xids_recv(struct tevent_req *req, > struct wb_sids2xids_state *state = tevent_req_data( > req, struct wb_sids2xids_state); > NTSTATUS status; >- uint32_t i, lookup_count = 0; >+ uint32_t i; > > if (tevent_req_is_nterror(req, &status)) { > DEBUG(5, ("wb_sids_to_xids failed: %s\n", nt_errstr(status))); >@@ -555,23 +546,10 @@ NTSTATUS wb_sids2xids_recv(struct tevent_req *req, > } > > for (i=0; i<state->num_sids; i++) { >- struct unixid xid; >- >- xid.id = UINT32_MAX; >- >- if (state->all_ids.ids[i].domain_index == UINT32_MAX) { >- xid = state->all_ids.ids[i].xid; >- } else { >- xid = state->ids.ids[lookup_count].xid; >- >- idmap_cache_set_sid2unixid( >- &state->lookup_sids[lookup_count], >- &xid); >- >- lookup_count += 1; >+ xids[i] = state->all_ids.ids[i].xid; >+ if (state->all_ids.ids[i].domain_index != UINT32_MAX) { >+ idmap_cache_set_sid2unixid(&state->sids[i], &xids[i]); > } >- >- xids[i] = xid; > } > > return NT_STATUS_OK; >-- >2.25.1 > > >From 81a9689c762d1a33a8c1e642ff81dc17e5387b39 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Sep 2020 23:06:02 +0200 >Subject: [PATCH 425/686] CVE-2020-25717 wb_sids2xids: fill cache as soon as > possible > >After adding entries to the cache we can mark them >as filled from the cache by setting its domain_index >to UINT32_MAX. > >This will allow further changes to fill the results >into state->all_ids in steps. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 3f4626ea6d235470195918b77af35ac2cfeb227c) >--- > source3/winbindd/wb_sids2xids.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index cdbc70a0b49..21bf5f901f3 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -455,6 +455,8 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > if (src->ids[si].xid.type != ID_TYPE_NOT_SPECIFIED) { > dst->ids[di].xid = src->ids[si].xid; > } >+ dst->ids[di].domain_index = UINT32_MAX; /* mark as valid */ >+ idmap_cache_set_sid2unixid(&state->sids[di], &dst->ids[di].xid); > } > > state->map_ids_in.num_ids = 0; >@@ -547,9 +549,6 @@ NTSTATUS wb_sids2xids_recv(struct tevent_req *req, > > for (i=0; i<state->num_sids; i++) { > xids[i] = state->all_ids.ids[i].xid; >- if (state->all_ids.ids[i].domain_index != UINT32_MAX) { >- idmap_cache_set_sid2unixid(&state->sids[i], &xids[i]); >- } > } > > return NT_STATUS_OK; >-- >2.25.1 > > >From 764e9b1d53900fd7652152d69a196119c20d273a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Sep 2020 17:13:14 +0200 >Subject: [PATCH 426/686] CVE-2020-25717 wb_sids2xids: build state->idmap_doms > based on wb_parent_idmap_config > >In future we'll try to avoid wb_lookupsids_send() and only call >it if needed. > >The domain name passed should be only relevant to find the correct >idmap backend, and these should all be available in >wb_parent_idmap_config as it was created before the idmap child was forked. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit c55f4f37589130a0d8952489da175bbcf53f6748) >--- > source3/winbindd/wb_sids2xids.c | 101 +++++++++++++++++++------------- > 1 file changed, 61 insertions(+), 40 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index 21bf5f901f3..3a3d47abbe5 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -193,6 +193,7 @@ static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq) > struct wb_sids2xids_state *state = tevent_req_data( > req, struct wb_sids2xids_state); > NTSTATUS status; >+ uint32_t i; > > status = wb_parent_idmap_setup_recv(subreq, &state->cfg); > TALLOC_FREE(subreq); >@@ -201,6 +202,66 @@ static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq) > } > SMB_ASSERT(state->cfg->num_doms > 0); > >+ /* >+ * Now we build a list with all domain >+ * with non cached entries >+ */ >+ for (i=0; i<state->num_sids; i++) { >+ struct wbint_TransID *t = &state->all_ids.ids[i]; >+ struct dom_sid domain_sid; >+ const char *domain_name = NULL; >+ int domain_index; >+ uint32_t rid = 0; >+ uint32_t di; >+ >+ if (t->domain_index == UINT32_MAX) { >+ /* ignore already filled entries */ >+ continue; >+ } >+ >+ sid_copy(&domain_sid, &state->sids[i]); >+ sid_split_rid(&domain_sid, &rid); >+ >+ for (di = 0; di < state->cfg->num_doms; di++) { >+ struct wb_parent_idmap_config_dom *dom = >+ &state->cfg->doms[di]; >+ bool match; >+ >+ match = dom_sid_equal(&domain_sid, >+ &dom->sid); >+ if (!match) { >+ continue; >+ } >+ >+ domain_name = dom->name; >+ break; >+ } >+ if (domain_name == NULL) { >+ struct winbindd_domain *wb_domain = NULL; >+ >+ /* >+ * Try to fill the name if we already know it >+ */ >+ wb_domain = find_domain_from_sid_noinit(&state->sids[i]); >+ if (wb_domain != NULL) { >+ domain_name = wb_domain->name; >+ } >+ } >+ if (domain_name == NULL) { >+ domain_name = ""; >+ } >+ >+ domain_index = init_lsa_ref_domain_list(state, >+ &state->idmap_doms, >+ domain_name, >+ &domain_sid); >+ if (domain_index == -1) { >+ tevent_req_oom(req); >+ return; >+ } >+ t->domain_index = domain_index; >+ } >+ > subreq = wb_lookupsids_send(state, > state->ev, > state->lookup_sids, >@@ -251,51 +312,11 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > } > > for (li = 0; li < state->lookup_count; li++) { >- const struct dom_sid *sid = &state->lookup_sids[li]; >- struct dom_sid dom_sid; > struct lsa_TranslatedName *n = &names->names[li]; > uint32_t ai = state->tmp_idx[li]; > struct wbint_TransID *t = &state->all_ids.ids[ai]; >- int domain_index; >- const char *domain_name = NULL; >- >- if (n->sid_index != UINT32_MAX) { >- const struct lsa_DomainInfo *info; >- bool match; >- >- info = &domains->domains[n->sid_index]; >- match = dom_sid_in_domain(info->sid, sid); >- if (match) { >- domain_name = info->name.string; >- } >- } >- if (domain_name == NULL) { >- struct winbindd_domain *wb_domain = NULL; >- >- /* >- * This is needed to handle Samba DCs >- * which always return sid_index == UINT32_MAX for >- * unknown sids. >- */ >- wb_domain = find_domain_from_sid_noinit(sid); >- if (wb_domain != NULL) { >- domain_name = wb_domain->name; >- } >- } >- if (domain_name == NULL) { >- domain_name = ""; >- } > >- sid_copy(&dom_sid, sid); >- sid_split_rid(&dom_sid, &t->rid); > t->type_hint = lsa_SidType_to_id_type(n->sid_type); >- domain_index = init_lsa_ref_domain_list( >- state, &state->idmap_doms, domain_name, &dom_sid); >- if (domain_index == -1) { >- tevent_req_oom(req); >- return; >- } >- t->domain_index = domain_index; > } > > TALLOC_FREE(names); >-- >2.25.1 > > >From ed210668072138fad7349fd315dd3d698c958cff Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 15 Sep 2020 17:26:11 +0200 >Subject: [PATCH 427/686] CVE-2020-25717 winbindd: allow idmap backends to mark > entries with ID_[TYPE_WB_]REQUIRE_TYPE > >This must only be used between winbindd parent and child! >It must not leak into outside world. > >Some backends require ID_TYPE_UID or ID_TYPE_GID as type_hint, >while others may only need ID_TYPE_BOTH in order to validate that >the domain exists. > >This will allow us to skip the wb_lookupsids_send/recv in the winbindd parent >in future and only do that on demand. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 493f5d6b078e0b0f80d1ef25043e2834cb4fcb87) >--- > librpc/idl/idmap.idl | 23 +++++++++++++++++-- > source3/passdb/lookup_sid.c | 7 ++++++ > source3/winbindd/idmap_autorid.c | 6 ++--- > source3/winbindd/idmap_ldap.c | 29 ++++++++++++++++++++++++ > source3/winbindd/idmap_rw.c | 32 +++++++++++++++++++++++++-- > source3/winbindd/idmap_tdb_common.c | 22 +++++++++++++++++- > source3/winbindd/wb_sids2xids.c | 11 +++++++++ > source3/winbindd/winbindd_dual_srv.c | 6 +++++ > source3/winbindd/winbindd_getgroups.c | 7 ++++++ > 9 files changed, 135 insertions(+), 8 deletions(-) > >diff --git a/librpc/idl/idmap.idl b/librpc/idl/idmap.idl >index 54fd888dcab..e58e39210c7 100644 >--- a/librpc/idl/idmap.idl >+++ b/librpc/idl/idmap.idl >@@ -11,7 +11,18 @@ interface idmap > ID_TYPE_NOT_SPECIFIED, > ID_TYPE_UID, > ID_TYPE_GID, >- ID_TYPE_BOTH >+ ID_TYPE_BOTH, >+ /* >+ * This are internal between winbindd >+ * parent and child. >+ * >+ * It means the idmap backend/child requires a valid type_hint >+ * for wbint_Sids2UnixIDs(): >+ * >+ * - ID_TYPE_UID or ID_TYPE_GID means the user/group exists >+ * - ID_TYPE_BOTH means that only the domain exist >+ */ >+ ID_TYPE_WB_REQUIRE_TYPE > } id_type; > > typedef [public] struct { >@@ -23,7 +34,15 @@ interface idmap > ID_UNKNOWN, > ID_MAPPED, > ID_UNMAPPED, >- ID_EXPIRED >+ ID_EXPIRED, >+ /* >+ * This means the idmap backend requires a valid type_hint >+ * in order to map a sid to a unix id. >+ * >+ * - ID_TYPE_UID or ID_TYPE_GID means the user/group exists >+ * - ID_TYPE_BOTH means that only the domain exist >+ */ >+ ID_REQUIRE_TYPE > } id_mapping; > > typedef [public] struct { >diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c >index a7a1d5faa8e..87f8ac81521 100644 >--- a/source3/passdb/lookup_sid.c >+++ b/source3/passdb/lookup_sid.c >@@ -1348,6 +1348,13 @@ done: > break; > case ID_TYPE_NOT_SPECIFIED: > break; >+ case ID_TYPE_WB_REQUIRE_TYPE: >+ /* >+ * these are internal between winbindd >+ * parent and child. >+ */ >+ smb_panic(__location__); >+ break; > } > } > >diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c >index 636852119b2..d97494360b0 100644 >--- a/source3/winbindd/idmap_autorid.c >+++ b/source3/winbindd/idmap_autorid.c >@@ -670,9 +670,9 @@ static NTSTATUS idmap_autorid_sid_to_id(struct idmap_tdb_common_context *common, > * range. > */ > >- DBG_NOTICE("Allocating range for domain %s refused\n", range.domsid); >- map->status = ID_UNMAPPED; >- return NT_STATUS_NONE_MAPPED; >+ DBG_NOTICE("Allocating range for domain %s required type_hint\n", range.domsid); >+ map->status = ID_REQUIRE_TYPE; >+ return NT_STATUS_SOME_NOT_MAPPED; > > allocate: > ret = idmap_autorid_acquire_range(autorid_db, &range); >diff --git a/source3/winbindd/idmap_ldap.c b/source3/winbindd/idmap_ldap.c >index 327b8119331..a4e3f835884 100644 >--- a/source3/winbindd/idmap_ldap.c >+++ b/source3/winbindd/idmap_ldap.c >@@ -249,6 +249,17 @@ static NTSTATUS idmap_ldap_allocate_id_internal(struct idmap_domain *dom, > LDAP_ATTR_GIDNUMBER); > break; > >+ case ID_TYPE_BOTH: >+ /* >+ * This is not supported here yet and >+ * already handled in idmap_rw_new_mapping() >+ */ >+ FALL_THROUGH; >+ case ID_TYPE_NOT_SPECIFIED: >+ /* >+ * This is handled in idmap_rw_new_mapping() >+ */ >+ FALL_THROUGH; > default: > DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type)); > return NT_STATUS_INVALID_PARAMETER; >@@ -854,6 +865,7 @@ static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom, > const char **attr_list; > char *filter = NULL; > bool multi = False; >+ size_t num_required = 0; > int idx = 0; > int bidx = 0; > int count; >@@ -1054,7 +1066,21 @@ again: > ids[i]->status = ID_UNMAPPED; > if (ids[i]->sid != NULL) { > ret = idmap_ldap_new_mapping(dom, ids[i]); >+ DBG_DEBUG("idmap_ldap_new_mapping returned %s\n", >+ nt_errstr(ret)); >+ if (NT_STATUS_EQUAL(ret, STATUS_SOME_UNMAPPED)) { >+ if (ids[i]->status == ID_REQUIRE_TYPE) { >+ num_required += 1; >+ continue; >+ } >+ } > if (!NT_STATUS_IS_OK(ret)) { >+ /* >+ * If we can't create >+ * a new mapping it's unlikely >+ * that it will work for the >+ * next entry. >+ */ > goto done; > } > } >@@ -1062,6 +1088,9 @@ again: > } > > ret = NT_STATUS_OK; >+ if (num_required > 0) { >+ ret = STATUS_SOME_UNMAPPED; >+ } > > done: > talloc_free(memctx); >diff --git a/source3/winbindd/idmap_rw.c b/source3/winbindd/idmap_rw.c >index 700a946fc62..71bfc14e204 100644 >--- a/source3/winbindd/idmap_rw.c >+++ b/source3/winbindd/idmap_rw.c >@@ -39,11 +39,39 @@ NTSTATUS idmap_rw_new_mapping(struct idmap_domain *dom, > return NT_STATUS_INVALID_PARAMETER; > } > >- if ((map->xid.type != ID_TYPE_UID) && (map->xid.type != ID_TYPE_GID)) { >+ if (map->sid == NULL) { > return NT_STATUS_INVALID_PARAMETER; > } > >- if (map->sid == NULL) { >+ switch (map->xid.type) { >+ case ID_TYPE_NOT_SPECIFIED: >+ /* >+ * We need to know if we need a user or group mapping. >+ * Ask the winbindd parent to provide a valid type hint. >+ */ >+ DBG_INFO("%s ID_TYPE_NOT_SPECIFIED => ID_REQUIRE_TYPE\n", >+ dom_sid_str_buf(map->sid, &buf)); >+ map->status = ID_REQUIRE_TYPE; >+ return NT_STATUS_SOME_NOT_MAPPED; >+ >+ case ID_TYPE_BOTH: >+ /* >+ * For now we still require >+ * an explicit type as hint >+ * and don't support ID_TYPE_BOTH >+ */ >+ DBG_INFO("%s ID_TYPE_BOTH => ID_REQUIRE_TYPE\n", >+ dom_sid_str_buf(map->sid, &buf)); >+ map->status = ID_REQUIRE_TYPE; >+ return NT_STATUS_SOME_NOT_MAPPED; >+ >+ case ID_TYPE_UID: >+ break; >+ >+ case ID_TYPE_GID: >+ break; >+ >+ default: > return NT_STATUS_INVALID_PARAMETER; > } > >diff --git a/source3/winbindd/idmap_tdb_common.c b/source3/winbindd/idmap_tdb_common.c >index 34269e3fe56..0df8f2f3103 100644 >--- a/source3/winbindd/idmap_tdb_common.c >+++ b/source3/winbindd/idmap_tdb_common.c >@@ -118,6 +118,17 @@ static NTSTATUS idmap_tdb_common_allocate_id(struct idmap_domain *dom, > hwmtype = "GID"; > break; > >+ case ID_TYPE_BOTH: >+ /* >+ * This is not supported here yet and >+ * already handled in idmap_rw_new_mapping() >+ */ >+ FALL_THROUGH; >+ case ID_TYPE_NOT_SPECIFIED: >+ /* >+ * This is handled in idmap_rw_new_mapping() >+ */ >+ FALL_THROUGH; > default: > DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type)); > return NT_STATUS_INVALID_PARAMETER; >@@ -529,7 +540,7 @@ static NTSTATUS idmap_tdb_common_sids_to_unixids_action(struct db_context *db, > void *private_data) > { > struct idmap_tdb_common_sids_to_unixids_context *state = private_data; >- size_t i, num_mapped = 0; >+ size_t i, num_mapped = 0, num_required = 0; > NTSTATUS ret = NT_STATUS_OK; > > DEBUG(10, ("idmap_tdb_common_sids_to_unixids: " >@@ -579,6 +590,12 @@ static NTSTATUS idmap_tdb_common_sids_to_unixids_action(struct db_context *db, > state->ids[i]); > DBG_DEBUG("idmap_tdb_common_new_mapping returned %s\n", > nt_errstr(ret)); >+ if (NT_STATUS_EQUAL(ret, STATUS_SOME_UNMAPPED)) { >+ if (state->ids[i]->status == ID_REQUIRE_TYPE) { >+ num_required += 1; >+ continue; >+ } >+ } > if (!NT_STATUS_IS_OK(ret)) { > ret = STATUS_SOME_UNMAPPED; > continue; >@@ -598,6 +615,9 @@ done: > } else { > ret = NT_STATUS_OK; > } >+ if (num_required > 0) { >+ ret = STATUS_SOME_UNMAPPED; >+ } > } > > return ret; >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index 3a3d47abbe5..35b6675520e 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -473,6 +473,17 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > for (si=0; si < src->num_ids; si++) { > uint32_t di = state->tmp_idx[si]; > >+ if (src->ids[si].xid.type == ID_TYPE_WB_REQUIRE_TYPE) { >+ /* >+ * This should not happen yet, as we always >+ * do a lookupsids and fill type_hint. >+ * >+ * Make sure we don't expose ID_TYPE_WB_REQUIRE_TYPE >+ * outside of winbindd! >+ */ >+ src->ids[si].xid.type = ID_TYPE_NOT_SPECIFIED; >+ } >+ > if (src->ids[si].xid.type != ID_TYPE_NOT_SPECIFIED) { > dst->ids[di].xid = src->ids[si].xid; > } >diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c >index b83a313ea45..9f8ff59d914 100644 >--- a/source3/winbindd/winbindd_dual_srv.c >+++ b/source3/winbindd/winbindd_dual_srv.c >@@ -226,6 +226,12 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p, > for (i=0; i<num_ids; i++) { > struct id_map *m = id_map_ptrs[i]; > >+ if (m->status == ID_REQUIRE_TYPE) { >+ ids[i].xid.id = UINT32_MAX; >+ ids[i].xid.type = ID_TYPE_WB_REQUIRE_TYPE; >+ continue; >+ } >+ > if (!idmap_unix_id_is_in_range(m->xid.id, dom)) { > DBG_DEBUG("id %"PRIu32" is out of range " > "%"PRIu32"-%"PRIu32" for domain %s\n", >diff --git a/source3/winbindd/winbindd_getgroups.c b/source3/winbindd/winbindd_getgroups.c >index 63206c28134..7182156578b 100644 >--- a/source3/winbindd/winbindd_getgroups.c >+++ b/source3/winbindd/winbindd_getgroups.c >@@ -202,6 +202,13 @@ static void winbindd_getgroups_sid2gid_done(struct tevent_req *subreq) > case ID_TYPE_BOTH: > include_gid = true; > break; >+ case ID_TYPE_WB_REQUIRE_TYPE: >+ /* >+ * these are internal between winbindd >+ * parent and child. >+ */ >+ smb_panic(__location__); >+ break; > } > > if (!include_gid) { >-- >2.25.1 > > >From 9901a06b5f816e78d18c787420e64770ca5ddef0 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Sep 2020 16:24:49 +0200 >Subject: [PATCH 428/686] CVE-2020-25717 wb_sids2xids: defer/skip > wb_lookupsids* unless we get ID_TYPE_WB_REQUIRE_TYPE > >We try to give a valid hint for predefined sids and >pass ID_TYPE_BOTH as a hint that the domain part of the sid is valid. > >In most cases the idmap child/backend does not require a type_hint >as mappings already exist. > >This is a speed up as we no longer need to contact a domain controller. > >It's also possible to accept kerberos authentication without reaching >out to a domain controller at all (if the idmap backend doesn't need a >hint). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Fri Oct 23 04:47:26 UTC 2020 on sn-devel-184 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 54b4d2d3cb307019a260d15c6e6b4a3fb7fc337c) >--- > source3/winbindd/wb_sids2xids.c | 177 ++++++++++++++++++++++++++++---- > 1 file changed, 158 insertions(+), 19 deletions(-) > >diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c >index 35b6675520e..650d104254a 100644 >--- a/source3/winbindd/wb_sids2xids.c >+++ b/source3/winbindd/wb_sids2xids.c >@@ -69,6 +69,7 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq); > static void wb_sids2xids_done(struct tevent_req *subreq); > static void wb_sids2xids_gotdc(struct tevent_req *subreq); > static void wb_sids2xids_next_sids2unix(struct tevent_req *req); >+static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type); > > struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >@@ -166,11 +167,6 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, > num_valid += 1; > continue; > } >- >- state->tmp_idx[state->lookup_count] = i; >- sid_copy(&state->lookup_sids[state->lookup_count], >- &state->sids[i]); >- state->lookup_count += 1; > } > > if (num_valid == num_sids) { >@@ -222,6 +218,25 @@ static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq) > sid_copy(&domain_sid, &state->sids[i]); > sid_split_rid(&domain_sid, &rid); > >+ if (t->type_hint == ID_TYPE_NOT_SPECIFIED) { >+ const char *tmp_name = NULL; >+ enum lsa_SidType sid_type = SID_NAME_USE_NONE; >+ const struct dom_sid *tmp_authority_sid = NULL; >+ const char *tmp_authority_name = NULL; >+ >+ /* >+ * Try to get a type hint from for predefined sids >+ */ >+ status = dom_sid_lookup_predefined_sid(&state->sids[i], >+ &tmp_name, >+ &sid_type, >+ &tmp_authority_sid, >+ &tmp_authority_name); >+ if (NT_STATUS_IS_OK(status)) { >+ t->type_hint = lsa_SidType_to_id_type(sid_type); >+ } >+ } >+ > for (di = 0; di < state->cfg->num_doms; di++) { > struct wb_parent_idmap_config_dom *dom = > &state->cfg->doms[di]; >@@ -251,6 +266,18 @@ static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq) > domain_name = ""; > } > >+ if (t->type_hint == ID_TYPE_NOT_SPECIFIED) { >+ if (domain_name[0] != '\0') { >+ /* >+ * We know the domain, we indicate this >+ * by passing ID_TYPE_BOTH as a hint >+ * >+ * Maybe that's already enough for the backend >+ */ >+ t->type_hint = ID_TYPE_BOTH; >+ } >+ } >+ > domain_index = init_lsa_ref_domain_list(state, > &state->idmap_doms, > domain_name, >@@ -262,14 +289,15 @@ static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq) > t->domain_index = domain_index; > } > >- subreq = wb_lookupsids_send(state, >- state->ev, >- state->lookup_sids, >- state->lookup_count); >- if (tevent_req_nomem(subreq, req)) { >- return; >- } >- tevent_req_set_callback(subreq, wb_sids2xids_lookupsids_done, req); >+ /* >+ * We defer lookupsids because it requires domain controller >+ * interaction. >+ * >+ * First we ask the idmap child without explicit type hints. >+ * In most cases mappings already exist in the backend and >+ * a type_hint is not needed. >+ */ >+ wb_sids2xids_next_sids2unix(req); > } > > static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map) >@@ -292,8 +320,6 @@ static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map) > return false; > } > >-static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type); >- > static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > { > struct tevent_req *req = tevent_req_callback_data( >@@ -311,17 +337,83 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) > return; > } > >+ if (domains == NULL) { >+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >+ return; >+ } >+ >+ if (names == NULL) { >+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >+ return; >+ } >+ > for (li = 0; li < state->lookup_count; li++) { > struct lsa_TranslatedName *n = &names->names[li]; > uint32_t ai = state->tmp_idx[li]; > struct wbint_TransID *t = &state->all_ids.ids[ai]; >+ enum id_type type_hint; >+ >+ type_hint = lsa_SidType_to_id_type(n->sid_type); >+ if (type_hint != ID_TYPE_NOT_SPECIFIED) { >+ /* >+ * We know it's a valid user or group. >+ */ >+ t->type_hint = type_hint; >+ continue; >+ } >+ >+ if (n->sid_index == UINT32_MAX) { >+ /* >+ * The domain is not known, there's >+ * no point to try mapping again. >+ * mark is done and add a negative cache >+ * entry. >+ */ >+ t->domain_index = UINT32_MAX; /* mark as valid */ >+ idmap_cache_set_sid2unixid(&state->sids[ai], &t->xid); >+ continue; >+ } > >- t->type_hint = lsa_SidType_to_id_type(n->sid_type); >+ if (n->sid_index >= domains->count) { >+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >+ return; >+ } >+ >+ if (domains->domains[n->sid_index].name.string == NULL) { >+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >+ return; >+ } >+ if (domains->domains[n->sid_index].sid == NULL) { >+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >+ return; >+ } >+ >+ if (t->type_hint != ID_TYPE_NOT_SPECIFIED) { >+ /* >+ * We already tried with a type hint there's >+ * no point to try mapping again with ID_TYPE_BOTH. >+ * >+ * Mark is done and add a negative cache entry. >+ */ >+ t->domain_index = UINT32_MAX; /* mark as valid */ >+ idmap_cache_set_sid2unixid(&state->sids[ai], &t->xid); >+ continue; >+ } >+ >+ /* >+ * We only know the domain exists, but the user doesn't >+ */ >+ t->type_hint = ID_TYPE_BOTH; > } > > TALLOC_FREE(names); > TALLOC_FREE(domains); > >+ /* >+ * Now that we have type_hints for the remaining sids, >+ * we need to restart with the first domain. >+ */ >+ state->dom_index = 0; > wb_sids2xids_next_sids2unix(req); > } > >@@ -339,7 +431,45 @@ static void wb_sids2xids_next_sids2unix(struct tevent_req *req) > state->tried_dclookup = false; > > if (state->dom_index == state->idmap_doms.count) { >- tevent_req_done(req); >+ if (state->lookup_count != 0) { >+ /* >+ * We already called wb_lookupsids_send() >+ * before, so we're done. >+ */ >+ tevent_req_done(req); >+ return; >+ } >+ >+ for (si=0; si < state->num_sids; si++) { >+ struct wbint_TransID *t = &state->all_ids.ids[si]; >+ >+ if (t->domain_index == UINT32_MAX) { >+ /* ignore already filled entries */ >+ continue; >+ } >+ >+ state->tmp_idx[state->lookup_count] = si; >+ sid_copy(&state->lookup_sids[state->lookup_count], >+ &state->sids[si]); >+ state->lookup_count += 1; >+ } >+ >+ if (state->lookup_count == 0) { >+ /* >+ * no wb_lookupsids_send() needed... >+ */ >+ tevent_req_done(req); >+ return; >+ } >+ >+ subreq = wb_lookupsids_send(state, >+ state->ev, >+ state->lookup_sids, >+ state->lookup_count); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, wb_sids2xids_lookupsids_done, req); > return; > } > >@@ -474,9 +604,18 @@ static void wb_sids2xids_done(struct tevent_req *subreq) > uint32_t di = state->tmp_idx[si]; > > if (src->ids[si].xid.type == ID_TYPE_WB_REQUIRE_TYPE) { >+ if (state->lookup_count == 0) { >+ /* >+ * The backend asks for more information >+ * (a type_hint), we'll do a lookupsids >+ * later. >+ */ >+ continue; >+ } >+ > /* >- * This should not happen yet, as we always >- * do a lookupsids and fill type_hint. >+ * lookupsids was not able to provide a type_hint that >+ * satisfied the backend. > * > * Make sure we don't expose ID_TYPE_WB_REQUIRE_TYPE > * outside of winbindd! >-- >2.25.1 > > >From d2aafbd022284d3bfeda3281f3368b849326314d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 23 Oct 2020 12:21:57 +0200 >Subject: [PATCH 429/686] CVE-2020-25717 s3:idmap_hash: reliable return > ID_TYPE_BOTH > >idmap_hash used to bounce back the requested type, >which was ID_TYPE_UID, ID_TYPE_GID or ID_TYPE_NOT_SPECIFIED >before as the winbindd parent always used a lookupsids. >When the lookupsids failed because of an unknown domain, >the idmap child weren't requested at all and the caller >sees ID_TYPE_NOT_SPECIFIED. > >This module should have supported ID_TYPE_BOTH since >samba-4.1.0, similar to idmap_rid and idmap_autorid. > >Now that the winbindd parent will pass ID_TYPE_BOTH in order to >indicate that the domain exists, it's better to always return >ID_TYPE_BOTH instead of a random mix of ID_TYPE_UID, ID_TYPE_GID >or ID_TYPE_BOTH. In order to request a type_hint it will return >ID_REQUIRE_TYPE for ID_TYPE_NOT_SPECIFIED, which means that >the parent at least assures that the domain sid exists. >And the caller still gets ID_TYPE_NOT_SPECIFIED if the >domain doesn't exist. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Fri Jan 22 11:32:46 UTC 2021 on sn-devel-184 > >(cherry picked from commit d8339056eef2845805f573bd8b0f3323370ecc8f) >Reviewed-by: Ralph Boehme <slow@samba.org> > >Autobuild-User(v4-14-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-14-test): Wed Jan 27 17:06:51 UTC 2021 on sn-devel-184 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 99673b77b069674a6145552eb870de8829dfa503) >--- > source3/winbindd/idmap_hash/idmap_hash.c | 35 ++++++++++++++++++++++++ > 1 file changed, 35 insertions(+) > >diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c >index be0ba45a044..d0bed7631a6 100644 >--- a/source3/winbindd/idmap_hash/idmap_hash.c >+++ b/source3/winbindd/idmap_hash/idmap_hash.c >@@ -261,6 +261,25 @@ static NTSTATUS sids_to_unixids(struct idmap_domain *dom, > > ids[i]->status = ID_UNMAPPED; > >+ if (ids[i]->xid.type == ID_TYPE_NOT_SPECIFIED) { >+ /* >+ * idmap_hash used to bounce back the requested type, >+ * which was ID_TYPE_UID, ID_TYPE_GID or >+ * ID_TYPE_NOT_SPECIFIED before as the winbindd parent >+ * always used a lookupsids. When the lookupsids >+ * failed because of an unknown domain, the idmap child >+ * weren't requested at all and the caller sees >+ * ID_TYPE_NOT_SPECIFIED. >+ * >+ * Now that the winbindd parent will pass ID_TYPE_BOTH >+ * in order to indicate that the domain exists. >+ * We should ask the parent to fallback to lookupsids >+ * if the domain is not known yet. >+ */ >+ ids[i]->status = ID_REQUIRE_TYPE; >+ continue; >+ } >+ > sid_copy(&sid, ids[i]->sid); > sid_split_rid(&sid, &rid); > >@@ -270,6 +289,22 @@ static NTSTATUS sids_to_unixids(struct idmap_domain *dom, > /* Check that both hashes are non-zero*/ > > if (h_domain && h_rid) { >+ /* >+ * idmap_hash used to bounce back the requested type, >+ * which was ID_TYPE_UID, ID_TYPE_GID or >+ * ID_TYPE_NOT_SPECIFIED before as the winbindd parent >+ * always used a lookupsids. >+ * >+ * This module should have supported ID_TYPE_BOTH since >+ * samba-4.1.0, similar to idmap_rid and idmap_autorid. >+ * >+ * Now that the winbindd parent will pass ID_TYPE_BOTH >+ * in order to indicate that the domain exists, it's >+ * better to always return ID_TYPE_BOTH instead of a >+ * random mix of ID_TYPE_UID, ID_TYPE_GID or >+ * ID_TYPE_BOTH. >+ */ >+ ids[i]->xid.type = ID_TYPE_BOTH; > ids[i]->xid.id = combine_hashes(h_domain, h_rid); > ids[i]->status = ID_MAPPED; > } >-- >2.25.1 > > >From 3afe8fdd12ef6a104d8322c17141f5387da5a777 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Tue, 31 Aug 2021 17:04:56 +0200 >Subject: [PATCH 430/686] CVE-2020-25717 winbindd: call > wb_parent_idmap_setup_send() in wb_queryuser_send() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14804 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 39c2ec72cb77945c3eb611fb1d7d7e9aad52bdfd) > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 7d1dd87a6538f8c7f1e4938b0ff52cbd231fff90) >--- > source3/winbindd/wb_queryuser.c | 30 +++++++++++++++++++++++++++--- > 1 file changed, 27 insertions(+), 3 deletions(-) > >diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c >index 9db51909c02..f5bc96f03f6 100644 >--- a/source3/winbindd/wb_queryuser.c >+++ b/source3/winbindd/wb_queryuser.c >@@ -25,10 +25,12 @@ > > struct wb_queryuser_state { > struct tevent_context *ev; >- struct wbint_userinfo *info; >+ struct wbint_userinfo *info; >+ const struct wb_parent_idmap_config *idmap_cfg; > bool tried_dclookup; > }; > >+static void wb_queryuser_idmap_setup_done(struct tevent_req *subreq); > static void wb_queryuser_got_uid(struct tevent_req *subreq); > static void wb_queryuser_got_domain(struct tevent_req *subreq); > static void wb_queryuser_got_dc(struct tevent_req *subreq); >@@ -60,13 +62,35 @@ struct tevent_req *wb_queryuser_send(TALLOC_CTX *mem_ctx, > > sid_copy(&info->user_sid, user_sid); > >+ subreq = wb_parent_idmap_setup_send(state, state->ev); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, wb_queryuser_idmap_setup_done, req); >+ return req; >+} >+ >+static void wb_queryuser_idmap_setup_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct wb_queryuser_state *state = tevent_req_data( >+ req, struct wb_queryuser_state); >+ NTSTATUS status; >+ >+ status = wb_parent_idmap_setup_recv(subreq, &state->idmap_cfg); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ > subreq = wb_sids2xids_send( > state, state->ev, &state->info->user_sid, 1); > if (tevent_req_nomem(subreq, req)) { >- return tevent_req_post(req, ev); >+ return; > } > tevent_req_set_callback(subreq, wb_queryuser_got_uid, req); >- return req; >+ return; > } > > static void wb_queryuser_got_uid(struct tevent_req *subreq) >-- >2.25.1 > > >From 87bb23480c26cf36aef7124b5fc24756441109fd Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 20 Aug 2021 15:04:49 +0200 >Subject: [PATCH 431/686] CVE-2020-25717 winbind: ensure > wb_parent_idmap_setup_send() gets called in winbindd_allocate_uid_send() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14804 >RN: winbindd can crash because idmap child state is not fully initialized > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> > >Autobuild-User(master): Volker Lendecke <vl@samba.org> >Autobuild-Date(master): Thu Sep 2 15:20:06 UTC 2021 on sn-devel-184 > >(cherry picked from commit d0f6d54354b02f5591706814fbd1e4844788fdfa) > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 446f89510f2e55a551e2975a6cbf01c6a023ba0c) >--- > source3/winbindd/winbindd_allocate_uid.c | 44 +++++++++++++++++++++--- > 1 file changed, 39 insertions(+), 5 deletions(-) > >diff --git a/source3/winbindd/winbindd_allocate_uid.c b/source3/winbindd/winbindd_allocate_uid.c >index 69ce61c872e..64711f1b661 100644 >--- a/source3/winbindd/winbindd_allocate_uid.c >+++ b/source3/winbindd/winbindd_allocate_uid.c >@@ -22,9 +22,11 @@ > #include "librpc/gen_ndr/ndr_winbind_c.h" > > struct winbindd_allocate_uid_state { >+ struct tevent_context *ev; > uint64_t uid; > }; > >+static void winbindd_allocate_uid_initialized(struct tevent_req *subreq); > static void winbindd_allocate_uid_done(struct tevent_req *subreq); > > struct tevent_req *winbindd_allocate_uid_send(TALLOC_CTX *mem_ctx, >@@ -34,25 +36,57 @@ struct tevent_req *winbindd_allocate_uid_send(TALLOC_CTX *mem_ctx, > { > struct tevent_req *req, *subreq; > struct winbindd_allocate_uid_state *state; >- struct dcerpc_binding_handle *child_binding_handle = NULL; > > req = tevent_req_create(mem_ctx, &state, > struct winbindd_allocate_uid_state); > if (req == NULL) { > return NULL; > } >+ state->ev = ev; > > DEBUG(3, ("allocate_uid\n")); > >- child_binding_handle = idmap_child_handle(); >+ subreq = wb_parent_idmap_setup_send(state, ev); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, winbindd_allocate_uid_initialized, req); >+ return req; >+} >+ >+static void winbindd_allocate_uid_initialized(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct dcerpc_binding_handle *child_binding_handle = NULL; >+ struct winbindd_allocate_uid_state *state = tevent_req_data( >+ req, struct winbindd_allocate_uid_state); >+ const struct wb_parent_idmap_config *cfg = NULL; >+ NTSTATUS status; >+ >+ status = wb_parent_idmap_setup_recv(subreq, &cfg); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ if (cfg->num_doms == 0) { >+ /* >+ * idmap_tdb also returns UNSUCCESSFUL if a range is full >+ */ >+ tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); >+ return; >+ } >+ >+ child_binding_handle = idmap_child_handle(); > >- subreq = dcerpc_wbint_AllocateUid_send(state, ev, child_binding_handle, >+ subreq = dcerpc_wbint_AllocateUid_send(state, >+ state->ev, >+ child_binding_handle, > &state->uid); > if (tevent_req_nomem(subreq, req)) { >- return tevent_req_post(req, ev); >+ return; > } > tevent_req_set_callback(subreq, winbindd_allocate_uid_done, req); >- return req; > } > > static void winbindd_allocate_uid_done(struct tevent_req *subreq) >-- >2.25.1 > > >From 1c9f79fe85278e8591b644649dbba4114821d509 Mon Sep 17 00:00:00 2001 >From: Alexander Bokovoy <ab@samba.org> >Date: Wed, 11 Nov 2020 14:42:55 +0200 >Subject: [PATCH 432/686] CVE-2020-25717 auth_sam: use pdb_get_domain_info to > look up DNS forest information > >When Samba is used as a part of FreeIPA domain controller, Windows >clients for a trusted AD forest may try to authenticate (perform logon >operation) as a REALM\name user account. > >Fix auth_sam plugins to accept DNS forest name if we are running on a DC >with PASSDB module providing domain information (e.g. pdb_get_domain_info() >returning non-NULL structure). Right now, only FreeIPA or Samba AD DC >PASSDB backends return this information but Samba AD DC configuration is >explicitly ignored by the two auth_sam (strict and netlogon3) modules. > >Detailed logs below: > >[2020/11/11 09:23:53.281296, 1, pid=42677, effective(65534, 65534), real(65534, 0), class=rpc_parse] ../../librpc/ndr/ndr.c:482(ndr_print_function_debug) > netr_LogonSamLogonWithFlags: struct netr_LogonSamLogonWithFlags > in: struct netr_LogonSamLogonWithFlags > server_name : * > server_name : '\\master.ipa.test' > computer_name : * > computer_name : 'AD1' > credential : * > credential: struct netr_Authenticator > cred: struct netr_Credential > data : 529f4b087c5f6546 > timestamp : Wed Nov 11 09:23:55 AM 2020 UTC > return_authenticator : * > return_authenticator: struct netr_Authenticator > cred: struct netr_Credential > data : 204f28f622010000 > timestamp : Fri May 2 06:37:50 AM 1986 UTC > logon_level : NetlogonNetworkTransitiveInformation (6) > logon : * > logon : union netr_LogonLevel(case 6) > network : * > network: struct netr_NetworkInfo > identity_info: struct netr_IdentityInfo > domain_name: struct lsa_String > length : 0x0010 (16) > size : 0x01fe (510) > string : * > string : 'IPA.TEST' > parameter_control : 0x00002ae0 (10976) > 0: MSV1_0_CLEARTEXT_PASSWORD_ALLOWED > 0: MSV1_0_UPDATE_LOGON_STATISTICS > 0: MSV1_0_RETURN_USER_PARAMETERS > 0: MSV1_0_DONT_TRY_GUEST_ACCOUNT > 1: MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT > 1: MSV1_0_RETURN_PASSWORD_EXPIRY > 1: MSV1_0_USE_CLIENT_CHALLENGE > 0: MSV1_0_TRY_GUEST_ACCOUNT_ONLY > 1: MSV1_0_RETURN_PROFILE_PATH > 0: MSV1_0_TRY_SPECIFIED_DOMAIN_ONLY > 1: MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT > 0: MSV1_0_DISABLE_PERSONAL_FALLBACK > 1: MSV1_0_ALLOW_FORCE_GUEST > 0: MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED > 0: MSV1_0_USE_DOMAIN_FOR_ROUTING_ONLY > 0: MSV1_0_ALLOW_MSVCHAPV2 > 0: MSV1_0_S4U2SELF > 0: MSV1_0_CHECK_LOGONHOURS_FOR_S4U > 0: MSV1_0_SUBAUTHENTICATION_DLL_EX > logon_id : 0x0000000000884ef2 (8933106) > account_name: struct lsa_String > length : 0x000e (14) > size : 0x000e (14) > string : * > string : 'idmuser' > workstation: struct lsa_String > length : 0x0000 (0) > size : 0x0000 (0) > string : * > string : '' > challenge : 417207867bd33c74 > nt: struct netr_ChallengeResponse > length : 0x00c0 (192) > size : 0x00c0 (192) > data : * > data: ARRAY(192) > [0000] A5 24 62 6E 31 DF 69 66 9E DC 54 D6 63 4C D6 2F .$bn1.if ..T.cL./ > [0010] 01 01 00 00 00 00 00 00 50 37 D7 60 0C B8 D6 01 ........ P7.`.... > [0020] 15 1B 38 4F 47 95 4D 62 00 00 00 00 02 00 0E 00 ..8OG.Mb ........ > [0030] 57 00 49 00 4E 00 32 00 30 00 31 00 36 00 01 00 W.I.N.2. 0.1.6... > [0040] 06 00 41 00 44 00 31 00 04 00 18 00 77 00 69 00 ..A.D.1. ....w.i. > [0050] 6E 00 32 00 30 00 31 00 36 00 2E 00 74 00 65 00 n.2.0.1. 6...t.e. > [0060] 73 00 74 00 03 00 20 00 61 00 64 00 31 00 2E 00 s.t... . a.d.1... > [0070] 77 00 69 00 6E 00 32 00 30 00 31 00 36 00 2E 00 w.i.n.2. 0.1.6... > [0080] 74 00 65 00 73 00 74 00 05 00 18 00 77 00 69 00 t.e.s.t. ....w.i. > [0090] 6E 00 32 00 30 00 31 00 36 00 2E 00 74 00 65 00 n.2.0.1. 6...t.e. > [00A0] 73 00 74 00 07 00 08 00 50 37 D7 60 0C B8 D6 01 s.t..... P7.`.... > [00B0] 06 00 04 00 02 00 00 00 00 00 00 00 00 00 00 00 ........ ........ > lm: struct netr_ChallengeResponse > length : 0x0018 (24) > size : 0x0018 (24) > data : * > data : 000000000000000000000000000000000000000000000000 > validation_level : 0x0006 (6) > flags : * > flags : 0x00000000 (0) > 0: NETLOGON_SAMLOGON_FLAG_PASS_TO_FOREST_ROOT > 0: NETLOGON_SAMLOGON_FLAG_PASS_CROSS_FOREST_HOP > 0: NETLOGON_SAMLOGON_FLAG_RODC_TO_OTHER_DOMAIN > 0: NETLOGON_SAMLOGON_FLAG_RODC_NTLM_REQUEST > >In such case checks for a workgroup name will not match the DNS forest >name used in the username specification: > >[2020/11/11 09:23:53.283055, 3, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:200(auth_check_ntlm_password) > check_ntlm_password: Checking password for unmapped user [IPA.TEST]\[idmuser]@[] with the new password interface >[2020/11/11 09:23:53.283073, 3, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:203(auth_check_ntlm_password) > check_ntlm_password: mapped user is: [IPA.TEST]\[idmuser]@[] >[2020/11/11 09:23:53.283082, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:213(auth_check_ntlm_password) > check_ntlm_password: auth_context challenge created by fixed >[2020/11/11 09:23:53.283091, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:216(auth_check_ntlm_password) > challenge is: >[2020/11/11 09:23:53.283099, 5, pid=42677, effective(65534, 65534), real(65534, 0)] ../../lib/util/util.c:678(dump_data) > [0000] 41 72 07 86 7B D3 3C 74 Ar..{.<t >[2020/11/11 09:23:53.283113, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth_sam.c:209(auth_sam_netlogon3_auth) > auth_sam_netlogon3_auth: Check auth for: [IPA.TEST]\[idmuser] >[2020/11/11 09:23:53.283123, 5, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth_sam.c:234(auth_sam_netlogon3_auth) > auth_sam_netlogon3_auth: IPA.TEST is not our domain name (DC for IPA) >[2020/11/11 09:23:53.283131, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:249(auth_check_ntlm_password) > auth_check_ntlm_password: sam_netlogon3 had nothing to say > >and overall authentication attempt will fail: auth_winbind will complain >that this domain is not a trusted one and refuse operating on it: > >[2020/11/11 09:23:53.283784, 10, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd.c:742(process_request_send) > process_request_send: process_request: Handling async request smbd(42677):PAM_AUTH_CRAP >[2020/11/11 09:23:53.283796, 3, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd_pam_auth_crap.c:110(winbindd_pam_auth_crap_send) > [42677]: pam auth crap domain: [IPA.TEST] user: idmuser >[2020/11/11 09:23:53.283810, 3, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd_pam.c:409(find_auth_domain) > Authentication for domain [IPA.TEST] refused as it is not a trusted domain >[2020/11/11 09:23:53.283825, 10, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd.c:810(process_request_done) > process_request_done: [smbd(42677):PAM_AUTH_CRAP]: NT_STATUS_NO_SUCH_USER >[2020/11/11 09:23:53.283844, 10, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd.c:855(process_request_written) > process_request_written: [smbd(42677):PAM_AUTH_CRAP]: delivered response to client > >Signed-off-by: Alexander Bokovoy <ab@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 2a8b672652dcbcf55ec59be537773d76f0f14d0a) >--- > source3/auth/auth_sam.c | 45 +++++++++++++++++++++++++++++++++++++---- > 1 file changed, 41 insertions(+), 4 deletions(-) > >diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c >index f9764d87e3c..8fc552d9242 100644 >--- a/source3/auth/auth_sam.c >+++ b/source3/auth/auth_sam.c >@@ -22,6 +22,7 @@ > > #include "includes.h" > #include "auth.h" >+#include "passdb.h" > > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_AUTH >@@ -139,10 +140,28 @@ static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context, > break; > case ROLE_DOMAIN_PDC: > case ROLE_DOMAIN_BDC: >- if ( !is_local_name && !is_my_domain ) { >- DEBUG(6,("check_samstrict_security: %s is not one of my local names or domain name (DC)\n", >- effective_domain)); >- return NT_STATUS_NOT_IMPLEMENTED; >+ if (!is_local_name && !is_my_domain) { >+ /* If we are running on a DC that has PASSDB module with domain >+ * information, check if DNS forest name is matching the domain >+ * name. This is the case of FreeIPA domain controller when >+ * trusted AD DCs attempt to authenticate FreeIPA users using >+ * the forest root domain (which is the only domain in FreeIPA). >+ */ >+ struct pdb_domain_info *dom_info = NULL; >+ >+ dom_info = pdb_get_domain_info(mem_ctx); >+ if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) { >+ is_my_domain = strequal(user_info->mapped.domain_name, >+ dom_info->dns_forest); >+ } >+ >+ TALLOC_FREE(dom_info); >+ if (!is_my_domain) { >+ DEBUG(6,("check_samstrict_security: %s is not one " >+ "of my local names or domain name (DC)\n", >+ effective_domain)); >+ return NT_STATUS_NOT_IMPLEMENTED; >+ } > } > > break; >@@ -224,6 +243,24 @@ static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context, > } > > is_my_domain = strequal(user_info->mapped.domain_name, lp_workgroup()); >+ if (!is_my_domain) { >+ /* If we are running on a DC that has PASSDB module with domain >+ * information, check if DNS forest name is matching the domain >+ * name. This is the case of FreeIPA domain controller when >+ * trusted AD DCs attempt to authenticate FreeIPA users using >+ * the forest root domain (which is the only domain in FreeIPA). >+ */ >+ struct pdb_domain_info *dom_info = NULL; >+ dom_info = pdb_get_domain_info(mem_ctx); >+ >+ if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) { >+ is_my_domain = strequal(user_info->mapped.domain_name, >+ dom_info->dns_forest); >+ } >+ >+ TALLOC_FREE(dom_info); >+ } >+ > if (!is_my_domain) { > DBG_INFO("%s is not our domain name (DC for %s)\n", > effective_domain, lp_workgroup()); >-- >2.25.1 > > >From e1abe3c8529e460ede7291d68f578273debfc490 Mon Sep 17 00:00:00 2001 >From: Alexander Bokovoy <ab@samba.org> >Date: Tue, 10 Nov 2020 17:35:24 +0200 >Subject: [PATCH 433/686] CVE-2020-25717 lookup_name: allow lookup names > prefixed with DNS forest root for FreeIPA DC > >In FreeIPA deployment with active Global Catalog service, when a two-way >trust to Active Directory forest is established, Windows systems can >look up FreeIPA users and groups. When using a security tab in Windows >Explorer on AD side, a lookup over a trusted forest might come as >realm\name instead of NetBIOS domain name: > >-------------------------------------------------------------------- >[2020/01/13 11:12:39.859134, 1, pid=33253, effective(1732401004, 1732401004), real(1732401004, 0), class=rpc_parse] ../../librpc/ndr/ndr.c:471(ndr_print_function_debug) > lsa_LookupNames3: struct lsa_LookupNames3 > in: struct lsa_LookupNames3 > handle : * > handle: struct policy_handle > handle_type : 0x00000000 (0) > uuid : 0000000e-0000-0000-1c5e-a750e5810000 > num_names : 0x00000001 (1) > names: ARRAY(1) > names: struct lsa_String > length : 0x001e (30) > size : 0x0020 (32) > string : * > string : 'ipa.test\admins' > sids : * > sids: struct lsa_TransSidArray3 > count : 0x00000000 (0) > sids : NULL > level : LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 (6) > count : * > count : 0x00000000 (0) > lookup_options : LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES (0) > client_revision : LSA_CLIENT_REVISION_2 (2) >-------------------------------------------------------------------- > >If we are running as a DC and PASSDB supports returning domain info >(pdb_get_domain_info() returns a valid structure), check domain of the >name in lookup_name() against DNS forest name and allow the request to >be done against the primary domain. This corresponds to FreeIPA's use of >Samba as a DC. For normal domain members a realm-based lookup falls back >to a lookup over to its own domain controller with the help of winbindd. > >Signed-off-by: Alexander Bokovoy <ab@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Alexander Bokovoy <ab@samba.org> >Autobuild-Date(master): Wed Nov 11 10:59:01 UTC 2020 on sn-devel-184 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 31c703766fd2b89737826fb7e9a707f0622bb8cd) >--- > source3/passdb/lookup_sid.c | 37 ++++++++++++++++++++++++++++--------- > 1 file changed, 28 insertions(+), 9 deletions(-) > >diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c >index 87f8ac81521..9f7891b7d4a 100644 >--- a/source3/passdb/lookup_sid.c >+++ b/source3/passdb/lookup_sid.c >@@ -113,17 +113,36 @@ bool lookup_name(TALLOC_CTX *mem_ctx, > full_name, domain, name)); > DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags)); > >- if (((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) && >- strequal(domain, get_global_sam_name())) >- { >+ if ((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) { >+ bool check_global_sam = false; >+ >+ check_global_sam = strequal(domain, get_global_sam_name()); >+ >+ /* If we are running on a DC that has PASSDB module with domain >+ * information, check if DNS forest name is matching the domain >+ * name. This is the case of FreeIPA domain controller when >+ * trusted AD DC looks up users found in a Global Catalog of >+ * the forest root domain. */ >+ if (!check_global_sam && (IS_DC)) { >+ struct pdb_domain_info *dom_info = NULL; >+ dom_info = pdb_get_domain_info(tmp_ctx); >+ >+ if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) { >+ check_global_sam = strequal(domain, dom_info->dns_forest); >+ } > >- /* It's our own domain, lookup the name in passdb */ >- if (lookup_global_sam_name(name, flags, &rid, &type)) { >- sid_compose(&sid, get_global_sam_sid(), rid); >- goto ok; >+ TALLOC_FREE(dom_info); >+ } >+ >+ if (check_global_sam) { >+ /* It's our own domain, lookup the name in passdb */ >+ if (lookup_global_sam_name(name, flags, &rid, &type)) { >+ sid_compose(&sid, get_global_sam_sid(), rid); >+ goto ok; >+ } >+ TALLOC_FREE(tmp_ctx); >+ return false; > } >- TALLOC_FREE(tmp_ctx); >- return false; > } > > if ((flags & LOOKUP_NAME_BUILTIN) && >-- >2.25.1 > > >From 40e3f77d4f8ec23c06380f02748258d11d4bcbbc Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de> >Date: Sun, 18 Oct 2020 21:07:14 +0200 >Subject: [PATCH 434/686] CVE-2020-25717 auth_generic: fix empty initializer > compile warning > >Signed-off-by: Bjoern Jacke <bjacke@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit cce4e8012c5eafb6d98111b92923d748d72d077b) >--- > source3/auth/auth_generic.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c >index 0e9c423efef..ec397377ae5 100644 >--- a/source3/auth/auth_generic.c >+++ b/source3/auth/auth_generic.c >@@ -66,7 +66,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > > if (pac_blob) { > #ifdef HAVE_KRB5 >- struct wbcAuthUserParams params = {}; >+ struct wbcAuthUserParams params = { 0 }; > struct wbcAuthUserInfo *info = NULL; > struct wbcAuthErrorInfo *err = NULL; > wbcErr wbc_err; >-- >2.25.1 > > >From 3ef097c582e6043331bb035950b6ecdf7b2516a1 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Wed, 14 Apr 2021 10:05:59 +0200 >Subject: [PATCH 435/686] CVE-2020-25717 auth3: Simplify > check_samba4_security() > >First set up "server_info" in a local variable and once it's fully set >up, assign it to the out parameter "pserver_info". > >Pointer dereferencing obfuscates the code for me. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 062a0c14c6ee0b74e7619af73747df59c5e67672) >--- > source3/auth/auth_samba4.c | 29 +++++++++++++++++------------ > 1 file changed, 17 insertions(+), 12 deletions(-) > >diff --git a/source3/auth/auth_samba4.c b/source3/auth/auth_samba4.c >index a71c75631d7..02013698cbd 100644 >--- a/source3/auth/auth_samba4.c >+++ b/source3/auth/auth_samba4.c >@@ -107,11 +107,12 @@ static struct server_id *new_server_id_task(TALLOC_CTX *mem_ctx) > * services the AD DC. It is tested via pdbtest. > */ > >-static NTSTATUS check_samba4_security(const struct auth_context *auth_context, >- void *my_private_data, >- TALLOC_CTX *mem_ctx, >- const struct auth_usersupplied_info *user_info, >- struct auth_serversupplied_info **server_info) >+static NTSTATUS check_samba4_security( >+ const struct auth_context *auth_context, >+ void *my_private_data, >+ TALLOC_CTX *mem_ctx, >+ const struct auth_usersupplied_info *user_info, >+ struct auth_serversupplied_info **pserver_info) > { > TALLOC_CTX *frame = talloc_stackframe(); > struct netr_SamInfo3 *info3 = NULL; >@@ -119,6 +120,7 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context, > struct auth_user_info_dc *user_info_dc; > struct auth4_context *auth4_context; > uint8_t authoritative = 0; >+ struct auth_serversupplied_info *server_info = NULL; > > nt_status = make_auth4_context_s4(auth_context, mem_ctx, &auth4_context); > if (!NT_STATUS_IS_OK(nt_status)) { >@@ -160,17 +162,19 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context, > } > > if (user_info->flags & USER_INFO_INFO3_AND_NO_AUTHZ) { >- *server_info = make_server_info(mem_ctx); >- if (*server_info == NULL) { >+ server_info = make_server_info(mem_ctx); >+ if (server_info == NULL) { > nt_status = NT_STATUS_NO_MEMORY; > goto done; > } >- (*server_info)->info3 = talloc_steal(*server_info, info3); >- >+ server_info->info3 = talloc_move(server_info, &info3); > } else { >- nt_status = make_server_info_info3(mem_ctx, user_info->client.account_name, >- user_info->mapped.domain_name, server_info, >- info3); >+ nt_status = make_server_info_info3( >+ mem_ctx, >+ user_info->client.account_name, >+ user_info->mapped.domain_name, >+ &server_info, >+ info3); > if (!NT_STATUS_IS_OK(nt_status)) { > DEBUG(10, ("make_server_info_info3 failed: %s\n", > nt_errstr(nt_status))); >@@ -178,6 +182,7 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context, > } > } > >+ *pserver_info = server_info; > nt_status = NT_STATUS_OK; > > done: >-- >2.25.1 > > >From a70551aeea7c675b6006cbcb35412c43fbf91522 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 13 Apr 2021 15:14:01 +0000 >Subject: [PATCH 436/686] CVE-2020-25717 auth: Simplify DEBUG statements in > make_auth3_context_for_ntlm() > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 8536bf7fce41c43bbed25f7ed4ce5775a1b9c0d5) >--- > source3/auth/auth.c | 15 +++++++++------ > 1 file changed, 9 insertions(+), 6 deletions(-) > >diff --git a/source3/auth/auth.c b/source3/auth/auth.c >index 0a96d591808..53daad12ca4 100644 >--- a/source3/auth/auth.c >+++ b/source3/auth/auth.c >@@ -516,28 +516,28 @@ NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx, > struct auth_context **auth_context) > { > const char *methods = NULL; >+ const char *role = NULL; > > switch (lp_server_role()) { > case ROLE_ACTIVE_DIRECTORY_DC: >- DEBUG(5,("Making default auth method list for server role = " >- "'active directory domain controller'\n")); >+ role = "'active directory domain controller'"; > methods = "samba4"; > break; > case ROLE_DOMAIN_MEMBER: >- DEBUG(5,("Making default auth method list for server role = 'domain member'\n")); >+ role = "'domain member'"; > methods = "anonymous sam winbind sam_ignoredomain"; > break; > case ROLE_DOMAIN_BDC: > case ROLE_DOMAIN_PDC: >- DEBUG(5,("Making default auth method list for DC\n")); >+ role = "'DC'"; > methods = "anonymous sam winbind sam_ignoredomain"; > break; > case ROLE_STANDALONE: >- DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = yes\n")); > if (lp_encrypt_passwords()) { >+ role = "'standalone server', encrypt passwords = yes"; > methods = "anonymous sam_ignoredomain"; > } else { >- DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = no\n")); >+ role = "'standalone server', encrypt passwords = no"; > methods = "anonymous unix"; > } > break; >@@ -546,6 +546,9 @@ NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx, > return NT_STATUS_UNSUCCESSFUL; > } > >+ DBG_INFO("Making default auth method list for server role = %s\n", >+ role); >+ > return make_auth_context_specific(mem_ctx, auth_context, methods); > } > >-- >2.25.1 > > >From 13c317b9d14d18f95bdbc62bdb0da7ac409eed97 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Wed, 14 Apr 2021 21:48:32 +0200 >Subject: [PATCH 437/686] CVE-2020-25717 auth4: Make auth_anonymous > pseudo-async > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 759573136876ef2b1b1c7484f99570d7de957e0d) >--- > source4/auth/ntlm/auth_anonymous.c | 66 ++++++++++++++++++++++++++---- > source4/auth/ntlm/wscript_build | 2 +- > 2 files changed, 58 insertions(+), 10 deletions(-) > >diff --git a/source4/auth/ntlm/auth_anonymous.c b/source4/auth/ntlm/auth_anonymous.c >index 83aeb431f5f..a25aacaa137 100644 >--- a/source4/auth/ntlm/auth_anonymous.c >+++ b/source4/auth/ntlm/auth_anonymous.c >@@ -20,9 +20,11 @@ > */ > > #include "includes.h" >+#include <tevent.h> > #include "auth/auth.h" > #include "auth/ntlm/auth_proto.h" > #include "param/param.h" >+#include "lib/util/tevent_ntstatus.h" > > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_AUTH >@@ -84,19 +86,65 @@ static NTSTATUS anonymous_want_check(struct auth_method_context *ctx, > * anonymou logons to be dealt with in one place. Non-anonymou logons 'fail' > * and pass onto the next module. > **/ >-static NTSTATUS anonymous_check_password(struct auth_method_context *ctx, >- TALLOC_CTX *mem_ctx, >- const struct auth_usersupplied_info *user_info, >- struct auth_user_info_dc **_user_info_dc, >- bool *authoritative) >+ >+struct anonymous_check_password_state { >+ struct auth_user_info_dc *user_info_dc; >+}; >+ >+static struct tevent_req *anonymous_check_password_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct auth_method_context *ctx, >+ const struct auth_usersupplied_info *user_info) >+{ >+ struct tevent_req *req = NULL; >+ struct anonymous_check_password_state *state = NULL; >+ NTSTATUS status; >+ >+ req = tevent_req_create( >+ mem_ctx, >+ &state, >+ struct anonymous_check_password_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ >+ status = auth_anonymous_user_info_dc( >+ state, >+ lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), >+ &state->user_info_dc); >+ if (tevent_req_nterror(req, status)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_done(req); >+ return tevent_req_post(req, ev); >+} >+ >+static NTSTATUS anonymous_check_password_recv( >+ struct tevent_req *req, >+ TALLOC_CTX *mem_ctx, >+ struct auth_user_info_dc **interim_info, >+ bool *authoritative) > { >- return auth_anonymous_user_info_dc(mem_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), _user_info_dc); >+ struct anonymous_check_password_state *state = tevent_req_data( >+ req, struct anonymous_check_password_state); >+ NTSTATUS status; >+ >+ if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); >+ return status; >+ } >+ *interim_info = talloc_move(mem_ctx, &state->user_info_dc); >+ tevent_req_received(req); >+ return NT_STATUS_OK; > } > >+ > static const struct auth_operations anonymous_auth_ops = { >- .name = "anonymous", >- .want_check = anonymous_want_check, >- .check_password = anonymous_check_password >+ .name = "anonymous", >+ .want_check = anonymous_want_check, >+ .check_password_send = anonymous_check_password_send, >+ .check_password_recv = anonymous_check_password_recv, > }; > > _PUBLIC_ NTSTATUS auth4_anonymous_init(TALLOC_CTX *ctx) >diff --git a/source4/auth/ntlm/wscript_build b/source4/auth/ntlm/wscript_build >index 50d301deca4..8f41cc9ec9e 100644 >--- a/source4/auth/ntlm/wscript_build >+++ b/source4/auth/ntlm/wscript_build >@@ -12,7 +12,7 @@ bld.SAMBA_MODULE('auth4_anonymous', > source='auth_anonymous.c', > subsystem='auth4', > init_function='auth4_anonymous_init', >- deps='talloc' >+ deps='tevent' > ) > > >-- >2.25.1 > > >From d4f33ee0c14a7f88e876ea7409e06b692521f46a Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Wed, 14 Apr 2021 22:22:18 +0200 >Subject: [PATCH 438/686] CVE-2020-25717 auth4: Make auth_developer > pseudo-async > >This is a simpler approach to really just wrap the code. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 43a1e42815718591faa8d526319b96d089a758fa) >--- > source4/auth/ntlm/auth_developer.c | 61 +++++++++++++++++++++++++++++- > source4/auth/ntlm/wscript_build | 2 +- > 2 files changed, 61 insertions(+), 2 deletions(-) > >diff --git a/source4/auth/ntlm/auth_developer.c b/source4/auth/ntlm/auth_developer.c >index b655283975b..551f0ae1605 100644 >--- a/source4/auth/ntlm/auth_developer.c >+++ b/source4/auth/ntlm/auth_developer.c >@@ -20,9 +20,11 @@ > */ > > #include "includes.h" >+#include <tevent.h> > #include "auth/auth.h" > #include "auth/ntlm/auth_proto.h" > #include "libcli/security/security.h" >+#include "lib/util/tevent_ntstatus.h" > > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_AUTH >@@ -135,10 +137,67 @@ static NTSTATUS name_to_ntstatus_check_password(struct auth_method_context *ctx, > return nt_status; > } > >+struct name_to_ntstatus_check_password_state { >+ struct auth_user_info_dc *user_info_dc; >+ bool authoritative; >+}; >+ >+static struct tevent_req *name_to_ntstatus_check_password_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct auth_method_context *ctx, >+ const struct auth_usersupplied_info *user_info) >+{ >+ struct tevent_req *req = NULL; >+ struct name_to_ntstatus_check_password_state *state = NULL; >+ NTSTATUS status; >+ >+ req = tevent_req_create( >+ mem_ctx, >+ &state, >+ struct name_to_ntstatus_check_password_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ >+ status = name_to_ntstatus_check_password( >+ ctx, >+ state, >+ user_info, >+ &state->user_info_dc, >+ &state->authoritative); >+ if (tevent_req_nterror(req, status)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_done(req); >+ return tevent_req_post(req, ev); >+} >+ >+static NTSTATUS name_to_ntstatus_check_password_recv( >+ struct tevent_req *req, >+ TALLOC_CTX *mem_ctx, >+ struct auth_user_info_dc **interim_info, >+ bool *authoritative) >+{ >+ struct name_to_ntstatus_check_password_state *state = tevent_req_data( >+ req, struct name_to_ntstatus_check_password_state); >+ NTSTATUS status; >+ >+ if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); >+ return status; >+ } >+ *interim_info = talloc_move(mem_ctx, &state->user_info_dc); >+ *authoritative = state->authoritative; >+ tevent_req_received(req); >+ return NT_STATUS_OK; >+} >+ > static const struct auth_operations name_to_ntstatus_auth_ops = { > .name = "name_to_ntstatus", > .want_check = name_to_ntstatus_want_check, >- .check_password = name_to_ntstatus_check_password >+ .check_password_send = name_to_ntstatus_check_password_send, >+ .check_password_recv = name_to_ntstatus_check_password_recv, > }; > > _PUBLIC_ NTSTATUS auth4_developer_init(TALLOC_CTX *ctx) >diff --git a/source4/auth/ntlm/wscript_build b/source4/auth/ntlm/wscript_build >index 8f41cc9ec9e..bb54909e1fc 100644 >--- a/source4/auth/ntlm/wscript_build >+++ b/source4/auth/ntlm/wscript_build >@@ -28,7 +28,7 @@ bld.SAMBA_MODULE('auth4_developer', > source='auth_developer.c', > subsystem='auth4', > init_function='auth4_developer_init', >- deps='talloc' >+ deps='tevent' > ) > > >-- >2.25.1 > > >From 6bbf465ea3e33fff3c4db19d0c21c120f6e4cd49 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Wed, 14 Apr 2021 21:59:55 +0200 >Subject: [PATCH 439/686] CVE-2020-25717 auth4: Make auth_unix pseudo-async > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit a6f42ab8a778b9863990da3112c2e868cd006303) >--- > source4/auth/ntlm/auth_unix.c | 85 ++++++++++++++++++++++++----------- > 1 file changed, 59 insertions(+), 26 deletions(-) > >diff --git a/source4/auth/ntlm/auth_unix.c b/source4/auth/ntlm/auth_unix.c >index 67cd5f3dc44..cfe4f1a073f 100644 >--- a/source4/auth/ntlm/auth_unix.c >+++ b/source4/auth/ntlm/auth_unix.c >@@ -27,6 +27,7 @@ > #include "lib/tsocket/tsocket.h" > #include "../libcli/auth/pam_errors.h" > #include "param/param.h" >+#include "lib/util/tevent_ntstatus.h" > > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_AUTH >@@ -713,46 +714,78 @@ static NTSTATUS authunix_want_check(struct auth_method_context *ctx, > return NT_STATUS_OK; > } > >-static NTSTATUS authunix_check_password(struct auth_method_context *ctx, >- TALLOC_CTX *mem_ctx, >- const struct auth_usersupplied_info *user_info, >- struct auth_user_info_dc **user_info_dc, >- bool *authoritative) >+struct authunix_check_password_state { >+ struct auth_user_info_dc *user_info_dc; >+}; >+ >+static struct tevent_req *authunix_check_password_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct auth_method_context *ctx, >+ const struct auth_usersupplied_info *user_info) > { >- TALLOC_CTX *check_ctx; >- NTSTATUS nt_status; >- struct passwd *pwd; >+ struct tevent_req *req = NULL; >+ struct authunix_check_password_state *state = NULL; >+ struct passwd *pwd = NULL; >+ NTSTATUS status; > >- if (user_info->password_state != AUTH_PASSWORD_PLAIN) { >- return NT_STATUS_INVALID_PARAMETER; >+ req = tevent_req_create( >+ mem_ctx, >+ &state, >+ struct authunix_check_password_state); >+ if (req == NULL) { >+ return NULL; > } > >- check_ctx = talloc_named_const(mem_ctx, 0, "check_unix_password"); >- if (check_ctx == NULL) { >- return NT_STATUS_NO_MEMORY; >+ if (user_info->password_state != AUTH_PASSWORD_PLAIN) { >+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); >+ return tevent_req_post(req, ev); > } > >- nt_status = check_unix_password(check_ctx, ctx->auth_ctx->lp_ctx, user_info, &pwd); >- if (!NT_STATUS_IS_OK(nt_status)) { >- talloc_free(check_ctx); >- return nt_status; >+ status = check_unix_password( >+ state, ctx->auth_ctx->lp_ctx, user_info, &pwd); >+ if (tevent_req_nterror(req, status)) { >+ return tevent_req_post(req, ev); > } > >- nt_status = authunix_make_user_info_dc(mem_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), >- user_info, pwd, user_info_dc); >- if (!NT_STATUS_IS_OK(nt_status)) { >- talloc_free(check_ctx); >- return nt_status; >+ status = authunix_make_user_info_dc( >+ state, >+ lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), >+ user_info, >+ pwd, >+ &state->user_info_dc); >+ if (tevent_req_nterror(req, status)) { >+ return tevent_req_post(req, ev); > } > >- talloc_free(check_ctx); >+ tevent_req_done(req); >+ return tevent_req_post(req, ev); >+} >+ >+static NTSTATUS authunix_check_password_recv( >+ struct tevent_req *req, >+ TALLOC_CTX *mem_ctx, >+ struct auth_user_info_dc **interim_info, >+ bool *authoritative) >+{ >+ struct authunix_check_password_state *state = tevent_req_data( >+ req, struct authunix_check_password_state); >+ NTSTATUS status; >+ >+ if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); >+ return status; >+ } >+ *interim_info = talloc_move(mem_ctx, &state->user_info_dc); >+ tevent_req_received(req); > return NT_STATUS_OK; > } > > static const struct auth_operations unix_ops = { >- .name = "unix", >- .want_check = authunix_want_check, >- .check_password = authunix_check_password >+ .name = "unix", >+ .want_check = authunix_want_check, >+ .check_password_send = authunix_check_password_send, >+ .check_password_recv = authunix_check_password_recv, > }; > > _PUBLIC_ NTSTATUS auth4_unix_init(TALLOC_CTX *ctx) >-- >2.25.1 > > >From 7b6eb0cd2627db1cbf2d21e2b3986a3539b8e512 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 15 Apr 2021 10:04:21 +0200 >Subject: [PATCH 440/686] CVE-2020-25717 auth4: Make auth_sam pseudo-async > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit f852fb4cd4e2bcd676a9ea104c5bf00979771eed) >--- > source4/auth/ntlm/auth_sam.c | 69 ++++++++++++++++++++++++++++++++++-- > 1 file changed, 67 insertions(+), 2 deletions(-) > >diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c >index 70eddc12c53..e4ebeae7523 100644 >--- a/source4/auth/ntlm/auth_sam.c >+++ b/source4/auth/ntlm/auth_sam.c >@@ -36,6 +36,7 @@ > #include "lib/messaging/irpc.h" > #include "libcli/auth/libcli_auth.h" > #include "libds/common/roles.h" >+#include "lib/util/tevent_ntstatus.h" > > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_AUTH >@@ -732,6 +733,68 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx > return NT_STATUS_OK; > } > >+struct authsam_check_password_state { >+ struct auth_user_info_dc *user_info_dc; >+ bool authoritative; >+}; >+ >+static struct tevent_req *authsam_check_password_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct auth_method_context *ctx, >+ const struct auth_usersupplied_info *user_info) >+{ >+ struct tevent_req *req = NULL; >+ struct authsam_check_password_state *state = NULL; >+ NTSTATUS status; >+ >+ req = tevent_req_create( >+ mem_ctx, &state, struct authsam_check_password_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ /* >+ * authsam_check_password_internals() sets this to false in >+ * the rodc case, otherwise it leaves it untouched. Default to >+ * "we're authoritative". >+ */ >+ state->authoritative = true; >+ >+ status = authsam_check_password_internals( >+ ctx, >+ state, >+ user_info, >+ &state->user_info_dc, >+ &state->authoritative); >+ if (tevent_req_nterror(req, status)) { >+ return tevent_req_post(req, ev); >+ } >+ >+ tevent_req_done(req); >+ return tevent_req_post(req, ev); >+} >+ >+static NTSTATUS authsam_check_password_recv( >+ struct tevent_req *req, >+ TALLOC_CTX *mem_ctx, >+ struct auth_user_info_dc **interim_info, >+ bool *authoritative) >+{ >+ struct authsam_check_password_state *state = tevent_req_data( >+ req, struct authsam_check_password_state); >+ NTSTATUS status; >+ >+ *authoritative = state->authoritative; >+ >+ if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); >+ return status; >+ } >+ *interim_info = talloc_move(mem_ctx, &state->user_info_dc); >+ tevent_req_received(req); >+ return NT_STATUS_OK; >+} >+ > static NTSTATUS authsam_ignoredomain_want_check(struct auth_method_context *ctx, > TALLOC_CTX *mem_ctx, > const struct auth_usersupplied_info *user_info) >@@ -887,14 +950,16 @@ static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx, > static const struct auth_operations sam_ignoredomain_ops = { > .name = "sam_ignoredomain", > .want_check = authsam_ignoredomain_want_check, >- .check_password = authsam_check_password_internals, >+ .check_password_send = authsam_check_password_send, >+ .check_password_recv = authsam_check_password_recv, > .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, > }; > > static const struct auth_operations sam_ops = { > .name = "sam", > .want_check = authsam_want_check, >- .check_password = authsam_check_password_internals, >+ .check_password_send = authsam_check_password_send, >+ .check_password_recv = authsam_check_password_recv, > .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, > }; > >-- >2.25.1 > > >From d5193105303b35b9ad78b9714098253d0d4cc5b7 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Wed, 14 Apr 2021 22:24:44 +0200 >Subject: [PATCH 441/686] CVE-2020-25717 auth4: Remove sync check_password from > auth_operations > >Remove complexity in the data structures, and pushes the async-ness >one level down. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >(cherry picked from commit 254af19ba89b4c42e5f45ec731e6577d2fcc6736) >--- > source4/auth/auth.h | 4 ---- > source4/auth/ntlm/auth.c | 44 ++++------------------------------------ > 2 files changed, 4 insertions(+), 44 deletions(-) > >diff --git a/source4/auth/auth.h b/source4/auth/auth.h >index 51895c9259f..3f9fb1ae3cb 100644 >--- a/source4/auth/auth.h >+++ b/source4/auth/auth.h >@@ -61,10 +61,6 @@ struct auth_operations { > > /* Given the user supplied info, check a password */ > >- NTSTATUS (*check_password)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, >- const struct auth_usersupplied_info *user_info, >- struct auth_user_info_dc **interim_info, >- bool *authoritative); > struct tevent_req *(*check_password_send)(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, > struct auth_method_context *ctx, >diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c >index 3a3fa7eaa59..7cf1be2e1f9 100644 >--- a/source4/auth/ntlm/auth.c >+++ b/source4/auth/ntlm/auth.c >@@ -331,7 +331,6 @@ static void auth_check_password_next(struct tevent_req *req) > struct auth_check_password_state *state = > tevent_req_data(req, struct auth_check_password_state); > struct tevent_req *subreq = NULL; >- bool authoritative = true; > NTSTATUS status; > > if (state->method == NULL) { >@@ -356,47 +355,12 @@ static void auth_check_password_next(struct tevent_req *req) > return; > } > >- if (state->method->ops->check_password_send != NULL) { >- subreq = state->method->ops->check_password_send(state, >- state->ev, >- state->method, >- state->user_info); >- if (tevent_req_nomem(subreq, req)) { >- return; >- } >- tevent_req_set_callback(subreq, >- auth_check_password_done, >- req); >- return; >- } >- >- if (state->method->ops->check_password == NULL) { >- tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >- return; >- } >- >- status = state->method->ops->check_password(state->method, >- state, >- state->user_info, >- &state->user_info_dc, >- &authoritative); >- if (!authoritative || >- NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { >- DEBUG(11,("auth_check_password_send: " >- "%s passes to the next method\n", >- state->method->ops->name)); >- state->method = state->method->next; >- auth_check_password_next(req); >- return; >- } >- >- /* the backend has handled the request */ >- >- if (tevent_req_nterror(req, status)) { >+ subreq = state->method->ops->check_password_send( >+ state, state->ev, state->method, state->user_info); >+ if (tevent_req_nomem(subreq, req)) { > return; > } >- >- tevent_req_done(req); >+ tevent_req_set_callback(subreq, auth_check_password_done, req); > } > > static void auth_check_password_done(struct tevent_req *subreq) >-- >2.25.1 > > >From 3b04b1989954c1550d87d0a878492b03650f1143 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 2 Nov 2021 15:39:53 +0100 >Subject: [PATCH 442/686] CVE-2020-25719 selftest/knownfail_mit_kdc: Add > pointless knownfail to allow a later cherry-pick to apply cleanly > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 >--- > selftest/knownfail_mit_kdc | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 0f845fb9b1c..4fc68ffd854 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -276,6 +276,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_ldap_service_ticket\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_get_ticket_for_host_service_of_machine_account\(ad_dc\) > # >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_request_no_pac\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required\(ad_dc\) > # >-- >2.25.1 > > >From 4f9358f9654013cc8bfcc11f0649a42dbecd5b30 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 13 Sep 2021 21:48:13 +1200 >Subject: [PATCH 443/686] CVE-2020-25722 selftest: Move > self.assertRaisesLdbError() to samba.tests.TestCase > >This is easier to reason with regarding which cases should work >and which cases should fail, avoiding issues where more success >than expected would be OK because a self.fail() was missed in a >try: block. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 298515cac2f35082483c2b4e4b7dbfe4df1d2e0c) > >[jsutton@samba.org Removed changes to non-existing file > source4/dsdb/tests/python/subtree_rename.py] >--- > python/samba/tests/__init__.py | 25 +++++++++++++++++++ > .../dsdb/tests/python/linked_attributes.py | 21 ---------------- > 2 files changed, 25 insertions(+), 21 deletions(-) > >diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py >index 525349626b4..1bcc3f4f04f 100644 >--- a/python/samba/tests/__init__.py >+++ b/python/samba/tests/__init__.py >@@ -296,6 +296,31 @@ class TestCase(unittest.TestCase): > > self.fail(msg) > >+ def assertRaisesLdbError(self, errcode, message, f, *args, **kwargs): >+ """Assert a function raises a particular LdbError.""" >+ try: >+ f(*args, **kwargs) >+ except ldb.LdbError as e: >+ (num, msg) = e.args >+ if num != errcode: >+ lut = {v: k for k, v in vars(ldb).items() >+ if k.startswith('ERR_') and isinstance(v, int)} >+ self.fail("%s, expected " >+ "LdbError %s, (%d) " >+ "got %s (%d) " >+ "%s" % (message, >+ lut.get(errcode), errcode, >+ lut.get(num), num, >+ msg)) >+ else: >+ lut = {v: k for k, v in vars(ldb).items() >+ if k.startswith('ERR_') and isinstance(v, int)} >+ self.fail("%s, expected " >+ "LdbError %s, (%d) " >+ "but we got success" % (message, >+ lut.get(errcode), >+ errcode)) >+ > > class LdbTestCase(TestCase): > """Trivial test case for running tests against a LDB.""" >diff --git a/source4/dsdb/tests/python/linked_attributes.py b/source4/dsdb/tests/python/linked_attributes.py >index d015065ab04..b14fefc46c1 100644 >--- a/source4/dsdb/tests/python/linked_attributes.py >+++ b/source4/dsdb/tests/python/linked_attributes.py >@@ -166,27 +166,6 @@ class LATests(samba.tests.TestCase): > attrs=['objectGUID']) > return str(misc.GUID(res[0]['objectGUID'][0])) > >- def assertRaisesLdbError(self, errcode, msg, f, *args, **kwargs): >- """Assert a function raises a particular LdbError.""" >- try: >- f(*args, **kwargs) >- except ldb.LdbError as e: >- (num, msg) = e.args >- if num != errcode: >- lut = {v: k for k, v in vars(ldb).items() >- if k.startswith('ERR_') and isinstance(v, int)} >- self.fail("%s, expected " >- "LdbError %s, (%d) " >- "got %s (%d)" % (msg, >- lut.get(errcode), errcode, >- lut.get(num), num)) >- else: >- lut = {v: k for k, v in vars(ldb).items() >- if k.startswith('ERR_') and isinstance(v, int)} >- self.fail("%s, expected " >- "LdbError %s, (%d) " >- "but we got success" % (msg, lut.get(errcode), errcode)) >- > def _test_la_backlinks(self, reveal=False): > tag = 'backlinks' > kwargs = {} >-- >2.25.1 > > >From d2d232da67711570864ff0bd0fbd0c262d5f8129 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 30 Aug 2021 10:07:31 +1200 >Subject: [PATCH 444/686] CVE-2020-25722 selftest: Modernise > user_account_control.py tests use a common self.OU > >We set and use a single self.OU to ensure consistancy and >reduce string duplication. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 >(cherry picked from commit 8b078bbf8717b9407cdbc1588dd065164ab78e1b) >--- > .../dsdb/tests/python/user_account_control.py | 46 +++++++++---------- > 1 file changed, 23 insertions(+), 23 deletions(-) > >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index 2d62d4c32b1..cb614b165e5 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -90,7 +90,7 @@ class UserAccountControlTests(samba.tests.TestCase): > def add_computer_ldap(self, computername, others=None, samdb=None): > if samdb is None: > samdb = self.samdb >- dn = "CN=%s,OU=test_computer_ou1,%s" % (computername, self.base_dn) >+ dn = "CN=%s,%s" % (computername, self.OU) > domainname = ldb.Dn(self.samdb, self.samdb.domain_dn()).canonical_str().replace("/", "") > samaccountname = "%s$" % computername > dnshostname = "%s.%s" % (computername, domainname) >@@ -131,8 +131,9 @@ class UserAccountControlTests(samba.tests.TestCase): > self.unpriv_user_pw = "samba123@" > self.unpriv_creds = self.get_creds(self.unpriv_user, self.unpriv_user_pw) > >- delete_force(self.admin_samdb, "CN=testcomputer-t,OU=test_computer_ou1,%s" % (self.base_dn)) >- delete_force(self.admin_samdb, "OU=test_computer_ou1,%s" % (self.base_dn)) >+ self.OU = "OU=test_computer_ou1,%s" % (self.base_dn) >+ >+ delete_force(self.admin_samdb, self.OU, controls=["tree_delete:0"]) > delete_force(self.admin_samdb, "CN=%s,CN=Users,%s" % (self.unpriv_user, self.base_dn)) > > self.admin_samdb.newuser(self.unpriv_user, self.unpriv_user_pw) >@@ -151,27 +152,27 @@ class UserAccountControlTests(samba.tests.TestCase): > self.samr_domain = self.samr.OpenDomain(self.samr_handle, security.SEC_FLAG_MAXIMUM_ALLOWED, self.domain_sid) > > self.sd_utils = sd_utils.SDUtils(self.admin_samdb) >+ self.admin_samdb.create_ou(self.OU) > >- self.admin_samdb.create_ou("OU=test_computer_ou1," + self.base_dn) > self.unpriv_user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) > mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(self.unpriv_user_sid) > >- old_sd = self.sd_utils.read_sd_on_dn("OU=test_computer_ou1," + self.base_dn) >+ old_sd = self.sd_utils.read_sd_on_dn(self.OU) > >- self.sd_utils.dacl_add_ace("OU=test_computer_ou1," + self.base_dn, mod) >+ self.sd_utils.dacl_add_ace(self.OU, mod) > > self.add_computer_ldap("testcomputer-t") > >- self.sd_utils.modify_sd_on_dn("OU=test_computer_ou1," + self.base_dn, old_sd) >+ self.sd_utils.modify_sd_on_dn(self.OU, old_sd) > > self.computernames = ["testcomputer-0"] > > # Get the SD of the template account, then force it to match > # what we expect for SeMachineAccountPrivilege accounts, so we > # can confirm we created the accounts correctly >- self.sd_reference_cc = self.sd_utils.read_sd_on_dn("CN=testcomputer-t,OU=test_computer_ou1,%s" % (self.base_dn)) >+ self.sd_reference_cc = self.sd_utils.read_sd_on_dn("CN=testcomputer-t,%s" % (self.OU)) > >- self.sd_reference_modify = self.sd_utils.read_sd_on_dn("CN=testcomputer-t,OU=test_computer_ou1,%s" % (self.base_dn)) >+ self.sd_reference_modify = self.sd_utils.read_sd_on_dn("CN=testcomputer-t,%s" % (self.OU)) > for ace in self.sd_reference_modify.dacl.aces: > if ace.type == security.SEC_ACE_TYPE_ACCESS_ALLOWED and ace.trustee == self.unpriv_user_sid: > ace.access_mask = ace.access_mask | security.SEC_ADS_SELF_WRITE | security.SEC_ADS_WRITE_PROP >@@ -191,9 +192,8 @@ class UserAccountControlTests(samba.tests.TestCase): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) > mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) > >- old_sd = self.sd_utils.read_sd_on_dn("OU=test_computer_ou1," + self.base_dn) >- >- self.sd_utils.dacl_add_ace("OU=test_computer_ou1," + self.base_dn, mod) >+ old_sd = self.sd_utils.read_sd_on_dn(self.OU) >+ self.sd_utils.dacl_add_ace(self.OU, mod) > > computername = self.computernames[0] > sd = ldb.MessageElement((ndr_pack(self.sd_reference_modify)), >@@ -276,9 +276,9 @@ class UserAccountControlTests(samba.tests.TestCase): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) > mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) > >- old_sd = self.sd_utils.read_sd_on_dn("OU=test_computer_ou1," + self.base_dn) >+ old_sd = self.sd_utils.read_sd_on_dn(self.OU) > >- self.sd_utils.dacl_add_ace("OU=test_computer_ou1," + self.base_dn, mod) >+ self.sd_utils.dacl_add_ace(self.OU, mod) > > computername = self.computernames[0] > self.add_computer_ldap(computername) >@@ -392,9 +392,9 @@ class UserAccountControlTests(samba.tests.TestCase): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) > mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) > >- old_sd = self.sd_utils.read_sd_on_dn("OU=test_computer_ou1," + self.base_dn) >+ old_sd = self.sd_utils.read_sd_on_dn(self.OU) > >- self.sd_utils.dacl_add_ace("OU=test_computer_ou1," + self.base_dn, mod) >+ self.sd_utils.dacl_add_ace(self.OU, mod) > > computername = self.computernames[0] > self.add_computer_ldap(computername) >@@ -446,9 +446,9 @@ class UserAccountControlTests(samba.tests.TestCase): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) > mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) > >- old_sd = self.sd_utils.read_sd_on_dn("OU=test_computer_ou1," + self.base_dn) >+ old_sd = self.sd_utils.read_sd_on_dn(self.OU) > >- self.sd_utils.dacl_add_ace("OU=test_computer_ou1," + self.base_dn, mod) >+ self.sd_utils.dacl_add_ace(self.OU, mod) > > computername = self.computernames[0] > self.add_computer_ldap(computername, others={"userAccountControl": [str(account_type)]}) >@@ -621,9 +621,9 @@ class UserAccountControlTests(samba.tests.TestCase): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) > mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) > >- old_sd = self.sd_utils.read_sd_on_dn("OU=test_computer_ou1," + self.base_dn) >+ old_sd = self.sd_utils.read_sd_on_dn(self.OU) > >- self.sd_utils.dacl_add_ace("OU=test_computer_ou1," + self.base_dn, mod) >+ self.sd_utils.dacl_add_ace(self.OU, mod) > > invalid_bits = set([UF_TEMP_DUPLICATE_ACCOUNT, UF_PARTIAL_SECRETS_ACCOUNT]) > # These bits are privileged, but authenticated users have that CAR by default, so this is a pain to test >@@ -637,7 +637,7 @@ class UserAccountControlTests(samba.tests.TestCase): > for bit in bits: > try: > self.add_computer_ldap(computername, others={"userAccountControl": [str(bit)]}) >- delete_force(self.admin_samdb, "CN=%s,OU=test_computer_ou1,%s" % (computername, self.base_dn)) >+ delete_force(self.admin_samdb, "CN=%s,%s" % (computername, self.OU)) > if bit in priv_bits: > self.fail("Unexpectdly able to set userAccountControl bit 0x%08X on %s" % (bit, computername)) > >@@ -659,9 +659,9 @@ class UserAccountControlTests(samba.tests.TestCase): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) > mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) > >- old_sd = self.sd_utils.read_sd_on_dn("OU=test_computer_ou1," + self.base_dn) >+ old_sd = self.sd_utils.read_sd_on_dn(self.OU) > >- self.sd_utils.dacl_add_ace("OU=test_computer_ou1," + self.base_dn, mod) >+ self.sd_utils.dacl_add_ace(self.OU, mod) > try: > # When creating a new object, you can not ever set the primaryGroupID > self.add_computer_ldap(computername, others={"primaryGroupID": [str(security.DOMAIN_RID_ADMINS)]}) >-- >2.25.1 > > >From 31bba6a15b12d36d16347266b504df13b3a7e744 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 30 Aug 2021 10:10:56 +1200 >Subject: [PATCH 445/686] CVE-2020-25722 selftest: Use addCleanup rather than > tearDown in user_account_control.py > >self.addCleanup() is called regardless of the test failure or error status >and so is more reliable, particularly during development. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 >(cherry picked from commit 8c455268165f0bbfce17407df2c1746a0e03f828) >--- > source4/dsdb/tests/python/user_account_control.py | 10 ++-------- > 1 file changed, 2 insertions(+), 8 deletions(-) > >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index cb614b165e5..81664079adf 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -144,6 +144,7 @@ class UserAccountControlTests(samba.tests.TestCase): > > self.unpriv_user_sid = ndr_unpack(security.dom_sid, res[0]["objectSid"][0]) > self.unpriv_user_dn = res[0].dn >+ self.addCleanup(self.admin_samdb.delete, self.unpriv_user_dn) > > self.samdb = SamDB(url=ldaphost, credentials=self.unpriv_creds, lp=lp) > >@@ -153,6 +154,7 @@ class UserAccountControlTests(samba.tests.TestCase): > > self.sd_utils = sd_utils.SDUtils(self.admin_samdb) > self.admin_samdb.create_ou(self.OU) >+ self.addCleanup(self.admin_samdb.delete, self.OU, ["tree_delete:1"]) > > self.unpriv_user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) > mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(self.unpriv_user_sid) >@@ -180,14 +182,6 @@ class UserAccountControlTests(samba.tests.TestCase): > # Now reconnect without domain admin rights > self.samdb = SamDB(url=ldaphost, credentials=self.unpriv_creds, lp=lp) > >- def tearDown(self): >- super(UserAccountControlTests, self).tearDown() >- for computername in self.computernames: >- delete_force(self.admin_samdb, "CN=%s,OU=test_computer_ou1,%s" % (computername, self.base_dn)) >- delete_force(self.admin_samdb, "CN=testcomputer-t,OU=test_computer_ou1,%s" % (self.base_dn)) >- delete_force(self.admin_samdb, "OU=test_computer_ou1,%s" % (self.base_dn)) >- delete_force(self.admin_samdb, "CN=%s,CN=Users,%s" % (self.unpriv_user, self.base_dn)) >- > def test_add_computer_sd_cc(self): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) > mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) >-- >2.25.1 > > >From 79e63a61b07c58dea48bd4528a1c2e6545def79b Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 30 Aug 2021 13:03:15 +1200 >Subject: [PATCH 446/686] CVE-2020-25722 pydsdb: Add API to return strings of > known UF_ flags > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 >(cherry picked from commit fb6c0b9e2a10c9559d3e056bb020bd2c990da998) > >[jsutton@samba.org Adapted to fix conflict] >--- > libds/common/flag_mapping.c | 50 +++++++++++++++++++++++++++++ > libds/common/flag_mapping.h | 1 + > libds/common/flags.h | 5 +++ > python/samba/tests/dsdb_api.py | 57 ++++++++++++++++++++++++++++++++++ > selftest/tests.py | 1 + > source4/dsdb/pydsdb.c | 30 ++++++++++++++++++ > 6 files changed, 144 insertions(+) > create mode 100644 python/samba/tests/dsdb_api.py > >diff --git a/libds/common/flag_mapping.c b/libds/common/flag_mapping.c >index ddc8ec5c198..020922db659 100644 >--- a/libds/common/flag_mapping.c >+++ b/libds/common/flag_mapping.c >@@ -164,3 +164,53 @@ uint32_t ds_uf2prim_group_rid(uint32_t uf) > > return prim_group_rid; > } >+ >+#define FLAG(x) { .name = #x, .uf = x } >+struct { >+ const char *name; >+ uint32_t uf; >+} user_account_control_name_map[] = { >+ FLAG(UF_SCRIPT), >+ FLAG(UF_ACCOUNTDISABLE), >+ FLAG(UF_00000004), >+ FLAG(UF_HOMEDIR_REQUIRED), >+ FLAG(UF_LOCKOUT), >+ FLAG(UF_PASSWD_NOTREQD), >+ FLAG(UF_PASSWD_CANT_CHANGE), >+ FLAG(UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED), >+ >+ FLAG(UF_TEMP_DUPLICATE_ACCOUNT), >+ FLAG(UF_NORMAL_ACCOUNT), >+ FLAG(UF_00000400), >+ FLAG(UF_INTERDOMAIN_TRUST_ACCOUNT), >+ >+ FLAG(UF_WORKSTATION_TRUST_ACCOUNT), >+ FLAG(UF_SERVER_TRUST_ACCOUNT), >+ FLAG(UF_00004000), >+ FLAG(UF_00008000), >+ >+ FLAG(UF_DONT_EXPIRE_PASSWD), >+ FLAG(UF_MNS_LOGON_ACCOUNT), >+ FLAG(UF_SMARTCARD_REQUIRED), >+ FLAG(UF_TRUSTED_FOR_DELEGATION), >+ >+ FLAG(UF_NOT_DELEGATED), >+ FLAG(UF_USE_DES_KEY_ONLY), >+ FLAG(UF_DONT_REQUIRE_PREAUTH), >+ FLAG(UF_PASSWORD_EXPIRED), >+ FLAG(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION), >+ FLAG(UF_NO_AUTH_DATA_REQUIRED), >+ FLAG(UF_PARTIAL_SECRETS_ACCOUNT), >+ FLAG(UF_USE_AES_KEYS) >+}; >+ >+const char *dsdb_user_account_control_flag_bit_to_string(uint32_t uf) >+{ >+ int i; >+ for (i=0; i < ARRAY_SIZE(user_account_control_name_map); i++) { >+ if (uf == user_account_control_name_map[i].uf) { >+ return user_account_control_name_map[i].name; >+ } >+ } >+ return NULL; >+} >diff --git a/libds/common/flag_mapping.h b/libds/common/flag_mapping.h >index ae721da894a..f08d5593af6 100644 >--- a/libds/common/flag_mapping.h >+++ b/libds/common/flag_mapping.h >@@ -31,5 +31,6 @@ uint32_t ds_uf2atype(uint32_t uf); > uint32_t ds_gtype2atype(uint32_t gtype); > enum lsa_SidType ds_atype_map(uint32_t atype); > uint32_t ds_uf2prim_group_rid(uint32_t uf); >+const char *dsdb_user_account_control_flag_bit_to_string(uint32_t uf); > > #endif /* __LIBDS_COMMON_FLAG_MAPPING_H__ */ >diff --git a/libds/common/flags.h b/libds/common/flags.h >index d436f2bafd8..75e04b0c488 100644 >--- a/libds/common/flags.h >+++ b/libds/common/flags.h >@@ -18,6 +18,8 @@ > along with this program. If not, see <http://www.gnu.org/licenses/>. > */ > >+/* Please keep this list in sync with the flag_mapping.c and pydsdb.c */ >+ > /* User flags for "userAccountControl" */ > #define UF_SCRIPT 0x00000001 /* NT or Lan Manager Login script must be executed */ > #define UF_ACCOUNTDISABLE 0x00000002 >@@ -53,6 +55,9 @@ > #define UF_PARTIAL_SECRETS_ACCOUNT 0x04000000 > #define UF_USE_AES_KEYS 0x08000000 > >+/* Please keep this list in sync with the flag_mapping.c and pydsdb.c */ >+ >+ > #define UF_TRUST_ACCOUNT_MASK (\ > UF_INTERDOMAIN_TRUST_ACCOUNT |\ > UF_WORKSTATION_TRUST_ACCOUNT |\ >diff --git a/python/samba/tests/dsdb_api.py b/python/samba/tests/dsdb_api.py >new file mode 100644 >index 00000000000..997407917af >--- /dev/null >+++ b/python/samba/tests/dsdb_api.py >@@ -0,0 +1,57 @@ >+# Unix SMB/CIFS implementation. Tests for dsdb >+# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2021 >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+"""Tests for samba.dsdb.""" >+ >+from samba.tests import TestCase, DynamicTestCase >+from samba.dsdb import user_account_control_flag_bit_to_string >+import samba >+ >+ >+@DynamicTestCase >+class DsdbFlagTests(TestCase): >+ >+ @classmethod >+ def setUpDynamicTestCases(cls): >+ >+ for x in dir(samba.dsdb): >+ if x.startswith("UF_"): >+ cls.generate_dynamic_test("test", >+ x, >+ x, >+ getattr(samba.dsdb, x)) >+ >+ >+ def _test_with_args(self, uf_string, uf_bit): >+ self.assertEqual(user_account_control_flag_bit_to_string(uf_bit), >+ uf_string) >+ >+ >+ def test_not_a_flag(self): >+ self.assertRaises(KeyError, >+ user_account_control_flag_bit_to_string, >+ 0xabcdef) >+ >+ def test_too_long(self): >+ self.assertRaises(OverflowError, >+ user_account_control_flag_bit_to_string, >+ 0xabcdefffff) >+ >+ def test_way_too_long(self): >+ self.assertRaises(OverflowError, >+ user_account_control_flag_bit_to_string, >+ 0xabcdeffffffffffff) >diff --git a/selftest/tests.py b/selftest/tests.py >index 1748feeefb4..06a62b52fd2 100644 >--- a/selftest/tests.py >+++ b/selftest/tests.py >@@ -87,6 +87,7 @@ planpythontestsuite("none", "samba.tests.s3registry", py3_compatible=True) > planpythontestsuite("none", "samba.tests.s3windb", py3_compatible=True) > planpythontestsuite("none", "samba.tests.s3idmapdb", py3_compatible=True) > planpythontestsuite("none", "samba.tests.samba3sam") >+planpythontestsuite("none", "samba.tests.dsdb_api") > planpythontestsuite("fileserver", "samba.tests.smbd_fuzztest") > planpythontestsuite( > "none", "wafsamba.tests.test_suite", >diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c >index 4996bedfe76..4f7cf82c29c 100644 >--- a/source4/dsdb/pydsdb.c >+++ b/source4/dsdb/pydsdb.c >@@ -33,6 +33,7 @@ > #include "lib/util/dlinklist.h" > #include "dsdb/kcc/garbage_collect_tombstones.h" > #include "dsdb/kcc/scavenge_dns_records.h" >+#include "libds/common/flag_mapping.h" > > > /* FIXME: These should be in a header file somewhere */ >@@ -1381,6 +1382,30 @@ static PyObject *py_dsdb_load_udv_v2(PyObject *self, PyObject *args) > return pylist; > } > >+static PyObject *py_dsdb_user_account_control_flag_bit_to_string(PyObject *self, PyObject *args) >+{ >+ const char *str; >+ long long uf; >+ if (!PyArg_ParseTuple(args, "L", &uf)) { >+ return NULL; >+ } >+ >+ if (uf > UINT32_MAX) { >+ return PyErr_Format(PyExc_OverflowError, "No UF_ flags are over UINT32_MAX"); >+ } >+ if (uf < 0) { >+ return PyErr_Format(PyExc_KeyError, "No UF_ flags are less then zero"); >+ } >+ >+ str = dsdb_user_account_control_flag_bit_to_string(uf); >+ if (str == NULL) { >+ return PyErr_Format(PyExc_KeyError, >+ "No such UF_ flag 0x%08x", >+ (unsigned int)uf); >+ } >+ return PyUnicode_FromString(str); >+} >+ > static PyMethodDef py_dsdb_methods[] = { > { "_samdb_server_site_name", (PyCFunction)py_samdb_server_site_name, > METH_VARARGS, "Get the server site name as a string"}, >@@ -1460,6 +1485,11 @@ static PyMethodDef py_dsdb_methods[] = { > "_dsdb_allocate_rid(samdb)" > " -> RID" }, > { "_dsdb_load_udv_v2", (PyCFunction)py_dsdb_load_udv_v2, METH_VARARGS, NULL }, >+ { "user_account_control_flag_bit_to_string", >+ (PyCFunction)py_dsdb_user_account_control_flag_bit_to_string, >+ METH_VARARGS, >+ "user_account_control_flag_bit_to_string(bit)" >+ " -> string name" }, > {0} > }; > >-- >2.25.1 > > >From 38340aabc853fb38bd62e5d7378c697c4ceb43ff Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 30 Aug 2021 14:37:06 +1200 >Subject: [PATCH 447/686] CVE-2020-25722 selftest: Use @DynamicTestCase in > user_account_control test_uac_bits_unrelated_modify() > >This is a nice easy example of how the test generation >code works, and it combined nicely with the earlier >patch to return string names from the UF_ constants. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 >(cherry picked from commit 8701ce492fc3a209035b152961d8c17e801b082a) >--- > .../dsdb/tests/python/user_account_control.py | 19 +++++++++++-------- > 1 file changed, 11 insertions(+), 8 deletions(-) > >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index 81664079adf..4ef43502c8c 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -27,7 +27,7 @@ from samba.samdb import SamDB > from samba.dcerpc import samr, security, lsa > from samba.credentials import Credentials > from samba.ndr import ndr_unpack, ndr_pack >-from samba.tests import delete_force >+from samba.tests import delete_force, DynamicTestCase > from samba import gensec, sd_utils > from samba.credentials import DONT_USE_KERBEROS > from ldb import SCOPE_SUBTREE, SCOPE_BASE, LdbError >@@ -41,6 +41,7 @@ from samba.dsdb import UF_SCRIPT, UF_ACCOUNTDISABLE, UF_00000004, UF_HOMEDIR_REQ > UF_TRUSTED_FOR_DELEGATION, UF_NOT_DELEGATED, UF_USE_DES_KEY_ONLY, UF_DONT_REQUIRE_PREAUTH, \ > UF_PASSWORD_EXPIRED, UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, UF_NO_AUTH_DATA_REQUIRED, \ > UF_PARTIAL_SECRETS_ACCOUNT, UF_USE_AES_KEYS >+from samba import dsdb > > > parser = optparse.OptionParser("user_account_control.py [options] <host>") >@@ -86,7 +87,15 @@ bits = [UF_SCRIPT, UF_ACCOUNTDISABLE, UF_00000004, UF_HOMEDIR_REQUIRED, > account_types = set([UF_NORMAL_ACCOUNT, UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT]) > > >+@DynamicTestCase > class UserAccountControlTests(samba.tests.TestCase): >+ @classmethod >+ def setUpDynamicTestCases(cls): >+ for account_type in [UF_NORMAL_ACCOUNT, UF_WORKSTATION_TRUST_ACCOUNT]: >+ account_type_str = dsdb.user_account_control_flag_bit_to_string(account_type) >+ cls.generate_dynamic_test("test_uac_bits_unrelated_modify", >+ account_type_str, account_type) >+ > def add_computer_ldap(self, computername, others=None, samdb=None): > if samdb is None: > samdb = self.samdb >@@ -436,7 +445,7 @@ class UserAccountControlTests(samba.tests.TestCase): > else: > self.fail("Unable to set userAccountControl bit 0x%08X on %s: %s" % (bit, m.dn, estr)) > >- def uac_bits_unrelated_modify_helper(self, account_type): >+ def _test_uac_bits_unrelated_modify_with_args(self, account_type): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) > mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) > >@@ -603,12 +612,6 @@ class UserAccountControlTests(samba.tests.TestCase): > UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD, > "bit 0X%08x should have been removed" % bit) > >- def test_uac_bits_unrelated_modify_normal(self): >- self.uac_bits_unrelated_modify_helper(UF_NORMAL_ACCOUNT) >- >- def test_uac_bits_unrelated_modify_workstation(self): >- self.uac_bits_unrelated_modify_helper(UF_WORKSTATION_TRUST_ACCOUNT) >- > def test_uac_bits_add(self): > computername = self.computernames[0] > >-- >2.25.1 > > >From 13ced857c2e549c4090d64d076cac71165e5e515 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 30 Aug 2021 14:51:27 +1200 >Subject: [PATCH 448/686] CVE-2020-25722 selftest: Replace internal loop in > test_uac_bits_add() using @DynamicTestClass > >This generates a single test per bit which is easier to >debug. Elsewhere we use this pattern where we want to >be able to put some cases in a knownfail, which is otherwise >not possible. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 >(cherry picked from commit 60f1b6cf0ef0bf6736d8db9c53fa48fe9f3d8e75) >--- > .../dsdb/tests/python/user_account_control.py | 54 ++++++++++++------- > 1 file changed, 35 insertions(+), 19 deletions(-) > >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index 4ef43502c8c..1a396740df0 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -96,6 +96,16 @@ class UserAccountControlTests(samba.tests.TestCase): > cls.generate_dynamic_test("test_uac_bits_unrelated_modify", > account_type_str, account_type) > >+ for bit in bits: >+ try: >+ bit_str = dsdb.user_account_control_flag_bit_to_string(bit) >+ except KeyError: >+ bit_str = hex(bit) >+ >+ cls.generate_dynamic_test("test_uac_bits_add", >+ bit_str, bit, bit_str) >+ >+ > def add_computer_ldap(self, computername, others=None, samdb=None): > if samdb is None: > samdb = self.samdb >@@ -612,7 +622,7 @@ class UserAccountControlTests(samba.tests.TestCase): > UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD, > "bit 0X%08x should have been removed" % bit) > >- def test_uac_bits_add(self): >+ def _test_uac_bits_add_with_args(self, bit, bit_str): > computername = self.computernames[0] > > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) >@@ -631,24 +641,30 @@ class UserAccountControlTests(samba.tests.TestCase): > priv_bits = set([UF_INTERDOMAIN_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT, > UF_TRUSTED_FOR_DELEGATION, UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION]) > >- for bit in bits: >- try: >- self.add_computer_ldap(computername, others={"userAccountControl": [str(bit)]}) >- delete_force(self.admin_samdb, "CN=%s,%s" % (computername, self.OU)) >- if bit in priv_bits: >- self.fail("Unexpectdly able to set userAccountControl bit 0x%08X on %s" % (bit, computername)) >- >- except LdbError as e4: >- (enum, estr) = e4.args >- if bit in invalid_bits: >- self.assertEqual(enum, ldb.ERR_OTHER, "Invalid bit 0x%08X was able to be set on %s" % (bit, computername)) >- # No point going on, try the next bit >- continue >- elif bit in priv_bits: >- self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) >- continue >- else: >- self.fail("Unable to set userAccountControl bit 0x%08X on %s: %s" % (bit, computername, estr)) >+ try: >+ self.add_computer_ldap(computername, others={"userAccountControl": [str(bit)]}) >+ delete_force(self.admin_samdb, "CN=%s,%s" % (computername, self.OU)) >+ if bit in priv_bits: >+ self.fail("Unexpectdly able to set userAccountControl bit 0x%08X (%s) on %s" >+ % (bit, bit_str, computername)) >+ >+ except LdbError as e4: >+ (enum, estr) = e4.args >+ if bit in invalid_bits: >+ self.assertEqual(enum, >+ ldb.ERR_OTHER, >+ "Invalid bit 0x%08X (%s) was able to be set on %s" >+ % (bit, >+ bit_str, >+ computername)) >+ elif bit in priv_bits: >+ self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ else: >+ self.fail("Unable to set userAccountControl bit 0x%08X (%s) on %s: %s" >+ % (bit, >+ bit_str, >+ computername, >+ estr)) > > def test_primarygroupID_cc_add(self): > computername = self.computernames[0] >-- >2.25.1 > > >From 9ff4723c5563e59b2407866f47bd005119278a60 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 30 Aug 2021 14:54:39 +1200 >Subject: [PATCH 449/686] CVE-2020-25722 selftest: Replace internal loop in > test_uac_bits_set() using @DynamicTestClass > >This generates a single test per bit which is easier to >debug. Elsewhere we use this pattern where we want to >be able to put some cases in a knownfail, which is otherwise >not possible. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 >(cherry picked from commit 17ae0319db53a7b88e7fb44a9e2fd4bf1d1daa0e) >--- > .../dsdb/tests/python/user_account_control.py | 45 ++++++++++--------- > 1 file changed, 25 insertions(+), 20 deletions(-) > >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index 1a396740df0..fd0ae38a3f9 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -105,6 +105,9 @@ class UserAccountControlTests(samba.tests.TestCase): > cls.generate_dynamic_test("test_uac_bits_add", > bit_str, bit, bit_str) > >+ cls.generate_dynamic_test("test_uac_bits_set", >+ bit_str, bit, bit_str) >+ > > def add_computer_ldap(self, computername, others=None, samdb=None): > if samdb is None: >@@ -401,7 +404,7 @@ class UserAccountControlTests(samba.tests.TestCase): > > self.assertEqual(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE) > >- def test_uac_bits_set(self): >+ def _test_uac_bits_set_with_args(self, bit, bit_str): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) > mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) > >@@ -435,25 +438,27 @@ class UserAccountControlTests(samba.tests.TestCase): > > invalid_bits = set([UF_TEMP_DUPLICATE_ACCOUNT, UF_PARTIAL_SECRETS_ACCOUNT]) > >- for bit in bits: >- m = ldb.Message() >- m.dn = res[0].dn >- m["userAccountControl"] = ldb.MessageElement(str(bit | UF_PASSWD_NOTREQD), >- ldb.FLAG_MOD_REPLACE, "userAccountControl") >- try: >- self.samdb.modify(m) >- if (bit in priv_bits): >- self.fail("Unexpectedly able to set userAccountControl bit 0x%08X on %s" % (bit, m.dn)) >- except LdbError as e: >- (enum, estr) = e.args >- if bit in invalid_bits: >- self.assertEqual(enum, ldb.ERR_OTHER, "was not able to set 0x%08X on %s" % (bit, m.dn)) >- # No point going on, try the next bit >- continue >- elif (bit in priv_bits): >- self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum) >- else: >- self.fail("Unable to set userAccountControl bit 0x%08X on %s: %s" % (bit, m.dn, estr)) >+ m = ldb.Message() >+ m.dn = res[0].dn >+ m["userAccountControl"] = ldb.MessageElement(str(bit | UF_PASSWD_NOTREQD), >+ ldb.FLAG_MOD_REPLACE, "userAccountControl") >+ try: >+ self.samdb.modify(m) >+ if (bit in priv_bits): >+ self.fail("Unexpectedly able to set userAccountControl bit 0x%08X (%s), on %s" >+ % (bit, bit_str, m.dn)) >+ except LdbError as e: >+ (enum, estr) = e.args >+ if bit in invalid_bits: >+ self.assertEqual(enum, >+ ldb.ERR_OTHER, >+ "was not able to set 0x%08X (%s) on %s" >+ % (bit, bit_str, m.dn)) >+ elif (bit in priv_bits): >+ self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum) >+ else: >+ self.fail("Unable to set userAccountControl bit 0x%08X (%s) on %s: %s" >+ % (bit, bit_str, m.dn, estr)) > > def _test_uac_bits_unrelated_modify_with_args(self, account_type): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) >-- >2.25.1 > > >From aa05a237d7a52cf56ade66f045ecf9c7318fc7ae Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 30 Aug 2021 18:17:47 +1200 >Subject: [PATCH 450/686] CVE-2020-25722 selftest: Update user_account_control > tests to pass against Windows 2019 > >This gets us closer to passing against Windows 2019, without >making major changes to what was tested. More tests are needed, >but it is important to get what was being tested tested again. > >Account types (eg UF_NORMAL_ACCOUNT, UF_WORKSTATION_TRUST_ACCOUNT) >are now required on all objects, this can't be omitted any more. > >Also for UF_NORMAL_ACCOUNT for these accounts without a password >set |UF_PASSWD_NOTREQD must be included. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Wed Sep 15 08:49:11 UTC 2021 on sn-devel-184 > >(cherry picked from commit d12cb47724c2e8d19a28286d4c3ef72271a002fd) > >[jsutton@samba.org Adapted knownfail to ad_dc_ntvfs] >--- > selftest/knownfail.d/user_account_control | 1 + > .../dsdb/tests/python/user_account_control.py | 114 ++++++++++++++++-- > 2 files changed, 103 insertions(+), 12 deletions(-) > create mode 100644 selftest/knownfail.d/user_account_control > >diff --git a/selftest/knownfail.d/user_account_control b/selftest/knownfail.d/user_account_control >new file mode 100644 >index 00000000000..82df3d16156 >--- /dev/null >+++ b/selftest/knownfail.d/user_account_control >@@ -0,0 +1 @@ >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_add_computer_cc_normal_bare.ad_dc_ntvfs >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index fd0ae38a3f9..efb83b2dcff 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -84,7 +84,7 @@ bits = [UF_SCRIPT, UF_ACCOUNTDISABLE, UF_00000004, UF_HOMEDIR_REQUIRED, > UF_PARTIAL_SECRETS_ACCOUNT, UF_USE_AES_KEYS, > int("0x10000000", 16), int("0x20000000", 16), int("0x40000000", 16), int("0x80000000", 16)] > >-account_types = set([UF_NORMAL_ACCOUNT, UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT]) >+account_types = set([UF_NORMAL_ACCOUNT, UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT, UF_INTERDOMAIN_TRUST_ACCOUNT]) > > > @DynamicTestCase >@@ -108,6 +108,11 @@ class UserAccountControlTests(samba.tests.TestCase): > cls.generate_dynamic_test("test_uac_bits_set", > bit_str, bit, bit_str) > >+ cls.generate_dynamic_test("test_uac_bits_add", >+ "UF_NORMAL_ACCOUNT_UF_PASSWD_NOTREQD", >+ UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD, >+ "UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD") >+ > > def add_computer_ldap(self, computername, others=None, samdb=None): > if samdb is None: >@@ -272,7 +277,7 @@ class UserAccountControlTests(samba.tests.TestCase): > > m = ldb.Message() > m.dn = res[0].dn >- m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_NORMAL_ACCOUNT), >+ m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD), > ldb.FLAG_MOD_REPLACE, "userAccountControl") > self.samdb.modify(m) > >@@ -334,9 +339,10 @@ class UserAccountControlTests(samba.tests.TestCase): > (enum, estr) = e10.args > self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum) > >+ > m = ldb.Message() > m.dn = res[0].dn >- m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_NORMAL_ACCOUNT), >+ m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD), > ldb.FLAG_MOD_REPLACE, "userAccountControl") > self.samdb.modify(m) > >@@ -351,6 +357,50 @@ class UserAccountControlTests(samba.tests.TestCase): > (enum, estr) = e11.args > self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum) > >+ def test_add_computer_cc_normal_bare(self): >+ user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) >+ mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) >+ >+ old_sd = self.sd_utils.read_sd_on_dn(self.OU) >+ self.sd_utils.dacl_add_ace(self.OU, mod) >+ >+ computername = self.computernames[0] >+ sd = ldb.MessageElement((ndr_pack(self.sd_reference_modify)), >+ ldb.FLAG_MOD_ADD, >+ "nTSecurityDescriptor") >+ self.add_computer_ldap(computername, >+ others={"nTSecurityDescriptor": sd}) >+ >+ res = self.admin_samdb.search("%s" % self.base_dn, >+ expression="(&(objectClass=computer)(samAccountName=%s$))" % computername, >+ scope=SCOPE_SUBTREE, >+ attrs=["ntSecurityDescriptor"]) >+ >+ desc = res[0]["nTSecurityDescriptor"][0] >+ desc = ndr_unpack(security.descriptor, desc, allow_remaining=True) >+ >+ sddl = desc.as_sddl(self.domain_sid) >+ self.assertEqual(self.sd_reference_modify.as_sddl(self.domain_sid), sddl) >+ >+ m = ldb.Message() >+ m.dn = res[0].dn >+ m["description"] = ldb.MessageElement( >+ ("A description"), ldb.FLAG_MOD_REPLACE, >+ "description") >+ self.samdb.modify(m) >+ >+ m = ldb.Message() >+ m.dn = res[0].dn >+ m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_NORMAL_ACCOUNT), >+ ldb.FLAG_MOD_REPLACE, "userAccountControl") >+ try: >+ self.samdb.modify(m) >+ self.fail("Unexpectedly able to set userAccountControl to be an Normal account without |UF_PASSWD_NOTREQD on %s" % m.dn) >+ except LdbError as e7: >+ (enum, estr) = e7.args >+ self.assertEqual(ldb.ERR_UNWILLING_TO_PERFORM, enum) >+ >+ > def test_admin_mod_uac(self): > computername = self.computernames[0] > self.add_computer_ldap(computername, samdb=self.admin_samdb) >@@ -469,13 +519,23 @@ class UserAccountControlTests(samba.tests.TestCase): > self.sd_utils.dacl_add_ace(self.OU, mod) > > computername = self.computernames[0] >- self.add_computer_ldap(computername, others={"userAccountControl": [str(account_type)]}) >+ if account_type == UF_WORKSTATION_TRUST_ACCOUNT: >+ self.add_computer_ldap(computername, others={"userAccountControl": [str(account_type)]}) >+ else: >+ self.add_computer_ldap(computername) > >- res = self.admin_samdb.search("%s" % self.base_dn, >- expression="(&(objectClass=computer)(samAccountName=%s$))" % computername, >+ res = self.admin_samdb.search(self.OU, >+ expression=f"(cn={computername})", > scope=SCOPE_SUBTREE, > attrs=["userAccountControl"]) >- self.assertEqual(int(res[0]["userAccountControl"][0]), account_type) >+ self.assertEqual(len(res), 1) >+ >+ orig_uac = int(res[0]["userAccountControl"][0]) >+ if account_type == UF_WORKSTATION_TRUST_ACCOUNT: >+ self.assertEqual(orig_uac, account_type) >+ else: >+ self.assertEqual(orig_uac & UF_NORMAL_ACCOUNT, >+ account_type) > > m = ldb.Message() > m.dn = res[0].dn >@@ -504,7 +564,7 @@ class UserAccountControlTests(samba.tests.TestCase): > # Reset this to the initial position, just to be sure > m = ldb.Message() > m.dn = res[0].dn >- m["userAccountControl"] = ldb.MessageElement(str(account_type), >+ m["userAccountControl"] = ldb.MessageElement(str(orig_uac), > ldb.FLAG_MOD_REPLACE, "userAccountControl") > self.admin_samdb.modify(m) > >@@ -513,7 +573,11 @@ class UserAccountControlTests(samba.tests.TestCase): > scope=SCOPE_SUBTREE, > attrs=["userAccountControl"]) > >- self.assertEqual(int(res[0]["userAccountControl"][0]), account_type) >+ if account_type == UF_WORKSTATION_TRUST_ACCOUNT: >+ self.assertEqual(orig_uac, account_type) >+ else: >+ self.assertEqual(orig_uac & UF_NORMAL_ACCOUNT, >+ account_type) > > m = ldb.Message() > m.dn = res[0].dn >@@ -521,6 +585,7 @@ class UserAccountControlTests(samba.tests.TestCase): > ldb.FLAG_MOD_REPLACE, "userAccountControl") > try: > self.admin_samdb.modify(m) >+ > if bit in invalid_bits: > self.fail("Should have been unable to set userAccountControl bit 0x%08X on %s" % (bit, m.dn)) > >@@ -534,6 +599,19 @@ class UserAccountControlTests(samba.tests.TestCase): > self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) > # No point going on, try the next bit > continue >+ >+ elif (account_type == UF_NORMAL_ACCOUNT) \ >+ and (bit in account_types) \ >+ and (bit != account_type): >+ self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM) >+ continue >+ >+ elif (account_type == UF_WORKSTATION_TRUST_ACCOUNT) \ >+ and (bit != UF_NORMAL_ACCOUNT) \ >+ and (bit != account_type): >+ self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM) >+ continue >+ > else: > self.fail("Unable to set userAccountControl bit 0x%08X on %s: %s" % (bit, m.dn, estr)) > >@@ -637,17 +715,27 @@ class UserAccountControlTests(samba.tests.TestCase): > > self.sd_utils.dacl_add_ace(self.OU, mod) > >- invalid_bits = set([UF_TEMP_DUPLICATE_ACCOUNT, UF_PARTIAL_SECRETS_ACCOUNT]) >+ invalid_bits = set([UF_TEMP_DUPLICATE_ACCOUNT]) >+ # UF_NORMAL_ACCOUNT is invalid alone, needs UF_PASSWD_NOTREQD >+ unwilling_bits = set([UF_NORMAL_ACCOUNT]) >+ > # These bits are privileged, but authenticated users have that CAR by default, so this is a pain to test > priv_to_auth_users_bits = set([UF_PASSWD_NOTREQD, UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, > UF_DONT_EXPIRE_PASSWD]) > > # These bits really are privileged > priv_bits = set([UF_INTERDOMAIN_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT, >- UF_TRUSTED_FOR_DELEGATION, UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION]) >+ UF_TRUSTED_FOR_DELEGATION, UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, >+ UF_PARTIAL_SECRETS_ACCOUNT]) >+ >+ if bit not in account_types and ((bit & UF_NORMAL_ACCOUNT) == 0): >+ bit_add = bit|UF_WORKSTATION_TRUST_ACCOUNT >+ else: >+ bit_add = bit > > try: >- self.add_computer_ldap(computername, others={"userAccountControl": [str(bit)]}) >+ >+ self.add_computer_ldap(computername, others={"userAccountControl": [str(bit_add)]}) > delete_force(self.admin_samdb, "CN=%s,%s" % (computername, self.OU)) > if bit in priv_bits: > self.fail("Unexpectdly able to set userAccountControl bit 0x%08X (%s) on %s" >@@ -664,6 +752,8 @@ class UserAccountControlTests(samba.tests.TestCase): > computername)) > elif bit in priv_bits: > self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ elif bit in unwilling_bits: >+ self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM) > else: > self.fail("Unable to set userAccountControl bit 0x%08X (%s) on %s: %s" > % (bit, >-- >2.25.1 > > >From d05856b71a580fc130f45ad3d924a4b306f2b32d Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 16 Sep 2021 16:09:24 +1200 >Subject: [PATCH 451/686] CVE-2020-25722 selftest: Use > self.assertRaisesLdbError() in user_account_control.py test > >This changes most of the simple pattern with self.samdb.modify() >to use the wrapper. Some other calls still need to be converted, while >the complex decision tree tests should remain as-is for now. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Mon Oct 4 21:55:43 UTC 2021 on sn-devel-184 > >(cherry picked from commit b45190bdac7bd9dcefd5ed88be4bd9a97a712664) >--- > .../dsdb/tests/python/user_account_control.py | 100 +++++++----------- > 1 file changed, 37 insertions(+), 63 deletions(-) > >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index efb83b2dcff..c9b50b83e9d 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -245,35 +245,27 @@ class UserAccountControlTests(samba.tests.TestCase): > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_SERVER_TRUST_ACCOUNT), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- try: >- self.samdb.modify(m) >- self.fail("Unexpectedly able to set userAccountControl to be a DC on %s" % m.dn) >- except LdbError as e5: >- (enum, estr) = e5.args >- self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum) >+ self.assertRaisesLdbError(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ f"Unexpectedly able to set userAccountControl to be a DC on {m.dn}", >+ self.samdb.modify, m) > > m = ldb.Message() > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_WORKSTATION_TRUST_ACCOUNT | > samba.dsdb.UF_PARTIAL_SECRETS_ACCOUNT), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- try: >- self.samdb.modify(m) >- self.fail("Unexpectedly able to set userAccountControl to be an RODC on %s" % m.dn) >- except LdbError as e6: >- (enum, estr) = e6.args >- self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum) >+ >+ self.assertRaisesLdbError(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ f"Unexpectedly able to set userAccountControl to be a RODC on {m.dn}", >+ self.samdb.modify, m) > > m = ldb.Message() > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_WORKSTATION_TRUST_ACCOUNT), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- try: >- self.samdb.modify(m) >- self.fail("Unexpectedly able to set userAccountControl to be an Workstation on %s" % m.dn) >- except LdbError as e7: >- (enum, estr) = e7.args >- self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum) >+ self.assertRaisesLdbError(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ f"Unexpectedly able to set userAccountControl to be a Workstation on {m.dn}", >+ self.samdb.modify, m) > > m = ldb.Message() > m.dn = res[0].dn >@@ -285,13 +277,10 @@ class UserAccountControlTests(samba.tests.TestCase): > m.dn = res[0].dn > m["primaryGroupID"] = ldb.MessageElement(str(security.DOMAIN_RID_ADMINS), > ldb.FLAG_MOD_REPLACE, "primaryGroupID") >- try: >- self.samdb.modify(m) >- except LdbError as e8: >- (enum, estr) = e8.args >- self.assertEqual(ldb.ERR_UNWILLING_TO_PERFORM, enum) >- return >- self.fail() >+ self.assertRaisesLdbError(ldb.ERR_UNWILLING_TO_PERFORM, >+ f"Unexpectedly able to set primaryGroupID on {m.dn}", >+ self.samdb.modify, m) >+ > > def test_mod_computer_cc(self): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) >@@ -321,24 +310,17 @@ class UserAccountControlTests(samba.tests.TestCase): > m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_WORKSTATION_TRUST_ACCOUNT | > samba.dsdb.UF_PARTIAL_SECRETS_ACCOUNT), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- try: >- self.samdb.modify(m) >- self.fail("Unexpectedly able to set userAccountControl on %s" % m.dn) >- except LdbError as e9: >- (enum, estr) = e9.args >- self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum) >+ self.assertRaisesLdbError(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ f"Unexpectedly able to set userAccountControl as RODC on {m.dn}", >+ self.samdb.modify, m) > > m = ldb.Message() > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_SERVER_TRUST_ACCOUNT), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- try: >- self.samdb.modify(m) >- self.fail() >- except LdbError as e10: >- (enum, estr) = e10.args >- self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum) >- >+ self.assertRaisesLdbError(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ f"Unexpectedly able to set userAccountControl as DC on {m.dn}", >+ self.samdb.modify, m) > > m = ldb.Message() > m.dn = res[0].dn >@@ -350,12 +332,10 @@ class UserAccountControlTests(samba.tests.TestCase): > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_WORKSTATION_TRUST_ACCOUNT), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- try: >- self.samdb.modify(m) >- self.fail("Unexpectedly able to set userAccountControl to be an Workstation on %s" % m.dn) >- except LdbError as e11: >- (enum, estr) = e11.args >- self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum) >+ self.assertRaisesLdbError(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ f"Unexpectedly able to set userAccountControl to be a workstation on {m.dn}", >+ self.samdb.modify, m) >+ > > def test_add_computer_cc_normal_bare(self): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) >@@ -393,12 +373,11 @@ class UserAccountControlTests(samba.tests.TestCase): > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_NORMAL_ACCOUNT), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- try: >- self.samdb.modify(m) >- self.fail("Unexpectedly able to set userAccountControl to be an Normal account without |UF_PASSWD_NOTREQD on %s" % m.dn) >- except LdbError as e7: >- (enum, estr) = e7.args >- self.assertEqual(ldb.ERR_UNWILLING_TO_PERFORM, enum) >+ self.assertRaisesLdbError(ldb.ERR_UNWILLING_TO_PERFORM, >+ f"Unexpectedly able to set userAccountControl to be an Normal " >+ "account without |UF_PASSWD_NOTREQD Unexpectedly able to " >+ "set userAccountControl to be a workstation on {m.dn}", >+ self.samdb.modify, m) > > > def test_admin_mod_uac(self): >@@ -420,12 +399,11 @@ class UserAccountControlTests(samba.tests.TestCase): > UF_PARTIAL_SECRETS_ACCOUNT | > UF_TRUSTED_FOR_DELEGATION), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- try: >- self.admin_samdb.modify(m) >- self.fail("Unexpectedly able to set userAccountControl to UF_WORKSTATION_TRUST_ACCOUNT|UF_PARTIAL_SECRETS_ACCOUNT|UF_TRUSTED_FOR_DELEGATION on %s" % m.dn) >- except LdbError as e12: >- (enum, estr) = e12.args >- self.assertEqual(ldb.ERR_OTHER, enum) >+ self.assertRaisesLdbError(ldb.ERR_OTHER, >+ f"Unexpectedly able to set userAccountControl to " >+ "UF_WORKSTATION_TRUST_ACCOUNT|UF_PARTIAL_SECRETS_ACCOUNT|" >+ "UF_TRUSTED_FOR_DELEGATION on {m.dn}", >+ self.admin_samdb.modify, m) > > m = ldb.Message() > m.dn = res[0].dn >@@ -835,14 +813,10 @@ class UserAccountControlTests(samba.tests.TestCase): > m["primaryGroupID"] = ldb.MessageElement( > [str(security.DOMAIN_RID_USERS)], ldb.FLAG_MOD_REPLACE, > "primaryGroupID") >- try: >- self.admin_samdb.modify(m) > >- # When creating a new object, you can not ever set the primaryGroupID >- self.fail("Unexpectedly able to set primaryGroupID to be other than DCS on %s" % computername) >- except LdbError as e15: >- (enum, estr) = e15.args >- self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM) >+ self.assertRaisesLdbError(ldb.ERR_UNWILLING_TO_PERFORM, >+ f"Unexpectedly able to set primaryGroupID to be other than DCS on {m.dn}", >+ self.admin_samdb.modify, m) > > def test_primarygroupID_priv_user_modify(self): > computername = self.computernames[0] >-- >2.25.1 > > >From e7a9d928007e3c8b1ecb57658fa0fbe4f776f783 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 21 Oct 2021 16:46:56 +1300 >Subject: [PATCH 452/686] CVE-2020-17049 tests/krb5: Check account name and SID > in PAC for S4U tests > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andreas Schneider <asn@cryptomilk.org> > >Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org> >Autobuild-Date(master): Mon Oct 25 09:23:35 UTC 2021 on sn-devel-184 > >(cherry picked from commit c174e9ebe715aad6910d53c1f427a0512c09d651) >--- > python/samba/tests/krb5/kdc_base_test.py | 4 ++++ > python/samba/tests/krb5/raw_testcase.py | 26 ++++++++++++++++++++++++ > python/samba/tests/krb5/s4u_tests.py | 12 +++++++++++ > 3 files changed, 42 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index b24c6376ab0..8ae9c24b0fc 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1337,6 +1337,8 @@ class KDCBaseTest(RawKerberosTest): > > def get_tgt(self, creds, to_rodc=False, kdc_options=None, > expected_flags=None, unexpected_flags=None, >+ expected_account_name=None, >+ expected_sid=None, > pac_request=True, expect_pac=True, fresh=False): > user_name = creds.get_username() > cache_key = (user_name, to_rodc, kdc_options, pac_request) >@@ -1386,6 +1388,8 @@ class KDCBaseTest(RawKerberosTest): > expected_cname=cname, > expected_srealm=realm, > expected_sname=sname, >+ expected_account_name=expected_account_name, >+ expected_sid=expected_sid, > expected_salt=salt, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index f352615db1f..fdf078ea788 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1984,6 +1984,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_anon=False, > expected_srealm=None, > expected_sname=None, >+ expected_account_name=None, >+ expected_sid=None, > expected_supported_etypes=None, > expected_flags=None, > unexpected_flags=None, >@@ -2033,6 +2035,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, >+ 'expected_account_name': expected_account_name, >+ 'expected_sid': expected_sid, > 'expected_supported_etypes': expected_supported_etypes, > 'expected_flags': expected_flags, > 'unexpected_flags': unexpected_flags, >@@ -2078,6 +2082,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_anon=False, > expected_srealm=None, > expected_sname=None, >+ expected_account_name=None, >+ expected_sid=None, > expected_supported_etypes=None, > expected_flags=None, > unexpected_flags=None, >@@ -2128,6 +2134,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, >+ 'expected_account_name': expected_account_name, >+ 'expected_sid': expected_sid, > 'expected_supported_etypes': expected_supported_etypes, > 'expected_flags': expected_flags, > 'unexpected_flags': unexpected_flags, >@@ -2561,6 +2569,9 @@ class RawKerberosTest(TestCaseInTempDir): > f'expected: {expected_types} ' > f'got: {buffer_types}') > >+ expected_account_name = kdc_exchange_dict['expected_account_name'] >+ expected_sid = kdc_exchange_dict['expected_sid'] >+ > for pac_buffer in pac.buffers: > if pac_buffer.type == krb5pac.PAC_TYPE_CONSTRAINED_DELEGATION: > expected_proxy_target = kdc_exchange_dict[ >@@ -2584,6 +2595,17 @@ class RawKerberosTest(TestCaseInTempDir): > > self.assertEqual(account_name, pac_buffer.info.account_name) > >+ elif pac_buffer.type == krb5pac.PAC_TYPE_LOGON_INFO: >+ logon_info = pac_buffer.info.info.info3.base >+ >+ if expected_account_name is not None: >+ self.assertEqual(expected_account_name, >+ str(logon_info.account_name)) >+ >+ if expected_sid is not None: >+ expected_rid = int(expected_sid.rsplit('-', 1)[1]) >+ self.assertEqual(expected_rid, logon_info.rid) >+ > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >@@ -3548,6 +3570,8 @@ class RawKerberosTest(TestCaseInTempDir): > etypes, > padata, > kdc_options, >+ expected_account_name=None, >+ expected_sid=None, > expected_flags=None, > unexpected_flags=None, > expected_supported_etypes=None, >@@ -3580,6 +3604,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_cname=expected_cname, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_account_name=expected_account_name, >+ expected_sid=expected_sid, > expected_supported_etypes=expected_supported_etypes, > ticket_decryption_key=ticket_decryption_key, > generate_padata_fn=generate_padata_fn, >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index ea629d29706..593ef94c910 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -238,6 +238,10 @@ class S4UKerberosTests(KDCBaseTest): > client_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, > names=[client_name]) > >+ samdb = self.get_samdb() >+ client_dn = client_creds.get_dn() >+ sid = self.get_objectSid(samdb, client_dn) >+ > service_name = service_creds.get_username()[:-1] > service_sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, > names=['host', service_name]) >@@ -279,6 +283,8 @@ class S4UKerberosTests(KDCBaseTest): > expected_cname=client_cname, > expected_srealm=realm, > expected_sname=service_sname, >+ expected_account_name=client_name, >+ expected_sid=sid, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, > ticket_decryption_key=service_decryption_key, >@@ -438,6 +444,10 @@ class S4UKerberosTests(KDCBaseTest): > account_type=self.AccountType.USER, > opts=client_opts) > >+ samdb = self.get_samdb() >+ client_dn = client_creds.get_dn() >+ sid = self.get_objectSid(samdb, client_dn) >+ > service1_opts = kdc_dict.pop('service1_opts', {}) > service2_opts = kdc_dict.pop('service2_opts', {}) > >@@ -552,6 +562,8 @@ class S4UKerberosTests(KDCBaseTest): > expected_cname=client_cname, > expected_srealm=service2_realm, > expected_sname=service2_sname, >+ expected_account_name=client_username, >+ expected_sid=sid, > expected_supported_etypes=service2_etypes, > ticket_decryption_key=service2_decryption_key, > check_error_fn=check_error_fn, >-- >2.25.1 > > >From be10e95c28d5da2b2dc6c2190e8d36ff602e39d7 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 10 Aug 2021 22:31:02 +1200 >Subject: [PATCH 453/686] CVE-2020-25722 dsdb: Tests for our known set of > privileged attributes > >This, except for where we choose to disagree, does pass >against Windows 2019. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14703 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14778 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14775 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted plantestsuite to use samba4srcdir path] >--- > selftest/knownfail.d/priv_attr | 54 ++++ > source4/dsdb/tests/python/priv_attrs.py | 388 ++++++++++++++++++++++++ > source4/selftest/tests.py | 2 + > 3 files changed, 444 insertions(+) > create mode 100644 selftest/knownfail.d/priv_attr > create mode 100644 source4/dsdb/tests/python/priv_attrs.py > >diff --git a/selftest/knownfail.d/priv_attr b/selftest/knownfail.d/priv_attr >new file mode 100644 >index 00000000000..31b9cb23b44 >--- /dev/null >+++ b/selftest/knownfail.d/priv_attr >@@ -0,0 +1,54 @@ >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_WP_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_WP_user >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_default_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_default_user >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_user >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_default_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_default_user >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_WP_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_WP_user >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_default_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_default_user >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_WP_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_WP_user >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_user >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_WP_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_WP_user >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_default_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_default_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_WP_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_WP_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_default_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_default_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_WP_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_WP_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_default_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_default_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_WP_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_WP_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_default_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_default_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_default_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_default_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_WP_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_WP_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_default_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_default_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-RODC_add_CC_WP_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-RODC_add_CC_default_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-computer_add_CC_WP_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-computer_add_CC_default_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_WP_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_WP_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_default_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_default_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_WP_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_WP_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_mod-del-add_CC_default_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_mod-replace_CC_default_computer >diff --git a/source4/dsdb/tests/python/priv_attrs.py b/source4/dsdb/tests/python/priv_attrs.py >new file mode 100644 >index 00000000000..ec2b13045e5 >--- /dev/null >+++ b/source4/dsdb/tests/python/priv_attrs.py >@@ -0,0 +1,388 @@ >+#!/usr/bin/env python3 >+# -*- coding: utf-8 -*- >+# This tests the restrictions on userAccountControl that apply even if write access is permitted >+# >+# Copyright Samuel Cabrero 2014 <samuelcabrero@kernevil.me> >+# Copyright Andrew Bartlett 2014 <abartlet@samba.org> >+# >+# Licenced under the GPLv3 >+# >+ >+import optparse >+import sys >+import unittest >+import samba >+import samba.getopt as options >+import samba.tests >+import ldb >+import base64 >+ >+sys.path.insert(0, "bin/python") >+from samba.tests.subunitrun import TestProgram, SubunitOptions >+from samba.tests import DynamicTestCase >+from samba.subunit.run import SubunitTestRunner >+from samba.auth import system_session >+from samba.samdb import SamDB >+from samba.dcerpc import samr, security, lsa >+from samba.credentials import Credentials >+from samba.ndr import ndr_unpack, ndr_pack >+from samba.tests import delete_force >+from samba import gensec, sd_utils >+from samba.credentials import DONT_USE_KERBEROS >+from ldb import SCOPE_SUBTREE, SCOPE_BASE, LdbError >+from ldb import Message, MessageElement, Dn >+from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE >+from samba.dsdb import UF_SCRIPT, UF_ACCOUNTDISABLE, UF_00000004, UF_HOMEDIR_REQUIRED, \ >+ UF_LOCKOUT, UF_PASSWD_NOTREQD, UF_PASSWD_CANT_CHANGE, UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED,\ >+ UF_TEMP_DUPLICATE_ACCOUNT, UF_NORMAL_ACCOUNT, UF_00000400, UF_INTERDOMAIN_TRUST_ACCOUNT, \ >+ UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT, UF_00004000, \ >+ UF_00008000, UF_DONT_EXPIRE_PASSWD, UF_MNS_LOGON_ACCOUNT, UF_SMARTCARD_REQUIRED, \ >+ UF_TRUSTED_FOR_DELEGATION, UF_NOT_DELEGATED, UF_USE_DES_KEY_ONLY, UF_DONT_REQUIRE_PREAUTH, \ >+ UF_PASSWORD_EXPIRED, UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, UF_NO_AUTH_DATA_REQUIRED, \ >+ UF_PARTIAL_SECRETS_ACCOUNT, UF_USE_AES_KEYS >+ >+ >+parser = optparse.OptionParser("user_account_control.py [options] <host>") >+sambaopts = options.SambaOptions(parser) >+parser.add_option_group(sambaopts) >+parser.add_option_group(options.VersionOptions(parser)) >+ >+# use command line creds if available >+credopts = options.CredentialsOptions(parser) >+parser.add_option_group(credopts) >+opts, args = parser.parse_args() >+ >+if len(args) < 1: >+ parser.print_usage() >+ sys.exit(1) >+host = args[0] >+ >+if "://" not in host: >+ ldaphost = "ldap://%s" % host >+else: >+ ldaphost = host >+ start = host.rindex("://") >+ host = host.lstrip(start + 3) >+ >+lp = sambaopts.get_loadparm() >+creds = credopts.get_credentials(lp) >+creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL) >+ >+ >+""" >+Check the combinations of: >+ >+rodc kdc >+a2d2 >+useraccountcontrol (trusted for delegation) >+sidHistory >+ >+x >+ >+add >+modify(replace) >+modify(add) >+ >+x >+ >+sd WP on add >+cc default perms >+admin created, WP to user >+ >+x >+ >+computer >+user >+""" >+ >+attrs = {"sidHistory": >+ {"value": ndr_pack(security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS)), >+ "priv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS}, >+ "msDS-AllowedToDelegateTo": >+ {"value": f"host/{host}", >+ "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS}, >+ "userAccountControl-a2d-user": >+ {"attr": "userAccountControl", >+ "value": str(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION|UF_NORMAL_ACCOUNT), >+ "priv-error": ldb.ERR_UNWILLING_TO_PERFORM, >+ "unpriv-add-error": ldb.ERR_UNWILLING_TO_PERFORM, >+ "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS}, >+ "userAccountControl-a2d-computer": >+ {"attr": "userAccountControl", >+ "value": str(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION|UF_WORKSTATION_TRUST_ACCOUNT), >+ "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ "only-1": "computer"}, >+ "userAccountControl-DC": >+ {"attr": "userAccountControl", >+ "value": str(UF_SERVER_TRUST_ACCOUNT), >+ "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ "only-2": "computer"}, >+ "userAccountControl-RODC": >+ {"attr": "userAccountControl", >+ "value": str(UF_PARTIAL_SECRETS_ACCOUNT|UF_WORKSTATION_TRUST_ACCOUNT), >+ "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ "only-1": "computer"}, >+ "msDS-SecondaryKrbTgtNumber": >+ {"value": "65536", >+ "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS}, >+ "primaryGroupID": >+ {"value": str(security.DOMAIN_RID_ADMINS), >+ "priv-error": ldb.ERR_UNWILLING_TO_PERFORM, >+ "unpriv-add-error": ldb.ERR_UNWILLING_TO_PERFORM, >+ "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS} >+ } >+ >+ >+ >+@DynamicTestCase >+class PrivAttrsTests(samba.tests.TestCase): >+ >+ def get_creds(self, target_username, target_password): >+ creds_tmp = Credentials() >+ creds_tmp.set_username(target_username) >+ creds_tmp.set_password(target_password) >+ creds_tmp.set_domain(creds.get_domain()) >+ creds_tmp.set_realm(creds.get_realm()) >+ creds_tmp.set_workstation(creds.get_workstation()) >+ creds_tmp.set_gensec_features(creds_tmp.get_gensec_features() >+ | gensec.FEATURE_SEAL) >+ creds_tmp.set_kerberos_state(DONT_USE_KERBEROS) # kinit is too expensive to use in a tight loop >+ return creds_tmp >+ >+ def assertGotLdbError(self, got, wanted): >+ if not self.strict_checking: >+ self.assertNotEqual(got, ldb.SUCCESS) >+ else: >+ self.assertEqual(got, wanted) >+ >+ def setUp(self): >+ super().setUp() >+ >+ strict_checking = samba.tests.env_get_var_value('STRICT_CHECKING', allow_missing=True) >+ if strict_checking is None: >+ strict_checking = '1' >+ self.strict_checking = bool(int(strict_checking)) >+ >+ self.admin_creds = creds >+ self.admin_samdb = SamDB(url=ldaphost, credentials=self.admin_creds, lp=lp) >+ self.domain_sid = security.dom_sid(self.admin_samdb.get_domain_sid()) >+ self.base_dn = self.admin_samdb.domain_dn() >+ >+ self.unpriv_user = "testuser1" >+ self.unpriv_user_pw = "samba123@" >+ self.unpriv_creds = self.get_creds(self.unpriv_user, self.unpriv_user_pw) >+ >+ self.admin_sd_utils = sd_utils.SDUtils(self.admin_samdb) >+ >+ self.test_ou_name = "OU=test_priv_attrs" >+ self.test_ou = self.test_ou_name + "," + self.base_dn >+ >+ delete_force(self.admin_samdb, self.test_ou, controls=["tree_delete:0"]) >+ >+ self.admin_samdb.create_ou(self.test_ou) >+ >+ expected_user_dn = f"CN={self.unpriv_user},{self.test_ou_name},{self.base_dn}" >+ >+ self.admin_samdb.newuser(self.unpriv_user, self.unpriv_user_pw, userou=self.test_ou_name) >+ res = self.admin_samdb.search(expected_user_dn, >+ scope=SCOPE_BASE, >+ attrs=["objectSid"]) >+ >+ self.assertEqual(1, len(res)) >+ >+ self.unpriv_user_dn = res[0].dn >+ self.addCleanup(delete_force, self.admin_samdb, self.unpriv_user_dn, controls=["tree_delete:0"]) >+ >+ self.unpriv_user_sid = self.admin_sd_utils.get_object_sid(self.unpriv_user_dn) >+ >+ self.unpriv_samdb = SamDB(url=ldaphost, credentials=self.unpriv_creds, lp=lp) >+ >+ @classmethod >+ def setUpDynamicTestCases(cls): >+ for test_name in attrs.keys(): >+ for add_or_mod in ["add", "mod-del-add", "mod-replace"]: >+ for permission in ["admin-add", "CC"]: >+ for sd in ["default", "WP"]: >+ for objectclass in ["computer", "user"]: >+ tname = f"{test_name}_{add_or_mod}_{permission}_{sd}_{objectclass}" >+ targs = (test_name, >+ add_or_mod, >+ permission, >+ sd, >+ objectclass) >+ cls.generate_dynamic_test("test_priv_attr", >+ tname, >+ *targs) >+ >+ def add_computer_ldap(self, computername, others=None, samdb=None): >+ dn = "CN=%s,%s" % (computername, self.test_ou) >+ domainname = ldb.Dn(samdb, samdb.domain_dn()).canonical_str().replace("/", "") >+ samaccountname = "%s$" % computername >+ dnshostname = "%s.%s" % (computername, domainname) >+ msg_dict = { >+ "dn": dn, >+ "objectclass": "computer"} >+ if others is not None: >+ msg_dict = dict(list(msg_dict.items()) + list(others.items())) >+ >+ msg = ldb.Message.from_dict(samdb, msg_dict) >+ msg["sAMAccountName"] = samaccountname >+ >+ print("Adding computer account %s" % computername) >+ try: >+ samdb.add(msg) >+ except ldb.LdbError: >+ print(msg) >+ raise >+ return msg.dn >+ >+ def add_user_ldap(self, username, others=None, samdb=None): >+ dn = "CN=%s,%s" % (username, self.test_ou) >+ domainname = ldb.Dn(samdb, samdb.domain_dn()).canonical_str().replace("/", "") >+ samaccountname = "%s$" % username >+ msg_dict = { >+ "dn": dn, >+ "objectclass": "user"} >+ if others is not None: >+ msg_dict = dict(list(msg_dict.items()) + list(others.items())) >+ >+ msg = ldb.Message.from_dict(samdb, msg_dict) >+ msg["sAMAccountName"] = samaccountname >+ >+ print("Adding user account %s" % username) >+ try: >+ samdb.add(msg) >+ except ldb.LdbError: >+ print(msg) >+ raise >+ return msg.dn >+ >+ def add_thing_ldap(self, user, others, samdb, objectclass): >+ if objectclass == "user": >+ dn = self.add_user_ldap(user, others, samdb=samdb) >+ elif objectclass == "computer": >+ dn = self.add_computer_ldap(user, others, samdb=samdb) >+ return dn >+ >+ def _test_priv_attr_with_args(self, test_name, add_or_mod, permission, sd, objectclass): >+ user="privattrs" >+ if "attr" in attrs[test_name]: >+ attr = attrs[test_name]["attr"] >+ else: >+ attr = test_name >+ if add_or_mod == "add": >+ others = {attr: attrs[test_name]["value"]} >+ else: >+ others = {} >+ >+ if permission == "CC": >+ samdb = self.unpriv_samdb >+ # Set CC on container to allow user add >+ mod = "(OA;CI;CC;bf967aba-0de6-11d0-a285-00aa003049e2;;%s)" % str(self.unpriv_user_sid) >+ self.admin_sd_utils.dacl_add_ace(self.test_ou, mod) >+ mod = "(OA;CI;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(self.unpriv_user_sid) >+ self.admin_sd_utils.dacl_add_ace(self.test_ou, mod) >+ >+ else: >+ samdb = self.admin_samdb >+ >+ if sd == "WP": >+ # Set SD to WP to the target user as part of add >+ sd = "O:%sG:DUD:(OA;CIID;RPWP;;;%s)(OA;;CR;00299570-246d-11d0-a768-00aa006e0529;;%s)" % (self.unpriv_user_sid, self.unpriv_user_sid, self.unpriv_user_sid) >+ tmp_desc = security.descriptor.from_sddl(sd, self.domain_sid) >+ others["ntSecurityDescriptor"] = ndr_pack(tmp_desc) >+ >+ if add_or_mod == "add": >+ >+ # only-1 and only-2 are due to windows behaviour >+ >+ if "only-1" in attrs[test_name] and \ >+ attrs[test_name]["only-1"] != objectclass: >+ try: >+ dn = self.add_thing_ldap(user, others, samdb, objectclass) >+ self.fail(f"{test_name}: Unexpectedly able to set {attr} on new {objectclass} as ADMIN (should fail LDAP_OBJECT_CLASS_VIOLATION)") >+ except LdbError as e5: >+ (enum, estr) = e5.args >+ self.assertGotLdbError(ldb.ERR_OBJECT_CLASS_VIOLATION, enum) >+ elif permission == "CC": >+ try: >+ dn = self.add_thing_ldap(user, others, samdb, objectclass) >+ self.fail(f"{test_name}: Unexpectedly able to set {attr} on new {objectclass}") >+ except LdbError as e5: >+ (enum, estr) = e5.args >+ if "unpriv-add-error" in attrs[test_name]: >+ self.assertGotLdbError(attrs[test_name]["unpriv-add-error"], \ >+ enum) >+ else: >+ self.assertGotLdbError(attrs[test_name]["unpriv-error"], \ >+ enum) >+ elif "only-2" in attrs[test_name] and \ >+ attrs[test_name]["only-2"] != objectclass: >+ try: >+ dn = self.add_thing_ldap(user, others, samdb, objectclass) >+ self.fail(f"{test_name}: Unexpectedly able to set {attr} on new {objectclass} as ADMIN (should fail LDAP_OBJECT_CLASS_VIOLATION)") >+ except LdbError as e5: >+ (enum, estr) = e5.args >+ self.assertGotLdbError(ldb.ERR_OBJECT_CLASS_VIOLATION, enum) >+ elif "priv-error" in attrs[test_name]: >+ try: >+ dn = self.add_thing_ldap(user, others, samdb, objectclass) >+ self.fail(f"{test_name}: Unexpectedly able to set {attr} on new {objectclass} as ADMIN") >+ except LdbError as e5: >+ (enum, estr) = e5.args >+ self.assertGotLdbError(attrs[test_name]["priv-error"], enum) >+ else: >+ try: >+ dn = self.add_thing_ldap(user, others, samdb, objectclass) >+ except LdbError as e5: >+ (enum, estr) = e5.args >+ self.fail(f"Failed to add account {user} as objectclass {objectclass}") >+ else: >+ try: >+ dn = self.add_thing_ldap(user, others, samdb, objectclass) >+ except LdbError as e5: >+ (enum, estr) = e5.args >+ self.fail(f"Failed to add account {user} as objectclass {objectclass}") >+ >+ if add_or_mod == "add": >+ return >+ >+ m = ldb.Message() >+ m.dn = dn >+ >+ # Do modify >+ if add_or_mod == "mod-del-add": >+ m["0"] = ldb.MessageElement([], >+ ldb.FLAG_MOD_DELETE, >+ attr) >+ m["1"] = ldb.MessageElement(attrs[test_name]["value"], >+ ldb.FLAG_MOD_ADD, >+ attr) >+ else: >+ m["0"] = ldb.MessageElement(attrs[test_name]["value"], >+ ldb.FLAG_MOD_REPLACE, >+ attr) >+ >+ try: >+ self.unpriv_samdb.modify(m) >+ self.fail(f"{test_name}: Unexpectedly able to set {attr} on {m.dn}") >+ except LdbError as e5: >+ (enum, estr) = e5.args >+ if attr == "userAccountControl" and sd == "default": >+ # We get a different error if we try and swap between >+ # being a computer back to being a user when created with "Create child" permissions >+ if (int(attrs[test_name]["value"]) & UF_NORMAL_ACCOUNT) \ >+ and objectclass == "computer" and permission == "CC": >+ self.assertGotLdbError(ldb.ERR_UNWILLING_TO_PERFORM, enum) >+ return >+ self.assertGotLdbError(attrs[test_name]["unpriv-error"], enum) >+ >+ >+ >+ >+runner = SubunitTestRunner() >+rc = 0 >+if not runner.run(unittest.makeSuite(PrivAttrsTests)).wasSuccessful(): >+ rc = 1 >+sys.exit(rc) >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 66e53c517ed..2d3447da2a5 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -947,6 +947,8 @@ plantestsuite("samba4.sam.python(fl2008r2dc)", "fl2008r2dc", [python, os.path.jo > plantestsuite("samba4.sam.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(samba4srcdir, "dsdb/tests/python/sam.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) > plantestsuite("samba4.asq.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(samba4srcdir, "dsdb/tests/python/asq.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) > plantestsuite("samba4.user_account_control.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(samba4srcdir, "dsdb/tests/python/user_account_control.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) >+plantestsuite("samba4.priv_attrs.python(ad_dc_default)", "ad_dc_default", ["STRICT_CHECKING=0", python, os.path.join(samba4srcdir, "dsdb/tests/python/priv_attrs.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) >+plantestsuite("samba4.priv_attrs.strict.python(ad_dc_default)", "ad_dc_default", [python, os.path.join(samba4srcdir, "dsdb/tests/python/priv_attrs.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) > planoldpythontestsuite("ad_dc_ntvfs:local", "dsdb_schema_info", > extra_path=[os.path.join(samba4srcdir, 'dsdb/tests/python')], > name="samba4.schemaInfo.python(ad_dc_ntvfs)", >-- >2.25.1 > > >From 71a4004867c823852daac270d2c9908c27f4c5eb Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 12 Aug 2021 11:10:09 +1200 >Subject: [PATCH 454/686] CVE-2020-25722 dsdb: Move krbtgt password setup after > the point of checking if any passwords are changed > >This allows the add of an RODC, before setting the password, to avoid >this module, which helps isolate testing of security around the >msDS-SecondaryKrbTgtNumber attribute. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14703 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > selftest/knownfail.d/priv_attr | 12 +- > .../dsdb/samdb/ldb_modules/password_hash.c | 106 +++++++++--------- > 2 files changed, 57 insertions(+), 61 deletions(-) > >diff --git a/selftest/knownfail.d/priv_attr b/selftest/knownfail.d/priv_attr >index 31b9cb23b44..ab6db192aae 100644 >--- a/selftest/knownfail.d/priv_attr >+++ b/selftest/knownfail.d/priv_attr >@@ -14,14 +14,10 @@ samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccoun > samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_WP_user > samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_computer > samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_user >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_WP_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_WP_user >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_default_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_default_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_WP_computer >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_WP_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_default_computer >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_admin-add_default_user >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_WP_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_WP_user >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_default_computer >+samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_default_user > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_WP_computer > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_WP_user > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_default_computer >diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c >index 71845b24ad8..9f1fcb996f1 100644 >--- a/source4/dsdb/samdb/ldb_modules/password_hash.c >+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c >@@ -2413,6 +2413,59 @@ static int setup_password_fields(struct setup_password_fields_io *io) > return LDB_SUCCESS; > } > >+ if (io->u.is_krbtgt) { >+ size_t min = 196; >+ size_t max = 255; >+ size_t diff = max - min; >+ size_t len = max; >+ struct ldb_val *krbtgt_utf16 = NULL; >+ >+ if (!io->ac->pwd_reset) { >+ return dsdb_module_werror(io->ac->module, >+ LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS, >+ WERR_DS_ATT_ALREADY_EXISTS, >+ "Password change on krbtgt not permitted!"); >+ } >+ >+ if (io->n.cleartext_utf16 == NULL) { >+ return dsdb_module_werror(io->ac->module, >+ LDB_ERR_UNWILLING_TO_PERFORM, >+ WERR_DS_INVALID_ATTRIBUTE_SYNTAX, >+ "Password reset on krbtgt requires UTF16!"); >+ } >+ >+ /* >+ * Instead of taking the callers value, >+ * we just generate a new random value here. >+ * >+ * Include null termination in the array. >+ */ >+ if (diff > 0) { >+ size_t tmp; >+ >+ generate_random_buffer((uint8_t *)&tmp, sizeof(tmp)); >+ >+ tmp %= diff; >+ >+ len = min + tmp; >+ } >+ >+ krbtgt_utf16 = talloc_zero(io->ac, struct ldb_val); >+ if (krbtgt_utf16 == NULL) { >+ return ldb_oom(ldb); >+ } >+ >+ *krbtgt_utf16 = data_blob_talloc_zero(krbtgt_utf16, >+ (len+1)*2); >+ if (krbtgt_utf16->data == NULL) { >+ return ldb_oom(ldb); >+ } >+ krbtgt_utf16->length = len * 2; >+ generate_secret_buffer(krbtgt_utf16->data, >+ krbtgt_utf16->length); >+ io->n.cleartext_utf16 = krbtgt_utf16; >+ } >+ > /* transform the old password (for password changes) */ > ret = setup_given_passwords(io, &io->og); > if (ret != LDB_SUCCESS) { >@@ -3586,59 +3639,6 @@ static int setup_io(struct ph_context *ac, > return ldb_operr(ldb); > } > >- if (io->u.is_krbtgt) { >- size_t min = 196; >- size_t max = 255; >- size_t diff = max - min; >- size_t len = max; >- struct ldb_val *krbtgt_utf16 = NULL; >- >- if (!ac->pwd_reset) { >- return dsdb_module_werror(ac->module, >- LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS, >- WERR_DS_ATT_ALREADY_EXISTS, >- "Password change on krbtgt not permitted!"); >- } >- >- if (io->n.cleartext_utf16 == NULL) { >- return dsdb_module_werror(ac->module, >- LDB_ERR_UNWILLING_TO_PERFORM, >- WERR_DS_INVALID_ATTRIBUTE_SYNTAX, >- "Password reset on krbtgt requires UTF16!"); >- } >- >- /* >- * Instead of taking the callers value, >- * we just generate a new random value here. >- * >- * Include null termination in the array. >- */ >- if (diff > 0) { >- size_t tmp; >- >- generate_random_buffer((uint8_t *)&tmp, sizeof(tmp)); >- >- tmp %= diff; >- >- len = min + tmp; >- } >- >- krbtgt_utf16 = talloc_zero(io->ac, struct ldb_val); >- if (krbtgt_utf16 == NULL) { >- return ldb_oom(ldb); >- } >- >- *krbtgt_utf16 = data_blob_talloc_zero(krbtgt_utf16, >- (len+1)*2); >- if (krbtgt_utf16->data == NULL) { >- return ldb_oom(ldb); >- } >- krbtgt_utf16->length = len * 2; >- generate_secret_buffer(krbtgt_utf16->data, >- krbtgt_utf16->length); >- io->n.cleartext_utf16 = krbtgt_utf16; >- } >- > if (existing_msg != NULL) { > NTSTATUS status; > >-- >2.25.1 > > >From cb6605a40683e359a16e49a1ec017d3d3566ed04 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 13 Aug 2021 17:42:23 +1200 >Subject: [PATCH 455/686] CVE-2020-25722 dsdb: Restrict the setting of > privileged attributes during LDAP add/modify > >The remaining failures in the priv_attrs (not the strict one) test are >due to missing objectclass constraints on the administrator which should >be addressed, but are not a security issue. > >A better test for confirming constraints between objectclass and >userAccountControl UF_NORMAL_ACCONT/UF_WORKSTATION_TRUST values would >be user_account_control.py. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14703 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14778 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14775 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > selftest/knownfail.d/priv_attr | 24 ---- > source4/dsdb/samdb/ldb_modules/samldb.c | 148 +++++++++++++++++++++--- > 2 files changed, 129 insertions(+), 43 deletions(-) > >diff --git a/selftest/knownfail.d/priv_attr b/selftest/knownfail.d/priv_attr >index ab6db192aae..c3a779010d9 100644 >--- a/selftest/knownfail.d/priv_attr >+++ b/selftest/knownfail.d/priv_attr >@@ -1,31 +1,7 @@ >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_WP_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_WP_user >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_default_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_default_user >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_user >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_default_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_default_user >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_WP_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_WP_user >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_default_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_default_user > samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_WP_computer > samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_WP_user > samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_computer > samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_user >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_WP_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_WP_user >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_default_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_default_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_WP_computer >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_WP_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_default_computer >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-AllowedToDelegateTo_add_CC_default_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_WP_computer >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_WP_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_default_computer >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_msDS-SecondaryKrbTgtNumber_add_CC_default_user > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_computer > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_user > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_default_computer >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 2e63f256cd2..f085d2454d9 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -1976,6 +1976,29 @@ static int samldb_check_user_account_control_invariants(struct samldb_ctx *ac, > return ret; > } > >+static int samldb_get_domain_secdesc(struct samldb_ctx *ac, >+ struct security_descriptor **domain_sd) >+{ >+ const char * const sd_attrs[] = {"ntSecurityDescriptor", NULL}; >+ struct ldb_result *res; >+ struct ldb_dn *domain_dn = ldb_get_default_basedn(ldb_module_get_ctx(ac->module)); >+ int ret = dsdb_module_search_dn(ac->module, ac, &res, >+ domain_dn, >+ sd_attrs, >+ DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED, >+ ac->req); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ if (res->count != 1) { >+ return ldb_module_operr(ac->module); >+ } >+ >+ return dsdb_get_sd_from_ldb_message(ldb_module_get_ctx(ac->module), >+ ac, res->msgs[0], domain_sd); >+ >+} >+ > /** > * Validate that the restriction in point 5 of MS-SAMR 3.1.1.8.10 userAccountControl is honoured > * >@@ -1987,12 +2010,8 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac, > { > int i, ret = 0; > bool need_acl_check = false; >- struct ldb_result *res; >- const char * const sd_attrs[] = {"ntSecurityDescriptor", NULL}; > struct security_token *user_token; > struct security_descriptor *domain_sd; >- struct ldb_dn *domain_dn = ldb_get_default_basedn(ldb_module_get_ctx(ac->module)); >- struct ldb_context *ldb = ldb_module_get_ctx(ac->module); > const struct uac_to_guid { > uint32_t uac; > uint32_t priv_to_change_from; >@@ -2078,21 +2097,7 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac, > return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; > } > >- ret = dsdb_module_search_dn(ac->module, ac, &res, >- domain_dn, >- sd_attrs, >- DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED, >- ac->req); >- if (ret != LDB_SUCCESS) { >- return ret; >- } >- if (res->count != 1) { >- return ldb_module_operr(ac->module); >- } >- >- ret = dsdb_get_sd_from_ldb_message(ldb, >- ac, res->msgs[0], &domain_sd); >- >+ ret = samldb_get_domain_secdesc(ac, &domain_sd); > if (ret != LDB_SUCCESS) { > return ret; > } >@@ -2154,6 +2159,8 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac, > return ldb_module_operr(ac->module); > } > if (map[i].guid) { >+ struct ldb_dn *domain_dn >+ = ldb_get_default_basedn(ldb_module_get_ctx(ac->module)); > dsdb_acl_debug(domain_sd, acl_user_token(ac->module), > domain_dn, > true, >@@ -3485,7 +3492,98 @@ static char *refer_if_rodc(struct ldb_context *ldb, struct ldb_request *req, > return NULL; > } > >+/* >+ * Restrict all access to sensitive attributes. >+ * >+ * We don't want to even inspect the values, so we can use the same >+ * routine for ADD and MODIFY. >+ * >+ */ >+ >+static int samldb_check_sensitive_attributes(struct samldb_ctx *ac) >+{ >+ struct ldb_message_element *el = NULL; >+ struct security_token *user_token = NULL; >+ int ret; >+ >+ if (dsdb_module_am_system(ac->module)) { >+ return LDB_SUCCESS; >+ } >+ >+ user_token = acl_user_token(ac->module); >+ if (user_token == NULL) { >+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; >+ } >+ >+ el = ldb_msg_find_element(ac->msg, "sidHistory"); >+ if (el) { >+ /* >+ * sidHistory is restricted to the (not implemented >+ * yet in Samba) DsAddSidHistory call (direct LDB access is >+ * as SYSTEM so will bypass this). >+ * >+ * If you want to modify this, say to merge domains, >+ * directly modify the sam.ldb as root. >+ */ >+ ldb_asprintf_errstring(ldb_module_get_ctx(ac->module), >+ "sidHistory " >+ "(entry %s) cannot be created " >+ "or changed over LDAP!", >+ ldb_dn_get_linearized(ac->msg->dn)); >+ return LDB_ERR_UNWILLING_TO_PERFORM; >+ } > >+ el = ldb_msg_find_element(ac->msg, "msDS-SecondaryKrbTgtNumber"); >+ if (el) { >+ struct security_descriptor *domain_sd; >+ /* >+ * msDS-SecondaryKrbTgtNumber allows the creator to >+ * become an RODC, this is trusted as an RODC >+ * account >+ */ >+ ret = samldb_get_domain_secdesc(ac, &domain_sd); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ ret = acl_check_extended_right(ac, domain_sd, >+ user_token, >+ GUID_DRS_DS_INSTALL_REPLICA, >+ SEC_ADS_CONTROL_ACCESS, >+ NULL); >+ if (ret != LDB_SUCCESS) { >+ ldb_asprintf_errstring(ldb_module_get_ctx(ac->module), >+ "msDS-SecondaryKrbTgtNumber " >+ "(entry %s) cannot be created " >+ "or changed without " >+ "DS-Install-Replica extended right!", >+ ldb_dn_get_linearized(ac->msg->dn)); >+ return ret; >+ } >+ } >+ >+ el = ldb_msg_find_element(ac->msg, "msDS-AllowedToDelegateTo"); >+ if (el) { >+ /* >+ * msDS-AllowedToDelegateTo is incredibly powerful, >+ * given that it allows a server to become ANY USER on >+ * the target server only listed by SPN so needs to be >+ * protected just as the userAccountControl >+ * UF_TRUSTED_FOR_DELEGATION is. >+ */ >+ >+ bool have_priv = security_token_has_privilege(user_token, >+ SEC_PRIV_ENABLE_DELEGATION); >+ if (have_priv == false) { >+ ldb_asprintf_errstring(ldb_module_get_ctx(ac->module), >+ "msDS-AllowedToDelegateTo " >+ "(entry %s) cannot be created " >+ "or changed without SePrivEnableDelegation!", >+ ldb_dn_get_linearized(ac->msg->dn)); >+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; >+ } >+ } >+ return LDB_SUCCESS; >+} > /* add */ > static int samldb_add(struct ldb_module *module, struct ldb_request *req) > { >@@ -3532,6 +3630,12 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req) > return ldb_operr(ldb); > } > >+ ret = samldb_check_sensitive_attributes(ac); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(ac); >+ return ret; >+ } >+ > el = ldb_msg_find_element(ac->msg, "fSMORoleOwner"); > if (el != NULL) { > ret = samldb_fsmo_role_owner_check(ac); >@@ -3739,6 +3843,12 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) > return ldb_operr(ldb); > } > >+ ret = samldb_check_sensitive_attributes(ac); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(ac); >+ return ret; >+ } >+ > if (is_undelete == NULL) { > el = ldb_msg_find_element(ac->msg, "primaryGroupID"); > if (el != NULL) { >-- >2.25.1 > > >From 3a8234b511976284e371a3bb3d1a4f1463a7fbc1 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 13 Sep 2021 20:34:54 +1200 >Subject: [PATCH 456/686] CVE-2020-25722 selftest: Extend priv_attrs test - > work around UF_NORMAL_ACCOUNT rules on Windows 2019 (requires > |UF_PASSWD_NOTREQD or a password) - extend to also cover the sensitive > UF_TRUSTED_FOR_DELEGATION > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14703 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14778 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14775 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > selftest/knownfail.d/priv_attr | 16 ++-------- > source4/dsdb/tests/python/priv_attrs.py | 40 +++++++++++++++---------- > 2 files changed, 27 insertions(+), 29 deletions(-) > >diff --git a/selftest/knownfail.d/priv_attr b/selftest/knownfail.d/priv_attr >index c3a779010d9..4b85a869089 100644 >--- a/selftest/knownfail.d/priv_attr >+++ b/selftest/knownfail.d/priv_attr >@@ -1,7 +1,3 @@ >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_WP_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_WP_user >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_computer >-samba4.priv_attrs.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_user > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_computer > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_user > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_default_computer >@@ -14,13 +10,5 @@ samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_use > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-RODC_add_CC_default_user > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-computer_add_CC_WP_user > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-computer_add_CC_default_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_WP_computer >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_WP_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_default_computer >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_default_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_WP_computer >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_WP_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_computer >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_admin-add_default_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_mod-del-add_CC_default_computer >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_mod-replace_CC_default_computer >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-computer_add_CC_WP_user >+samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-computer_add_CC_default_user >diff --git a/source4/dsdb/tests/python/priv_attrs.py b/source4/dsdb/tests/python/priv_attrs.py >index ec2b13045e5..aa35dcc1317 100644 >--- a/source4/dsdb/tests/python/priv_attrs.py >+++ b/source4/dsdb/tests/python/priv_attrs.py >@@ -99,30 +99,47 @@ attrs = {"sidHistory": > {"value": ndr_pack(security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS)), > "priv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, > "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS}, >- "msDS-AllowedToDelegateTo": >+ >+ "msDS-AllowedToDelegateTo": > {"value": f"host/{host}", > "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS}, >- "userAccountControl-a2d-user": >+ >+ "userAccountControl-a2d-user": > {"attr": "userAccountControl", >- "value": str(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION|UF_NORMAL_ACCOUNT), >- "priv-error": ldb.ERR_UNWILLING_TO_PERFORM, >- "unpriv-add-error": ldb.ERR_UNWILLING_TO_PERFORM, >+ "value": str(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION|UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD), > "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS}, >- "userAccountControl-a2d-computer": >+ >+ "userAccountControl-a2d-computer": > {"attr": "userAccountControl", > "value": str(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION|UF_WORKSTATION_TRUST_ACCOUNT), > "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, > "only-1": "computer"}, >- "userAccountControl-DC": >+ >+ # This flag makes many legitimate authenticated clients >+ # send a forwardable ticket-granting-ticket to the server >+ "userAccountControl-t4d-user": >+ {"attr": "userAccountControl", >+ "value": str(UF_TRUSTED_FOR_DELEGATION|UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD), >+ "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS}, >+ >+ "userAccountControl-t4d-computer": >+ {"attr": "userAccountControl", >+ "value": str(UF_TRUSTED_FOR_DELEGATION|UF_WORKSTATION_TRUST_ACCOUNT), >+ "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ "only-1": "computer"}, >+ >+ "userAccountControl-DC": > {"attr": "userAccountControl", > "value": str(UF_SERVER_TRUST_ACCOUNT), > "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, > "only-2": "computer"}, >- "userAccountControl-RODC": >+ >+ "userAccountControl-RODC": > {"attr": "userAccountControl", > "value": str(UF_PARTIAL_SECRETS_ACCOUNT|UF_WORKSTATION_TRUST_ACCOUNT), > "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, > "only-1": "computer"}, >+ > "msDS-SecondaryKrbTgtNumber": > {"value": "65536", > "unpriv-error": ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS}, >@@ -369,13 +386,6 @@ class PrivAttrsTests(samba.tests.TestCase): > self.fail(f"{test_name}: Unexpectedly able to set {attr} on {m.dn}") > except LdbError as e5: > (enum, estr) = e5.args >- if attr == "userAccountControl" and sd == "default": >- # We get a different error if we try and swap between >- # being a computer back to being a user when created with "Create child" permissions >- if (int(attrs[test_name]["value"]) & UF_NORMAL_ACCOUNT) \ >- and objectclass == "computer" and permission == "CC": >- self.assertGotLdbError(ldb.ERR_UNWILLING_TO_PERFORM, enum) >- return > self.assertGotLdbError(attrs[test_name]["unpriv-error"], enum) > > >-- >2.25.1 > > >From 399aa9e1a4a51a9458cb3c9cb54f6635a6574955 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 13 Sep 2021 10:21:03 +1200 >Subject: [PATCH 457/686] CVE-2020-25722 selftest: Test combinations of account > type and objectclass for creating a user > >The idea here is to split out the restrictions seen on Windows 2019 >at the schema level, as seen when acting as an administrator. > >These pass against Windows 2019 except for the account type swapping >which is not wanted. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > .../user_account_control-uac_mod_lock | 11 ++ > .../dsdb/tests/python/user_account_control.py | 165 ++++++++++++++++++ > 2 files changed, 176 insertions(+) > create mode 100644 selftest/knownfail.d/user_account_control-uac_mod_lock > >diff --git a/selftest/knownfail.d/user_account_control-uac_mod_lock b/selftest/knownfail.d/user_account_control-uac_mod_lock >new file mode 100644 >index 00000000000..a70534506f3 >--- /dev/null >+++ b/selftest/knownfail.d/user_account_control-uac_mod_lock >@@ -0,0 +1,11 @@ >+# We do not want user account control account type swapping, so we mark these as knownfail >+^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_computer_replace >+^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_user_replace >+^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_SERVER_TRUST_ACCOUNT_computer_replace >+^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_replace >+^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_WORKSTATION_TRUST_ACCOUNT_deladd >+^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_WORKSTATION_TRUST_ACCOUNT_replace >+^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_SERVER_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_deladd >+^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_SERVER_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_replace >+^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_deladd >+^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_replace >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index c9b50b83e9d..442fe741220 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -91,6 +91,41 @@ account_types = set([UF_NORMAL_ACCOUNT, UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_ > class UserAccountControlTests(samba.tests.TestCase): > @classmethod > def setUpDynamicTestCases(cls): >+ for account_type in [UF_NORMAL_ACCOUNT, >+ UF_WORKSTATION_TRUST_ACCOUNT, >+ UF_SERVER_TRUST_ACCOUNT]: >+ account_type_str = dsdb.user_account_control_flag_bit_to_string(account_type) >+ for objectclass in ["computer", "user"]: >+ test_name = f"{account_type_str}_{objectclass}" >+ cls.generate_dynamic_test("test_objectclass_uac_lock", >+ test_name, >+ account_type, >+ objectclass) >+ >+ for account_type in [UF_NORMAL_ACCOUNT, >+ UF_WORKSTATION_TRUST_ACCOUNT, >+ UF_SERVER_TRUST_ACCOUNT]: >+ account_type_str = dsdb.user_account_control_flag_bit_to_string(account_type) >+ for account_type2 in [UF_NORMAL_ACCOUNT, >+ UF_WORKSTATION_TRUST_ACCOUNT, >+ UF_SERVER_TRUST_ACCOUNT]: >+ for how in ["replace", "deladd"]: >+ account_type2_str = dsdb.user_account_control_flag_bit_to_string(account_type2) >+ test_name = f"{account_type_str}_{account_type2_str}_{how}" >+ cls.generate_dynamic_test("test_objectclass_uac_mod_lock", >+ test_name, >+ account_type, >+ account_type2, >+ how) >+ for objectclass in ["user", "computer"]: >+ for how in ["replace", "deladd"]: >+ test_name = f"{account_type_str}_{objectclass}_{how}" >+ cls.generate_dynamic_test("test_objectclass_mod_lock", >+ test_name, >+ account_type, >+ objectclass, >+ how) >+ > for account_type in [UF_NORMAL_ACCOUNT, UF_WORKSTATION_TRUST_ACCOUNT]: > account_type_str = dsdb.user_account_control_flag_bit_to_string(account_type) > cls.generate_dynamic_test("test_uac_bits_unrelated_modify", >@@ -844,6 +879,136 @@ class UserAccountControlTests(samba.tests.TestCase): > "primaryGroupID") > self.admin_samdb.modify(m) > >+ def _test_objectclass_uac_lock_with_args(self, >+ account_type, >+ objectclass): >+ name = "oc_uac_lock$" >+ dn = "CN=%s,%s" % (name, self.OU) >+ msg_dict = { >+ "dn": dn, >+ "objectclass": objectclass, >+ "samAccountName": name, >+ "userAccountControl": str(account_type | UF_PASSWD_NOTREQD)} >+ >+ account_type_str = dsdb.user_account_control_flag_bit_to_string(account_type) >+ >+ print(f"Adding account {name} as {account_type_str} with objectclass {objectclass}") >+ >+ if (objectclass == "user" \ >+ and account_type == UF_NORMAL_ACCOUNT): >+ self.admin_samdb.add(msg_dict) >+ elif objectclass == "computer": >+ self.admin_samdb.add(msg_dict) >+ else: >+ self.assertRaisesLdbError(ldb.ERR_OBJECT_CLASS_VIOLATION, >+ "Should have been unable to {account_type_str} on {objectclass}", >+ self.admin_samdb.add, msg_dict) >+ >+ def _test_objectclass_uac_mod_lock_with_args(self, >+ account_type, >+ account_type2, >+ how): >+ name = "uac_mod_lock$" >+ dn = "CN=%s,%s" % (name, self.OU) >+ if account_type == UF_NORMAL_ACCOUNT: >+ objectclass = "user" >+ else: >+ objectclass = "computer" >+ >+ msg_dict = { >+ "dn": dn, >+ "objectclass": objectclass, >+ "samAccountName": name, >+ "userAccountControl": str(account_type | UF_PASSWD_NOTREQD)} >+ >+ account_type_str \ >+ = dsdb.user_account_control_flag_bit_to_string(account_type) >+ account_type2_str \ >+ = dsdb.user_account_control_flag_bit_to_string(account_type2) >+ >+ print(f"Adding account {name} as {account_type_str} with objectclass {objectclass}") >+ >+ self.admin_samdb.add(msg_dict) >+ >+ m = ldb.Message() >+ m.dn = ldb.Dn(self.admin_samdb, dn) >+ if how == "replace": >+ m["userAccountControl"] = ldb.MessageElement(str(account_type2 | UF_PASSWD_NOTREQD), >+ ldb.FLAG_MOD_REPLACE, "userAccountControl") >+ elif how == "deladd": >+ m["0userAccountControl"] = ldb.MessageElement([], >+ ldb.FLAG_MOD_DELETE, "userAccountControl") >+ m["1userAccountControl"] = ldb.MessageElement(str(account_type2 | UF_PASSWD_NOTREQD), >+ ldb.FLAG_MOD_ADD, "userAccountControl") >+ else: >+ raise ValueError(f"{how} was not a valid argument") >+ >+ if (account_type in [UF_SERVER_TRUST_ACCOUNT, >+ UF_WORKSTATION_TRUST_ACCOUNT]) and \ >+ (account_type2 in [UF_SERVER_TRUST_ACCOUNT, >+ UF_WORKSTATION_TRUST_ACCOUNT]): >+ self.admin_samdb.modify(m) >+ elif (account_type == account_type2): >+ self.admin_samdb.modify(m) >+ else: >+ self.assertRaisesLdbError(ldb.ERR_UNWILLING_TO_PERFORM, >+ f"Should have been unable to change {account_type_str} to {account_type2_str}", >+ self.admin_samdb.modify, m) >+ >+ def _test_objectclass_mod_lock_with_args(self, >+ account_type, >+ objectclass, >+ how): >+ name = "uac_mod_lock$" >+ dn = "CN=%s,%s" % (name, self.OU) >+ if objectclass == "computer": >+ new_objectclass = ["top", >+ "person", >+ "organizationalPerson", >+ "user"] >+ elif objectclass == "user": >+ new_objectclass = ["top", >+ "person", >+ "organizationalPerson", >+ "user", >+ "computer"] >+ >+ msg_dict = { >+ "dn": dn, >+ "objectclass": objectclass, >+ "samAccountName": name, >+ "userAccountControl": str(account_type | UF_PASSWD_NOTREQD)} >+ >+ account_type_str = dsdb.user_account_control_flag_bit_to_string(account_type) >+ >+ print(f"Adding account {name} as {account_type_str} with objectclass {objectclass}") >+ >+ try: >+ self.admin_samdb.add(msg_dict) >+ if (objectclass == "user" \ >+ and account_type != UF_NORMAL_ACCOUNT): >+ self.fail("Able to create {account_type_str} on {objectclass}") >+ except LdbError as e: >+ (enum, estr) = e.args >+ self.assertEqual(enum, ldb.ERR_OBJECT_CLASS_VIOLATION) >+ >+ if objectclass == "user" and account_type != UF_NORMAL_ACCOUNT: >+ return >+ >+ m = ldb.Message() >+ m.dn = ldb.Dn(self.admin_samdb, dn) >+ if how == "replace": >+ m["objectclass"] = ldb.MessageElement(new_objectclass, >+ ldb.FLAG_MOD_REPLACE, "objectclass") >+ elif how == "adddel": >+ m["0objectclass"] = ldb.MessageElement([], >+ ldb.FLAG_MOD_DELETE, "objectclass") >+ m["1objectclass"] = ldb.MessageElement(new_objectclass, >+ ldb.FLAG_MOD_ADD, "objectclass") >+ >+ self.assertRaisesLdbError(ldb.ERR_UNWILLING_TO_PERFORM, >+ "Should have been unable Able to change objectclass of a {objectclass}", >+ self.admin_samdb.modify, m) > > runner = SubunitTestRunner() > rc = 0 >-- >2.25.1 > > >From d6eb635e476d2546bf7907e85e35f2f9ac8c77b7 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 20 Sep 2021 12:35:51 +1200 >Subject: [PATCH 458/686] CVE-2020-25722 selftest: allow for future failures in > BindTests.test_virtual_email_account_style_bind > >This allows for any failures here to be handled via the knownfail system. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > auth/credentials/tests/bind.py | 13 +++++++++++-- > 1 file changed, 11 insertions(+), 2 deletions(-) > >diff --git a/auth/credentials/tests/bind.py b/auth/credentials/tests/bind.py >index 8bee6f96c62..b6b65a56c75 100755 >--- a/auth/credentials/tests/bind.py >+++ b/auth/credentials/tests/bind.py >@@ -90,7 +90,8 @@ class BindTests(samba.tests.TestCase): > # this test to detect when the LDAP DN is being double-parsed > # but must be in the user@realm style to allow the account to > # be created >- self.ldb.add_ldif(""" >+ try: >+ self.ldb.add_ldif(""" > dn: """ + self.virtual_user_dn + """ > cn: frednurk@""" + self.realm + """ > displayName: Fred Nurk >@@ -103,13 +104,21 @@ objectClass: person > objectClass: top > objectClass: user > """) >+ except LdbError as e: >+ (num, msg) = e.args >+ self.fail(f"Failed to create e-mail user: {msg}") >+ > self.addCleanup(delete_force, self.ldb, self.virtual_user_dn) >- self.ldb.modify_ldif(""" >+ try: >+ self.ldb.modify_ldif(""" > dn: """ + self.virtual_user_dn + """ > changetype: modify > replace: unicodePwd > unicodePwd:: """ + base64.b64encode(u"\"P@ssw0rd\"".encode('utf-16-le')).decode('utf8') + """ > """) >+ except LdbError as e: >+ (num, msg) = e.args >+ self.fail(f"Failed to set password on e-mail user: {msg}") > > self.ldb.enable_account('distinguishedName=%s' % self.virtual_user_dn) > >-- >2.25.1 > > >From fd32a4e9c15f0f63a60627b49cc862836318256c Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 20 Sep 2021 14:54:03 +1200 >Subject: [PATCH 459/686] CVE-2020-25722 selftest: Catch possible errors in > PasswordSettingsTestCase.test_pso_none_applied() > >This allows future patches to restrict changing the account type >without triggering an error. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > .../dsdb/tests/python/password_settings.py | 30 ++++++++++++------- > 1 file changed, 19 insertions(+), 11 deletions(-) > >diff --git a/source4/dsdb/tests/python/password_settings.py b/source4/dsdb/tests/python/password_settings.py >index fcb671690c3..e1c49d7bffb 100644 >--- a/source4/dsdb/tests/python/password_settings.py >+++ b/source4/dsdb/tests/python/password_settings.py >@@ -594,19 +594,27 @@ class PasswordSettingsTestCase(PasswordTestCase): > dummy_pso.apply_to(user.dn) > self.assertTrue(user.get_resultant_PSO() == dummy_pso.dn) > >- # now clear the ADS_UF_NORMAL_ACCOUNT flag for the user, which should >- # mean a resultant PSO is no longer returned (we're essentially turning >- # the user into a DC here, which is a little overkill but tests >- # behaviour as per the Windows specification) >- self.set_attribute(user.dn, "userAccountControl", >- str(dsdb.UF_WORKSTATION_TRUST_ACCOUNT), >- operation=FLAG_MOD_REPLACE) >+ try: >+ # now clear the ADS_UF_NORMAL_ACCOUNT flag for the user, which should >+ # mean a resultant PSO is no longer returned (we're essentially turning >+ # the user into a DC here, which is a little overkill but tests >+ # behaviour as per the Windows specification) >+ self.set_attribute(user.dn, "userAccountControl", >+ str(dsdb.UF_WORKSTATION_TRUST_ACCOUNT), >+ operation=FLAG_MOD_REPLACE) >+ except ldb.LdbError as e: >+ (num, msg) = e.args >+ self.fail("Failed to change user into a workstation: {msg}") > self.assertIsNone(user.get_resultant_PSO()) > >- # reset it back to a normal user account >- self.set_attribute(user.dn, "userAccountControl", >- str(dsdb.UF_NORMAL_ACCOUNT), >- operation=FLAG_MOD_REPLACE) >+ try: >+ # reset it back to a normal user account >+ self.set_attribute(user.dn, "userAccountControl", >+ str(dsdb.UF_NORMAL_ACCOUNT), >+ operation=FLAG_MOD_REPLACE) >+ except ldb.LdbError as e: >+ (num, msg) = e.args >+ self.fail("Failed to change user back into a user: {msg}") > self.assertTrue(user.get_resultant_PSO() == dummy_pso.dn) > > # no PSO should be returned if RID is equal to DOMAIN_USER_RID_KRBTGT >-- >2.25.1 > > >From f7d6a36a859d5c6277f80f7cc1978c209a075ebd Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 17 Sep 2021 13:41:40 +1200 >Subject: [PATCH 460/686] CVE-2020-25722 selftest: Catch errors from > samdb.modify() in user_account_control tests > >This will allow these to be listed in a knownfail shortly. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > .../dsdb/tests/python/user_account_control.py | 31 ++++++++++++++++--- > 1 file changed, 26 insertions(+), 5 deletions(-) > >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index 442fe741220..a22a72f12da 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -306,7 +306,11 @@ class UserAccountControlTests(samba.tests.TestCase): > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- self.samdb.modify(m) >+ try: >+ self.samdb.modify(m) >+ except LdbError as e: >+ (enum, estr) = e.args >+ self.fail(f"got {estr} setting userAccountControl to UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD") > > m = ldb.Message() > m.dn = res[0].dn >@@ -361,7 +365,11 @@ class UserAccountControlTests(samba.tests.TestCase): > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- self.samdb.modify(m) >+ try: >+ self.samdb.modify(m) >+ except LdbError as e: >+ (enum, estr) = e.args >+ self.fail(f"got {estr} setting userAccountControl to UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD") > > m = ldb.Message() > m.dn = res[0].dn >@@ -458,7 +466,11 @@ class UserAccountControlTests(samba.tests.TestCase): > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(UF_ACCOUNTDISABLE), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- self.admin_samdb.modify(m) >+ try: >+ self.admin_samdb.modify(m) >+ except LdbError as e: >+ (enum, estr) = e.args >+ self.fail(f"got {estr} setting userAccountControl to UF_ACCOUNTDISABLE (as admin)") > > res = self.admin_samdb.search("%s" % self.base_dn, > expression="(&(objectClass=computer)(samAccountName=%s$))" % computername, >@@ -579,7 +591,11 @@ class UserAccountControlTests(samba.tests.TestCase): > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(orig_uac), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- self.admin_samdb.modify(m) >+ try: >+ self.admin_samdb.modify(m) >+ except LdbError as e: >+ (enum, estr) = e.args >+ self.fail(f"got {estr} resetting userAccountControl to initial value {orig_uac:#08x}") > > res = self.admin_samdb.search("%s" % self.base_dn, > expression="(&(objectClass=computer)(samAccountName=%s$))" % computername, >@@ -898,7 +914,12 @@ class UserAccountControlTests(samba.tests.TestCase): > and account_type == UF_NORMAL_ACCOUNT): > self.admin_samdb.add(msg_dict) > elif objectclass == "computer": >- self.admin_samdb.add(msg_dict) >+ try: >+ self.admin_samdb.add(msg_dict) >+ except ldb.LdbError as e: >+ (num, msg) = e.args >+ self.fail("Failed to create {objectclass} account " >+ "with {account_type_string}") > else: > self.assertRaisesLdbError(ldb.ERR_OBJECT_CLASS_VIOLATION, > "Should have been unable to {account_type_str} on {objectclass}", >-- >2.25.1 > > >From 98307b102a9ca77d78e30dbea0e1ff4aec636c68 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 16 Sep 2021 08:46:42 +1200 >Subject: [PATCH 461/686] CVE-2020-25722 dsdb: objectclass computer becomes > UF_WORKSTATION_TRUST by default > >There are a lot of knownfail entries added with this commit. These >all need to be addressed and removed in subsequent commits which >will restructure the tests to pass within this new reality. > >This default applies even to users with administrator rights, >as changing the default based on permissions would break >to many assumptions. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/uac_objectclass_restrict | 42 +++++++++++++++++++ > source4/dsdb/samdb/ldb_modules/samldb.c | 27 +++++++++--- > 2 files changed, 64 insertions(+), 5 deletions(-) > create mode 100644 selftest/knownfail.d/uac_objectclass_restrict > >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >new file mode 100644 >index 00000000000..488fac15574 >--- /dev/null >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -0,0 +1,42 @@ >+# Knownfail entries due to restricting the creation of computer/user >+# accounts (in terms of userAccountControl) that do not match the objectclass >+# >+# All these tests need to be fixed and the entries here removed >+ >+^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_isCriticalSystemObject\(fl2008r2dc\) >+^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_userAccountControl\(fl2008r2dc\) >+^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_users_groups\(fl2008r2dc\) >+^samba4.ldap.python\(ad_dc_ntvfs\).__main__.BasicTests.test_all\(ad_dc_ntvfs\) >+^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_isCriticalSystemObject\(ad_dc_ntvfs\) >+^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_userAccountControl\(ad_dc_ntvfs\) >+^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_users_groups\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_add_computer_sd_cc\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_admin_mod_uac\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_computer_cc\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x10000000\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x20000000\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x40000000\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x80000000\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00000004\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00000400\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00004000\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00008000\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_ACCOUNTDISABLE\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_DONT_EXPIRE_PASSWD\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_DONT_REQUIRE_PREAUTH\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_HOMEDIR_REQUIRED\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_LOCKOUT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_MNS_LOGON_ACCOUNT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NOT_DELEGATED\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NO_AUTH_DATA_REQUIRED\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWD_CANT_CHANGE\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWD_NOTREQD\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWORD_EXPIRED\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SCRIPT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SMARTCARD_REQUIRED\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_AES_KEYS\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_DES_KEY_ONLY\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index f085d2454d9..380cafbbeb2 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -1413,19 +1413,33 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) > > switch(ac->type) { > case SAMLDB_TYPE_USER: { >+ bool is_computer_objectclass; > bool uac_generated = false, uac_add_flags = false; >- >+ uint32_t default_user_account_control = UF_NORMAL_ACCOUNT; > /* Step 1.2: Default values */ > ret = dsdb_user_obj_set_defaults(ldb, ac->msg, ac->req); > if (ret != LDB_SUCCESS) return ret; > >+ is_computer_objectclass >+ = (samdb_find_attribute(ldb, >+ ac->msg, >+ "objectclass", >+ "computer") >+ != NULL); >+ >+ if (is_computer_objectclass) { >+ default_user_account_control >+ = UF_WORKSTATION_TRUST_ACCOUNT; >+ } >+ >+ > /* On add operations we might need to generate a > * "userAccountControl" (if it isn't specified). */ > el = ldb_msg_find_element(ac->msg, "userAccountControl"); > if ((el == NULL) && (ac->req->operation == LDB_ADD)) { > ret = samdb_msg_set_uint(ldb, ac->msg, ac->msg, > "userAccountControl", >- UF_NORMAL_ACCOUNT); >+ default_user_account_control); > if (ret != LDB_SUCCESS) { > return ret; > } >@@ -1444,11 +1458,14 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) > raw_uac = user_account_control; > /* > * "userAccountControl" = 0 or missing one of >- * the types means "UF_NORMAL_ACCOUNT". See >- * MS-SAMR 3.1.1.8.10 point 8 >+ * the types means "UF_NORMAL_ACCOUNT" >+ * or "UF_WORKSTATION_TRUST_ACCOUNT" (if a computer). >+ * See MS-SAMR 3.1.1.8.10 point 8 > */ > if ((user_account_control & UF_ACCOUNT_TYPE_MASK) == 0) { >- user_account_control = UF_NORMAL_ACCOUNT | user_account_control; >+ user_account_control >+ = default_user_account_control >+ | user_account_control; > uac_generated = true; > } > >-- >2.25.1 > > >From 75cd874d9736da6f263372b08586f691846cfba2 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 22 Oct 2021 15:42:08 +1300 >Subject: [PATCH 462/686] CVE-2020-25722 dsdb: Improve privileged and > unprivileged tests for objectclass/doller/UAC > >This helps ensure we cover off all the cases that matter >for objectclass/trailing-doller/userAccountControl > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/uac_dollar_lock | 1 + > selftest/knownfail.d/uac_objectclass_restrict | 18 +- > .../user_account_control-uac_mod_lock | 11 -- > .../dsdb/tests/python/user_account_control.py | 172 +++++++++++++----- > 4 files changed, 142 insertions(+), 60 deletions(-) > create mode 100644 selftest/knownfail.d/uac_dollar_lock > delete mode 100644 selftest/knownfail.d/user_account_control-uac_mod_lock > >diff --git a/selftest/knownfail.d/uac_dollar_lock b/selftest/knownfail.d/uac_dollar_lock >new file mode 100644 >index 00000000000..8c70c859fa4 >--- /dev/null >+++ b/selftest/knownfail.d/uac_dollar_lock >@@ -0,0 +1 @@ >+^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_cc_plain >\ No newline at end of file >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index 488fac15574..efeed0701bf 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -13,6 +13,22 @@ > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_add_computer_sd_cc\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_admin_mod_uac\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_computer_cc\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_computer_replace\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_user_replace\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_SERVER_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_NORMAL_ACCOUNT_computer_cc_plain\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_NORMAL_ACCOUNT_computer_cc_withdollar\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_SERVER_TRUST_ACCOUNT_user_cc_plain\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_SERVER_TRUST_ACCOUNT_user_cc_withdollar\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_WORKSTATION_TRUST_ACCOUNT_deladd_wp\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_WORKSTATION_TRUST_ACCOUNT_replace_wp\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_SERVER_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_deladd_wp\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_SERVER_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_replace_wp\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_deladd_wp\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_replace_wp\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x10000000\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x20000000\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x40000000\(ad_dc_ntvfs\) >@@ -38,5 +54,3 @@ > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SMARTCARD_REQUIRED\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_AES_KEYS\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_DES_KEY_ONLY\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) >diff --git a/selftest/knownfail.d/user_account_control-uac_mod_lock b/selftest/knownfail.d/user_account_control-uac_mod_lock >deleted file mode 100644 >index a70534506f3..00000000000 >--- a/selftest/knownfail.d/user_account_control-uac_mod_lock >+++ /dev/null >@@ -1,11 +0,0 @@ >-# We do not want user account control account type swapping, so we mark these as knownfail >-^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_computer_replace >-^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_user_replace >-^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_SERVER_TRUST_ACCOUNT_computer_replace >-^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_replace >-^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_WORKSTATION_TRUST_ACCOUNT_deladd >-^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_WORKSTATION_TRUST_ACCOUNT_replace >-^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_SERVER_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_deladd >-^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_SERVER_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_replace >-^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_deladd >-^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_replace >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index a22a72f12da..dabbac6373a 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -91,32 +91,43 @@ account_types = set([UF_NORMAL_ACCOUNT, UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_ > class UserAccountControlTests(samba.tests.TestCase): > @classmethod > def setUpDynamicTestCases(cls): >+ for priv in [(True, "priv"), (False, "cc")]: >+ for account_type in [UF_NORMAL_ACCOUNT, >+ UF_WORKSTATION_TRUST_ACCOUNT, >+ UF_SERVER_TRUST_ACCOUNT]: >+ account_type_str = dsdb.user_account_control_flag_bit_to_string(account_type) >+ for objectclass in ["computer", "user"]: >+ for name in [("oc_uac_lock$", "withdollar"), \ >+ ("oc_uac_lock", "plain")]: >+ test_name = f"{account_type_str}_{objectclass}_{priv[1]}_{name[1]}" >+ cls.generate_dynamic_test("test_objectclass_uac_dollar_lock", >+ test_name, >+ account_type, >+ objectclass, >+ name[0], >+ priv[0]) >+ >+ for priv in [(True, "priv"), (False, "wp")]: >+ for account_type in [UF_NORMAL_ACCOUNT, >+ UF_WORKSTATION_TRUST_ACCOUNT, >+ UF_SERVER_TRUST_ACCOUNT]: >+ account_type_str = dsdb.user_account_control_flag_bit_to_string(account_type) >+ for account_type2 in [UF_NORMAL_ACCOUNT, >+ UF_WORKSTATION_TRUST_ACCOUNT, >+ UF_SERVER_TRUST_ACCOUNT]: >+ for how in ["replace", "deladd"]: >+ account_type2_str = dsdb.user_account_control_flag_bit_to_string(account_type2) >+ test_name = f"{account_type_str}_{account_type2_str}_{how}_{priv[1]}" >+ cls.generate_dynamic_test("test_objectclass_uac_mod_lock", >+ test_name, >+ account_type, >+ account_type2, >+ how, >+ priv[0]) > for account_type in [UF_NORMAL_ACCOUNT, > UF_WORKSTATION_TRUST_ACCOUNT, > UF_SERVER_TRUST_ACCOUNT]: > account_type_str = dsdb.user_account_control_flag_bit_to_string(account_type) >- for objectclass in ["computer", "user"]: >- test_name = f"{account_type_str}_{objectclass}" >- cls.generate_dynamic_test("test_objectclass_uac_lock", >- test_name, >- account_type, >- objectclass) >- >- for account_type in [UF_NORMAL_ACCOUNT, >- UF_WORKSTATION_TRUST_ACCOUNT, >- UF_SERVER_TRUST_ACCOUNT]: >- account_type_str = dsdb.user_account_control_flag_bit_to_string(account_type) >- for account_type2 in [UF_NORMAL_ACCOUNT, >- UF_WORKSTATION_TRUST_ACCOUNT, >- UF_SERVER_TRUST_ACCOUNT]: >- for how in ["replace", "deladd"]: >- account_type2_str = dsdb.user_account_control_flag_bit_to_string(account_type2) >- test_name = f"{account_type_str}_{account_type2_str}_{how}" >- cls.generate_dynamic_test("test_objectclass_uac_mod_lock", >- test_name, >- account_type, >- account_type2, >- how) > for objectclass in ["user", "computer"]: > for how in ["replace", "deladd"]: > test_name = f"{account_type_str}_{objectclass}_{how}" >@@ -895,10 +906,11 @@ class UserAccountControlTests(samba.tests.TestCase): > "primaryGroupID") > self.admin_samdb.modify(m) > >- def _test_objectclass_uac_lock_with_args(self, >- account_type, >- objectclass): >- name = "oc_uac_lock$" >+ def _test_objectclass_uac_dollar_lock_with_args(self, >+ account_type, >+ objectclass, >+ name, >+ priv): > dn = "CN=%s,%s" % (name, self.OU) > msg_dict = { > "dn": dn, >@@ -910,25 +922,57 @@ class UserAccountControlTests(samba.tests.TestCase): > > print(f"Adding account {name} as {account_type_str} with objectclass {objectclass}") > >- if (objectclass == "user" \ >- and account_type == UF_NORMAL_ACCOUNT): >- self.admin_samdb.add(msg_dict) >- elif objectclass == "computer": >- try: >- self.admin_samdb.add(msg_dict) >- except ldb.LdbError as e: >- (num, msg) = e.args >- self.fail("Failed to create {objectclass} account " >- "with {account_type_string}") >+ if priv: >+ samdb = self.admin_samdb > else: >- self.assertRaisesLdbError(ldb.ERR_OBJECT_CLASS_VIOLATION, >- "Should have been unable to {account_type_str} on {objectclass}", >- self.admin_samdb.add, msg_dict) >+ user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) >+ mod = "(OA;;CC;;;%s)" % str(user_sid) >+ >+ self.sd_utils.dacl_add_ace(self.OU, mod) >+ samdb = self.samdb >+ >+ enum = ldb.SUCCESS >+ try: >+ samdb.add(msg_dict) >+ except ldb.LdbError as e: >+ (enum, msg) = e.args >+ >+ if (account_type == UF_SERVER_TRUST_ACCOUNT >+ and objectclass != "computer"): >+ self.assertEqual(enum, ldb.ERR_OBJECT_CLASS_VIOLATION) >+ return >+ >+ if priv == False and account_type == UF_SERVER_TRUST_ACCOUNT: >+ self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ return >+ >+ if (objectclass == "user" >+ and account_type != UF_NORMAL_ACCOUNT): >+ self.assertEqual(enum, ldb.ERR_OBJECT_CLASS_VIOLATION) >+ return >+ >+ if (not priv and objectclass == "computer" >+ and account_type == UF_NORMAL_ACCOUNT): >+ self.assertEqual(enum, ldb.ERR_OBJECT_CLASS_VIOLATION) >+ return >+ >+ if priv and account_type == UF_NORMAL_ACCOUNT: >+ self.assertEqual(enum, 0) >+ return >+ >+ if (priv == False and >+ account_type != UF_NORMAL_ACCOUNT and >+ name[-1] != '$'): >+ self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM) >+ return >+ >+ self.assertEqual(enum, 0) > > def _test_objectclass_uac_mod_lock_with_args(self, > account_type, > account_type2, >- how): >+ how, >+ priv): > name = "uac_mod_lock$" > dn = "CN=%s,%s" % (name, self.OU) > if account_type == UF_NORMAL_ACCOUNT: >@@ -949,10 +993,25 @@ class UserAccountControlTests(samba.tests.TestCase): > > print(f"Adding account {name} as {account_type_str} with objectclass {objectclass}") > >+ if priv: >+ samdb = self.admin_samdb >+ else: >+ samdb = self.samdb >+ >+ user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) >+ >+ # Create the object as admin > self.admin_samdb.add(msg_dict) > >+ # We want to test what the underlying rules for non-admins >+ # regardless of security descriptors are, so set this very, >+ # dangerously, broadly >+ mod = "(OA;;WP;;;%s)" % str(user_sid) >+ >+ self.sd_utils.dacl_add_ace(dn, mod) >+ > m = ldb.Message() >- m.dn = ldb.Dn(self.admin_samdb, dn) >+ m.dn = ldb.Dn(samdb, dn) > if how == "replace": > m["userAccountControl"] = ldb.MessageElement(str(account_type2 | UF_PASSWD_NOTREQD), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >@@ -964,17 +1023,36 @@ class UserAccountControlTests(samba.tests.TestCase): > else: > raise ValueError(f"{how} was not a valid argument") > >- if (account_type in [UF_SERVER_TRUST_ACCOUNT, >- UF_WORKSTATION_TRUST_ACCOUNT]) and \ >+ if (account_type == account_type2): >+ samdb.modify(m) >+ elif (account_type == UF_NORMAL_ACCOUNT) and \ >+ (account_type2 == UF_SERVER_TRUST_ACCOUNT) and not priv: >+ self.assertRaisesLdbError(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ f"Should have been unable to change {account_type_str} to {account_type2_str}", >+ samdb.modify, m) >+ elif (account_type == UF_NORMAL_ACCOUNT) and \ >+ (account_type2 == UF_SERVER_TRUST_ACCOUNT) and priv: >+ self.assertRaisesLdbError(ldb.ERR_UNWILLING_TO_PERFORM, >+ f"Should have been unable to change {account_type_str} to {account_type2_str}", >+ samdb.modify, m) >+ elif (account_type == UF_WORKSTATION_TRUST_ACCOUNT) and \ >+ (account_type2 == UF_SERVER_TRUST_ACCOUNT) and not priv: >+ self.assertRaisesLdbError(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ f"Should have been unable to change {account_type_str} to {account_type2_str}", >+ samdb.modify, m) >+ elif priv: >+ samdb.modify(m) >+ elif (account_type in [UF_SERVER_TRUST_ACCOUNT, >+ UF_WORKSTATION_TRUST_ACCOUNT]) and \ > (account_type2 in [UF_SERVER_TRUST_ACCOUNT, > UF_WORKSTATION_TRUST_ACCOUNT]): >- self.admin_samdb.modify(m) >+ samdb.modify(m) > elif (account_type == account_type2): >- self.admin_samdb.modify(m) >+ samdb.modify(m) > else: >- self.assertRaisesLdbError(ldb.ERR_UNWILLING_TO_PERFORM, >+ self.assertRaisesLdbError(ldb.ERR_OBJECT_CLASS_VIOLATION, > f"Should have been unable to change {account_type_str} to {account_type2_str}", >- self.admin_samdb.modify, m) >+ samdb.modify, m) > > def _test_objectclass_mod_lock_with_args(self, > account_type, >-- >2.25.1 > > >From 115d26b302e2b5da9671aef9efa1ef1c37ebd200 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 29 Oct 2021 23:33:32 +1300 >Subject: [PATCH 463/686] CVE-2020-25722 dsdb: Add tests for modifying > objectClass, userAccountControl and sAMAccountName > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14889 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/uac_mod_lock | 46 ++++++ > .../dsdb/tests/python/user_account_control.py | 150 ++++++++++++++++++ > 2 files changed, 196 insertions(+) > create mode 100644 selftest/knownfail.d/uac_mod_lock > >diff --git a/selftest/knownfail.d/uac_mod_lock b/selftest/knownfail.d/uac_mod_lock >new file mode 100644 >index 00000000000..293ad985f7f >--- /dev/null >+++ b/selftest/knownfail.d/uac_mod_lock >@@ -0,0 +1,46 @@ >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_user_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_user_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_user_UF_NORMAL_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_user_UF_NORMAL_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_None_UF_NORMAL_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_NORMAL_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_NORMAL_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_SERVER_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_SERVER_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_None_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_user_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_keep_dollar >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_user_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index dabbac6373a..1633998ada4 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -124,6 +124,46 @@ class UserAccountControlTests(samba.tests.TestCase): > account_type2, > how, > priv[0]) >+ >+ for objectclass in ["computer", "user"]: >+ account_types = [UF_NORMAL_ACCOUNT] >+ if objectclass == "computer": >+ account_types.append(UF_WORKSTATION_TRUST_ACCOUNT) >+ account_types.append(UF_SERVER_TRUST_ACCOUNT) >+ >+ for account_type in account_types: >+ account_type_str = ( >+ dsdb.user_account_control_flag_bit_to_string( >+ account_type)) >+ for account_type2 in [UF_NORMAL_ACCOUNT, >+ UF_WORKSTATION_TRUST_ACCOUNT, >+ UF_SERVER_TRUST_ACCOUNT, >+ UF_PARTIAL_SECRETS_ACCOUNT, >+ None]: >+ if account_type2 is None: >+ account_type2_str = None >+ else: >+ account_type2_str = ( >+ dsdb.user_account_control_flag_bit_to_string( >+ account_type2)) >+ >+ for objectclass2 in ["computer", "user", None]: >+ for name2 in [("oc_uac_lock", "remove_dollar"), >+ (None, "keep_dollar")]: >+ test_name = (f"{priv[1]}_{objectclass}_" >+ f"{account_type_str}_to_" >+ f"{objectclass2}_" >+ f"{account_type2_str}_" >+ f"{name2[1]}") >+ cls.generate_dynamic_test("test_mod_lock", >+ test_name, >+ objectclass, >+ objectclass2, >+ account_type, >+ account_type2, >+ name2[0], >+ priv[0]) >+ > for account_type in [UF_NORMAL_ACCOUNT, > UF_WORKSTATION_TRUST_ACCOUNT, > UF_SERVER_TRUST_ACCOUNT]: >@@ -968,6 +1008,116 @@ class UserAccountControlTests(samba.tests.TestCase): > > self.assertEqual(enum, 0) > >+ def _test_mod_lock_with_args(self, >+ objectclass, >+ objectclass2, >+ account_type, >+ account_type2, >+ name2, >+ priv): >+ name = "oc_uac_lock$" >+ >+ dn = "CN=%s,%s" % (name, self.OU) >+ msg_dict = { >+ "dn": dn, >+ "objectclass": objectclass, >+ "samAccountName": name, >+ "userAccountControl": str(account_type | UF_PASSWD_NOTREQD)} >+ >+ account_type_str = dsdb.user_account_control_flag_bit_to_string( >+ account_type) >+ >+ print(f"Adding account {name} as {account_type_str} " >+ f"with objectclass {objectclass}") >+ >+ # Create the object as admin >+ self.admin_samdb.add(msg_dict) >+ >+ if priv: >+ samdb = self.admin_samdb >+ else: >+ samdb = self.samdb >+ >+ user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) >+ >+ # We want to test what the underlying rules for non-admins regardless >+ # of security descriptors are, so set this very, dangerously, broadly >+ mod = f"(OA;;WP;;;{user_sid})" >+ >+ self.sd_utils.dacl_add_ace(dn, mod) >+ >+ msg = "Modifying account" >+ if name2 is not None: >+ msg += f" to {name2}" >+ if account_type2 is not None: >+ account_type2_str = dsdb.user_account_control_flag_bit_to_string( >+ account_type2) >+ msg += f" as {account_type2_str}" >+ else: >+ account_type2_str = None >+ if objectclass2 is not None: >+ msg += f" with objectClass {objectclass2}" >+ print(msg) >+ >+ msg = ldb.Message(ldb.Dn(samdb, dn)) >+ if objectclass2 is not None: >+ msg["objectClass"] = ldb.MessageElement(objectclass2, >+ ldb.FLAG_MOD_REPLACE, >+ "objectClass") >+ if name2 is not None: >+ msg["sAMAccountName"] = ldb.MessageElement(name2, >+ ldb.FLAG_MOD_REPLACE, >+ "sAMAccountName") >+ if account_type2 is not None: >+ msg["userAccountControl"] = ldb.MessageElement( >+ str(account_type2 | UF_PASSWD_NOTREQD), >+ ldb.FLAG_MOD_REPLACE, >+ "userAccountControl") >+ enum = ldb.SUCCESS >+ try: >+ samdb.modify(msg) >+ except ldb.LdbError as e: >+ enum, _ = e.args >+ >+ # Setting userAccountControl to be an RODC is not allowed. >+ if account_type2 == UF_PARTIAL_SECRETS_ACCOUNT: >+ self.assertEqual(enum, ldb.ERR_OTHER) >+ return >+ >+ # Unprivileged users cannot change userAccountControl. The exception is >+ # changing a non-normal account to UF_WORKSTATION_TRUST_ACCOUNT, which >+ # is allowed. >+ if (not priv >+ and account_type2 is not None >+ and account_type != account_type2 >+ and (account_type == UF_NORMAL_ACCOUNT >+ or account_type2 != UF_WORKSTATION_TRUST_ACCOUNT)): >+ self.assertIn(enum, [ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ ldb.ERR_OBJECT_CLASS_VIOLATION]) >+ return >+ >+ # A non-computer account cannot have UF_SERVER_TRUST_ACCOUNT. >+ if objectclass == "user" and account_type2 == UF_SERVER_TRUST_ACCOUNT: >+ self.assertIn(enum, [ldb.ERR_UNWILLING_TO_PERFORM, >+ ldb.ERR_OBJECT_CLASS_VIOLATION]) >+ return >+ >+ # The objectClass is not allowed to change. >+ if objectclass2 is not None and objectclass != objectclass2: >+ self.assertIn(enum, [ldb.ERR_OBJECT_CLASS_VIOLATION, >+ ldb.ERR_UNWILLING_TO_PERFORM]) >+ return >+ >+ # Unprivileged users cannot remove the trailing dollar from a computer >+ # account. >+ if not priv and objectclass == "computer" and ( >+ name2 is not None and name2[-1] != "$"): >+ self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM) >+ return >+ >+ self.assertEqual(enum, 0) >+ return >+ > def _test_objectclass_uac_mod_lock_with_args(self, > account_type, > account_type2, >-- >2.25.1 > > >From 62b7b93d9298b6d8f4c8a63525eb326c2d09ce4d Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 22 Oct 2021 16:07:46 +1300 >Subject: [PATCH 464/686] CVE-2020-25722 dsdb: Prohibit mismatch between UF_ > account types and objectclass. > >There are a lot of knownfail entries added with this commit. These >all need to be addressed and removed in subsequent commits which >will restructure the tests to pass within this new reality. > >The restriction is not applied to users with administrator rights, >as this breaks a lot of tests and provides no security benefit. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/priv_attr | 6 - > selftest/knownfail.d/uac_mod_lock | 6 - > selftest/knownfail.d/uac_objectclass_restrict | 35 ++-- > source4/dsdb/samdb/ldb_modules/samldb.c | 153 ++++++++++++++---- > 4 files changed, 145 insertions(+), 55 deletions(-) > >diff --git a/selftest/knownfail.d/priv_attr b/selftest/knownfail.d/priv_attr >index 4b85a869089..e0d6104cec9 100644 >--- a/selftest/knownfail.d/priv_attr >+++ b/selftest/knownfail.d/priv_attr >@@ -6,9 +6,3 @@ samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sid > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_WP_user > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_default_computer > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_default_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-RODC_add_CC_WP_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-RODC_add_CC_default_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-computer_add_CC_WP_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-computer_add_CC_default_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-computer_add_CC_WP_user >-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-computer_add_CC_default_user >diff --git a/selftest/knownfail.d/uac_mod_lock b/selftest/knownfail.d/uac_mod_lock >index 293ad985f7f..c70f20b0741 100644 >--- a/selftest/knownfail.d/uac_mod_lock >+++ b/selftest/knownfail.d/uac_mod_lock >@@ -24,16 +24,10 @@ > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_NORMAL_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_NORMAL_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_SERVER_TRUST_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_SERVER_TRUST_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_keep_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index efeed0701bf..66f552f0184 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -10,6 +10,16 @@ > ^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_isCriticalSystemObject\(ad_dc_ntvfs\) > ^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_userAccountControl\(ad_dc_ntvfs\) > ^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_users_groups\(ad_dc_ntvfs\) >+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-DC_add_CC_WP_user\(ad_dc_default\) >+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-DC_add_CC_default_user\(ad_dc_default\) >+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_WP_computer\(ad_dc_default\) >+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_default_computer\(ad_dc_default\) >+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_mod-del-add_CC_default_computer\(ad_dc_default\) >+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_mod-replace_CC_default_computer\(ad_dc_default\) >+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-user_add_CC_WP_computer\(ad_dc_default\) >+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-user_add_CC_default_computer\(ad_dc_default\) >+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-user_mod-del-add_CC_default_computer\(ad_dc_default\) >+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-user_mod-replace_CC_default_computer\(ad_dc_default\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_add_computer_sd_cc\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_admin_mod_uac\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_computer_cc\(ad_dc_ntvfs\) >@@ -17,18 +27,6 @@ > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_user_replace\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_SERVER_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_NORMAL_ACCOUNT_computer_cc_plain\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_NORMAL_ACCOUNT_computer_cc_withdollar\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_SERVER_TRUST_ACCOUNT_user_cc_plain\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_SERVER_TRUST_ACCOUNT_user_cc_withdollar\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_WORKSTATION_TRUST_ACCOUNT_deladd_wp\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_WORKSTATION_TRUST_ACCOUNT_replace_wp\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_SERVER_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_deladd_wp\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_SERVER_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_replace_wp\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_deladd_wp\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_replace_wp\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x10000000\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x20000000\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x40000000\(ad_dc_ntvfs\) >@@ -54,3 +52,16 @@ > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SMARTCARD_REQUIRED\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_AES_KEYS\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_DES_KEY_ONLY\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_deladd_priv\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_deladd_wp\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_replace_priv\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_replace_wp\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_INTERDOMAIN_TRUST_ACCOUNT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_NORMAL_ACCOUNT_UF_PASSWD_NOTREQD\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_INTERDOMAIN_TRUST_ACCOUNT\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_TRUSTED_FOR_DELEGATION\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION\(ad_dc_ntvfs\) >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 380cafbbeb2..4521a37ce25 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -1365,7 +1365,8 @@ static int samldb_check_user_account_control_rules(struct samldb_ctx *ac, > struct dom_sid *sid, > uint32_t req_uac, > uint32_t user_account_control, >- uint32_t user_account_control_old); >+ uint32_t user_account_control_old, >+ bool is_computer_objectclass); > > /* > * "Objectclass" trigger (MS-SAMR 3.1.1.8.1) >@@ -1484,21 +1485,12 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) > ret = samldb_check_user_account_control_rules(ac, NULL, > raw_uac, > user_account_control, >- 0); >+ 0, >+ is_computer_objectclass); > if (ret != LDB_SUCCESS) { > return ret; > } > >- /* Workstation and (read-only) DC objects do need objectclass "computer" */ >- if ((samdb_find_attribute(ldb, ac->msg, >- "objectclass", "computer") == NULL) && >- (user_account_control & >- (UF_SERVER_TRUST_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT))) { >- ldb_set_errstring(ldb, >- "samldb: Requested account type does need objectclass 'computer'!"); >- return LDB_ERR_OBJECT_CLASS_VIOLATION; >- } >- > /* add "sAMAccountType" attribute */ > ret = dsdb_user_obj_set_account_type(ldb, ac->msg, user_account_control, NULL); > if (ret != LDB_SUCCESS) { >@@ -1993,6 +1985,106 @@ static int samldb_check_user_account_control_invariants(struct samldb_ctx *ac, > return ret; > } > >+/* >+ * It would be best if these rules apply, always, but for now they >+ * apply only to non-admins >+ */ >+static int samldb_check_user_account_control_objectclass_invariants( >+ struct samldb_ctx *ac, >+ uint32_t user_account_control, >+ uint32_t user_account_control_old, >+ bool is_computer_objectclass) >+{ >+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module); >+ >+ uint32_t old_ufa = user_account_control_old & UF_ACCOUNT_TYPE_MASK; >+ uint32_t new_ufa = user_account_control & UF_ACCOUNT_TYPE_MASK; >+ >+ uint32_t old_rodc = user_account_control_old & UF_PARTIAL_SECRETS_ACCOUNT; >+ uint32_t new_rodc = user_account_control & UF_PARTIAL_SECRETS_ACCOUNT; >+ >+ bool is_admin; >+ struct security_token *user_token >+ = acl_user_token(ac->module); >+ if (user_token == NULL) { >+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; >+ } >+ >+ is_admin >+ = security_token_has_builtin_administrators(user_token); >+ >+ >+ /* >+ * We want to allow changes to (eg) disable an account >+ * that was created wrong, only checking the >+ * objectclass if the account type changes. >+ */ >+ if (old_ufa == new_ufa && old_rodc == new_rodc) { >+ return LDB_SUCCESS; >+ } >+ >+ switch (new_ufa) { >+ case UF_NORMAL_ACCOUNT: >+ if (is_computer_objectclass && !is_admin) { >+ ldb_asprintf_errstring(ldb, >+ "%08X: samldb: UF_NORMAL_ACCOUNT " >+ "requires objectclass 'user' not 'computer'!", >+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4)); >+ return LDB_ERR_OBJECT_CLASS_VIOLATION; >+ } >+ break; >+ >+ case UF_INTERDOMAIN_TRUST_ACCOUNT: >+ if (is_computer_objectclass) { >+ ldb_asprintf_errstring(ldb, >+ "%08X: samldb: UF_INTERDOMAIN_TRUST_ACCOUNT " >+ "requires objectclass 'user' not 'computer'!", >+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4)); >+ return LDB_ERR_OBJECT_CLASS_VIOLATION; >+ } >+ break; >+ >+ case UF_WORKSTATION_TRUST_ACCOUNT: >+ if (!is_computer_objectclass) { >+ /* >+ * Modify of a user account account into a >+ * workstation without objectclass computer >+ * as an admin is still permitted, but not >+ * to make an RODC >+ */ >+ if (is_admin >+ && ac->req->operation == LDB_MODIFY >+ && new_rodc == 0) { >+ break; >+ } >+ ldb_asprintf_errstring(ldb, >+ "%08X: samldb: UF_WORKSTATION_TRUST_ACCOUNT " >+ "requires objectclass 'computer'!", >+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4)); >+ return LDB_ERR_OBJECT_CLASS_VIOLATION; >+ } >+ break; >+ >+ case UF_SERVER_TRUST_ACCOUNT: >+ if (!is_computer_objectclass) { >+ ldb_asprintf_errstring(ldb, >+ "%08X: samldb: UF_SERVER_TRUST_ACCOUNT " >+ "requires objectclass 'computer'!", >+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4)); >+ return LDB_ERR_OBJECT_CLASS_VIOLATION; >+ } >+ break; >+ >+ default: >+ ldb_asprintf_errstring(ldb, >+ "%08X: samldb: invalid userAccountControl[0x%08X]", >+ W_ERROR_V(WERR_INVALID_PARAMETER), >+ user_account_control); >+ return LDB_ERR_OTHER; >+ } >+ return LDB_SUCCESS; >+} >+ > static int samldb_get_domain_secdesc(struct samldb_ctx *ac, > struct security_descriptor **domain_sd) > { >@@ -2191,7 +2283,8 @@ static int samldb_check_user_account_control_rules(struct samldb_ctx *ac, > struct dom_sid *sid, > uint32_t req_uac, > uint32_t user_account_control, >- uint32_t user_account_control_old) >+ uint32_t user_account_control_old, >+ bool is_computer_objectclass) > { > int ret; > struct dsdb_control_password_user_account_control *uac = NULL; >@@ -2200,6 +2293,14 @@ static int samldb_check_user_account_control_rules(struct samldb_ctx *ac, > if (ret != LDB_SUCCESS) { > return ret; > } >+ ret = samldb_check_user_account_control_objectclass_invariants(ac, >+ user_account_control, >+ user_account_control_old, >+ is_computer_objectclass); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ > ret = samldb_check_user_account_control_acl(ac, sid, user_account_control, user_account_control_old); > if (ret != LDB_SUCCESS) { > return ret; >@@ -2261,7 +2362,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) > "objectSid", > NULL > }; >- bool is_computer = false; >+ bool is_computer_objectclass = false; > bool old_is_critical = false; > bool new_is_critical = false; > >@@ -2316,7 +2417,10 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) > "lockoutTime", 0); > old_is_critical = ldb_msg_find_attr_as_bool(res->msgs[0], > "isCriticalSystemObject", 0); >- /* When we do not have objectclass "computer" we cannot switch to a (read-only) DC */ >+ /* >+ * When we do not have objectclass "computer" we cannot >+ * switch to a workstation or (RO)DC >+ */ > el = ldb_msg_find_element(res->msgs[0], "objectClass"); > if (el == NULL) { > return ldb_operr(ldb); >@@ -2324,7 +2428,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) > computer_val = data_blob_string_const("computer"); > val = ldb_msg_find_val(el, &computer_val); > if (val != NULL) { >- is_computer = true; >+ is_computer_objectclass = true; > } > > old_ufa = old_uac & UF_ACCOUNT_TYPE_MASK; >@@ -2349,7 +2453,8 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) > ret = samldb_check_user_account_control_rules(ac, sid, > raw_uac, > new_uac, >- old_uac); >+ old_uac, >+ is_computer_objectclass); > if (ret != LDB_SUCCESS) { > return ret; > } >@@ -2371,25 +2476,11 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) > case UF_WORKSTATION_TRUST_ACCOUNT: > new_is_critical = false; > if (new_uac & UF_PARTIAL_SECRETS_ACCOUNT) { >- if (!is_computer) { >- ldb_asprintf_errstring(ldb, >- "%08X: samldb: UF_PARTIAL_SECRETS_ACCOUNT " >- "requires objectclass 'computer'!", >- W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4)); >- return LDB_ERR_UNWILLING_TO_PERFORM; >- } > new_is_critical = true; > } > break; > > case UF_SERVER_TRUST_ACCOUNT: >- if (!is_computer) { >- ldb_asprintf_errstring(ldb, >- "%08X: samldb: UF_SERVER_TRUST_ACCOUNT " >- "requires objectclass 'computer'!", >- W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4)); >- return LDB_ERR_UNWILLING_TO_PERFORM; >- } > new_is_critical = true; > break; > >-- >2.25.1 > > >From d81e991cbcf82ecaa4fcf9f27252b2922fca85f0 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 28 Oct 2021 14:47:30 +1300 >Subject: [PATCH 465/686] CVE-2020-25722 selftest/priv_attrs: Mention that > these knownfails are OK (for now) > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14775 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > selftest/knownfail.d/priv_attr | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/selftest/knownfail.d/priv_attr b/selftest/knownfail.d/priv_attr >index e0d6104cec9..5d3713eafe3 100644 >--- a/selftest/knownfail.d/priv_attr >+++ b/selftest/knownfail.d/priv_attr >@@ -1,3 +1,8 @@ >+# These priv_attrs tests would be good to fix, but are not fatal as >+# the testsuite is run twice, once with and once without STRICT_CHECKING=0 >+# >+# These knownfails show that we can improve our error matching against Windows. >+# > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_computer > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_WP_user > samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_CC_default_computer >-- >2.25.1 > > >From 5785953151ad37df1519d8e9e21496e7cb4b2ccd Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 22 Oct 2021 16:18:51 +1300 >Subject: [PATCH 466/686] CVE-2020-25722 selftest: Adapt selftest to > restriction on swapping account types > >This makes many of our tests pass again. We do not pass against Windows 2019 on all >as this does not have this restriction at this time. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/uac_objectclass_restrict | 29 +--------- > .../dsdb/tests/python/user_account_control.py | 54 +++++++++++++------ > 2 files changed, 39 insertions(+), 44 deletions(-) > >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index 66f552f0184..88ee353594d 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -27,31 +27,7 @@ > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_user_replace\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_SERVER_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x10000000\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x20000000\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x40000000\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_0x80000000\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00000004\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00000400\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00004000\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00008000\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_ACCOUNTDISABLE\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_DONT_EXPIRE_PASSWD\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_DONT_REQUIRE_PREAUTH\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_HOMEDIR_REQUIRED\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_LOCKOUT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_MNS_LOGON_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NOT_DELEGATED\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NO_AUTH_DATA_REQUIRED\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWD_CANT_CHANGE\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWD_NOTREQD\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWORD_EXPIRED\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SCRIPT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SMARTCARD_REQUIRED\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_AES_KEYS\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_DES_KEY_ONLY\(ad_dc_ntvfs\) >+^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SERVER_TRUST_ACCOUNT\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) >@@ -62,6 +38,3 @@ > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_INTERDOMAIN_TRUST_ACCOUNT\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_NORMAL_ACCOUNT_UF_PASSWD_NOTREQD\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_INTERDOMAIN_TRUST_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_TRUSTED_FOR_DELEGATION\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION\(ad_dc_ntvfs\) >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index 1633998ada4..7a7cfd40b72 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -219,6 +219,23 @@ class UserAccountControlTests(samba.tests.TestCase): > print("Adding computer account %s" % computername) > samdb.add(msg) > >+ def add_user_ldap(self, username, others=None, samdb=None): >+ if samdb is None: >+ samdb = self.samdb >+ dn = "CN=%s,%s" % (username, self.OU) >+ samaccountname = "%s" % username >+ msg_dict = { >+ "dn": dn, >+ "objectclass": "user"} >+ if others is not None: >+ msg_dict = dict(list(msg_dict.items()) + list(others.items())) >+ >+ msg = ldb.Message.from_dict(self.samdb, msg_dict) >+ msg["sAMAccountName"] = samaccountname >+ >+ print("Adding user account %s" % username) >+ samdb.add(msg) >+ > def get_creds(self, target_username, target_password): > creds_tmp = Credentials() > creds_tmp.set_username(target_username) >@@ -532,17 +549,21 @@ class UserAccountControlTests(samba.tests.TestCase): > > def _test_uac_bits_set_with_args(self, bit, bit_str): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) >- mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) >+ # Allow the creation of any children and write to any >+ # attributes (this is not a test of ACLs, this is a test of >+ # non-ACL userAccountControl rules >+ mod = f"(OA;CI;WP;;;{user_sid})(OA;;CC;;;{user_sid})" > > old_sd = self.sd_utils.read_sd_on_dn(self.OU) > > self.sd_utils.dacl_add_ace(self.OU, mod) > >+ # We want to start with UF_NORMAL_ACCOUNT, so we make a user > computername = self.computernames[0] >- self.add_computer_ldap(computername) >+ self.add_user_ldap(computername) > > res = self.admin_samdb.search("%s" % self.base_dn, >- expression="(&(objectClass=computer)(samAccountName=%s$))" % computername, >+ expression="(&(objectClass=user)(cn=%s))" % computername, > scope=SCOPE_SUBTREE, > attrs=[]) > >@@ -588,7 +609,11 @@ class UserAccountControlTests(samba.tests.TestCase): > > def _test_uac_bits_unrelated_modify_with_args(self, account_type): > user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) >- mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) >+ >+ # Allow the creation of any children and write to any >+ # attributes (this is not a test of ACLs, this is a test of >+ # non-ACL userAccountControl rules >+ mod = f"(OA;CI;WP;;;{user_sid})(OA;;CC;;;{user_sid})" > > old_sd = self.sd_utils.read_sd_on_dn(self.OU) > >@@ -596,22 +621,19 @@ class UserAccountControlTests(samba.tests.TestCase): > > computername = self.computernames[0] > if account_type == UF_WORKSTATION_TRUST_ACCOUNT: >- self.add_computer_ldap(computername, others={"userAccountControl": [str(account_type)]}) >- else: > self.add_computer_ldap(computername) >+ else: >+ self.add_user_ldap(computername) > > res = self.admin_samdb.search(self.OU, >- expression=f"(cn={computername})", >+ expression=f"(&(objectclass=user)(cn={computername}))", > scope=SCOPE_SUBTREE, > attrs=["userAccountControl"]) > self.assertEqual(len(res), 1) > > orig_uac = int(res[0]["userAccountControl"][0]) >- if account_type == UF_WORKSTATION_TRUST_ACCOUNT: >- self.assertEqual(orig_uac, account_type) >- else: >- self.assertEqual(orig_uac & UF_NORMAL_ACCOUNT, >- account_type) >+ self.assertEqual(orig_uac & account_type, >+ account_type) > > m = ldb.Message() > m.dn = res[0].dn >@@ -649,7 +671,7 @@ class UserAccountControlTests(samba.tests.TestCase): > self.fail(f"got {estr} resetting userAccountControl to initial value {orig_uac:#08x}") > > res = self.admin_samdb.search("%s" % self.base_dn, >- expression="(&(objectClass=computer)(samAccountName=%s$))" % computername, >+ expression="(&(objectClass=user)(cn=%s))" % computername, > scope=SCOPE_SUBTREE, > attrs=["userAccountControl"]) > >@@ -696,7 +718,7 @@ class UserAccountControlTests(samba.tests.TestCase): > self.fail("Unable to set userAccountControl bit 0x%08X on %s: %s" % (bit, m.dn, estr)) > > res = self.admin_samdb.search("%s" % self.base_dn, >- expression="(&(objectClass=computer)(samAccountName=%s$))" % computername, >+ expression="(&(objectClass=user)(cn=%s))" % computername, > scope=SCOPE_SUBTREE, > attrs=["userAccountControl"]) > >@@ -726,7 +748,7 @@ class UserAccountControlTests(samba.tests.TestCase): > self.fail("Unable to set userAccountControl bit 0x%08X on %s: %s" % (bit, m.dn, estr)) > > res = self.admin_samdb.search("%s" % self.base_dn, >- expression="(&(objectClass=computer)(samAccountName=%s$))" % computername, >+ expression="(&(objectClass=user)(cn=%s))" % computername, > scope=SCOPE_SUBTREE, > attrs=["userAccountControl"]) > >@@ -767,7 +789,7 @@ class UserAccountControlTests(samba.tests.TestCase): > self.fail("Unexpectedly unable to remove userAccountControl bit 0x%08X on %s: %s" % (bit, m.dn, estr)) > > res = self.admin_samdb.search("%s" % self.base_dn, >- expression="(&(objectClass=computer)(samAccountName=%s$))" % computername, >+ expression="(&(objectClass=user)(cn=%s))" % computername, > scope=SCOPE_SUBTREE, > attrs=["userAccountControl"]) > >-- >2.25.1 > > >From 862755665f8876914f43882c12ab64d2e088b2dd Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Wed, 22 Sep 2021 11:28:05 +1200 >Subject: [PATCH 467/686] CVE-2020-25722 dsdb: samldb_objectclass_trigger() is > only called on ADD, so remove indentation > >This makes the code less indented and simpler to understand. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 187 ++++++++++++------------ > 1 file changed, 93 insertions(+), 94 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 4521a37ce25..49108bdc9ea 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -1371,9 +1371,9 @@ static int samldb_check_user_account_control_rules(struct samldb_ctx *ac, > /* > * "Objectclass" trigger (MS-SAMR 3.1.1.8.1) > * >- * Has to be invoked on "add" and "modify" operations on "user", "computer" and >+ * Has to be invoked on "add" operations on "user", "computer" and > * "group" objects. >- * ac->msg contains the "add"/"modify" message >+ * ac->msg contains the "add" > * ac->type contains the object type (main objectclass) > */ > static int samldb_objectclass_trigger(struct samldb_ctx *ac) >@@ -1414,6 +1414,8 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) > > switch(ac->type) { > case SAMLDB_TYPE_USER: { >+ uint32_t raw_uac; >+ uint32_t user_account_control; > bool is_computer_objectclass; > bool uac_generated = false, uac_add_flags = false; > uint32_t default_user_account_control = UF_NORMAL_ACCOUNT; >@@ -1437,7 +1439,7 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) > /* On add operations we might need to generate a > * "userAccountControl" (if it isn't specified). */ > el = ldb_msg_find_element(ac->msg, "userAccountControl"); >- if ((el == NULL) && (ac->req->operation == LDB_ADD)) { >+ if (el == NULL) { > ret = samdb_msg_set_uint(ldb, ac->msg, ac->msg, > "userAccountControl", > default_user_account_control); >@@ -1449,114 +1451,111 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) > } > > el = ldb_msg_find_element(ac->msg, "userAccountControl"); >- if (el != NULL) { >- uint32_t raw_uac; >- uint32_t user_account_control; >- /* Step 1.3: "userAccountControl" -> "sAMAccountType" mapping */ >- user_account_control = ldb_msg_find_attr_as_uint(ac->msg, >- "userAccountControl", >- 0); >- raw_uac = user_account_control; >- /* >- * "userAccountControl" = 0 or missing one of >- * the types means "UF_NORMAL_ACCOUNT" >- * or "UF_WORKSTATION_TRUST_ACCOUNT" (if a computer). >- * See MS-SAMR 3.1.1.8.10 point 8 >- */ >- if ((user_account_control & UF_ACCOUNT_TYPE_MASK) == 0) { >- user_account_control >- = default_user_account_control >- | user_account_control; >- uac_generated = true; >- } >+ SMB_ASSERT(el != NULL); > >- /* >- * As per MS-SAMR 3.1.1.8.10 these flags have not to be set >- */ >- if ((user_account_control & UF_LOCKOUT) != 0) { >- user_account_control &= ~UF_LOCKOUT; >- uac_generated = true; >- } >- if ((user_account_control & UF_PASSWORD_EXPIRED) != 0) { >- user_account_control &= ~UF_PASSWORD_EXPIRED; >- uac_generated = true; >- } >+ /* Step 1.3: "userAccountControl" -> "sAMAccountType" mapping */ >+ user_account_control = ldb_msg_find_attr_as_uint(ac->msg, >+ "userAccountControl", >+ 0); >+ raw_uac = user_account_control; >+ /* >+ * "userAccountControl" = 0 or missing one of >+ * the types means "UF_NORMAL_ACCOUNT" >+ * or "UF_WORKSTATION_TRUST_ACCOUNT" (if a computer). >+ * See MS-SAMR 3.1.1.8.10 point 8 >+ */ >+ if ((user_account_control & UF_ACCOUNT_TYPE_MASK) == 0) { >+ user_account_control >+ = default_user_account_control >+ | user_account_control; >+ uac_generated = true; >+ } >+ >+ /* >+ * As per MS-SAMR 3.1.1.8.10 these flags have not to be set >+ */ >+ if ((user_account_control & UF_LOCKOUT) != 0) { >+ user_account_control &= ~UF_LOCKOUT; >+ uac_generated = true; >+ } >+ if ((user_account_control & UF_PASSWORD_EXPIRED) != 0) { >+ user_account_control &= ~UF_PASSWORD_EXPIRED; >+ uac_generated = true; >+ } > >- ret = samldb_check_user_account_control_rules(ac, NULL, >- raw_uac, >- user_account_control, >- 0, >- is_computer_objectclass); >+ ret = samldb_check_user_account_control_rules(ac, NULL, >+ raw_uac, >+ user_account_control, >+ 0, >+ is_computer_objectclass); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ >+ /* add "sAMAccountType" attribute */ >+ ret = dsdb_user_obj_set_account_type(ldb, ac->msg, user_account_control, NULL); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ >+ /* "isCriticalSystemObject" might be set */ >+ if (user_account_control & >+ (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) { >+ ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", >+ "TRUE"); > if (ret != LDB_SUCCESS) { > return ret; > } >- >- /* add "sAMAccountType" attribute */ >- ret = dsdb_user_obj_set_account_type(ldb, ac->msg, user_account_control, NULL); >+ el2 = ldb_msg_find_element(ac->msg, >+ "isCriticalSystemObject"); >+ el2->flags = LDB_FLAG_MOD_REPLACE; >+ } else if (user_account_control & UF_WORKSTATION_TRUST_ACCOUNT) { >+ ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", >+ "FALSE"); > if (ret != LDB_SUCCESS) { > return ret; > } >+ el2 = ldb_msg_find_element(ac->msg, >+ "isCriticalSystemObject"); >+ el2->flags = LDB_FLAG_MOD_REPLACE; >+ } > >- /* "isCriticalSystemObject" might be set */ >- if (user_account_control & >- (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) { >- ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", >- "TRUE"); >- if (ret != LDB_SUCCESS) { >- return ret; >- } >- el2 = ldb_msg_find_element(ac->msg, >- "isCriticalSystemObject"); >- el2->flags = LDB_FLAG_MOD_REPLACE; >- } else if (user_account_control & UF_WORKSTATION_TRUST_ACCOUNT) { >- ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", >- "FALSE"); >- if (ret != LDB_SUCCESS) { >- return ret; >- } >- el2 = ldb_msg_find_element(ac->msg, >- "isCriticalSystemObject"); >- el2->flags = LDB_FLAG_MOD_REPLACE; >- } >- >- /* Step 1.4: "userAccountControl" -> "primaryGroupID" mapping */ >- if (!ldb_msg_find_element(ac->msg, "primaryGroupID")) { >- uint32_t rid; >+ /* Step 1.4: "userAccountControl" -> "primaryGroupID" mapping */ >+ if (!ldb_msg_find_element(ac->msg, "primaryGroupID")) { >+ uint32_t rid; > >- ret = dsdb_user_obj_set_primary_group_id(ldb, ac->msg, user_account_control, &rid); >+ ret = dsdb_user_obj_set_primary_group_id(ldb, ac->msg, user_account_control, &rid); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ /* >+ * Older AD deployments don't know about the >+ * RODC group >+ */ >+ if (rid == DOMAIN_RID_READONLY_DCS) { >+ ret = samldb_prim_group_tester(ac, rid); > if (ret != LDB_SUCCESS) { > return ret; > } >- /* >- * Older AD deployments don't know about the >- * RODC group >- */ >- if (rid == DOMAIN_RID_READONLY_DCS) { >- ret = samldb_prim_group_tester(ac, rid); >- if (ret != LDB_SUCCESS) { >- return ret; >- } >- } > } >+ } > >- /* Step 1.5: Add additional flags when needed */ >- /* Obviously this is done when the "userAccountControl" >- * has been generated here (tested against Windows >- * Server) */ >- if (uac_generated) { >- if (uac_add_flags) { >- user_account_control |= UF_ACCOUNTDISABLE; >- user_account_control |= UF_PASSWD_NOTREQD; >- } >- >- ret = samdb_msg_set_uint(ldb, ac->msg, ac->msg, >- "userAccountControl", >- user_account_control); >- if (ret != LDB_SUCCESS) { >- return ret; >- } >+ /* Step 1.5: Add additional flags when needed */ >+ /* Obviously this is done when the "userAccountControl" >+ * has been generated here (tested against Windows >+ * Server) */ >+ if (uac_generated) { >+ if (uac_add_flags) { >+ user_account_control |= UF_ACCOUNTDISABLE; >+ user_account_control |= UF_PASSWD_NOTREQD; > } > >+ ret = samdb_msg_set_uint(ldb, ac->msg, ac->msg, >+ "userAccountControl", >+ user_account_control); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } > } > break; > } >-- >2.25.1 > > >From b4307737607b1c93d6bb85a6b94bb2a680ddb647 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Wed, 22 Sep 2021 11:29:02 +1200 >Subject: [PATCH 468/686] CVE-2020-25722 dsdb: Add restrictions on computer > accounts without a trailing $ > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/uac_dollar_lock | 1 - > selftest/knownfail.d/uac_mod_lock | 12 -- > source4/dsdb/samdb/ldb_modules/samldb.c | 171 +++++++++++++++++++++--- > 3 files changed, 154 insertions(+), 30 deletions(-) > delete mode 100644 selftest/knownfail.d/uac_dollar_lock > >diff --git a/selftest/knownfail.d/uac_dollar_lock b/selftest/knownfail.d/uac_dollar_lock >deleted file mode 100644 >index 8c70c859fa4..00000000000 >--- a/selftest/knownfail.d/uac_dollar_lock >+++ /dev/null >@@ -1 +0,0 @@ >-^samba4.user_account_control.python\(.*\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_cc_plain >\ No newline at end of file >diff --git a/selftest/knownfail.d/uac_mod_lock b/selftest/knownfail.d/uac_mod_lock >index c70f20b0741..79db7dc7a8f 100644 >--- a/selftest/knownfail.d/uac_mod_lock >+++ b/selftest/knownfail.d/uac_mod_lock >@@ -20,21 +20,9 @@ > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_user_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_user_UF_NORMAL_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_user_UF_NORMAL_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_None_UF_NORMAL_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_SERVER_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_SERVER_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_None_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_user_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_keep_dollar > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_user_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 49108bdc9ea..d6e37e75a81 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -68,6 +68,13 @@ struct samldb_ctx { > /* used for add operations */ > enum samldb_add_type type; > >+ /* >+ * should we apply the need_trailing_dollar restriction to >+ * samAccountName >+ */ >+ >+ bool need_trailing_dollar; >+ > /* the resulting message */ > struct ldb_message *msg; > >@@ -232,12 +239,86 @@ static int samldb_unique_attr_check(struct samldb_ctx *ac, const char *attr, > > static int samldb_sam_accountname_valid_check(struct samldb_ctx *ac) > { >- int ret = samldb_unique_attr_check(ac, "samAccountName", NULL, >- ldb_get_default_basedn( >- ldb_module_get_ctx(ac->module))); >- if (ret == LDB_ERR_OBJECT_CLASS_VIOLATION) { >+ int ret = 0; >+ bool is_admin; >+ struct security_token *user_token = NULL; >+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module); >+ struct ldb_message_element *el = dsdb_get_single_valued_attr(ac->msg, "samAccountName", >+ ac->req->operation); >+ if (el == NULL || el->num_values == 0) { >+ ldb_asprintf_errstring(ldb, >+ "%08X: samldb: 'samAccountName' can't be deleted/empty!", >+ W_ERROR_V(WERR_DS_ILLEGAL_MOD_OPERATION)); >+ if (ac->req->operation == LDB_ADD) { >+ return LDB_ERR_CONSTRAINT_VIOLATION; >+ } else { >+ return LDB_ERR_UNWILLING_TO_PERFORM; >+ } >+ } >+ >+ ret = samldb_unique_attr_check(ac, "samAccountName", NULL, >+ ldb_get_default_basedn( >+ ldb_module_get_ctx(ac->module))); >+ >+ /* >+ * Error code munging to try and match what must be some quite >+ * strange code-paths in Windows >+ */ >+ if (ret == LDB_ERR_CONSTRAINT_VIOLATION >+ && ac->req->operation == LDB_MODIFY) { >+ ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; >+ } else if (ret == LDB_ERR_OBJECT_CLASS_VIOLATION) { > ret = LDB_ERR_CONSTRAINT_VIOLATION; > } >+ >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ >+ if (!ac->need_trailing_dollar) { >+ return LDB_SUCCESS; >+ } >+ >+ /* This does not permit a single $ */ >+ if (el->values[0].length < 2) { >+ ldb_asprintf_errstring(ldb, >+ "%08X: samldb: 'samAccountName' " >+ "can't just be one character!", >+ W_ERROR_V(WERR_DS_ILLEGAL_MOD_OPERATION)); >+ return LDB_ERR_UNWILLING_TO_PERFORM; >+ } >+ >+ user_token = acl_user_token(ac->module); >+ if (user_token == NULL) { >+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; >+ } >+ >+ is_admin >+ = security_token_has_builtin_administrators(user_token); >+ >+ if (is_admin) { >+ /* >+ * Administrators are allowed to select strange names. >+ * This is poor practice but not prevented. >+ */ >+ return false; >+ } >+ >+ if (el->values[0].data[el->values[0].length - 1] != '$') { >+ ldb_asprintf_errstring(ldb, >+ "%08X: samldb: 'samAccountName' " >+ "must have a trailing $!", >+ W_ERROR_V(WERR_DS_ILLEGAL_MOD_OPERATION)); >+ return LDB_ERR_UNWILLING_TO_PERFORM; >+ } >+ if (el->values[0].data[el->values[0].length - 2] == '$') { >+ ldb_asprintf_errstring(ldb, >+ "%08X: samldb: 'samAccountName' " >+ "must not have a double trailing $!", >+ W_ERROR_V(WERR_DS_ILLEGAL_MOD_OPERATION)); >+ return LDB_ERR_UNWILLING_TO_PERFORM; >+ } >+ > return ret; > } > >@@ -554,17 +635,31 @@ static int samldb_schema_add_handle_mapiid(struct samldb_ctx *ac) > } > > /* sAMAccountName handling */ >-static int samldb_generate_sAMAccountName(struct ldb_context *ldb, >+static int samldb_generate_sAMAccountName(struct samldb_ctx *ac, > struct ldb_message *msg) > { >+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module); > char *name; > >- /* Format: $000000-000000000000 */ >+ /* >+ * This is currently a Samba-only behaviour, to add a trailing >+ * $ even for the generated accounts. >+ */ >+ >+ if (ac->need_trailing_dollar) { >+ /* Format: $000000-00000000000$ */ >+ name = talloc_asprintf(msg, "$%.6X-%.6X%.5X$", >+ (unsigned int)generate_random(), >+ (unsigned int)generate_random(), >+ (unsigned int)generate_random()); >+ } else { >+ /* Format: $000000-000000000000 */ > >- name = talloc_asprintf(msg, "$%.6X-%.6X%.6X", >- (unsigned int)generate_random(), >- (unsigned int)generate_random(), >- (unsigned int)generate_random()); >+ name = talloc_asprintf(msg, "$%.6X-%.6X%.6X", >+ (unsigned int)generate_random(), >+ (unsigned int)generate_random(), >+ (unsigned int)generate_random()); >+ } > if (name == NULL) { > return ldb_oom(ldb); > } >@@ -573,11 +668,10 @@ static int samldb_generate_sAMAccountName(struct ldb_context *ldb, > > static int samldb_check_sAMAccountName(struct samldb_ctx *ac) > { >- struct ldb_context *ldb = ldb_module_get_ctx(ac->module); > int ret; > > if (ldb_msg_find_element(ac->msg, "sAMAccountName") == NULL) { >- ret = samldb_generate_sAMAccountName(ldb, ac->msg); >+ ret = samldb_generate_sAMAccountName(ac, ac->msg); > if (ret != LDB_SUCCESS) { > return ret; > } >@@ -1492,6 +1586,20 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) > return ret; > } > >+ /* >+ * Require, for non-admin modifications, a trailing $ >+ * for either objectclass=computer or a trust account >+ * type in userAccountControl >+ */ >+ if ((user_account_control >+ & UF_TRUST_ACCOUNT_MASK) != 0) { >+ ac->need_trailing_dollar = true; >+ } >+ >+ if (is_computer_objectclass) { >+ ac->need_trailing_dollar = true; >+ } >+ > /* add "sAMAccountType" attribute */ > ret = dsdb_user_obj_set_account_type(ldb, ac->msg, user_account_control, NULL); > if (ret != LDB_SUCCESS) { >@@ -4004,12 +4112,41 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) > > el = ldb_msg_find_element(ac->msg, "sAMAccountName"); > if (el != NULL) { >+ uint32_t user_account_control; >+ struct ldb_result *res = NULL; >+ const char * const attrs[] = { "userAccountControl", >+ "objectclass", >+ NULL }; >+ ret = dsdb_module_search_dn(ac->module, >+ ac, >+ &res, >+ ac->msg->dn, >+ attrs, >+ DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED, >+ ac->req); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ >+ user_account_control >+ = ldb_msg_find_attr_as_uint(res->msgs[0], >+ "userAccountControl", >+ 0); >+ >+ if ((user_account_control >+ & UF_TRUST_ACCOUNT_MASK) != 0) { >+ ac->need_trailing_dollar = true; >+ >+ } else if (samdb_find_attribute(ldb, >+ res->msgs[0], >+ "objectclass", >+ "computer") >+ != NULL) { >+ ac->need_trailing_dollar = true; >+ } >+ > ret = samldb_sam_accountname_valid_check(ac); >- /* >- * Other errors are checked for elsewhere, we just >- * want to prevent duplicates >- */ >- if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { >+ if (ret != LDB_SUCCESS) { > return ret; > } > } >-- >2.25.1 > > >From 0c9c7ae5bc2269f39813cbcd0d0dc26989536cb3 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 21 Oct 2021 11:57:22 +1300 >Subject: [PATCH 469/686] CVE-2020-25722 selftest: Adapt sam.py > test_isCriticalSystemObject to new UF_WORKSTATION_TRUST_ACCOUNT default > >Objects with objectclass computer now have UF_WORKSTATION_TRUST_ACCOUNT >by default and so this test must adapt. > >The changes to this test passes against Windows 2019 except for >the new behaviour around the UF_WORKSTATION_TRUST_ACCOUNT default. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > .../knownfail.d/sam-isCriticalSystemObject | 1 + > selftest/knownfail.d/uac_objectclass_restrict | 2 -- > source4/dsdb/tests/python/sam.py | 36 ++++++++++++++++++- > 3 files changed, 36 insertions(+), 3 deletions(-) > create mode 100644 selftest/knownfail.d/sam-isCriticalSystemObject > >diff --git a/selftest/knownfail.d/sam-isCriticalSystemObject b/selftest/knownfail.d/sam-isCriticalSystemObject >new file mode 100644 >index 00000000000..a6351a81907 >--- /dev/null >+++ b/selftest/knownfail.d/sam-isCriticalSystemObject >@@ -0,0 +1 @@ >+^samba4.sam.python\(.*\).__main__.SamTests.test_isCriticalSystemObject_user >\ No newline at end of file >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index 88ee353594d..4899d3f7898 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -3,11 +3,9 @@ > # > # All these tests need to be fixed and the entries here removed > >-^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_isCriticalSystemObject\(fl2008r2dc\) > ^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_userAccountControl\(fl2008r2dc\) > ^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_users_groups\(fl2008r2dc\) > ^samba4.ldap.python\(ad_dc_ntvfs\).__main__.BasicTests.test_all\(ad_dc_ntvfs\) >-^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_isCriticalSystemObject\(ad_dc_ntvfs\) > ^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_userAccountControl\(ad_dc_ntvfs\) > ^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_users_groups\(ad_dc_ntvfs\) > ^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-DC_add_CC_WP_user\(ad_dc_default\) >diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py >index 02a8d2d52b4..2b3f0653daf 100755 >--- a/source4/dsdb/tests/python/sam.py >+++ b/source4/dsdb/tests/python/sam.py >@@ -2926,6 +2926,39 @@ class SamTests(samba.tests.TestCase): > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >+ def test_isCriticalSystemObject_user(self): >+ """Test the isCriticalSystemObject behaviour""" >+ print("Testing isCriticalSystemObject behaviour\n") >+ >+ # Add tests (of a user) >+ >+ ldb.add({ >+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn, >+ "objectclass": "user"}) >+ >+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, >+ scope=SCOPE_BASE, >+ attrs=["isCriticalSystemObject"]) >+ self.assertTrue(len(res1) == 1) >+ self.assertTrue("isCriticalSystemObject" not in res1[0]) >+ >+ # Modification tests >+ m = Message() >+ >+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >+ m["userAccountControl"] = MessageElement(str(UF_WORKSTATION_TRUST_ACCOUNT), >+ FLAG_MOD_REPLACE, "userAccountControl") >+ ldb.modify(m) >+ >+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, >+ scope=SCOPE_BASE, >+ attrs=["isCriticalSystemObject"]) >+ self.assertTrue(len(res1) == 1) >+ self.assertTrue("isCriticalSystemObject" in res1[0]) >+ self.assertEqual(str(res1[0]["isCriticalSystemObject"][0]), "FALSE") >+ >+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >+ > def test_isCriticalSystemObject(self): > """Test the isCriticalSystemObject behaviour""" > print("Testing isCriticalSystemObject behaviour\n") >@@ -2940,7 +2973,8 @@ class SamTests(samba.tests.TestCase): > scope=SCOPE_BASE, > attrs=["isCriticalSystemObject"]) > self.assertTrue(len(res1) == 1) >- self.assertTrue("isCriticalSystemObject" not in res1[0]) >+ self.assertTrue("isCriticalSystemObject" in res1[0]) >+ self.assertEqual(str(res1[0]["isCriticalSystemObject"][0]), "FALSE") > > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >-- >2.25.1 > > >From 563c6188d12e45cc03ee1d7fb12e4b9b46c28e1a Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 21 Oct 2021 13:02:42 +1300 >Subject: [PATCH 470/686] CVE-2020-25722 samdb: Fill in isCriticalSystemObject > on any account type change > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > selftest/knownfail.d/sam-isCriticalSystemObject | 1 - > source4/dsdb/samdb/ldb_modules/samldb.c | 10 ++++++++-- > 2 files changed, 8 insertions(+), 3 deletions(-) > delete mode 100644 selftest/knownfail.d/sam-isCriticalSystemObject > >diff --git a/selftest/knownfail.d/sam-isCriticalSystemObject b/selftest/knownfail.d/sam-isCriticalSystemObject >deleted file mode 100644 >index a6351a81907..00000000000 >--- a/selftest/knownfail.d/sam-isCriticalSystemObject >+++ /dev/null >@@ -1 +0,0 @@ >-^samba4.sam.python\(.*\).__main__.SamTests.test_isCriticalSystemObject_user >\ No newline at end of file >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index d6e37e75a81..babcbd26ee7 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -2621,8 +2621,14 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) > el->flags = LDB_FLAG_MOD_REPLACE; > } > >- /* "isCriticalSystemObject" might be set/changed */ >- if (old_is_critical != new_is_critical) { >+ /* >+ * "isCriticalSystemObject" might be set/changed >+ * >+ * Even a change from UF_NORMAL_ACCOUNT (implicitly FALSE) to >+ * UF_WORKSTATION_TRUST_ACCOUNT (actually FALSE) triggers >+ * creating the attribute. >+ */ >+ if (old_is_critical != new_is_critical || old_atype != new_atype) { > ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", > new_is_critical ? "TRUE": "FALSE"); > if (ret != LDB_SUCCESS) { >-- >2.25.1 > > >From 8a9473fefde91859627b2955ab88cf723f8acf86 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 21 Oct 2021 14:03:05 +1300 >Subject: [PATCH 471/686] CVE-2020-25722 selftest: Split > test_userAccountControl into unit tests > >The parts that create and delete a single object can be >safely split out into an individual test. > >At this point the parts that fail against Windows 2019 are: > >error: __main__.SamTests.test_userAccountControl_computer_add_normal [ >_ldb.LdbError: (53, 'LDAP error 53 LDAP_UNWILLING_TO_PERFORM - <0000052D: SvcErr: DSID-031A1236, problem 5003 (WILL_NOT_PERFORM), data 0\n> <>') >error: __main__.SamTests.test_userAccountControl_computer_modify [ >_ldb.LdbError: (53, 'LDAP error 53 LDAP_UNWILLING_TO_PERFORM - <0000052D: SvcErr: DSID-031A1236, problem 5003 (WILL_NOT_PERFORM), data 0\n> <>') >error: __main__.SamTests.test_userAccountControl_user_add_0_uac [ >_ldb.LdbError: (53, 'LDAP error 53 LDAP_UNWILLING_TO_PERFORM - <0000052D: SvcErr: DSID-031A1236, problem 5003 (WILL_NOT_PERFORM), data 0\n> <>') >error: __main__.SamTests.test_userAccountControl_user_add_normal [ >_ldb.LdbError: (53, 'LDAP error 53 LDAP_UNWILLING_TO_PERFORM - <0000052D: SvcErr: DSID-031A1236, problem 5003 (WILL_NOT_PERFORM), data 0\n> <>') >error: __main__.SamTests.test_userAccountControl_user_modify [ >_ldb.LdbError: (53, 'LDAP error 53 LDAP_UNWILLING_TO_PERFORM - <0000052D: SvcErr: DSID-031A1236, problem 5003 (WILL_NOT_PERFORM), data 0\n> <>') > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/uac_objectclass_restrict | 6 ++++-- > source4/dsdb/tests/python/sam.py | 21 ++++++++++++++++++- > 2 files changed, 24 insertions(+), 3 deletions(-) > >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index 4899d3f7898..b0910494d1e 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -3,10 +3,12 @@ > # > # All these tests need to be fixed and the entries here removed > >-^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_userAccountControl\(fl2008r2dc\) >+^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_computer_add_0_uac >+^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_computer_add_trust >+^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_computer_modify >+^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_user_modify > ^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_users_groups\(fl2008r2dc\) > ^samba4.ldap.python\(ad_dc_ntvfs\).__main__.BasicTests.test_all\(ad_dc_ntvfs\) >-^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_userAccountControl\(ad_dc_ntvfs\) > ^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_users_groups\(ad_dc_ntvfs\) > ^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-DC_add_CC_WP_user\(ad_dc_default\) > ^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-DC_add_CC_default_user\(ad_dc_default\) >diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py >index 2b3f0653daf..712624bc781 100755 >--- a/source4/dsdb/tests/python/sam.py >+++ b/source4/dsdb/tests/python/sam.py >@@ -1885,7 +1885,7 @@ class SamTests(samba.tests.TestCase): > > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >- def test_userAccountControl(self): >+ def test_userAccountControl_user_add_0_uac(self): > """Test the userAccountControl behaviour""" > print("Testing userAccountControl behaviour\n") > >@@ -1913,12 +1913,15 @@ class SamTests(samba.tests.TestCase): > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_PASSWD_NOTREQD == 0) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >+ def test_userAccountControl_user_add_normal(self): >+ """Test the userAccountControl behaviour""" > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, > "objectclass": "user", > "userAccountControl": str(UF_NORMAL_ACCOUNT)}) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >+ def test_userAccountControl_user_add_normal_pwnotreq(self): > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, > "objectclass": "user", >@@ -1933,6 +1936,7 @@ class SamTests(samba.tests.TestCase): > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >+ def test_userAccountControl_user_add_normal_pwnotreq_lockout_expired(self): > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, > "objectclass": "user", >@@ -1952,6 +1956,7 @@ class SamTests(samba.tests.TestCase): > self.assertTrue(int(res1[0]["pwdLastSet"][0]) == 0) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >+ def test_userAccountControl_user_add_temp_dup(self): > try: > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, >@@ -1963,6 +1968,7 @@ class SamTests(samba.tests.TestCase): > self.assertEqual(num, ERR_OTHER) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >+ def test_userAccountControl_user_add_server(self): > try: > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, >@@ -1974,6 +1980,7 @@ class SamTests(samba.tests.TestCase): > self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >+ def test_userAccountControl_user_add_workstation(self): > try: > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, >@@ -1984,6 +1991,7 @@ class SamTests(samba.tests.TestCase): > self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >+ def test_userAccountControl_user_add_rodc(self): > try: > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, >@@ -1994,6 +2002,7 @@ class SamTests(samba.tests.TestCase): > self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > >+ def test_userAccountControl_user_add_trust(self): > try: > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, >@@ -2007,6 +2016,7 @@ class SamTests(samba.tests.TestCase): > > # Modify operation > >+ def test_userAccountControl_user_modify(self): > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, > "objectclass": "user"}) >@@ -2177,6 +2187,7 @@ class SamTests(samba.tests.TestCase): > (num, _) = e69.args > self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > >+ def test_userAccountControl_computer_add_0_uac(self): > # With a computer object > > # Add operation >@@ -2201,12 +2212,14 @@ class SamTests(samba.tests.TestCase): > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_PASSWD_NOTREQD == 0) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >+ def test_userAccountControl_computer_add_normal(self): > ldb.add({ > "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, > "objectclass": "computer", > "userAccountControl": str(UF_NORMAL_ACCOUNT)}) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >+ def test_userAccountControl_computer_add_normal_pwnotreqd(self): > ldb.add({ > "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, > "objectclass": "computer", >@@ -2221,6 +2234,7 @@ class SamTests(samba.tests.TestCase): > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >+ def test_userAccountControl_computer_add_normal_pwnotreqd_lockout_expired(self): > ldb.add({ > "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, > "objectclass": "computer", >@@ -2240,6 +2254,7 @@ class SamTests(samba.tests.TestCase): > self.assertTrue(int(res1[0]["pwdLastSet"][0]) == 0) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >+ def test_userAccountControl_computer_add_temp_dup(self): > try: > ldb.add({ > "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, >@@ -2251,6 +2266,7 @@ class SamTests(samba.tests.TestCase): > self.assertEqual(num, ERR_OTHER) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >+ def test_userAccountControl_computer_add_server(self): > ldb.add({ > "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, > "objectclass": "computer", >@@ -2263,6 +2279,7 @@ class SamTests(samba.tests.TestCase): > ATYPE_WORKSTATION_TRUST) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >+ def test_userAccountControl_computer_add_workstation(self): > try: > ldb.add({ > "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, >@@ -2273,6 +2290,7 @@ class SamTests(samba.tests.TestCase): > self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >+ def test_userAccountControl_computer_add_trust(self): > try: > ldb.add({ > "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, >@@ -2284,6 +2302,7 @@ class SamTests(samba.tests.TestCase): > self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >+ def test_userAccountControl_computer_modify(self): > # Modify operation > > ldb.add({ >-- >2.25.1 > > >From a82aa19b71a2c25c90bb4bb011436165daee90a3 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 21 Oct 2021 15:06:14 +1300 >Subject: [PATCH 472/686] CVE-2020-25722 selftest: Adjust sam.py > test_userAccountControl_computer_add_trust to new reality > >We now enforce that a trust account must be a user. > >These can not be added over LDAP anyway, and our C >code in the RPC server gets this right in any case. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > selftest/knownfail.d/uac_objectclass_restrict | 1 - > source4/dsdb/tests/python/sam.py | 2 +- > 2 files changed, 1 insertion(+), 2 deletions(-) > >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index b0910494d1e..3e2871d5608 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -4,7 +4,6 @@ > # All these tests need to be fixed and the entries here removed > > ^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_computer_add_0_uac >-^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_computer_add_trust > ^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_computer_modify > ^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_user_modify > ^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_users_groups\(fl2008r2dc\) >diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py >index 712624bc781..b910d74176f 100755 >--- a/source4/dsdb/tests/python/sam.py >+++ b/source4/dsdb/tests/python/sam.py >@@ -2299,7 +2299,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e72: > (num, _) = e72.args >- self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > > def test_userAccountControl_computer_modify(self): >-- >2.25.1 > > >From 6610161791aed7c233a14d7713429a98c7ececcd Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 21 Oct 2021 15:14:28 +1300 >Subject: [PATCH 473/686] CVE-2020-25722 selftest: New objects of > objectclass=computer are workstations by default now > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > selftest/knownfail.d/uac_objectclass_restrict | 1 - > source4/dsdb/tests/python/sam.py | 4 ++-- > 2 files changed, 2 insertions(+), 3 deletions(-) > >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index 3e2871d5608..a50d73b955f 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -3,7 +3,6 @@ > # > # All these tests need to be fixed and the entries here removed > >-^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_computer_add_0_uac > ^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_computer_modify > ^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_user_modify > ^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_users_groups\(fl2008r2dc\) >diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py >index b910d74176f..b0095e5aa05 100755 >--- a/source4/dsdb/tests/python/sam.py >+++ b/source4/dsdb/tests/python/sam.py >@@ -2207,7 +2207,7 @@ class SamTests(samba.tests.TestCase): > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) > self.assertEqual(int(res1[0]["sAMAccountType"][0]), >- ATYPE_NORMAL_ACCOUNT) >+ ATYPE_WORKSTATION_TRUST) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_PASSWD_NOTREQD == 0) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) >@@ -2315,7 +2315,7 @@ class SamTests(samba.tests.TestCase): > attrs=["sAMAccountType", "userAccountControl"]) > self.assertTrue(len(res1) == 1) > self.assertEqual(int(res1[0]["sAMAccountType"][0]), >- ATYPE_NORMAL_ACCOUNT) >+ ATYPE_WORKSTATION_TRUST) > self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0) > > # As computer you can switch from a normal account to a workstation >-- >2.25.1 > > >From bbeaa236a13c18b455fcff271387741a68a6f191 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 21 Oct 2021 15:19:19 +1300 >Subject: [PATCH 474/686] CVE-2020-25722 selftest: Adapt sam.py test to > userAccountControl/objectclass restrictions > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > selftest/knownfail.d/uac_objectclass_restrict | 2 -- > source4/dsdb/tests/python/sam.py | 6 +++--- > 2 files changed, 3 insertions(+), 5 deletions(-) > >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index a50d73b955f..c722177a79d 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -3,8 +3,6 @@ > # > # All these tests need to be fixed and the entries here removed > >-^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_computer_modify >-^samba4.sam.python\(.*\).__main__.SamTests.test_userAccountControl_user_modify > ^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_users_groups\(fl2008r2dc\) > ^samba4.ldap.python\(ad_dc_ntvfs\).__main__.BasicTests.test_all\(ad_dc_ntvfs\) > ^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_users_groups\(ad_dc_ntvfs\) >diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py >index b0095e5aa05..fcea4a89e70 100755 >--- a/source4/dsdb/tests/python/sam.py >+++ b/source4/dsdb/tests/python/sam.py >@@ -2135,7 +2135,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e67: > (num, _) = e67.args >- self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >@@ -2154,7 +2154,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e68: > (num, _) = e68.args >- self.assertEqual(num, ERR_UNWILLING_TO_PERFORM) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["sAMAccountType"]) >@@ -2502,7 +2502,7 @@ class SamTests(samba.tests.TestCase): > self.fail() > except LdbError as e76: > (num, _) = e76.args >- self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # "primaryGroupID" does not change if account type remains the same > >-- >2.25.1 > > >From 3755b90a240e6ac472e948e6b067169633815716 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 21 Oct 2021 15:42:46 +1300 >Subject: [PATCH 475/686] CVE-2020-25722 selftest: adapt ldap.py/sam.py > test_all tests to new default computer behaviour > >Objects of objectclass computer are computers by default now and this changes >the sAMAccountType and primaryGroupID as well as userAccountControl > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/uac_objectclass_restrict | 3 --- > source4/dsdb/tests/python/ldap.py | 13 +++++++------ > source4/dsdb/tests/python/sam.py | 4 +++- > 3 files changed, 10 insertions(+), 10 deletions(-) > >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index c722177a79d..aed4590cb4f 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -3,9 +3,6 @@ > # > # All these tests need to be fixed and the entries here removed > >-^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_users_groups\(fl2008r2dc\) >-^samba4.ldap.python\(ad_dc_ntvfs\).__main__.BasicTests.test_all\(ad_dc_ntvfs\) >-^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_users_groups\(ad_dc_ntvfs\) > ^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-DC_add_CC_WP_user\(ad_dc_default\) > ^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-DC_add_CC_default_user\(ad_dc_default\) > ^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_WP_computer\(ad_dc_default\) >diff --git a/source4/dsdb/tests/python/ldap.py b/source4/dsdb/tests/python/ldap.py >index 5a607e9a509..d6113e3345d 100755 >--- a/source4/dsdb/tests/python/ldap.py >+++ b/source4/dsdb/tests/python/ldap.py >@@ -48,6 +48,7 @@ from samba.dsdb import (UF_NORMAL_ACCOUNT, > ATYPE_WORKSTATION_TRUST, SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE, > SYSTEM_FLAG_CONFIG_ALLOW_RENAME, SYSTEM_FLAG_CONFIG_ALLOW_MOVE, > SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE) >+from samba.dcerpc.security import DOMAIN_RID_DOMAIN_MEMBERS > > from samba.ndr import ndr_pack, ndr_unpack > from samba.dcerpc import security, lsa >@@ -2007,9 +2008,9 @@ delete: description > self.assertTrue("objectGUID" in res[0]) > self.assertTrue("whenCreated" in res[0]) > self.assertEqual(str(res[0]["objectCategory"][0]), ("CN=Computer,%s" % ldb.get_schema_basedn())) >- self.assertEqual(int(res[0]["primaryGroupID"][0]), 513) >- self.assertEqual(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT) >- self.assertEqual(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) >+ self.assertEqual(int(res[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS) >+ self.assertEqual(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST) >+ self.assertEqual(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) > > delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn) > >@@ -2488,9 +2489,9 @@ member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """ > self.assertTrue("objectGUID" in res[0]) > self.assertTrue("whenCreated" in res[0]) > self.assertEqual(str(res[0]["objectCategory"]), ("CN=Computer,%s" % ldb.get_schema_basedn())) >- self.assertEqual(int(res[0]["primaryGroupID"][0]), 513) >- self.assertEqual(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT) >- self.assertEqual(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) >+ self.assertEqual(int(res[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS) >+ self.assertEqual(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST) >+ self.assertEqual(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) > self.assertEqual(str(res[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper()) > self.assertEqual(len(res[0]["memberOf"]), 1) > >diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py >index fcea4a89e70..8e5d3e15576 100755 >--- a/source4/dsdb/tests/python/sam.py >+++ b/source4/dsdb/tests/python/sam.py >@@ -291,7 +291,9 @@ class SamTests(samba.tests.TestCase): > > ldb.add({ > "dn": "cn=ldaptestuser,cn=users," + self.base_dn, >- "objectclass": "computer"}) >+ "objectclass": "computer", >+ "userAccountControl": str(UF_NORMAL_ACCOUNT | >+ UF_PASSWD_NOTREQD)}) > > res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, > scope=SCOPE_BASE, attrs=["primaryGroupID"]) >-- >2.25.1 > > >From 5ca54cc9e41b95b633d4c839488ed35efaf649f0 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 22 Oct 2021 22:40:06 +1300 >Subject: [PATCH 476/686] CVE-2020-25722 selftest: Allow > self.assertRaisesLdbError() to take a list of errors to match with > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > python/samba/tests/__init__.py | 30 ++++++++++++------- > selftest/knownfail.d/uac_objectclass_restrict | 2 -- > .../dsdb/tests/python/user_account_control.py | 5 ++++ > 3 files changed, 25 insertions(+), 12 deletions(-) > >diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py >index 1bcc3f4f04f..579b21f7f17 100644 >--- a/python/samba/tests/__init__.py >+++ b/python/samba/tests/__init__.py >@@ -21,6 +21,7 @@ from __future__ import print_function > import os > import tempfile > import warnings >+import collections > import ldb > import samba > from samba import param >@@ -302,23 +303,32 @@ class TestCase(unittest.TestCase): > f(*args, **kwargs) > except ldb.LdbError as e: > (num, msg) = e.args >- if num != errcode: >+ if isinstance(errcode, collections.abc.Container): >+ found = num in errcode >+ else: >+ found = num == errcode >+ if not found: > lut = {v: k for k, v in vars(ldb).items() > if k.startswith('ERR_') and isinstance(v, int)} >- self.fail("%s, expected " >- "LdbError %s, (%d) " >- "got %s (%d) " >- "%s" % (message, >- lut.get(errcode), errcode, >- lut.get(num), num, >- msg)) >+ if isinstance(errcode, collections.abc.Container): >+ errcode_name = ' '.join(lut.get(x) for x in errcode) >+ else: >+ errcode_name = lut.get(errcode) >+ self.fail(f"{message}, expected " >+ f"LdbError {errcode_name}, {errcode} " >+ f"got {lut.get(num)} ({num}) " >+ f"{msg}") > else: > lut = {v: k for k, v in vars(ldb).items() > if k.startswith('ERR_') and isinstance(v, int)} >+ if isinstance(errcode, collections.abc.Container): >+ errcode_name = ' '.join(lut.get(x) for x in errcode) >+ else: >+ errcode_name = lut.get(errcode) > self.fail("%s, expected " >- "LdbError %s, (%d) " >+ "LdbError %s, (%s) " > "but we got success" % (message, >- lut.get(errcode), >+ errcode_name, > errcode)) > > >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index aed4590cb4f..22ce57a63cd 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -20,8 +20,6 @@ > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_user_replace\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_SERVER_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SERVER_TRUST_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_set_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_deladd_priv\(ad_dc_ntvfs\) >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index 7a7cfd40b72..ed68a683e69 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -594,6 +594,9 @@ class UserAccountControlTests(samba.tests.TestCase): > if (bit in priv_bits): > self.fail("Unexpectedly able to set userAccountControl bit 0x%08X (%s), on %s" > % (bit, bit_str, m.dn)) >+ if (bit in account_types and bit != UF_NORMAL_ACCOUNT): >+ self.fail("Unexpectedly able to set userAccountControl bit 0x%08X (%s), on %s" >+ % (bit, bit_str, m.dn)) > except LdbError as e: > (enum, estr) = e.args > if bit in invalid_bits: >@@ -601,6 +604,8 @@ class UserAccountControlTests(samba.tests.TestCase): > ldb.ERR_OTHER, > "was not able to set 0x%08X (%s) on %s" > % (bit, bit_str, m.dn)) >+ elif (bit in account_types): >+ self.assertIn(enum, [ldb.ERR_OBJECT_CLASS_VIOLATION, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS]) > elif (bit in priv_bits): > self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum) > else: >-- >2.25.1 > > >From 03bbe148edd1dc09f5deb87736cbd3bfb4e993cb Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 22 Oct 2021 22:54:52 +1300 >Subject: [PATCH 477/686] CVE-2020-25722 selftest/user_account_control: Allow a > broader set of possible errors > >This favors a test that confirms we got an error over getting exactly >the right error, at least for now. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/uac_objectclass_restrict | 4 ---- > selftest/knownfail.d/user_account_control | 1 - > source4/dsdb/tests/python/user_account_control.py | 12 ++++++++---- > 3 files changed, 8 insertions(+), 9 deletions(-) > delete mode 100644 selftest/knownfail.d/user_account_control > >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index 22ce57a63cd..366b6049b31 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -22,10 +22,6 @@ > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_deladd_priv\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_deladd_wp\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_replace_priv\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_replace_wp\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_INTERDOMAIN_TRUST_ACCOUNT\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_NORMAL_ACCOUNT_UF_PASSWD_NOTREQD\(ad_dc_ntvfs\) >diff --git a/selftest/knownfail.d/user_account_control b/selftest/knownfail.d/user_account_control >deleted file mode 100644 >index 82df3d16156..00000000000 >--- a/selftest/knownfail.d/user_account_control >+++ /dev/null >@@ -1 +0,0 @@ >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_add_computer_cc_normal_bare.ad_dc_ntvfs >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index ed68a683e69..f99f370679b 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -484,7 +484,8 @@ class UserAccountControlTests(samba.tests.TestCase): > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_NORMAL_ACCOUNT), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- self.assertRaisesLdbError(ldb.ERR_UNWILLING_TO_PERFORM, >+ self.assertRaisesLdbError([ldb.ERR_OBJECT_CLASS_VIOLATION, >+ ldb.ERR_UNWILLING_TO_PERFORM], > f"Unexpectedly able to set userAccountControl to be an Normal " > "account without |UF_PASSWD_NOTREQD Unexpectedly able to " > "set userAccountControl to be a workstation on {m.dn}", >@@ -1204,12 +1205,14 @@ class UserAccountControlTests(samba.tests.TestCase): > samdb.modify(m) > elif (account_type == UF_NORMAL_ACCOUNT) and \ > (account_type2 == UF_SERVER_TRUST_ACCOUNT) and not priv: >- self.assertRaisesLdbError(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ self.assertRaisesLdbError([ldb.ERR_OBJECT_CLASS_VIOLATION, >+ ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS], > f"Should have been unable to change {account_type_str} to {account_type2_str}", > samdb.modify, m) > elif (account_type == UF_NORMAL_ACCOUNT) and \ > (account_type2 == UF_SERVER_TRUST_ACCOUNT) and priv: >- self.assertRaisesLdbError(ldb.ERR_UNWILLING_TO_PERFORM, >+ self.assertRaisesLdbError([ldb.ERR_OBJECT_CLASS_VIOLATION, >+ ldb.ERR_UNWILLING_TO_PERFORM], > f"Should have been unable to change {account_type_str} to {account_type2_str}", > samdb.modify, m) > elif (account_type == UF_WORKSTATION_TRUST_ACCOUNT) and \ >@@ -1282,7 +1285,8 @@ class UserAccountControlTests(samba.tests.TestCase): > m["1objectclass"] = ldb.MessageElement(new_objectclass, > ldb.FLAG_MOD_ADD, "objectclass") > >- self.assertRaisesLdbError(ldb.ERR_UNWILLING_TO_PERFORM, >+ self.assertRaisesLdbError([ldb.ERR_OBJECT_CLASS_VIOLATION, >+ ldb.ERR_UNWILLING_TO_PERFORM], > "Should have been unable Able to change objectclass of a {objectclass}", > self.admin_samdb.modify, m) > >-- >2.25.1 > > >From 7d779eba8462f9f32cc960fcba6885948ade8eca Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 22 Oct 2021 23:41:23 +1300 >Subject: [PATCH 478/686] CVE-2020-25722 selftest/user_account_control: more > work to cope with UAC/objectclass defaults and lock > >This new restriction breaks a large number of assumptions in the tests, like >that you can remove some UF_ flags, because it turns out doing so will >make the 'computer' a 'user' again, and this will fail. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/uac_objectclass_restrict | 6 --- > .../dsdb/tests/python/user_account_control.py | 46 ++++++++++++------- > 2 files changed, 29 insertions(+), 23 deletions(-) > >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index 366b6049b31..51387ae0786 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -14,14 +14,8 @@ > ^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-user_mod-del-add_CC_default_computer\(ad_dc_default\) > ^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-user_mod-replace_CC_default_computer\(ad_dc_default\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_add_computer_sd_cc\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_admin_mod_uac\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_computer_cc\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_computer_replace\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_user_replace\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_SERVER_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_INTERDOMAIN_TRUST_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_NORMAL_ACCOUNT\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_uac_bits_add_UF_NORMAL_ACCOUNT_UF_PASSWD_NOTREQD\(ad_dc_ntvfs\) >diff --git a/source4/dsdb/tests/python/user_account_control.py b/source4/dsdb/tests/python/user_account_control.py >index f99f370679b..6a0ef73b29a 100755 >--- a/source4/dsdb/tests/python/user_account_control.py >+++ b/source4/dsdb/tests/python/user_account_control.py >@@ -433,11 +433,10 @@ class UserAccountControlTests(samba.tests.TestCase): > m.dn = res[0].dn > m["userAccountControl"] = ldb.MessageElement(str(samba.dsdb.UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD), > ldb.FLAG_MOD_REPLACE, "userAccountControl") >- try: >- self.samdb.modify(m) >- except LdbError as e: >- (enum, estr) = e.args >- self.fail(f"got {estr} setting userAccountControl to UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD") >+ >+ self.assertRaisesLdbError(ldb.ERR_OBJECT_CLASS_VIOLATION, >+ f"Unexpectedly able to set userAccountControl as to UF_NORMAL_ACCOUNT|UF_PASSWD_NOTREQD on {m.dn}", >+ self.samdb.modify, m) > > m = ldb.Message() > m.dn = res[0].dn >@@ -501,7 +500,7 @@ class UserAccountControlTests(samba.tests.TestCase): > scope=SCOPE_SUBTREE, > attrs=["userAccountControl"]) > >- self.assertEqual(int(res[0]["userAccountControl"][0]), (UF_NORMAL_ACCOUNT | >+ self.assertEqual(int(res[0]["userAccountControl"][0]), (UF_WORKSTATION_TRUST_ACCOUNT | > UF_ACCOUNTDISABLE | > UF_PASSWD_NOTREQD)) > >@@ -681,11 +680,9 @@ class UserAccountControlTests(samba.tests.TestCase): > scope=SCOPE_SUBTREE, > attrs=["userAccountControl"]) > >- if account_type == UF_WORKSTATION_TRUST_ACCOUNT: >- self.assertEqual(orig_uac, account_type) >- else: >- self.assertEqual(orig_uac & UF_NORMAL_ACCOUNT, >- account_type) >+ self.assertEqual(len(res), 1) >+ reset_uac = int(res[0]["userAccountControl"][0]) >+ self.assertEqual(orig_uac, reset_uac) > > m = ldb.Message() > m.dn = res[0].dn >@@ -704,14 +701,16 @@ class UserAccountControlTests(samba.tests.TestCase): > # No point going on, try the next bit > continue > elif bit in super_priv_bits: >- self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ self.assertIn(enum, (ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, >+ ldb.ERR_OBJECT_CLASS_VIOLATION)) > # No point going on, try the next bit > continue > > elif (account_type == UF_NORMAL_ACCOUNT) \ > and (bit in account_types) \ > and (bit != account_type): >- self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM) >+ self.assertIn(enum, (ldb.ERR_UNWILLING_TO_PERFORM, >+ ldb.ERR_OBJECT_CLASS_VIOLATION)) > continue > > elif (account_type == UF_WORKSTATION_TRUST_ACCOUNT) \ >@@ -789,7 +788,10 @@ class UserAccountControlTests(samba.tests.TestCase): > > except LdbError as e3: > (enum, estr) = e3.args >- if bit in priv_to_remove_bits: >+ if account_type == UF_WORKSTATION_TRUST_ACCOUNT: >+ # Because removing any bit would change the account back to a user, which is locked by objectclass >+ self.assertIn(enum, (ldb.ERR_OBJECT_CLASS_VIOLATION, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS)) >+ elif bit in priv_to_remove_bits: > self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) > else: > self.fail("Unexpectedly unable to remove userAccountControl bit 0x%08X on %s: %s" % (bit, m.dn, estr)) >@@ -808,7 +810,7 @@ class UserAccountControlTests(samba.tests.TestCase): > self.assertEqual(int(res[0]["userAccountControl"][0]), > bit | UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD, > "bit 0X%08x should not have been removed" % bit) >- else: >+ elif account_type != UF_WORKSTATION_TRUST_ACCOUNT: > self.assertEqual(int(res[0]["userAccountControl"][0]), > UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD, > "bit 0X%08x should have been removed" % bit) >@@ -859,9 +861,19 @@ class UserAccountControlTests(samba.tests.TestCase): > bit_str, > computername)) > elif bit in priv_bits: >- self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ if bit == UF_INTERDOMAIN_TRUST_ACCOUNT: >+ self.assertIn(enum, (ldb.ERR_OBJECT_CLASS_VIOLATION, >+ ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS)) >+ else: >+ self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) > elif bit in unwilling_bits: >- self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM) >+ # This can fail early as user in a computer is not permitted as non-admin >+ self.assertIn(enum, (ldb.ERR_UNWILLING_TO_PERFORM, >+ ldb.ERR_OBJECT_CLASS_VIOLATION)) >+ elif bit & UF_NORMAL_ACCOUNT: >+ # This can fail early as user in a computer is not permitted as non-admin >+ self.assertIn(enum, (ldb.ERR_UNWILLING_TO_PERFORM, >+ ldb.ERR_OBJECT_CLASS_VIOLATION)) > else: > self.fail("Unable to set userAccountControl bit 0x%08X (%s) on %s: %s" > % (bit, >-- >2.25.1 > > >From b8657d189ea66a84274fa099266f1a3d3a64305e Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 27 Sep 2021 11:20:19 +1300 >Subject: [PATCH 479/686] CVE-2020-25721 krb5pac: Add new buffers for > samAccountName and objectSID > >These appear when PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID is set. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14835 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > librpc/idl/krb5pac.idl | 18 ++++++++++++++++-- > librpc/ndr/ndr_krb5pac.c | 4 ++-- > 2 files changed, 18 insertions(+), 4 deletions(-) > >diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl >index 141894ec5f1..475890bac76 100644 >--- a/librpc/idl/krb5pac.idl >+++ b/librpc/idl/krb5pac.idl >@@ -86,15 +86,29 @@ interface krb5pac > } PAC_CONSTRAINED_DELEGATION; > > typedef [bitmap32bit] bitmap { >- PAC_UPN_DNS_FLAG_CONSTRUCTED = 0x00000001 >+ PAC_UPN_DNS_FLAG_CONSTRUCTED = 0x00000001, >+ PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID = 0x00000002 > } PAC_UPN_DNS_FLAGS; > >+ typedef struct { >+ [value(2*strlen_m(samaccountname))] uint16 samaccountname_size; >+ [relative_short,subcontext(0),subcontext_size(samaccountname_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *samaccountname; >+ [value(ndr_size_dom_sid(objectsid, ndr->flags))] uint16 objectsid_size; >+ [relative_short,subcontext(0),subcontext_size(objectsid_size)] dom_sid *objectsid; >+ } PAC_UPN_DNS_INFO_SAM_NAME_AND_SID; >+ >+ typedef [nodiscriminant] union { >+ [case(PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID)] PAC_UPN_DNS_INFO_SAM_NAME_AND_SID sam_name_and_sid; >+ [default]; >+ } PAC_UPN_DNS_INFO_EX; >+ > typedef struct { > [value(2*strlen_m(upn_name))] uint16 upn_name_size; > [relative_short,subcontext(0),subcontext_size(upn_name_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *upn_name; > [value(2*strlen_m(dns_domain_name))] uint16 dns_domain_name_size; > [relative_short,subcontext(0),subcontext_size(dns_domain_name_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *dns_domain_name; > PAC_UPN_DNS_FLAGS flags; >+ [switch_is(flags & PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID)] PAC_UPN_DNS_INFO_EX ex; > } PAC_UPN_DNS_INFO; > > typedef [public] struct { >@@ -142,7 +156,7 @@ interface krb5pac > > typedef [public,nopush,nopull] struct { > PAC_TYPE type; >- [value(_ndr_size_PAC_INFO(info, type, 0))] uint32 _ndr_size; >+ [value(_ndr_size_PAC_INFO(info, type, LIBNDR_FLAG_ALIGN8))] uint32 _ndr_size; > /* > * We need to have two subcontexts to get the padding right, > * the outer subcontext uses NDR_ROUND(_ndr_size, 8), while >diff --git a/librpc/ndr/ndr_krb5pac.c b/librpc/ndr/ndr_krb5pac.c >index a9ae2c4a789..57b28df9e52 100644 >--- a/librpc/ndr/ndr_krb5pac.c >+++ b/librpc/ndr/ndr_krb5pac.c >@@ -41,7 +41,7 @@ enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const > if (ndr_flags & NDR_SCALARS) { > NDR_CHECK(ndr_push_align(ndr, 4)); > NDR_CHECK(ndr_push_PAC_TYPE(ndr, NDR_SCALARS, r->type)); >- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,0))); >+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,LIBNDR_FLAG_ALIGN8))); > { > uint32_t _flags_save_PAC_INFO = ndr->flags; > ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); >@@ -59,7 +59,7 @@ enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const > { > struct ndr_push *_ndr_info_pad; > struct ndr_push *_ndr_info; >- size_t _ndr_size = _ndr_size_PAC_INFO(r->info, r->type, 0); >+ size_t _ndr_size = _ndr_size_PAC_INFO(r->info, r->type, LIBNDR_FLAG_ALIGN8); > NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info_pad, 0, NDR_ROUND(_ndr_size, 8))); > NDR_CHECK(ndr_push_subcontext_start(_ndr_info_pad, &_ndr_info, 0, _ndr_size)); > NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->info, r->type)); >-- >2.25.1 > > >From aa1b4cc6afdd390a986abed8fe3f688605fdeeee Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 15:48:35 +1300 >Subject: [PATCH 480/686] CVE-2020-25718 tests/krb5: Allow tests accounts to > replicate to RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/rodc_tests.py | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/python/samba/tests/krb5/rodc_tests.py b/python/samba/tests/krb5/rodc_tests.py >index 302ae865cf1..0e252d90262 100755 >--- a/python/samba/tests/krb5/rodc_tests.py >+++ b/python/samba/tests/krb5/rodc_tests.py >@@ -41,11 +41,13 @@ class RodcKerberosTests(KDCBaseTest): > user_creds = self.get_cached_creds( > account_type=self.AccountType.USER, > opts={ >+ 'allowed_replication': True, > 'revealed_to_rodc': True > }) > target_creds = self.get_cached_creds( > account_type=self.AccountType.COMPUTER, > opts={ >+ 'allowed_replication': True, > 'revealed_to_rodc': True > }) > >-- >2.25.1 > > >From 0266a46d5807ffbc901fca751652010a660a0412 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 18 Oct 2021 14:59:01 +1300 >Subject: [PATCH 481/686] CVE-2020-25719 CVE-2020-25717 tests/krb5: Modify > get_service_ticket() to use _generic_kdc_exchange() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14799 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 54 ++++++++++++------------ > 1 file changed, 27 insertions(+), 27 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 8ae9c24b0fc..c129883e7cd 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1275,7 +1275,7 @@ class KDCBaseTest(RawKerberosTest): > expected_flags=None, unexpected_flags=None, > fresh=False): > user_name = tgt.cname['name-string'][0] >- target_name = target_creds.get_username() >+ target_name = target_creds.get_username()[:-1] > cache_key = (user_name, target_name, service, to_rodc, kdc_options) > > if not fresh: >@@ -1288,40 +1288,40 @@ class KDCBaseTest(RawKerberosTest): > > if kdc_options is None: > kdc_options = '0' >- kdc_options = krb5_asn1.KDCOptions(kdc_options) >- >- key = tgt.session_key >- ticket = tgt.ticket >+ kdc_options = str(krb5_asn1.KDCOptions(kdc_options)) > >- cname = tgt.cname >- realm = tgt.crealm >- >- target_name = target_creds.get_username()[:-1] > sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, > names=[service, target_name]) >+ srealm = target_creds.get_realm() > >- rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype, >- to_rodc=to_rodc, >- service_creds=target_creds, >- kdc_options=kdc_options, >- expected_flags=expected_flags, >- unexpected_flags=unexpected_flags) >+ authenticator_subkey = self.RandomKey(kcrypto.Enctype.AES256) > >- service_ticket = rep['ticket'] >+ decryption_key = self.TicketDecryptionKey_from_creds(target_creds) > >- ticket_etype = service_ticket['enc-part']['etype'] >- target_key = self.TicketDecryptionKey_from_creds(target_creds, >- etype=ticket_etype) >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=tgt.crealm, >+ expected_cname=tgt.cname, >+ expected_srealm=srealm, >+ expected_sname=sname, >+ expected_supported_etypes=target_creds.tgs_supported_enctypes, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, >+ ticket_decryption_key=decryption_key, >+ check_rep_fn=self.generic_check_kdc_rep, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ tgt=tgt, >+ authenticator_subkey=authenticator_subkey, >+ kdc_options=kdc_options, >+ to_rodc=to_rodc) > >- session_key = self.EncryptionKey_import(enc_part['key']) >+ rep = self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=None, >+ realm=srealm, >+ sname=sname, >+ etypes=etype) >+ self.check_tgs_reply(rep) > >- service_ticket_creds = KerberosTicketCreds(service_ticket, >- session_key, >- crealm=realm, >- cname=cname, >- srealm=realm, >- sname=sname, >- decryption_key=target_key) >+ service_ticket_creds = kdc_exchange_dict['rep_ticket_creds'] > > if to_rodc: > krbtgt_creds = self.get_rodc_krbtgt_creds() >-- >2.25.1 > > >From 23933fdb65453d894cb242bfc83f2dc016195679 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 18 Oct 2021 15:00:38 +1300 >Subject: [PATCH 482/686] CVE-2020-25719 CVE-2020-25717 tests/krb5: Add > pac_request parameter to get_service_ticket() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14799 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index c129883e7cd..813af767dbd 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1273,10 +1273,11 @@ class KDCBaseTest(RawKerberosTest): > def get_service_ticket(self, tgt, target_creds, service='host', > to_rodc=False, kdc_options=None, > expected_flags=None, unexpected_flags=None, >- fresh=False): >+ pac_request=True, expect_pac=True, fresh=False): > user_name = tgt.cname['name-string'][0] > target_name = target_creds.get_username()[:-1] >- cache_key = (user_name, target_name, service, to_rodc, kdc_options) >+ cache_key = (user_name, target_name, service, to_rodc, kdc_options, >+ pac_request) > > if not fresh: > ticket = self.tkt_cache.get(cache_key) >@@ -1312,6 +1313,8 @@ class KDCBaseTest(RawKerberosTest): > tgt=tgt, > authenticator_subkey=authenticator_subkey, > kdc_options=kdc_options, >+ pac_request=pac_request, >+ expect_pac=expect_pac, > to_rodc=to_rodc) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >@@ -1329,6 +1332,7 @@ class KDCBaseTest(RawKerberosTest): > krbtgt_creds = self.get_krbtgt_creds() > krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) > self.verify_ticket(service_ticket_creds, krbtgt_key, >+ expect_pac=expect_pac, > expect_ticket_checksum=self.tkt_sig_support) > > self.tkt_cache[cache_key] = service_ticket_creds >-- >2.25.1 > > >From 3b5183f7d61323429d572d404aa8b569ce6fedea Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:40:09 +1300 >Subject: [PATCH 483/686] CVE-2020-25722 tests/krb5: Allow creating server > accounts > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14776 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 7 +++++++ > 1 file changed, 7 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 813af767dbd..a0da89041c4 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -38,12 +38,14 @@ from samba.dsdb import ( > DS_DOMAIN_FUNCTION_2000, > DS_DOMAIN_FUNCTION_2008, > DS_GUID_COMPUTERS_CONTAINER, >+ DS_GUID_DOMAIN_CONTROLLERS_CONTAINER, > DS_GUID_USERS_CONTAINER, > UF_WORKSTATION_TRUST_ACCOUNT, > UF_NO_AUTH_DATA_REQUIRED, > UF_NORMAL_ACCOUNT, > UF_NOT_DELEGATED, > UF_PARTIAL_SECRETS_ACCOUNT, >+ UF_SERVER_TRUST_ACCOUNT, > UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION > ) > from samba.join import DCJoinContext >@@ -94,6 +96,7 @@ class KDCBaseTest(RawKerberosTest): > class AccountType(Enum): > USER = auto() > COMPUTER = auto() >+ SERVER = auto() > > @classmethod > def setUpClass(cls): >@@ -245,6 +248,8 @@ class KDCBaseTest(RawKerberosTest): > if ou is None: > if account_type is account_type.COMPUTER: > guid = DS_GUID_COMPUTERS_CONTAINER >+ elif account_type is account_type.SERVER: >+ guid = DS_GUID_DOMAIN_CONTROLLERS_CONTAINER > else: > guid = DS_GUID_USERS_CONTAINER > >@@ -265,6 +270,8 @@ class KDCBaseTest(RawKerberosTest): > account_name += '$' > if account_type is self.AccountType.COMPUTER: > account_control |= UF_WORKSTATION_TRUST_ACCOUNT >+ elif account_type is self.AccountType.SERVER: >+ account_control |= UF_SERVER_TRUST_ACCOUNT > else: > self.fail() > >-- >2.25.1 > > >From 5d5c20124d981cf1f5b7ee33546ec766f57c026c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 30 Sep 2021 16:53:22 +1300 >Subject: [PATCH 484/686] CVE-2020-25719 tests/krb5: Add is_tgt() helper method > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14686 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/raw_testcase.py | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index fdf078ea788..055209fd09d 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3086,8 +3086,7 @@ class RawKerberosTest(TestCaseInTempDir): > def verify_ticket(self, ticket, krbtgt_key, expect_pac=True, > expect_ticket_checksum=True): > # Check if the ticket is a TGT. >- sname = ticket.ticket['sname'] >- is_tgt = self.is_tgs(sname) >+ is_tgt = self.is_tgt(ticket) > > # Decrypt the ticket. > >@@ -3506,6 +3505,10 @@ class RawKerberosTest(TestCaseInTempDir): > name = principal['name-string'][0] > return name in ('krbtgt', b'krbtgt') > >+ def is_tgt(self, ticket): >+ sname = ticket.ticket['sname'] >+ return self.is_tgs(sname) >+ > def get_empty_pac(self): > return self.AuthorizationData_create(AD_WIN2K_PAC, bytes(1)) > >-- >2.25.1 > > >From ddcb3d259a88babc66b3dc87f53de585d087e7ff Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 19 Oct 2021 15:02:10 +1300 >Subject: [PATCH 485/686] CVE-2020-25719 tests/krb5: Add method to get unique > username for test accounts > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14686 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index a0da89041c4..e85574c51cb 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -711,8 +711,7 @@ class KDCBaseTest(RawKerberosTest): > > rodc_dn = self.get_server_dn(rodc_samdb) > >- user_name = self.account_base + str(self.account_id) >- type(self).account_id += 1 >+ user_name = self.get_new_username() > if name_prefix is not None: > user_name = name_prefix + user_name > if name_suffix is not None: >@@ -821,6 +820,12 @@ class KDCBaseTest(RawKerberosTest): > > return creds > >+ def get_new_username(self): >+ user_name = self.account_base + str(self.account_id) >+ type(self).account_id += 1 >+ >+ return user_name >+ > def get_client_creds(self, > allow_missing_password=False, > allow_missing_keys=True): >-- >2.25.1 > > >From 4175f6889379e931764b54f04afadd7abb24df3a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 15:48:20 +1300 >Subject: [PATCH 486/686] MS CVE-2020-17049 tests/krb5: Allow tests to pass if > ticket signature checksum type is wrong > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/raw_testcase.py | 21 +++++++++++++++++++-- > 1 file changed, 19 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 055209fd09d..62e1b9867dd 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2375,6 +2375,13 @@ class RawKerberosTest(TestCaseInTempDir): > krbtgt_creds = self.get_krbtgt_creds() > krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) > >+ krbtgt_keys = [krbtgt_key] >+ if not self.strict_checking: >+ krbtgt_key_rc4 = self.TicketDecryptionKey_from_creds( >+ krbtgt_creds, >+ etype=kcrypto.Enctype.RC4) >+ krbtgt_keys.append(krbtgt_key_rc4) >+ > expect_pac = kdc_exchange_dict['expect_pac'] > > ticket_session_key = None >@@ -2522,7 +2529,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(ticket_decryption_key) > > if ticket_decryption_key is not None: >- self.verify_ticket(ticket_creds, krbtgt_key, expect_pac=expect_pac, >+ self.verify_ticket(ticket_creds, krbtgt_keys, expect_pac=expect_pac, > expect_ticket_checksum=expect_ticket_checksum > or self.tkt_sig_support) > >@@ -3083,7 +3090,7 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_blob) > self.assertEqual(expected_checksum, checksum) > >- def verify_ticket(self, ticket, krbtgt_key, expect_pac=True, >+ def verify_ticket(self, ticket, krbtgt_keys, expect_pac=True, > expect_ticket_checksum=True): > # Check if the ticket is a TGT. > is_tgt = self.is_tgt(ticket) >@@ -3171,6 +3178,16 @@ class RawKerberosTest(TestCaseInTempDir): > > kdc_checksum, kdc_ctype = checksums[ > krb5pac.PAC_TYPE_KDC_CHECKSUM] >+ >+ if isinstance(krbtgt_keys, collections.abc.Container): >+ if self.strict_checking: >+ krbtgt_key = krbtgt_keys[0] >+ else: >+ krbtgt_key = next(key for key in krbtgt_keys >+ if key.ctype == kdc_ctype) >+ else: >+ krbtgt_key = krbtgt_keys >+ > krbtgt_key.verify_rodc_checksum(KU_NON_KERB_CKSUM_SALT, > server_checksum, > kdc_ctype, >-- >2.25.1 > > >From ae8141184ecbdc4335b1fffe9fa2cf8afa1cf752 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 21 Oct 2021 16:46:23 +1300 >Subject: [PATCH 487/686] CVE-2020-25721 tests/krb5: Check PAC buffer types > when STRICT_CHECKING=0 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14835 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/raw_testcase.py | 23 ++++++++++++++--------- > 1 file changed, 14 insertions(+), 9 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 62e1b9867dd..8e55790272a 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1102,13 +1102,14 @@ class RawKerberosTest(TestCaseInTempDir): > f"unexpected in {v}") > > def assertSequenceElementsEqual(self, expected, got, *, >- require_strict=None): >- if self.strict_checking: >+ require_strict=None, >+ require_ordered=True): >+ if self.strict_checking and require_ordered: > self.assertEqual(expected, got) > else: > fail_msg = f'expected: {expected} got: {got}' > >- if require_strict is not None: >+ if not self.strict_checking and require_strict is not None: > fail_msg += f' (ignoring: {require_strict})' > expected = (x for x in expected if x not in require_strict) > got = (x for x in got if x not in require_strict) >@@ -2569,12 +2570,16 @@ class RawKerberosTest(TestCaseInTempDir): > if not self.is_tgs(expected_sname): > expected_types.append(krb5pac.PAC_TYPE_TICKET_CHECKSUM) > >- if self.strict_checking: >- buffer_types = [pac_buffer.type >- for pac_buffer in pac.buffers] >- self.assertCountEqual(expected_types, buffer_types, >- f'expected: {expected_types} ' >- f'got: {buffer_types}') >+ require_strict = {krb5pac.PAC_TYPE_CLIENT_CLAIMS_INFO} >+ if not self.tkt_sig_support: >+ require_strict.add(krb5pac.PAC_TYPE_TICKET_CHECKSUM) >+ >+ buffer_types = [pac_buffer.type >+ for pac_buffer in pac.buffers] >+ self.assertSequenceElementsEqual( >+ expected_types, buffer_types, >+ require_ordered=False, >+ require_strict=require_strict) > > expected_account_name = kdc_exchange_dict['expected_account_name'] > expected_sid = kdc_exchange_dict['expected_sid'] >-- >2.25.1 > > >From 3c5f73e34cee5b791368e79cd877c7ae096577c5 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 22 Oct 2021 11:37:31 +1300 >Subject: [PATCH 488/686] CVE-2020-25719 CVE-2020-25717 tests/krb5: Refactor > create_ccache_with_user() to take credentials of target service > >This allows us to use get_tgt() and get_service_ticket() to obtain >tickets, which simplifies the logic. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14799 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 43 ++++++------------------ > python/samba/tests/krb5/test_ccache.py | 2 +- > python/samba/tests/krb5/test_ldap.py | 7 ++-- > python/samba/tests/krb5/test_rpc.py | 7 ++-- > python/samba/tests/krb5/test_smb.py | 7 ++-- > 5 files changed, 27 insertions(+), 39 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index e85574c51cb..e77a940f411 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1283,11 +1283,13 @@ class KDCBaseTest(RawKerberosTest): > return rep, enc_part > > def get_service_ticket(self, tgt, target_creds, service='host', >+ target_name=None, > to_rodc=False, kdc_options=None, > expected_flags=None, unexpected_flags=None, > pac_request=True, expect_pac=True, fresh=False): > user_name = tgt.cname['name-string'][0] >- target_name = target_creds.get_username()[:-1] >+ if target_name is None: >+ target_name = target_creds.get_username()[:-1] > cache_key = (user_name, target_name, service, to_rodc, kdc_options, > pac_request) > >@@ -1669,51 +1671,28 @@ class KDCBaseTest(RawKerberosTest): > > return cachefile > >- def create_ccache_with_user(self, user_credentials, mach_name, >- service="host"): >+ def create_ccache_with_user(self, user_credentials, mach_credentials, >+ service="host", target_name=None): > # Obtain a service ticket authorising the user and place it into a > # newly created credentials cache file. > > user_name = user_credentials.get_username() > realm = user_credentials.get_realm() > >- # Do the initial AS-REQ, should get a pre-authentication required >- # response >- etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) > cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, > names=[user_name]) >- sname = self.PrincipalName_create(name_type=NT_SRV_HST, >- names=["krbtgt", realm]) >- >- rep = self.as_req(cname, sname, realm, etype) >- self.check_pre_authentication(rep) > >- # Do the next AS-REQ >- padata = self.get_enc_timestamp_pa_data(user_credentials, rep) >- key = self.get_as_rep_key(user_credentials, rep) >- rep = self.as_req(cname, sname, realm, etype, padata=[padata]) >- self.check_as_reply(rep) >+ tgt = self.get_tgt(user_credentials) > > # Request a ticket to the host service on the machine account >- ticket = rep['ticket'] >- enc_part = self.get_as_rep_enc_data(key, rep) >- key = self.EncryptionKey_import(enc_part['key']) >- cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >- names=[user_name]) >- sname = self.PrincipalName_create(name_type=NT_SRV_HST, >- names=[service, mach_name]) >- >- (rep, enc_part) = self.tgs_req( >- cname, sname, realm, ticket, key, etype) >- self.check_tgs_reply(rep) >- key = self.EncryptionKey_import(enc_part['key']) >- >- # Check the contents of the pac, and the ticket >- ticket = rep['ticket'] >+ ticket = self.get_service_ticket(tgt, mach_credentials, >+ service=service, >+ target_name=target_name) > > # Write the ticket into a credentials cache file that can be ingested > # by the main credentials code. >- cachefile = self.create_ccache(cname, ticket, enc_part) >+ cachefile = self.create_ccache(cname, ticket.ticket, >+ ticket.encpart_private) > > # Create a credentials object to reference the credentials cache. > creds = Credentials() >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >index 6a2b78398ac..040ae5cc9a1 100755 >--- a/python/samba/tests/krb5/test_ccache.py >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -67,7 +67,7 @@ class CcacheTests(KDCBaseTest): > # ticket, to ensure that the krbtgt ticket doesn't also need to be > # stored. > (creds, cachefile) = self.create_ccache_with_user(user_credentials, >- mach_name) >+ mach_credentials) > > # Authenticate in-process to the machine account using the user's > # cached credentials. >diff --git a/python/samba/tests/krb5/test_ldap.py b/python/samba/tests/krb5/test_ldap.py >index 95b2d24221a..7d9ffebe298 100755 >--- a/python/samba/tests/krb5/test_ldap.py >+++ b/python/samba/tests/krb5/test_ldap.py >@@ -53,13 +53,16 @@ class LdapTests(KDCBaseTest): > # Create the user account. > (user_credentials, _) = self.create_account(samdb, user_name) > >+ mach_credentials = self.get_dc_creds() >+ > # Talk to the KDC to obtain the service ticket, which gets placed into > # the cache. The machine account name has to match the name in the > # ticket, to ensure that the krbtgt ticket doesn't also need to be > # stored. > (creds, cachefile) = self.create_ccache_with_user(user_credentials, >- mach_name, >- service) >+ mach_credentials, >+ service, >+ mach_name) > > # Authenticate in-process to the machine account using the user's > # cached credentials. >diff --git a/python/samba/tests/krb5/test_rpc.py b/python/samba/tests/krb5/test_rpc.py >index 40ac6df7a35..ef8dd4dcbf5 100755 >--- a/python/samba/tests/krb5/test_rpc.py >+++ b/python/samba/tests/krb5/test_rpc.py >@@ -50,13 +50,16 @@ class RpcTests(KDCBaseTest): > # Create the user account. > (user_credentials, _) = self.create_account(samdb, user_name) > >+ mach_credentials = self.get_dc_creds() >+ > # Talk to the KDC to obtain the service ticket, which gets placed into > # the cache. The machine account name has to match the name in the > # ticket, to ensure that the krbtgt ticket doesn't also need to be > # stored. > (creds, cachefile) = self.create_ccache_with_user(user_credentials, >- mach_name, >- service) >+ mach_credentials, >+ service, >+ mach_name) > > # Authenticate in-process to the machine account using the user's > # cached credentials. >diff --git a/python/samba/tests/krb5/test_smb.py b/python/samba/tests/krb5/test_smb.py >index eebc9a9d4fe..1e70ed322bf 100755 >--- a/python/samba/tests/krb5/test_smb.py >+++ b/python/samba/tests/krb5/test_smb.py >@@ -55,13 +55,16 @@ class SmbTests(KDCBaseTest): > # Create the user account. > (user_credentials, _) = self.create_account(samdb, user_name) > >+ mach_credentials = self.get_dc_creds() >+ > # Talk to the KDC to obtain the service ticket, which gets placed into > # the cache. The machine account name has to match the name in the > # ticket, to ensure that the krbtgt ticket doesn't also need to be > # stored. > (creds, cachefile) = self.create_ccache_with_user(user_credentials, >- mach_name, >- service) >+ mach_credentials, >+ service, >+ mach_name) > > # Set the Kerberos 5 credentials cache environment variable. This is > # required because the codepath that gets run (gse_krb5) looks for it >-- >2.25.1 > > >From bfd9b5f7e0559a30d1d276bf2c16f75f103b9081 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 22 Oct 2021 11:37:37 +1300 >Subject: [PATCH 489/686] CVE-2020-25719 CVE-2020-25717 tests/krb5: Allow > create_ccache_with_user() to return a ticket without a PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14799 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index e77a940f411..aed4c427ab0 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1672,7 +1672,7 @@ class KDCBaseTest(RawKerberosTest): > return cachefile > > def create_ccache_with_user(self, user_credentials, mach_credentials, >- service="host", target_name=None): >+ service="host", target_name=None, pac=True): > # Obtain a service ticket authorising the user and place it into a > # newly created credentials cache file. > >@@ -1689,6 +1689,9 @@ class KDCBaseTest(RawKerberosTest): > service=service, > target_name=target_name) > >+ if not pac: >+ ticket = self.modified_ticket(ticket, exclude_pac=True) >+ > # Write the ticket into a credentials cache file that can be ingested > # by the main credentials code. > cachefile = self.create_ccache(cname, ticket.ticket, >-- >2.25.1 > > >From b107c73f7de99ec150672f77c9570d50b9e727e7 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 21 Oct 2021 15:45:00 +1300 >Subject: [PATCH 490/686] CVE-2020-25722 tests/krb5: Add KDC tests for 3-part > SPNs > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14776 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 1 + > python/samba/tests/krb5/spn_tests.py | 212 +++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > selftest/knownfail_heimdal_kdc | 6 + > selftest/knownfail_mit_kdc | 6 + > source4/selftest/tests.py | 10 ++ > 6 files changed, 236 insertions(+) > create mode 100755 python/samba/tests/krb5/spn_tests.py > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index aed4c427ab0..cc23484ba2c 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -97,6 +97,7 @@ class KDCBaseTest(RawKerberosTest): > USER = auto() > COMPUTER = auto() > SERVER = auto() >+ RODC = auto() > > @classmethod > def setUpClass(cls): >diff --git a/python/samba/tests/krb5/spn_tests.py b/python/samba/tests/krb5/spn_tests.py >new file mode 100755 >index 00000000000..62d2ea081bc >--- /dev/null >+++ b/python/samba/tests/krb5/spn_tests.py >@@ -0,0 +1,212 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) 2020 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import os >+import sys >+ >+from samba.tests import DynamicTestCase >+ >+import ldb >+ >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+from samba.tests.krb5.raw_testcase import KerberosCredentials >+from samba.tests.krb5.rfc4120_constants import ( >+ AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5, >+ KDC_ERR_S_PRINCIPAL_UNKNOWN, >+ NT_PRINCIPAL, >+) >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+@DynamicTestCase >+class SpnTests(KDCBaseTest): >+ test_account_types = { >+ 'computer': KDCBaseTest.AccountType.COMPUTER, >+ 'server': KDCBaseTest.AccountType.SERVER, >+ 'rodc': KDCBaseTest.AccountType.RODC >+ } >+ test_spns = { >+ '2_part': 'ldap/{{account}}', >+ '3_part_our_domain': 'ldap/{{account}}/{netbios_domain_name}', >+ '3_part_our_realm': 'ldap/{{account}}/{dns_domain_name}', >+ '3_part_not_our_realm': 'ldap/{{account}}/test', >+ '3_part_instance': 'ldap/{{account}}:test/{dns_domain_name}' >+ } >+ >+ @classmethod >+ def setUpClass(cls): >+ super().setUpClass() >+ >+ cls._mock_rodc_creds = None >+ >+ @classmethod >+ def setUpDynamicTestCases(cls): >+ for account_type_name, account_type in cls.test_account_types.items(): >+ for spn_name, spn in cls.test_spns.items(): >+ tname = f'{spn_name}_spn_{account_type_name}' >+ targs = (account_type, spn) >+ cls.generate_dynamic_test('test_spn', tname, *targs) >+ >+ def _test_spn_with_args(self, account_type, spn): >+ target_creds = self._get_creds(account_type) >+ spn = self._format_spn(spn, target_creds) >+ >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=spn.split('/')) >+ >+ client_creds = self.get_client_creds() >+ tgt = self.get_tgt(client_creds) >+ >+ samdb = self.get_samdb() >+ netbios_domain_name = samdb.domain_netbios_name() >+ dns_domain_name = samdb.domain_dns_name() >+ >+ subkey = self.RandomKey(tgt.session_key.etype) >+ >+ etypes = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5,) >+ >+ if account_type is self.AccountType.SERVER: >+ ticket_etype = AES256_CTS_HMAC_SHA1_96 >+ else: >+ ticket_etype = None >+ decryption_key = self.TicketDecryptionKey_from_creds( >+ target_creds, etype=ticket_etype) >+ >+ if (spn.count('/') > 1 >+ and (spn.endswith(netbios_domain_name) >+ or spn.endswith(dns_domain_name)) >+ and account_type is not self.AccountType.SERVER >+ and account_type is not self.AccountType.RODC): >+ expected_error_mode = KDC_ERR_S_PRINCIPAL_UNKNOWN >+ check_error_fn = self.generic_check_kdc_error >+ check_rep_fn = None >+ else: >+ expected_error_mode = 0 >+ check_error_fn = None >+ check_rep_fn = self.generic_check_kdc_rep >+ >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=tgt.crealm, >+ expected_cname=tgt.cname, >+ expected_srealm=tgt.srealm, >+ expected_sname=sname, >+ ticket_decryption_key=decryption_key, >+ check_rep_fn=check_rep_fn, >+ check_error_fn=check_error_fn, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ expected_error_mode=expected_error_mode, >+ tgt=tgt, >+ authenticator_subkey=subkey, >+ kdc_options='0', >+ expect_edata=False) >+ >+ self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=None, >+ realm=tgt.srealm, >+ sname=sname, >+ etypes=etypes) >+ >+ def setUp(self): >+ super().setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def _format_spns(self, spns, creds=None): >+ return map(lambda spn: self._format_spn(spn, creds), spns) >+ >+ def _format_spn(self, spn, creds=None): >+ samdb = self.get_samdb() >+ >+ spn = spn.format(netbios_domain_name=samdb.domain_netbios_name(), >+ dns_domain_name=samdb.domain_dns_name()) >+ >+ if creds is not None: >+ account_name = creds.get_username() >+ spn = spn.format(account=account_name) >+ >+ return spn >+ >+ def _get_creds(self, account_type): >+ spns = self._format_spns(self.test_spns.values()) >+ >+ if account_type is self.AccountType.RODC: >+ creds = self._mock_rodc_creds >+ if creds is None: >+ creds = self._get_mock_rodc_creds(spns) >+ type(self)._mock_rodc_creds = creds >+ else: >+ creds = self.get_cached_creds( >+ account_type=account_type, >+ opts={ >+ 'spn': spns >+ }) >+ >+ return creds >+ >+ def _get_mock_rodc_creds(self, spns): >+ rodc_ctx = self.get_mock_rodc_ctx() >+ >+ for spn in spns: >+ spn = spn.format(account=rodc_ctx.myname) >+ if spn not in rodc_ctx.SPNs: >+ rodc_ctx.SPNs.append(spn) >+ >+ samdb = self.get_samdb() >+ rodc_dn = ldb.Dn(samdb, rodc_ctx.acct_dn) >+ >+ msg = ldb.Message(rodc_dn) >+ msg['servicePrincipalName'] = ldb.MessageElement( >+ rodc_ctx.SPNs, >+ ldb.FLAG_MOD_REPLACE, >+ 'servicePrincipalName') >+ samdb.modify(msg) >+ >+ creds = KerberosCredentials() >+ creds.guess(self.get_lp()) >+ creds.set_realm(rodc_ctx.realm.upper()) >+ creds.set_domain(rodc_ctx.domain_name) >+ creds.set_password(rodc_ctx.acct_pass) >+ creds.set_username(rodc_ctx.myname) >+ creds.set_workstation(rodc_ctx.samname) >+ creds.set_dn(rodc_dn) >+ creds.set_spn(rodc_ctx.SPNs) >+ >+ res = samdb.search(base=rodc_dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KeyVersionNumber']) >+ kvno = int(res[0].get('msDS-KeyVersionNumber', idx=0)) >+ creds.set_kvno(kvno) >+ >+ keys = self.get_keys(samdb, rodc_dn) >+ self.creds_set_keys(creds, keys) >+ >+ return creds >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = False >+ global_hexdump = False >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 887bc29504c..2bf891dc8b3 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -102,6 +102,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/fast_tests.py', > 'python/samba/tests/krb5/rodc_tests.py', > 'python/samba/tests/krb5/salt_tests.py', >+ 'python/samba/tests/krb5/spn_tests.py', > } > > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index b39b11c3c53..45524d70fa2 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -255,3 +255,9 @@ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_auth_data_required > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_a > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_b >+# >+# SPN tests >+# >+^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_instance_spn_computer >+^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_domain_spn_computer >+^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_realm_spn_computer >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 4fc68ffd854..c86f9c2c2ea 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -374,3 +374,9 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc > ^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc > ^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >+# >+# SPN tests >+# >+^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_instance_spn_computer >+^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_domain_spn_computer >+^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_realm_spn_computer >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 2d3447da2a5..58f7683e008 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1343,6 +1343,16 @@ planpythontestsuite( > 'FAST_SUPPORT': have_fast_support, > 'TKT_SIG_SUPPORT': tkt_sig_support > }) >+planpythontestsuite( >+ "ad_dc", >+ "samba.tests.krb5.spn_tests", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support >+ }) > > for env in [ > 'vampire_dc', >-- >2.25.1 > > >From 1a3025442cc0e852e1c3d141e610cbf98457ca73 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 13 Oct 2021 16:07:09 +1300 >Subject: [PATCH 491/686] CVE-2020-25721 ndrdump: Add tests for PAC with > UPN_DNS_INFO > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14835 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Adapted to fix conflicts] >--- > python/samba/tests/blackbox/ndrdump.py | 35 +++ > .../tests/krb5pac_upn_dns_info_ex.b64.txt | 1 + > .../librpc/tests/krb5pac_upn_dns_info_ex.txt | 220 ++++++++++++++++++ > ...5pac_upn_dns_info_ex_not_supported.b64.txt | 1 + > .../krb5pac_upn_dns_info_ex_not_supported.txt | 213 +++++++++++++++++ > 5 files changed, 470 insertions(+) > create mode 100644 source4/librpc/tests/krb5pac_upn_dns_info_ex.b64.txt > create mode 100644 source4/librpc/tests/krb5pac_upn_dns_info_ex.txt > create mode 100644 source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.b64.txt > create mode 100644 source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.txt > >diff --git a/python/samba/tests/blackbox/ndrdump.py b/python/samba/tests/blackbox/ndrdump.py >index 5cc3eceb353..d00e04b485b 100644 >--- a/python/samba/tests/blackbox/ndrdump.py >+++ b/python/samba/tests/blackbox/ndrdump.py >@@ -56,6 +56,41 @@ class NdrDumpTests(BlackboxTestCase): > except BlackboxProcessError as e: > self.fail(e) > >+ def test_ndrdump_upn_dns_info_ex(self): >+ with open(self.data_path( >+ 'krb5pac_upn_dns_info_ex.txt')) as f: >+ expected = f.read() >+ data_path = self.data_path( >+ 'krb5pac_upn_dns_info_ex.b64.txt') >+ >+ try: >+ actual = self.check_output( >+ 'ndrdump --debug-stdout -d0 krb5pac PAC_DATA struct ' >+ '--validate --base64-input ' + data_path) >+ except BlackboxProcessError as e: >+ self.fail(e) >+ >+ self.assertEqual(actual, expected.encode('utf-8')) >+ >+ def test_ndrdump_upn_dns_info_ex_not_supported(self): >+ with open(self.data_path( >+ 'krb5pac_upn_dns_info_ex_not_supported.txt')) as f: >+ expected = f.read() >+ data_path = self.data_path( >+ 'krb5pac_upn_dns_info_ex_not_supported.b64.txt') >+ >+ try: >+ # This PAC has been edited to remove the >+ # PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID bit, so that we can >+ # simulate older versions of Samba parsing this structure. >+ actual = self.check_output( >+ 'ndrdump --debug-stdout -d0 krb5pac PAC_DATA struct ' >+ '--validate --base64-input ' + data_path) >+ except BlackboxProcessError as e: >+ self.fail(e) >+ >+ self.assertEqual(actual, expected.encode('utf-8')) >+ > def test_ndrdump_Krb5ccache(self): > expected = open(self.data_path("../../../source3/selftest/" > "ktest-krb5_ccache-2.txt")).read() >diff --git a/source4/librpc/tests/krb5pac_upn_dns_info_ex.b64.txt b/source4/librpc/tests/krb5pac_upn_dns_info_ex.b64.txt >new file mode 100644 >index 00000000000..02b570624bc >--- /dev/null >+++ b/source4/librpc/tests/krb5pac_upn_dns_info_ex.b64.txt >@@ -0,0 +1 @@ >+BgAAAAAAAAABAAAA0AEAAGgAAAAAAAAACgAAABwAAAA4AgAAAAAAAAwAAACoAAAAWAIAAAAAAAAGAAAAFAAAAAADAAAAAAAABwAAABAAAAAYAwAAAAAAABAAAAAQAAAAKAMAAAAAAAABEAgAzMzMzMABAAAAAAAAAAACAAAAAAAAAAAA/////////3//////////f7pMcCzXv9cBugzaVqDA1wG6zMkh2ODXARIAEgAEAAIAAAAAAAgAAgAAAAAADAACAAAAAAAQAAIAAAAAABQAAgAAAAAAGAACAAAAAACOBAAAAQIAAAEAAAAcAAIAIAAAAAAAAAAAAAAAAAAAAAAAAAAOABAAIAACABYAGAAkAAIAKAACAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAALAACAAAAAAAAAAAAAAAAAAkAAAAAAAAACQAAAHQAcwB0AHQAawB0AHUAcwByAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAECAAAHAAAACAAAAAAAAAAHAAAATABPAEMAQQBMAEQAQwAAAAwAAAAAAAAACwAAAFMAQQBNAEIAQQBEAE8ATQBBAEkATgAAAAQAAAABBAAAAAAABRUAAAC2fvX0wDGiOufKt1QBAAAAMAACAAcAAAABAAAAAQEAAAAAABIBAAAAAAAAAIC3ISzXv9cBEgB0AHMAdAB0AGsAdAB1AHMAcgAAAAAANgAYACIAUAADAAAAEgB4ABwAigAAAAAAdABzAHQAdABrAHQAdQBzAHIAQABzAGEAbQBiAGEALgBlAHgAYQBtAHAAbABlAC4AYwBvAG0AAABTAEEATQBCAEEALgBFAFgAQQBNAFAATABFAC4AQwBPAE0AAAAAAAAAdABzAHQAdABrAHQAdQBzAHIAAQUAAAAAAAUVAAAAtn719MAxojrnyrdUjgQAAAAAdv///ys5aox2KdqNY8CVVxkQbs4AAAAAEAAAAFrUeP0b8Pbct0VlVhAAAAB4SC+IGKoLP+0030o= >diff --git a/source4/librpc/tests/krb5pac_upn_dns_info_ex.txt b/source4/librpc/tests/krb5pac_upn_dns_info_ex.txt >new file mode 100644 >index 00000000000..9747d1b6d3a >--- /dev/null >+++ b/source4/librpc/tests/krb5pac_upn_dns_info_ex.txt >@@ -0,0 +1,220 @@ >+pull returned Success >+ PAC_DATA: struct PAC_DATA >+ num_buffers : 0x00000006 (6) >+ version : 0x00000000 (0) >+ buffers: ARRAY(6) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_LOGON_INFO (1) >+ _ndr_size : 0x000001d0 (464) >+ info : * >+ info : union PAC_INFO(case 1) >+ logon_info: struct PAC_LOGON_INFO_CTR >+ info : * >+ info: struct PAC_LOGON_INFO >+ info3: struct netr_SamInfo3 >+ base: struct netr_SamBaseInfo >+ logon_time : NTTIME(0) >+ logoff_time : Thu Sep 14 02:48:05 AM 30828 UTC >+ kickoff_time : Thu Sep 14 02:48:05 AM 30828 UTC >+ last_password_change : Wed Oct 13 02:08:12 AM 2021 UTC >+ allow_password_change : Thu Oct 14 02:08:12 AM 2021 UTC >+ force_password_change : Wed Nov 24 02:08:12 AM 2021 UTC >+ account_name: struct lsa_String >+ length : 0x0012 (18) >+ size : 0x0012 (18) >+ string : * >+ string : 'tsttktusr' >+ full_name: struct lsa_String >+ length : 0x0000 (0) >+ size : 0x0000 (0) >+ string : * >+ string : '' >+ logon_script: struct lsa_String >+ length : 0x0000 (0) >+ size : 0x0000 (0) >+ string : * >+ string : '' >+ profile_path: struct lsa_String >+ length : 0x0000 (0) >+ size : 0x0000 (0) >+ string : * >+ string : '' >+ home_directory: struct lsa_String >+ length : 0x0000 (0) >+ size : 0x0000 (0) >+ string : * >+ string : '' >+ home_drive: struct lsa_String >+ length : 0x0000 (0) >+ size : 0x0000 (0) >+ string : * >+ string : '' >+ logon_count : 0x0000 (0) >+ bad_password_count : 0x0000 (0) >+ rid : 0x0000048e (1166) >+ primary_gid : 0x00000201 (513) >+ groups: struct samr_RidWithAttributeArray >+ count : 0x00000001 (1) >+ rids : * >+ rids: ARRAY(1) >+ rids: struct samr_RidWithAttribute >+ rid : 0x00000201 (513) >+ attributes : 0x00000007 (7) >+ 1: SE_GROUP_MANDATORY >+ 1: SE_GROUP_ENABLED_BY_DEFAULT >+ 1: SE_GROUP_ENABLED >+ 0: SE_GROUP_OWNER >+ 0: SE_GROUP_USE_FOR_DENY_ONLY >+ 0: SE_GROUP_INTEGRITY >+ 0: SE_GROUP_INTEGRITY_ENABLED >+ 0: SE_GROUP_RESOURCE >+ 0x00: SE_GROUP_LOGON_ID (0) >+ user_flags : 0x00000020 (32) >+ 0: NETLOGON_GUEST >+ 0: NETLOGON_NOENCRYPTION >+ 0: NETLOGON_CACHED_ACCOUNT >+ 0: NETLOGON_USED_LM_PASSWORD >+ 1: NETLOGON_EXTRA_SIDS >+ 0: NETLOGON_SUBAUTH_SESSION_KEY >+ 0: NETLOGON_SERVER_TRUST_ACCOUNT >+ 0: NETLOGON_NTLMV2_ENABLED >+ 0: NETLOGON_RESOURCE_GROUPS >+ 0: NETLOGON_PROFILE_PATH_RETURNED >+ 0: NETLOGON_GRACE_LOGON >+ key: struct netr_UserSessionKey >+ key: ARRAY(16): <REDACTED SECRET VALUES> >+ logon_server: struct lsa_StringLarge >+ length : 0x000e (14) >+ size : 0x0010 (16) >+ string : * >+ string : 'LOCALDC' >+ logon_domain: struct lsa_StringLarge >+ length : 0x0016 (22) >+ size : 0x0018 (24) >+ string : * >+ string : 'SAMBADOMAIN' >+ domain_sid : * >+ domain_sid : S-1-5-21-4109729462-983708096-1421331175 >+ LMSessKey: struct netr_LMSessionKey >+ key: ARRAY(8): <REDACTED SECRET VALUES> >+ acct_flags : 0x00000010 (16) >+ 0: ACB_DISABLED >+ 0: ACB_HOMDIRREQ >+ 0: ACB_PWNOTREQ >+ 0: ACB_TEMPDUP >+ 1: ACB_NORMAL >+ 0: ACB_MNS >+ 0: ACB_DOMTRUST >+ 0: ACB_WSTRUST >+ 0: ACB_SVRTRUST >+ 0: ACB_PWNOEXP >+ 0: ACB_AUTOLOCK >+ 0: ACB_ENC_TXT_PWD_ALLOWED >+ 0: ACB_SMARTCARD_REQUIRED >+ 0: ACB_TRUSTED_FOR_DELEGATION >+ 0: ACB_NOT_DELEGATED >+ 0: ACB_USE_DES_KEY_ONLY >+ 0: ACB_DONT_REQUIRE_PREAUTH >+ 0: ACB_PW_EXPIRED >+ 0: ACB_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION >+ 0: ACB_NO_AUTH_DATA_REQD >+ 0: ACB_PARTIAL_SECRETS_ACCOUNT >+ 0: ACB_USE_AES_KEYS >+ sub_auth_status : 0x00000000 (0) >+ last_successful_logon : NTTIME(0) >+ last_failed_logon : NTTIME(0) >+ failed_logon_count : 0x00000000 (0) >+ reserved : 0x00000000 (0) >+ sidcount : 0x00000001 (1) >+ sids : * >+ sids: ARRAY(1) >+ sids: struct netr_SidAttr >+ sid : * >+ sid : S-1-18-1 >+ attributes : 0x00000007 (7) >+ 1: SE_GROUP_MANDATORY >+ 1: SE_GROUP_ENABLED_BY_DEFAULT >+ 1: SE_GROUP_ENABLED >+ 0: SE_GROUP_OWNER >+ 0: SE_GROUP_USE_FOR_DENY_ONLY >+ 0: SE_GROUP_INTEGRITY >+ 0: SE_GROUP_INTEGRITY_ENABLED >+ 0: SE_GROUP_RESOURCE >+ 0x00: SE_GROUP_LOGON_ID (0) >+ resource_groups: struct PAC_DOMAIN_GROUP_MEMBERSHIP >+ domain_sid : NULL >+ groups: struct samr_RidWithAttributeArray >+ count : 0x00000000 (0) >+ rids : NULL >+ _pad : 0x00000000 (0) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_LOGON_NAME (10) >+ _ndr_size : 0x0000001c (28) >+ info : * >+ info : union PAC_INFO(case 10) >+ logon_name: struct PAC_LOGON_NAME >+ logon_time : Wed Oct 13 02:08:11 AM 2021 UTC >+ size : 0x0012 (18) >+ account_name : 'tsttktusr' >+ _pad : 0x00000000 (0) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_UPN_DNS_INFO (12) >+ _ndr_size : 0x000000a8 (168) >+ info : * >+ info : union PAC_INFO(case 12) >+ upn_dns_info: struct PAC_UPN_DNS_INFO >+ upn_name_size : 0x0036 (54) >+ upn_name : * >+ upn_name : 'tsttktusr@samba.example.com' >+ dns_domain_name_size : 0x0022 (34) >+ dns_domain_name : * >+ dns_domain_name : 'SAMBA.EXAMPLE.COM' >+ flags : 0x00000003 (3) >+ 1: PAC_UPN_DNS_FLAG_CONSTRUCTED >+ 1: PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID >+ ex : union PAC_UPN_DNS_INFO_EX(case 2) >+ sam_name_and_sid: struct PAC_UPN_DNS_INFO_SAM_NAME_AND_SID >+ samaccountname_size : 0x0012 (18) >+ samaccountname : * >+ samaccountname : 'tsttktusr' >+ objectsid_size : 0x001c (28) >+ objectsid : * >+ objectsid : S-1-5-21-4109729462-983708096-1421331175-1166 >+ _pad : 0x00000000 (0) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_SRV_CHECKSUM (6) >+ _ndr_size : 0x00000014 (20) >+ info : * >+ info : union PAC_INFO(case 6) >+ srv_cksum: struct PAC_SIGNATURE_DATA >+ type : 0xffffff76 (4294967158) >+ signature : DATA_BLOB length=16 >+[0000] 2B 39 6A 8C 76 29 DA 8D 63 C0 95 57 19 10 6E CE +9j.v).. c..W..n. >+ _pad : 0x00000000 (0) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_KDC_CHECKSUM (7) >+ _ndr_size : 0x00000010 (16) >+ info : * >+ info : union PAC_INFO(case 7) >+ kdc_cksum: struct PAC_SIGNATURE_DATA >+ type : 0x00000010 (16) >+ signature : DATA_BLOB length=12 >+[0000] 5A D4 78 FD 1B F0 F6 DC B7 45 65 56 Z.x..... .EeV >+ _pad : 0x00000000 (0) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_TICKET_CHECKSUM (16) >+ _ndr_size : 0x00000010 (16) >+ info : * >+ info : union PAC_INFO(case 16) >+ ticket_checksum: struct PAC_SIGNATURE_DATA >+ type : 0x00000010 (16) >+ signature : DATA_BLOB length=12 >+[0000] 78 48 2F 88 18 AA 0B 3F ED 34 DF 4A xH/....? .4.J >+ _pad : 0x00000000 (0) >+push returned Success >+pull returned Success >+WARNING! orig bytes:824 validated pushed bytes:832 >+WARNING! orig pulled bytes:824 validated pulled bytes:832 >+WARNING! orig and validated differ at byte 0x2C (44) >+WARNING! orig byte[0x2C] = 0xA8 validated byte[0x2C] = 0xB0 >+dump OK >diff --git a/source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.b64.txt b/source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.b64.txt >new file mode 100644 >index 00000000000..cd99b9d0b0a >--- /dev/null >+++ b/source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.b64.txt >@@ -0,0 +1 @@ >+BgAAAAAAAAABAAAA0AEAAGgAAAAAAAAACgAAABwAAAA4AgAAAAAAAAwAAACoAAAAWAIAAAAAAAAGAAAAFAAAAAADAAAAAAAABwAAABAAAAAYAwAAAAAAABAAAAAQAAAAKAMAAAAAAAABEAgAzMzMzMABAAAAAAAAAAACAAAAAAAAAAAA/////////3//////////f7pMcCzXv9cBugzaVqDA1wG6zMkh2ODXARIAEgAEAAIAAAAAAAgAAgAAAAAADAACAAAAAAAQAAIAAAAAABQAAgAAAAAAGAACAAAAAACOBAAAAQIAAAEAAAAcAAIAIAAAAAAAAAAAAAAAAAAAAAAAAAAOABAAIAACABYAGAAkAAIAKAACAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAALAACAAAAAAAAAAAAAAAAAAkAAAAAAAAACQAAAHQAcwB0AHQAawB0AHUAcwByAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAECAAAHAAAACAAAAAAAAAAHAAAATABPAEMAQQBMAEQAQwAAAAwAAAAAAAAACwAAAFMAQQBNAEIAQQBEAE8ATQBBAEkATgAAAAQAAAABBAAAAAAABRUAAAC2fvX0wDGiOufKt1QBAAAAMAACAAcAAAABAAAAAQEAAAAAABIBAAAAAAAAAIC3ISzXv9cBEgB0AHMAdAB0AGsAdAB1AHMAcgAAAAAANgAYACIAUAABAAAAEgB4ABwAigAAAAAAdABzAHQAdABrAHQAdQBzAHIAQABzAGEAbQBiAGEALgBlAHgAYQBtAHAAbABlAC4AYwBvAG0AAABTAEEATQBCAEEALgBFAFgAQQBNAFAATABFAC4AQwBPAE0AAAAAAAAAdABzAHQAdABrAHQAdQBzAHIAAQUAAAAAAAUVAAAAtn719MAxojrnyrdUjgQAAAAAdv///ys5aox2KdqNY8CVVxkQbs4AAAAAEAAAAFrUeP0b8Pbct0VlVhAAAAB4SC+IGKoLP+0030o= >diff --git a/source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.txt b/source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.txt >new file mode 100644 >index 00000000000..d29832ede49 >--- /dev/null >+++ b/source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.txt >@@ -0,0 +1,213 @@ >+pull returned Success >+ PAC_DATA: struct PAC_DATA >+ num_buffers : 0x00000006 (6) >+ version : 0x00000000 (0) >+ buffers: ARRAY(6) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_LOGON_INFO (1) >+ _ndr_size : 0x000001d0 (464) >+ info : * >+ info : union PAC_INFO(case 1) >+ logon_info: struct PAC_LOGON_INFO_CTR >+ info : * >+ info: struct PAC_LOGON_INFO >+ info3: struct netr_SamInfo3 >+ base: struct netr_SamBaseInfo >+ logon_time : NTTIME(0) >+ logoff_time : Thu Sep 14 02:48:05 AM 30828 UTC >+ kickoff_time : Thu Sep 14 02:48:05 AM 30828 UTC >+ last_password_change : Wed Oct 13 02:08:12 AM 2021 UTC >+ allow_password_change : Thu Oct 14 02:08:12 AM 2021 UTC >+ force_password_change : Wed Nov 24 02:08:12 AM 2021 UTC >+ account_name: struct lsa_String >+ length : 0x0012 (18) >+ size : 0x0012 (18) >+ string : * >+ string : 'tsttktusr' >+ full_name: struct lsa_String >+ length : 0x0000 (0) >+ size : 0x0000 (0) >+ string : * >+ string : '' >+ logon_script: struct lsa_String >+ length : 0x0000 (0) >+ size : 0x0000 (0) >+ string : * >+ string : '' >+ profile_path: struct lsa_String >+ length : 0x0000 (0) >+ size : 0x0000 (0) >+ string : * >+ string : '' >+ home_directory: struct lsa_String >+ length : 0x0000 (0) >+ size : 0x0000 (0) >+ string : * >+ string : '' >+ home_drive: struct lsa_String >+ length : 0x0000 (0) >+ size : 0x0000 (0) >+ string : * >+ string : '' >+ logon_count : 0x0000 (0) >+ bad_password_count : 0x0000 (0) >+ rid : 0x0000048e (1166) >+ primary_gid : 0x00000201 (513) >+ groups: struct samr_RidWithAttributeArray >+ count : 0x00000001 (1) >+ rids : * >+ rids: ARRAY(1) >+ rids: struct samr_RidWithAttribute >+ rid : 0x00000201 (513) >+ attributes : 0x00000007 (7) >+ 1: SE_GROUP_MANDATORY >+ 1: SE_GROUP_ENABLED_BY_DEFAULT >+ 1: SE_GROUP_ENABLED >+ 0: SE_GROUP_OWNER >+ 0: SE_GROUP_USE_FOR_DENY_ONLY >+ 0: SE_GROUP_INTEGRITY >+ 0: SE_GROUP_INTEGRITY_ENABLED >+ 0: SE_GROUP_RESOURCE >+ 0x00: SE_GROUP_LOGON_ID (0) >+ user_flags : 0x00000020 (32) >+ 0: NETLOGON_GUEST >+ 0: NETLOGON_NOENCRYPTION >+ 0: NETLOGON_CACHED_ACCOUNT >+ 0: NETLOGON_USED_LM_PASSWORD >+ 1: NETLOGON_EXTRA_SIDS >+ 0: NETLOGON_SUBAUTH_SESSION_KEY >+ 0: NETLOGON_SERVER_TRUST_ACCOUNT >+ 0: NETLOGON_NTLMV2_ENABLED >+ 0: NETLOGON_RESOURCE_GROUPS >+ 0: NETLOGON_PROFILE_PATH_RETURNED >+ 0: NETLOGON_GRACE_LOGON >+ key: struct netr_UserSessionKey >+ key: ARRAY(16): <REDACTED SECRET VALUES> >+ logon_server: struct lsa_StringLarge >+ length : 0x000e (14) >+ size : 0x0010 (16) >+ string : * >+ string : 'LOCALDC' >+ logon_domain: struct lsa_StringLarge >+ length : 0x0016 (22) >+ size : 0x0018 (24) >+ string : * >+ string : 'SAMBADOMAIN' >+ domain_sid : * >+ domain_sid : S-1-5-21-4109729462-983708096-1421331175 >+ LMSessKey: struct netr_LMSessionKey >+ key: ARRAY(8): <REDACTED SECRET VALUES> >+ acct_flags : 0x00000010 (16) >+ 0: ACB_DISABLED >+ 0: ACB_HOMDIRREQ >+ 0: ACB_PWNOTREQ >+ 0: ACB_TEMPDUP >+ 1: ACB_NORMAL >+ 0: ACB_MNS >+ 0: ACB_DOMTRUST >+ 0: ACB_WSTRUST >+ 0: ACB_SVRTRUST >+ 0: ACB_PWNOEXP >+ 0: ACB_AUTOLOCK >+ 0: ACB_ENC_TXT_PWD_ALLOWED >+ 0: ACB_SMARTCARD_REQUIRED >+ 0: ACB_TRUSTED_FOR_DELEGATION >+ 0: ACB_NOT_DELEGATED >+ 0: ACB_USE_DES_KEY_ONLY >+ 0: ACB_DONT_REQUIRE_PREAUTH >+ 0: ACB_PW_EXPIRED >+ 0: ACB_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION >+ 0: ACB_NO_AUTH_DATA_REQD >+ 0: ACB_PARTIAL_SECRETS_ACCOUNT >+ 0: ACB_USE_AES_KEYS >+ sub_auth_status : 0x00000000 (0) >+ last_successful_logon : NTTIME(0) >+ last_failed_logon : NTTIME(0) >+ failed_logon_count : 0x00000000 (0) >+ reserved : 0x00000000 (0) >+ sidcount : 0x00000001 (1) >+ sids : * >+ sids: ARRAY(1) >+ sids: struct netr_SidAttr >+ sid : * >+ sid : S-1-18-1 >+ attributes : 0x00000007 (7) >+ 1: SE_GROUP_MANDATORY >+ 1: SE_GROUP_ENABLED_BY_DEFAULT >+ 1: SE_GROUP_ENABLED >+ 0: SE_GROUP_OWNER >+ 0: SE_GROUP_USE_FOR_DENY_ONLY >+ 0: SE_GROUP_INTEGRITY >+ 0: SE_GROUP_INTEGRITY_ENABLED >+ 0: SE_GROUP_RESOURCE >+ 0x00: SE_GROUP_LOGON_ID (0) >+ resource_groups: struct PAC_DOMAIN_GROUP_MEMBERSHIP >+ domain_sid : NULL >+ groups: struct samr_RidWithAttributeArray >+ count : 0x00000000 (0) >+ rids : NULL >+ _pad : 0x00000000 (0) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_LOGON_NAME (10) >+ _ndr_size : 0x0000001c (28) >+ info : * >+ info : union PAC_INFO(case 10) >+ logon_name: struct PAC_LOGON_NAME >+ logon_time : Wed Oct 13 02:08:11 AM 2021 UTC >+ size : 0x0012 (18) >+ account_name : 'tsttktusr' >+ _pad : 0x00000000 (0) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_UPN_DNS_INFO (12) >+ _ndr_size : 0x000000a8 (168) >+ info : * >+ info : union PAC_INFO(case 12) >+ upn_dns_info: struct PAC_UPN_DNS_INFO >+ upn_name_size : 0x0036 (54) >+ upn_name : * >+ upn_name : 'tsttktusr@samba.example.com' >+ dns_domain_name_size : 0x0022 (34) >+ dns_domain_name : * >+ dns_domain_name : 'SAMBA.EXAMPLE.COM' >+ flags : 0x00000001 (1) >+ 1: PAC_UPN_DNS_FLAG_CONSTRUCTED >+ 0: PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID >+ ex : union PAC_UPN_DNS_INFO_EX(case 0) >+ _pad : 0x00000000 (0) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_SRV_CHECKSUM (6) >+ _ndr_size : 0x00000014 (20) >+ info : * >+ info : union PAC_INFO(case 6) >+ srv_cksum: struct PAC_SIGNATURE_DATA >+ type : 0xffffff76 (4294967158) >+ signature : DATA_BLOB length=16 >+[0000] 2B 39 6A 8C 76 29 DA 8D 63 C0 95 57 19 10 6E CE +9j.v).. c..W..n. >+ _pad : 0x00000000 (0) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_KDC_CHECKSUM (7) >+ _ndr_size : 0x00000010 (16) >+ info : * >+ info : union PAC_INFO(case 7) >+ kdc_cksum: struct PAC_SIGNATURE_DATA >+ type : 0x00000010 (16) >+ signature : DATA_BLOB length=12 >+[0000] 5A D4 78 FD 1B F0 F6 DC B7 45 65 56 Z.x..... .EeV >+ _pad : 0x00000000 (0) >+ buffers: struct PAC_BUFFER >+ type : PAC_TYPE_TICKET_CHECKSUM (16) >+ _ndr_size : 0x00000010 (16) >+ info : * >+ info : union PAC_INFO(case 16) >+ ticket_checksum: struct PAC_SIGNATURE_DATA >+ type : 0x00000010 (16) >+ signature : DATA_BLOB length=12 >+[0000] 78 48 2F 88 18 AA 0B 3F ED 34 DF 4A xH/....? .4.J >+ _pad : 0x00000000 (0) >+push returned Success >+pull returned Success >+WARNING! orig bytes:824 validated pushed bytes:768 >+WARNING! orig pulled bytes:824 validated pulled bytes:768 >+WARNING! orig and validated differ at byte 0x2C (44) >+WARNING! orig byte[0x2C] = 0xA8 validated byte[0x2C] = 0x70 >+dump OK >-- >2.25.1 > > >From f1735c026278ad72d48b66e69a4050015ce48c58 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 18 Oct 2021 15:02:39 +1300 >Subject: [PATCH 492/686] CVE-2020-25719 tests/krb5: Add tests for requiring > and issuing a PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 124 ++++++++++++++++++++--- > selftest/knownfail_heimdal_kdc | 9 ++ > selftest/knownfail_mit_kdc | 6 ++ > 3 files changed, 123 insertions(+), 16 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index f36704f998c..fbeb5fe61fb 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -31,6 +31,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_ERROR, > KRB_TGS_REP, > KDC_ERR_BADMATCH, >+ KDC_ERR_BADOPTION, > NT_PRINCIPAL, > NT_SRV_INST, > ) >@@ -214,7 +215,8 @@ class KdcTgsTests(KDCBaseTest): > "rep = {%s},%s" % (rep, pac_data)) > > def _make_tgs_request(self, client_creds, service_creds, tgt, >- expect_pac=True): >+ pac_request=None, expect_pac=True, >+ expect_error=False): > client_account = client_creds.get_username() > cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, > names=[client_account]) >@@ -241,6 +243,15 @@ class KdcTgsTests(KDCBaseTest): > > authenticator_subkey = self.RandomKey(kcrypto.Enctype.AES256) > >+ if expect_error: >+ expected_error_mode = KDC_ERR_BADOPTION >+ check_error_fn = self.generic_check_kdc_error >+ check_rep_fn = None >+ else: >+ expected_error_mode = 0 >+ check_error_fn = None >+ check_rep_fn = self.generic_check_kdc_rep >+ > kdc_exchange_dict = self.tgs_exchange_dict( > expected_crealm=expected_crealm, > expected_cname=expected_cname, >@@ -248,12 +259,14 @@ class KdcTgsTests(KDCBaseTest): > expected_sname=expected_sname, > expected_supported_etypes=expected_supported_etypes, > ticket_decryption_key=target_decryption_key, >- check_rep_fn=self.generic_check_kdc_rep, >+ check_error_fn=check_error_fn, >+ check_rep_fn=check_rep_fn, > check_kdc_private_fn=self.generic_check_kdc_private, >- expected_error_mode=0, >+ expected_error_mode=expected_error_mode, > tgt=tgt, > authenticator_subkey=authenticator_subkey, > kdc_options=kdc_options, >+ pac_request=pac_request, > expect_pac=expect_pac) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >@@ -261,25 +274,43 @@ class KdcTgsTests(KDCBaseTest): > realm=realm, > sname=sname, > etypes=etypes) >- self.check_reply(rep, KRB_TGS_REP) >+ if expect_error: >+ self.check_error_rep(rep, expected_error_mode) >+ >+ return None >+ else: >+ self.check_reply(rep, KRB_TGS_REP) >+ >+ return kdc_exchange_dict['rep_ticket_creds'] >+ >+ def test_request(self): >+ client_creds = self.get_client_creds() >+ service_creds = self.get_service_creds() >+ >+ tgt = self.get_tgt(client_creds) >+ >+ pac = self.get_ticket_pac(tgt) >+ self.assertIsNotNone(pac) >+ >+ ticket = self._make_tgs_request(client_creds, service_creds, tgt) > >- return kdc_exchange_dict['rep_ticket_creds'] >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) > > def test_request_no_pac(self): > client_creds = self.get_client_creds() > service_creds = self.get_service_creds() > >- tgt = self.get_tgt(client_creds, pac_request=False, >- expect_pac=False) >+ tgt = self.get_tgt(client_creds, pac_request=False) > >- pac = self.get_ticket_pac(tgt, expect_pac=False) >- self.assertIsNone(pac) >+ pac = self.get_ticket_pac(tgt) >+ self.assertIsNotNone(pac) > > ticket = self._make_tgs_request(client_creds, service_creds, tgt, >- expect_pac=False) >+ pac_request=False) > >- pac = self.get_ticket_pac(ticket, expect_pac=False) >- self.assertIsNone(pac) >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) > > def test_client_no_auth_data_required(self): > client_creds = self.get_cached_creds( >@@ -297,6 +328,23 @@ class KdcTgsTests(KDCBaseTest): > pac = self.get_ticket_pac(ticket) > self.assertIsNotNone(pac) > >+ def test_no_pac_client_no_auth_data_required(self): >+ client_creds = self.get_cached_creds( >+ account_type=self.AccountType.USER, >+ opts={'no_auth_data_required': True}) >+ service_creds = self.get_service_creds() >+ >+ tgt = self.get_tgt(client_creds, pac_request=False) >+ >+ pac = self.get_ticket_pac(tgt) >+ self.assertIsNotNone(pac) >+ >+ ticket = self._make_tgs_request(client_creds, service_creds, tgt, >+ pac_request=False) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ > def test_service_no_auth_data_required(self): > client_creds = self.get_client_creds() > service_creds = self.get_cached_creds( >@@ -314,8 +362,42 @@ class KdcTgsTests(KDCBaseTest): > pac = self.get_ticket_pac(ticket, expect_pac=False) > self.assertIsNone(pac) > >- def test_remove_pac(self): >+ def test_no_pac_service_no_auth_data_required(self): > client_creds = self.get_client_creds() >+ service_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'no_auth_data_required': True}) >+ >+ tgt = self.get_tgt(client_creds, pac_request=False) >+ >+ pac = self.get_ticket_pac(tgt) >+ self.assertIsNotNone(pac) >+ >+ ticket = self._make_tgs_request(client_creds, service_creds, tgt, >+ pac_request=False, expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ def test_remove_pac_service_no_auth_data_required(self): >+ client_creds = self.get_client_creds() >+ service_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'no_auth_data_required': True}) >+ >+ tgt = self.modified_ticket(self.get_tgt(client_creds), >+ exclude_pac=True) >+ >+ pac = self.get_ticket_pac(tgt, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ self._make_tgs_request(client_creds, service_creds, tgt, >+ expect_pac=False, expect_error=True) >+ >+ def test_remove_pac_client_no_auth_data_required(self): >+ client_creds = self.get_cached_creds( >+ account_type=self.AccountType.USER, >+ opts={'no_auth_data_required': True}) > service_creds = self.get_service_creds() > > tgt = self.modified_ticket(self.get_tgt(client_creds), >@@ -324,12 +406,22 @@ class KdcTgsTests(KDCBaseTest): > pac = self.get_ticket_pac(tgt, expect_pac=False) > self.assertIsNone(pac) > >- ticket = self._make_tgs_request(client_creds, service_creds, tgt, >- expect_pac=False) >+ self._make_tgs_request(client_creds, service_creds, tgt, >+ expect_pac=False, expect_error=True) > >- pac = self.get_ticket_pac(ticket, expect_pac=False) >+ def test_remove_pac(self): >+ client_creds = self.get_client_creds() >+ service_creds = self.get_service_creds() >+ >+ tgt = self.modified_ticket(self.get_tgt(client_creds), >+ exclude_pac=True) >+ >+ pac = self.get_ticket_pac(tgt, expect_pac=False) > self.assertIsNone(pac) > >+ self._make_tgs_request(client_creds, service_creds, tgt, >+ expect_pac=False, expect_error=True) >+ > > if __name__ == "__main__": > global_asn1_print = False >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 45524d70fa2..410ba83123c 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -261,3 +261,12 @@ > ^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_instance_spn_computer > ^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_domain_spn_computer > ^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_realm_spn_computer >+# >+# KDC TGS PAC tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_no_pac_client_no_auth_data_required >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_no_pac_service_no_auth_data_required >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_client_no_auth_data_required >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_service_no_auth_data_required >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_request_no_pac >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index c86f9c2c2ea..8612d05b3da 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -276,7 +276,13 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_ldap_service_ticket\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_get_ticket_for_host_service_of_machine_account\(ad_dc\) > # >+# KDC TGS PAC tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_no_pac_client_no_auth_data_required\(ad_dc\) >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_no_pac_service_no_auth_data_required\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac\(ad_dc\) >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_client_no_auth_data_required\(ad_dc\) >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_service_no_auth_data_required\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_request_no_pac\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required\(ad_dc\) > # >-- >2.25.1 > > >From ba193d002311e1525c2317d3264a8e72a857e463 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 19 Oct 2021 14:39:36 +1300 >Subject: [PATCH 493/686] CVE-2020-25719 tests/krb5: Add a test for making an > S4U2Self request without a PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14686 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/s4u_tests.py | 37 ++++++++++++++++++++++++++-- > selftest/knownfail_heimdal_kdc | 1 + > 2 files changed, 36 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index 593ef94c910..a80a7b3427e 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -256,6 +256,17 @@ class S4UKerberosTests(KDCBaseTest): > if unexpected_flags is not None: > unexpected_flags = krb5_asn1.TicketFlags(unexpected_flags) > >+ expected_error_mode = kdc_dict.pop('expected_error_mode', 0) >+ expected_status = kdc_dict.pop('expected_status', None) >+ if expected_error_mode: >+ check_error_fn = self.generic_check_kdc_error >+ check_rep_fn = None >+ else: >+ check_error_fn = None >+ check_rep_fn = self.generic_check_kdc_rep >+ >+ self.assertIsNone(expected_status) >+ > kdc_options = kdc_dict.pop('kdc_options', '0') > kdc_options = krb5_asn1.KDCOptions(kdc_options) > >@@ -290,9 +301,11 @@ class S4UKerberosTests(KDCBaseTest): > ticket_decryption_key=service_decryption_key, > expect_ticket_checksum=True, > generate_padata_fn=generate_s4u2self_padata, >- check_rep_fn=self.generic_check_kdc_rep, >+ check_error_fn=check_error_fn, >+ check_rep_fn=check_rep_fn, > check_kdc_private_fn=self.generic_check_kdc_private, >- expected_error_mode=0, >+ expected_error_mode=expected_error_mode, >+ expected_status=expected_status, > tgt=service_tgt, > authenticator_subkey=authenticator_subkey, > kdc_options=str(kdc_options), >@@ -321,6 +334,26 @@ class S4UKerberosTests(KDCBaseTest): > 'expected_flags': 'forwardable' > }) > >+ # Test performing an S4U2Self operation with a forwardable ticket that does >+ # not contain a PAC. The request should fail. >+ def test_s4u2self_no_pac(self): >+ def forwardable_no_pac(ticket): >+ ticket = self.set_ticket_forwardable(ticket, flag=True) >+ return self.remove_ticket_pac(ticket) >+ >+ self._run_s4u2self_test( >+ { >+ 'expected_error_mode': (KDC_ERR_GENERIC, >+ KDC_ERR_BADOPTION), >+ 'expected_status': ntstatus.NT_STATUS_INVALID_PARAMETER, >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': forwardable_no_pac, >+ 'expected_flags': 'forwardable' >+ }) >+ > # Test performing an S4U2Self operation without requesting a forwardable > # ticket. The resulting ticket should not have the 'forwardable' flag set. > def test_s4u2self_without_forwardable(self): >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 410ba83123c..f141efa86e5 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -243,6 +243,7 @@ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_service_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_forwardable >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_no_pac > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_empty_allowed > # > # The lack of KRB5SignedPath means we no longer return >-- >2.25.1 > > >From 48c204bdb6a1a615c0c315dcd93eb4d7bb27bab2 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 19 Oct 2021 20:02:45 +1300 >Subject: [PATCH 494/686] CVE-2020-25719 tests/krb5: Add principal aliasing > test > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14686 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/alias_tests.py | 201 +++++++++++++++++++ > python/samba/tests/krb5/rfc4120_constants.py | 1 + > python/samba/tests/usage.py | 1 + > selftest/knownfail_heimdal_kdc | 7 + > selftest/knownfail_mit_kdc | 7 + > source4/selftest/tests.py | 10 + > 6 files changed, 227 insertions(+) > create mode 100755 python/samba/tests/krb5/alias_tests.py > >diff --git a/python/samba/tests/krb5/alias_tests.py b/python/samba/tests/krb5/alias_tests.py >new file mode 100755 >index 00000000000..60213845a44 >--- /dev/null >+++ b/python/samba/tests/krb5/alias_tests.py >@@ -0,0 +1,201 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# Copyright (C) 2021 Catalyst.Net Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+ >+import ldb >+ >+from samba.tests import delete_force >+import samba.tests.krb5.kcrypto as kcrypto >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+from samba.tests.krb5.rfc4120_constants import ( >+ AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5, >+ KDC_ERR_CLIENT_NAME_MISMATCH, >+ NT_PRINCIPAL, >+) >+ >+sys.path.insert(0, 'bin/python') >+os.environ['PYTHONUNBUFFERED'] = '1' >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class AliasTests(KDCBaseTest): >+ def test_dc_alias_rename(self): >+ self._run_dc_alias(action='rename') >+ >+ def test_dc_alias_delete(self): >+ self._run_dc_alias(action='delete') >+ >+ def _run_dc_alias(self, action=None): >+ target_creds = self.get_dc_creds() >+ target_name = target_creds.get_username()[:-1] >+ >+ self._run_alias(target_name, lambda: target_creds, action=action) >+ >+ def test_create_alias_rename(self): >+ self._run_create_alias(action='rename') >+ >+ def test_create_alias_delete(self): >+ self._run_create_alias(action='delete') >+ >+ def _run_create_alias(self, action=None): >+ target_name = self.get_new_username() >+ >+ def create_target(): >+ samdb = self.get_samdb() >+ >+ realm = samdb.domain_dns_name().lower() >+ >+ hostname = f'{target_name}.{realm}' >+ spn = f'ldap/{hostname}' >+ >+ details = { >+ 'dNSHostName': hostname >+ } >+ >+ creds, fn = self.create_account( >+ samdb, >+ target_name, >+ account_type=self.AccountType.COMPUTER, >+ spn=spn, >+ additional_details=details) >+ >+ return creds >+ >+ self._run_alias(target_name, create_target, action=action) >+ >+ def _run_alias(self, target_name, target_creds_fn, action=None): >+ samdb = self.get_samdb() >+ >+ mach_name = self.get_new_username() >+ >+ # Create a machine account. >+ mach_creds, mach_dn = self.create_account( >+ samdb, mach_name, account_type=self.AccountType.COMPUTER) >+ self.addCleanup(delete_force, samdb, mach_dn) >+ >+ mach_sid = self.get_objectSid(samdb, mach_dn) >+ realm = mach_creds.get_realm() >+ >+ # The account salt doesn't change when the account is renamed. >+ old_salt = mach_creds.get_salt() >+ mach_creds.set_forced_salt(old_salt) >+ >+ # Rename the account to alias with the target account. >+ msg = ldb.Message(ldb.Dn(samdb, mach_dn)) >+ msg['sAMAccountName'] = ldb.MessageElement(target_name, >+ ldb.FLAG_MOD_REPLACE, >+ 'sAMAccountName') >+ samdb.modify(msg) >+ mach_creds.set_username(target_name) >+ >+ # Get a TGT for the machine account. >+ tgt = self.get_tgt(mach_creds, kdc_options='0', fresh=True) >+ >+ # Check the PAC. >+ pac_data = self.get_pac_data(tgt.ticket_private['authorization-data']) >+ >+ upn = f'{target_name}@{realm.lower()}' >+ >+ self.assertEqual(target_name, str(pac_data.account_name)) >+ self.assertEqual(mach_sid, pac_data.account_sid) >+ self.assertEqual(target_name, pac_data.logon_name) >+ self.assertEqual(upn, pac_data.upn) >+ self.assertEqual(realm, pac_data.domain_name) >+ >+ # Rename or delete the machine account. >+ if action == 'rename': >+ mach_name2 = self.get_new_username() >+ >+ msg = ldb.Message(ldb.Dn(samdb, mach_dn)) >+ msg['sAMAccountName'] = ldb.MessageElement(mach_name2, >+ ldb.FLAG_MOD_REPLACE, >+ 'sAMAccountName') >+ samdb.modify(msg) >+ elif action == 'delete': >+ samdb.delete(mach_dn) >+ else: >+ self.fail(action) >+ >+ # Get the credentials for the target account. >+ target_creds = target_creds_fn() >+ >+ # Look up the DNS host name of the target account. >+ target_dn = target_creds.get_dn() >+ res = samdb.search(target_dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['dNSHostName']) >+ target_hostname = str(res[0].get('dNSHostName', idx=0)) >+ >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=['ldap', target_hostname]) >+ target_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[target_name]) >+ >+ target_decryption_key = self.TicketDecryptionKey_from_creds( >+ target_creds) >+ >+ authenticator_subkey = self.RandomKey(kcrypto.Enctype.AES256) >+ >+ etypes = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ >+ def generate_s4u2self_padata(_kdc_exchange_dict, >+ _callback_dict, >+ req_body): >+ padata = self.PA_S4U2Self_create(name=target_cname, >+ realm=realm, >+ tgt_session_key=tgt.session_key, >+ ctype=None) >+ return [padata], req_body >+ >+ expected_error_mode = KDC_ERR_CLIENT_NAME_MISMATCH >+ >+ # Make a request using S4U2Self. The request should fail. >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=realm, >+ expected_cname=target_cname, >+ expected_srealm=realm, >+ expected_sname=sname, >+ ticket_decryption_key=target_decryption_key, >+ generate_padata_fn=generate_s4u2self_padata, >+ expected_error_mode=expected_error_mode, >+ check_error_fn=self.generic_check_kdc_error, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ tgt=tgt, >+ authenticator_subkey=authenticator_subkey, >+ kdc_options='0', >+ expect_pac=True) >+ >+ rep = self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=None, >+ realm=realm, >+ sname=sname, >+ etypes=etypes) >+ self.check_error_rep(rep, expected_error_mode) >+ >+ >+if __name__ == '__main__': >+ global_asn1_print = False >+ global_hexdump = False >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index 39bb2db8e32..b643185f767 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -81,6 +81,7 @@ KDC_ERR_SKEW = 37 > KDC_ERR_MODIFIED = 41 > KDC_ERR_INAPP_CKSUM = 50 > KDC_ERR_GENERIC = 60 >+KDC_ERR_CLIENT_NAME_MISMATCH = 75 > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS = 93 > > # Extended error types >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 2bf891dc8b3..d15e67ba617 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -103,6 +103,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/rodc_tests.py', > 'python/samba/tests/krb5/salt_tests.py', > 'python/samba/tests/krb5/spn_tests.py', >+ 'python/samba/tests/krb5/alias_tests.py', > } > > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index f141efa86e5..5e0d958ee59 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -271,3 +271,10 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_client_no_auth_data_required > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_service_no_auth_data_required > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_request_no_pac >+# >+# Alias tests >+# >+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_delete >+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_rename >+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_delete >+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_rename >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 8612d05b3da..4441be9d203 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -386,3 +386,10 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_instance_spn_computer > ^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_domain_spn_computer > ^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_realm_spn_computer >+# >+# Alias tests >+# >+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_delete >+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_rename >+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_delete >+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_rename >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 58f7683e008..ff293dbd580 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1353,6 +1353,16 @@ planpythontestsuite( > 'FAST_SUPPORT': have_fast_support, > 'TKT_SIG_SUPPORT': tkt_sig_support > }) >+planpythontestsuite( >+ "ad_dc", >+ "samba.tests.krb5.alias_tests", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support >+ }) > > for env in [ > 'vampire_dc', >-- >2.25.1 > > >From b03d472f2b6427e7a220545d12588c249a5b5070 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 21 Oct 2021 11:45:23 +1300 >Subject: [PATCH 495/686] CVE-2020-25718 tests/krb5: Add tests for RODC-printed > and invalid TGTs > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 6 +- > python/samba/tests/krb5/kdc_tgs_tests.py | 808 +++++++++++++++++++ > python/samba/tests/krb5/rfc4120_constants.py | 1 + > selftest/knownfail_heimdal_kdc | 64 ++ > selftest/knownfail_mit_kdc | 67 ++ > 5 files changed, 944 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index cc23484ba2c..4fe7485c492 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -657,7 +657,8 @@ class KDCBaseTest(RawKerberosTest): > 'delegation_to_spn': None, > 'delegation_from_dn': None, > 'trusted_to_auth_for_delegation': False, >- 'fast_support': False >+ 'fast_support': False, >+ 'id': None > } > > account_opts = { >@@ -698,7 +699,8 @@ class KDCBaseTest(RawKerberosTest): > delegation_to_spn, > delegation_from_dn, > trusted_to_auth_for_delegation, >- fast_support): >+ fast_support, >+ id): > if account_type is self.AccountType.USER: > self.assertIsNone(spn) > self.assertIsNone(delegation_to_spn) >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index fbeb5fe61fb..74f1032163e 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -20,6 +20,13 @@ > import sys > import os > >+import ldb >+ >+ >+from samba import dsdb >+ >+from samba.dcerpc import krb5pac >+ > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > >@@ -32,6 +39,10 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_TGS_REP, > KDC_ERR_BADMATCH, > KDC_ERR_BADOPTION, >+ KDC_ERR_CLIENT_NAME_MISMATCH, >+ KDC_ERR_POLICY, >+ KDC_ERR_S_PRINCIPAL_UNKNOWN, >+ KDC_ERR_TGT_REVOKED, > NT_PRINCIPAL, > NT_SRV_INST, > ) >@@ -422,6 +433,803 @@ class KdcTgsTests(KDCBaseTest): > self._make_tgs_request(client_creds, service_creds, tgt, > expect_pac=False, expect_error=True) > >+ # Test making a TGS request. >+ def test_tgs_req(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ self._run_tgs(tgt, expected_error=0) >+ >+ def test_renew_req(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, renewable=True) >+ self._renew_tgt(tgt, expected_error=0) >+ >+ def test_validate_req(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, invalid=True) >+ self._validate_tgt(tgt, expected_error=0) >+ >+ def test_s4u2self_req(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ self._s4u2self(tgt, creds, expected_error=0) >+ >+ def test_user2user_req(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ self._user2user(tgt, creds, expected_error=0) >+ >+ # Test making a request without a PAC. >+ def test_tgs_no_pac(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, remove_pac=True) >+ self._run_tgs(tgt, expected_error=KDC_ERR_BADOPTION) >+ >+ def test_renew_no_pac(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, renewable=True, remove_pac=True) >+ self._renew_tgt(tgt, expected_error=KDC_ERR_BADOPTION) >+ >+ def test_validate_no_pac(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, invalid=True, remove_pac=True) >+ self._validate_tgt(tgt, expected_error=KDC_ERR_BADOPTION) >+ >+ def test_s4u2self_no_pac(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, remove_pac=True) >+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_BADOPTION) >+ >+ def test_user2user_no_pac(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, remove_pac=True) >+ self._user2user(tgt, creds, expected_error=KDC_ERR_BADOPTION) >+ >+ # Test changing the SID in the PAC to that of another account. >+ def test_tgs_sid_mismatch_existing(self): >+ creds = self._get_creds() >+ existing_rid = self._get_existing_rid() >+ tgt = self._get_tgt(creds, new_rid=existing_rid) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_renew_sid_mismatch_existing(self): >+ creds = self._get_creds() >+ existing_rid = self._get_existing_rid() >+ tgt = self._get_tgt(creds, renewable=True, new_rid=existing_rid) >+ self._renew_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_validate_sid_mismatch_existing(self): >+ creds = self._get_creds() >+ existing_rid = self._get_existing_rid() >+ tgt = self._get_tgt(creds, invalid=True, new_rid=existing_rid) >+ self._validate_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_s4u2self_sid_mismatch_existing(self): >+ creds = self._get_creds() >+ existing_rid = self._get_existing_rid() >+ tgt = self._get_tgt(creds, new_rid=existing_rid) >+ self._s4u2self(tgt, creds, >+ expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_user2user_sid_mismatch_existing(self): >+ creds = self._get_creds() >+ existing_rid = self._get_existing_rid() >+ tgt = self._get_tgt(creds, new_rid=existing_rid) >+ self._user2user(tgt, creds, >+ expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ # Test changing the SID in the PAC to a non-existent one. >+ def test_tgs_sid_mismatch_nonexisting(self): >+ creds = self._get_creds() >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, new_rid=nonexistent_rid) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_renew_sid_mismatch_nonexisting(self): >+ creds = self._get_creds() >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, renewable=True, >+ new_rid=nonexistent_rid) >+ self._renew_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_validate_sid_mismatch_nonexisting(self): >+ creds = self._get_creds() >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, invalid=True, >+ new_rid=nonexistent_rid) >+ self._validate_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_s4u2self_sid_mismatch_nonexisting(self): >+ creds = self._get_creds() >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, new_rid=nonexistent_rid) >+ self._s4u2self(tgt, creds, >+ expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_user2user_sid_mismatch_nonexisting(self): >+ creds = self._get_creds() >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, new_rid=nonexistent_rid) >+ self._user2user(tgt, creds, >+ expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ # Test with an RODC-issued ticket where the client is revealed to the RODC. >+ def test_tgs_rodc_revealed(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._run_tgs(tgt, expected_error=0) >+ >+ def test_renew_rodc_revealed(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, renewable=True, from_rodc=True) >+ self._renew_tgt(tgt, expected_error=0) >+ >+ def test_validate_rodc_revealed(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, invalid=True, from_rodc=True) >+ self._validate_tgt(tgt, expected_error=0) >+ >+ def test_s4u2self_rodc_revealed(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._s4u2self(tgt, creds, expected_error=0) >+ >+ def test_user2user_rodc_revealed(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._user2user(tgt, creds, expected_error=0) >+ >+ # Test with an RODC-issued ticket where the SID in the PAC is changed to >+ # that of another account. >+ def test_tgs_rodc_sid_mismatch_existing(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ existing_rid = self._get_existing_rid(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_renew_rodc_sid_mismatch_existing(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ existing_rid = self._get_existing_rid(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, renewable=True, from_rodc=True, >+ new_rid=existing_rid) >+ self._renew_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_validate_rodc_sid_mismatch_existing(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ existing_rid = self._get_existing_rid(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, invalid=True, from_rodc=True, >+ new_rid=existing_rid) >+ self._validate_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_s4u2self_rodc_sid_mismatch_existing(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ existing_rid = self._get_existing_rid(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid) >+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_user2user_rodc_sid_mismatch_existing(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ existing_rid = self._get_existing_rid(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid) >+ self._user2user(tgt, creds, >+ expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ # Test with an RODC-issued ticket where the SID in the PAC is changed to a >+ # non-existent one. >+ def test_tgs_rodc_sid_mismatch_nonexisting(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_renew_rodc_sid_mismatch_nonexisting(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, renewable=True, from_rodc=True, >+ new_rid=nonexistent_rid) >+ self._renew_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_validate_rodc_sid_mismatch_nonexisting(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, invalid=True, from_rodc=True, >+ new_rid=nonexistent_rid) >+ self._validate_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_s4u2self_rodc_sid_mismatch_nonexisting(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid) >+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_user2user_rodc_sid_mismatch_nonexisting(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid) >+ self._user2user(tgt, creds, >+ expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ # Test with an RODC-issued ticket where the client is not revealed to the >+ # RODC. >+ def test_tgs_rodc_not_revealed(self): >+ creds = self._get_creds(replication_allowed=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ # TODO: error code >+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_renew_rodc_not_revealed(self): >+ creds = self._get_creds(replication_allowed=True) >+ tgt = self._get_tgt(creds, renewable=True, from_rodc=True) >+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_validate_rodc_not_revealed(self): >+ creds = self._get_creds(replication_allowed=True) >+ tgt = self._get_tgt(creds, invalid=True, from_rodc=True) >+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_s4u2self_rodc_not_revealed(self): >+ creds = self._get_creds(replication_allowed=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_user2user_rodc_not_revealed(self): >+ creds = self._get_creds(replication_allowed=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ # Test with an RODC-issued ticket where the RODC account does not have the >+ # PARTIAL_SECRETS bit set. >+ def test_tgs_rodc_no_partial_secrets(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._remove_rodc_partial_secrets() >+ self._run_tgs(tgt, expected_error=KDC_ERR_POLICY) >+ >+ def test_renew_rodc_no_partial_secrets(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, renewable=True, from_rodc=True) >+ self._remove_rodc_partial_secrets() >+ self._renew_tgt(tgt, expected_error=KDC_ERR_POLICY) >+ >+ def test_validate_rodc_no_partial_secrets(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, invalid=True, from_rodc=True) >+ self._remove_rodc_partial_secrets() >+ self._validate_tgt(tgt, expected_error=KDC_ERR_POLICY) >+ >+ def test_s4u2self_rodc_no_partial_secrets(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._remove_rodc_partial_secrets() >+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_POLICY) >+ >+ def test_user2user_rodc_no_partial_secrets(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._remove_rodc_partial_secrets() >+ self._user2user(tgt, creds, expected_error=KDC_ERR_POLICY) >+ >+ # Test with an RODC-issued ticket where the RODC account does not have an >+ # msDS-KrbTgtLink. >+ def test_tgs_rodc_no_krbtgt_link(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._remove_rodc_krbtgt_link() >+ self._run_tgs(tgt, expected_error=KDC_ERR_POLICY) >+ >+ def test_renew_rodc_no_krbtgt_link(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, renewable=True, from_rodc=True) >+ self._remove_rodc_krbtgt_link() >+ self._renew_tgt(tgt, expected_error=KDC_ERR_POLICY) >+ >+ def test_validate_rodc_no_krbtgt_link(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, invalid=True, from_rodc=True) >+ self._remove_rodc_krbtgt_link() >+ self._validate_tgt(tgt, expected_error=KDC_ERR_POLICY) >+ >+ def test_s4u2self_rodc_no_krbtgt_link(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._remove_rodc_krbtgt_link() >+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_POLICY) >+ >+ def test_user2user_rodc_no_krbtgt_link(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._remove_rodc_krbtgt_link() >+ self._user2user(tgt, creds, expected_error=KDC_ERR_POLICY) >+ >+ # Test with an RODC-issued ticket where the client is not allowed to >+ # replicate to the RODC. >+ def test_tgs_rodc_not_allowed(self): >+ creds = self._get_creds(revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_renew_rodc_not_allowed(self): >+ creds = self._get_creds(revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, renewable=True, from_rodc=True) >+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_validate_rodc_not_allowed(self): >+ creds = self._get_creds(revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, invalid=True, from_rodc=True) >+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_s4u2self_rodc_not_allowed(self): >+ creds = self._get_creds(revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_user2user_rodc_not_allowed(self): >+ creds = self._get_creds(revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ # Test with an RODC-issued ticket where the client is denied from >+ # replicating to the RODC. >+ def test_tgs_rodc_denied(self): >+ creds = self._get_creds(replication_denied=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_renew_rodc_denied(self): >+ creds = self._get_creds(replication_denied=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, renewable=True, from_rodc=True) >+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_validate_rodc_denied(self): >+ creds = self._get_creds(replication_denied=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, invalid=True, from_rodc=True) >+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_s4u2self_rodc_denied(self): >+ creds = self._get_creds(replication_denied=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_user2user_rodc_denied(self): >+ creds = self._get_creds(replication_denied=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ # Test with an RODC-issued ticket where the client is both allowed and >+ # denied replicating to the RODC. >+ def test_tgs_rodc_allowed_denied(self): >+ creds = self._get_creds(replication_allowed=True, >+ replication_denied=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_renew_rodc_allowed_denied(self): >+ creds = self._get_creds(replication_allowed=True, >+ replication_denied=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, renewable=True, from_rodc=True) >+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_validate_rodc_allowed_denied(self): >+ creds = self._get_creds(replication_allowed=True, >+ replication_denied=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, invalid=True, from_rodc=True) >+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_s4u2self_rodc_allowed_denied(self): >+ creds = self._get_creds(replication_allowed=True, >+ replication_denied=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ def test_user2user_rodc_allowed_denied(self): >+ creds = self._get_creds(replication_allowed=True, >+ replication_denied=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True) >+ self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) >+ >+ # Test user-to-user with incorrect service principal names. >+ def test_user2user_matching_sname_host(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ user_name = self._get_mach_creds().get_username() >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=['host', user_name]) >+ >+ self._user2user(tgt, creds, sname=sname, >+ expected_error=KDC_ERR_S_PRINCIPAL_UNKNOWN) >+ >+ def test_user2user_matching_sname_no_host(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ user_name = self._get_mach_creds().get_username() >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ >+ self._user2user(tgt, creds, sname=sname, >+ expected_error=KDC_ERR_BADMATCH) >+ >+ def test_user2user_wrong_sname(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ other_creds = self.get_service_creds() >+ user_name = other_creds.get_username() >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ >+ self._user2user(tgt, creds, sname=sname, >+ expected_error=(KDC_ERR_BADMATCH, >+ KDC_ERR_BADOPTION)) >+ >+ def test_user2user_non_existent_sname(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=['host', 'non_existent_user']) >+ >+ self._user2user(tgt, creds, sname=sname, >+ expected_error=KDC_ERR_S_PRINCIPAL_UNKNOWN) >+ >+ def test_user2user_service_ticket(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ service_creds = self.get_service_creds() >+ service_ticket = self.get_service_ticket(tgt, service_creds) >+ >+ self._user2user(service_ticket, creds, expected_error=KDC_ERR_POLICY) >+ >+ def _get_tgt(self, >+ client_creds, >+ renewable=False, >+ invalid=False, >+ from_rodc=False, >+ new_rid=None, >+ remove_pac=False): >+ self.assertFalse(renewable and invalid) >+ >+ if remove_pac: >+ self.assertIsNone(new_rid) >+ >+ tgt = self.get_tgt(client_creds) >+ >+ if from_rodc: >+ krbtgt_creds = self.get_mock_rodc_krbtgt_creds() >+ else: >+ krbtgt_creds = self.get_krbtgt_creds() >+ >+ if new_rid is not None: >+ def change_sid_fn(pac): >+ for pac_buffer in pac.buffers: >+ if pac_buffer.type == krb5pac.PAC_TYPE_LOGON_INFO: >+ logon_info = pac_buffer.info.info >+ >+ logon_info.info3.base.rid = new_rid >+ >+ return pac >+ >+ modify_pac_fn = change_sid_fn >+ else: >+ modify_pac_fn = None >+ >+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ if remove_pac: >+ checksum_keys = None >+ else: >+ checksum_keys = { >+ krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key >+ } >+ >+ if renewable: >+ def set_renewable(enc_part): >+ # Set the renewable flag. >+ renewable_flag = krb5_asn1.TicketFlags('renewable') >+ pos = len(tuple(renewable_flag)) - 1 >+ >+ flags = enc_part['flags'] >+ self.assertLessEqual(pos, len(flags)) >+ >+ new_flags = flags[:pos] + '1' + flags[pos + 1:] >+ enc_part['flags'] = new_flags >+ >+ # Set the renew-till time to be in the future. >+ renew_till = self.get_KerberosTime(offset=100 * 60 * 60) >+ enc_part['renew-till'] = renew_till >+ >+ return enc_part >+ >+ modify_fn = set_renewable >+ elif invalid: >+ def set_invalid(enc_part): >+ # Set the invalid flag. >+ invalid_flag = krb5_asn1.TicketFlags('invalid') >+ pos = len(tuple(invalid_flag)) - 1 >+ >+ flags = enc_part['flags'] >+ self.assertLessEqual(pos, len(flags)) >+ >+ new_flags = flags[:pos] + '1' + flags[pos + 1:] >+ enc_part['flags'] = new_flags >+ >+ # Set the ticket start time to be in the past. >+ past_time = self.get_KerberosTime(offset=-100 * 60 * 60) >+ enc_part['starttime'] = past_time >+ >+ return enc_part >+ >+ modify_fn = set_invalid >+ else: >+ modify_fn = None >+ >+ return self.modified_ticket( >+ tgt, >+ new_ticket_key=krbtgt_key, >+ modify_fn=modify_fn, >+ modify_pac_fn=modify_pac_fn, >+ exclude_pac=remove_pac, >+ update_pac_checksums=not remove_pac, >+ checksum_keys=checksum_keys) >+ >+ def _remove_rodc_partial_secrets(self): >+ samdb = self.get_samdb() >+ >+ rodc_ctx = self.get_mock_rodc_ctx() >+ rodc_dn = ldb.Dn(samdb, rodc_ctx.acct_dn) >+ >+ def add_rodc_partial_secrets(): >+ msg = ldb.Message() >+ msg.dn = rodc_dn >+ msg['userAccountControl'] = ldb.MessageElement( >+ str(rodc_ctx.userAccountControl), >+ ldb.FLAG_MOD_REPLACE, >+ 'userAccountControl') >+ samdb.modify(msg) >+ >+ self.addCleanup(add_rodc_partial_secrets) >+ >+ uac = rodc_ctx.userAccountControl & ~dsdb.UF_PARTIAL_SECRETS_ACCOUNT >+ >+ msg = ldb.Message() >+ msg.dn = rodc_dn >+ msg['userAccountControl'] = ldb.MessageElement( >+ str(uac), >+ ldb.FLAG_MOD_REPLACE, >+ 'userAccountControl') >+ samdb.modify(msg) >+ >+ def _remove_rodc_krbtgt_link(self): >+ samdb = self.get_samdb() >+ >+ rodc_ctx = self.get_mock_rodc_ctx() >+ rodc_dn = ldb.Dn(samdb, rodc_ctx.acct_dn) >+ >+ def add_rodc_krbtgt_link(): >+ msg = ldb.Message() >+ msg.dn = rodc_dn >+ msg['msDS-KrbTgtLink'] = ldb.MessageElement( >+ rodc_ctx.new_krbtgt_dn, >+ ldb.FLAG_MOD_ADD, >+ 'msDS-KrbTgtLink') >+ samdb.modify(msg) >+ >+ self.addCleanup(add_rodc_krbtgt_link) >+ >+ msg = ldb.Message() >+ msg.dn = rodc_dn >+ msg['msDS-KrbTgtLink'] = ldb.MessageElement( >+ [], >+ ldb.FLAG_MOD_DELETE, >+ 'msDS-KrbTgtLink') >+ samdb.modify(msg) >+ >+ def _get_creds(self, >+ replication_allowed=False, >+ replication_denied=False, >+ revealed_to_rodc=False): >+ return self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={ >+ 'allowed_replication_mock': replication_allowed, >+ 'denied_replication_mock': replication_denied, >+ 'revealed_to_mock_rodc': revealed_to_rodc, >+ 'id': 0 >+ }) >+ >+ def _get_existing_rid(self, >+ replication_allowed=False, >+ replication_denied=False, >+ revealed_to_rodc=False): >+ other_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={ >+ 'allowed_replication_mock': replication_allowed, >+ 'denied_replication_mock': replication_denied, >+ 'revealed_to_mock_rodc': revealed_to_rodc, >+ 'id': 1 >+ }) >+ >+ samdb = self.get_samdb() >+ >+ other_dn = other_creds.get_dn() >+ other_sid = self.get_objectSid(samdb, other_dn) >+ >+ other_rid = int(other_sid.rsplit('-', 1)[1]) >+ >+ return other_rid >+ >+ def _get_mach_creds(self): >+ return self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={ >+ 'allowed_replication_mock': True, >+ 'denied_replication_mock': False, >+ 'revealed_to_mock_rodc': True, >+ 'id': 2 >+ }) >+ >+ def _get_non_existent_rid(self): >+ return (1 << 30) - 1 >+ >+ def _run_tgs(self, tgt, expected_error): >+ target_creds = self.get_service_creds() >+ self._tgs_req(tgt, expected_error, target_creds) >+ >+ def _renew_tgt(self, tgt, expected_error): >+ krbtgt_creds = self.get_krbtgt_creds() >+ kdc_options = str(krb5_asn1.KDCOptions('renew')) >+ self._tgs_req(tgt, expected_error, krbtgt_creds, >+ kdc_options=kdc_options) >+ >+ def _validate_tgt(self, tgt, expected_error): >+ krbtgt_creds = self.get_krbtgt_creds() >+ kdc_options = str(krb5_asn1.KDCOptions('validate')) >+ self._tgs_req(tgt, expected_error, krbtgt_creds, >+ kdc_options=kdc_options) >+ >+ def _s4u2self(self, tgt, tgt_creds, expected_error): >+ user_creds = self._get_mach_creds() >+ >+ user_name = user_creds.get_username() >+ user_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ user_realm = user_creds.get_realm() >+ >+ def generate_s4u2self_padata(_kdc_exchange_dict, >+ _callback_dict, >+ req_body): >+ padata = self.PA_S4U2Self_create( >+ name=user_cname, >+ realm=user_realm, >+ tgt_session_key=tgt.session_key, >+ ctype=None) >+ >+ return [padata], req_body >+ >+ self._tgs_req(tgt, expected_error, tgt_creds, >+ expected_cname=user_cname, >+ generate_padata_fn=generate_s4u2self_padata, >+ expect_claims=False) >+ >+ def _user2user(self, tgt, tgt_creds, expected_error, sname=None): >+ user_creds = self._get_mach_creds() >+ user_tgt = self.get_tgt(user_creds) >+ >+ kdc_options = str(krb5_asn1.KDCOptions('enc-tkt-in-skey')) >+ self._tgs_req(user_tgt, expected_error, tgt_creds, >+ kdc_options=kdc_options, >+ additional_ticket=tgt, >+ sname=sname) >+ >+ def _tgs_req(self, tgt, expected_error, target_creds, >+ kdc_options='0', >+ expected_cname=None, >+ additional_ticket=None, >+ generate_padata_fn=None, >+ sname=None, >+ expect_claims=True): >+ srealm = target_creds.get_realm() >+ >+ if sname is None: >+ target_name = target_creds.get_username() >+ if target_name == 'krbtgt': >+ sname = self.PrincipalName_create(name_type=NT_SRV_INST, >+ names=[target_name, srealm]) >+ else: >+ if target_name[-1] == '$': >+ target_name = target_name[:-1] >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=['host', target_name]) >+ >+ if additional_ticket is not None: >+ additional_tickets = [additional_ticket.ticket] >+ decryption_key = additional_ticket.session_key >+ else: >+ additional_tickets = None >+ decryption_key = self.TicketDecryptionKey_from_creds( >+ target_creds) >+ >+ subkey = self.RandomKey(tgt.session_key.etype) >+ >+ etypes = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ >+ if expected_error: >+ check_error_fn = self.generic_check_kdc_error >+ check_rep_fn = None >+ else: >+ check_error_fn = None >+ check_rep_fn = self.generic_check_kdc_rep >+ >+ if expected_cname is None: >+ expected_cname = tgt.cname >+ >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=tgt.crealm, >+ expected_cname=expected_cname, >+ expected_srealm=srealm, >+ expected_sname=sname, >+ ticket_decryption_key=decryption_key, >+ generate_padata_fn=generate_padata_fn, >+ check_error_fn=check_error_fn, >+ check_rep_fn=check_rep_fn, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ expected_error_mode=expected_error, >+ tgt=tgt, >+ authenticator_subkey=subkey, >+ kdc_options=kdc_options, >+ expect_edata=False, >+ expect_claims=expect_claims) >+ >+ self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=None, >+ realm=srealm, >+ sname=sname, >+ etypes=etypes, >+ additional_tickets=additional_tickets) >+ > > if __name__ == "__main__": > global_asn1_print = False >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index b643185f767..490cd255ec3 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -72,6 +72,7 @@ KDC_ERR_POLICY = 12 > KDC_ERR_BADOPTION = 13 > KDC_ERR_ETYPE_NOSUPP = 14 > KDC_ERR_SUMTYPE_NOSUPP = 15 >+KDC_ERR_TGT_REVOKED = 20 > KDC_ERR_PREAUTH_FAILED = 24 > KDC_ERR_PREAUTH_REQUIRED = 25 > KDC_ERR_BAD_INTEGRITY = 31 >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 5e0d958ee59..27c2dfe3be3 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -278,3 +278,67 @@ > ^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_rename > ^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_delete > ^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_rename >+# >+# KDC TGT tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_allowed_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_no_krbtgt_link >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_no_partial_secrets >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_allowed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_allowed_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_no_krbtgt_link >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_no_partial_secrets >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_allowed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_krbtgt_link >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_partial_secrets >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_allowed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_host >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_no_host >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_non_existent_sname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_allowed_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_no_krbtgt_link >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_no_partial_secrets >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_not_allowed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_not_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_allowed_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_no_krbtgt_link >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_no_partial_secrets >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_allowed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_nonexisting >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 4441be9d203..84f74e5523e 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -393,3 +393,70 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_rename > ^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_delete > ^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_rename >+# >+# KDC TGT tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_allowed_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_no_krbtgt_link >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_no_partial_secrets >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_allowed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_req >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_allowed_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_no_krbtgt_link >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_no_partial_secrets >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_allowed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_krbtgt_link >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_partial_secrets >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_allowed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_no_host >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_allowed_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_no_krbtgt_link >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_no_partial_secrets >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_not_allowed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_not_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_allowed_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_denied >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_no_krbtgt_link >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_no_partial_secrets >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_allowed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_revealed >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_nonexisting >-- >2.25.1 > > >From 8dec071a44067fd3c6ef54702118af4b4c76b772 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 28 Oct 2021 16:20:07 +1300 >Subject: [PATCH 496/686] CVE-2020-25719 tests/krb5: Add tests for including > authdata without a PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 32 +++++++++++++++++++++++- > python/samba/tests/krb5/raw_testcase.py | 14 +++++++---- > selftest/knownfail_heimdal_kdc | 5 ++++ > selftest/knownfail_mit_kdc | 5 ++++ > 4 files changed, 50 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 74f1032163e..5de79c30e1b 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -485,6 +485,34 @@ class KdcTgsTests(KDCBaseTest): > tgt = self._get_tgt(creds, remove_pac=True) > self._user2user(tgt, creds, expected_error=KDC_ERR_BADOPTION) > >+ # Test making a request with authdata and without a PAC. >+ def test_tgs_authdata_no_pac(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, remove_pac=True, allow_empty_authdata=True) >+ self._run_tgs(tgt, expected_error=KDC_ERR_BADOPTION) >+ >+ def test_renew_authdata_no_pac(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, renewable=True, remove_pac=True, >+ allow_empty_authdata=True) >+ self._renew_tgt(tgt, expected_error=KDC_ERR_BADOPTION) >+ >+ def test_validate_authdata_no_pac(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, invalid=True, remove_pac=True, >+ allow_empty_authdata=True) >+ self._validate_tgt(tgt, expected_error=KDC_ERR_BADOPTION) >+ >+ def test_s4u2self_authdata_no_pac(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, remove_pac=True, allow_empty_authdata=True) >+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_BADOPTION) >+ >+ def test_user2user_authdata_no_pac(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, remove_pac=True, allow_empty_authdata=True) >+ self._user2user(tgt, creds, expected_error=KDC_ERR_BADOPTION) >+ > # Test changing the SID in the PAC to that of another account. > def test_tgs_sid_mismatch_existing(self): > creds = self._get_creds() >@@ -928,7 +956,8 @@ class KdcTgsTests(KDCBaseTest): > invalid=False, > from_rodc=False, > new_rid=None, >- remove_pac=False): >+ remove_pac=False, >+ allow_empty_authdata=False): > self.assertFalse(renewable and invalid) > > if remove_pac: >@@ -1011,6 +1040,7 @@ class KdcTgsTests(KDCBaseTest): > modify_fn=modify_fn, > modify_pac_fn=modify_pac_fn, > exclude_pac=remove_pac, >+ allow_empty_authdata=allow_empty_authdata, > update_pac_checksums=not remove_pac, > checksum_keys=checksum_keys) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 8e55790272a..b5ac393ea67 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3224,6 +3224,7 @@ class RawKerberosTest(TestCaseInTempDir): > modify_fn=None, > modify_pac_fn=None, > exclude_pac=False, >+ allow_empty_authdata=False, > update_pac_checksums=True, > checksum_keys=None, > include_checksums=None): >@@ -3332,8 +3333,10 @@ class RawKerberosTest(TestCaseInTempDir): > > # Replace the PAC in the authorization data and re-add it to the > # ticket enc-part. >- auth_data, _ = self.replace_pac(auth_data, new_pac, >- expect_pac=expect_pac) >+ auth_data, _ = self.replace_pac( >+ auth_data, new_pac, >+ expect_pac=expect_pac, >+ allow_empty_authdata=allow_empty_authdata) > enc_part['authorization-data'] = auth_data > > # Re-encrypt the ticket enc-part with the new key. >@@ -3454,7 +3457,8 @@ class RawKerberosTest(TestCaseInTempDir): > > kdc_checksum_buffer.info.signature = kdc_checksum > >- def replace_pac(self, auth_data, new_pac, expect_pac=True): >+ def replace_pac(self, auth_data, new_pac, expect_pac=True, >+ allow_empty_authdata=False): > if new_pac is not None: > self.assertElementEqual(new_pac, 'ad-type', AD_WIN2K_PAC) > self.assertElementPresent(new_pac, 'ad-data') >@@ -3483,7 +3487,7 @@ class RawKerberosTest(TestCaseInTempDir): > if expect_pac: > self.assertIsNotNone(old_pac, 'Expected PAC') > >- if relevant_elems: >+ if relevant_elems or allow_empty_authdata: > ad_relevant = self.der_encode( > relevant_elems, > asn1Spec=krb5_asn1.AD_IF_RELEVANT()) >@@ -3494,7 +3498,7 @@ class RawKerberosTest(TestCaseInTempDir): > else: > authdata_elem = None > >- if authdata_elem is not None: >+ if authdata_elem is not None or allow_empty_authdata: > new_auth_data.append(authdata_elem) > > if expect_pac: >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 27c2dfe3be3..572fbb0e0cd 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -281,6 +281,7 @@ > # > # KDC TGT tests > # >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_denied >@@ -292,6 +293,7 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_denied >@@ -303,6 +305,7 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_denied >@@ -314,6 +317,7 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_host > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_no_host > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac >@@ -331,6 +335,7 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_denied >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 84f74e5523e..127fcdc425d 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -396,6 +396,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > # > # KDC TGT tests > # >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_denied >@@ -408,6 +409,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_req > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_allowed_denied >@@ -421,6 +423,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_denied >@@ -433,6 +436,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_no_host > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req >@@ -448,6 +452,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_denied >-- >2.25.1 > > >From c08e18c9e6531d93aa0b95fc061cf604f595fa82 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 21 Oct 2021 16:46:56 +1300 >Subject: [PATCH 497/686] CVE-2020-25721 tests/krb5: Add tests for extended > PAC_UPN_DNS_INFO PAC buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14835 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 3 +- > python/samba/tests/krb5/kdc_tgs_tests.py | 51 +++++++++++++++++++++++- > python/samba/tests/krb5/raw_testcase.py | 41 +++++++++++++++++++ > python/samba/tests/krb5/s4u_tests.py | 2 + > selftest/knownfail_heimdal_kdc | 4 ++ > selftest/knownfail_mit_kdc | 4 ++ > 6 files changed, 103 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 4fe7485c492..9be6cbab30b 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1358,7 +1358,7 @@ class KDCBaseTest(RawKerberosTest): > > def get_tgt(self, creds, to_rodc=False, kdc_options=None, > expected_flags=None, unexpected_flags=None, >- expected_account_name=None, >+ expected_account_name=None, expected_upn_name=None, > expected_sid=None, > pac_request=True, expect_pac=True, fresh=False): > user_name = creds.get_username() >@@ -1410,6 +1410,7 @@ class KDCBaseTest(RawKerberosTest): > expected_srealm=realm, > expected_sname=sname, > expected_account_name=expected_account_name, >+ expected_upn_name=expected_upn_name, > expected_sid=expected_sid, > expected_salt=salt, > expected_flags=expected_flags, >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 5de79c30e1b..5313dbc6045 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -227,7 +227,10 @@ class KdcTgsTests(KDCBaseTest): > > def _make_tgs_request(self, client_creds, service_creds, tgt, > pac_request=None, expect_pac=True, >- expect_error=False): >+ expect_error=False, >+ expected_account_name=None, >+ expected_upn_name=None, >+ expected_sid=None): > client_account = client_creds.get_username() > cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, > names=[client_account]) >@@ -268,6 +271,9 @@ class KdcTgsTests(KDCBaseTest): > expected_cname=expected_cname, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_account_name=expected_account_name, >+ expected_upn_name=expected_upn_name, >+ expected_sid=expected_sid, > expected_supported_etypes=expected_supported_etypes, > ticket_decryption_key=target_decryption_key, > check_error_fn=check_error_fn, >@@ -433,6 +439,49 @@ class KdcTgsTests(KDCBaseTest): > self._make_tgs_request(client_creds, service_creds, tgt, > expect_pac=False, expect_error=True) > >+ def test_upn_dns_info_ex_user(self): >+ client_creds = self.get_client_creds() >+ self._run_upn_dns_info_ex_test(client_creds) >+ >+ def test_upn_dns_info_ex_mac(self): >+ mach_creds = self.get_mach_creds() >+ self._run_upn_dns_info_ex_test(mach_creds) >+ >+ def test_upn_dns_info_ex_upn_user(self): >+ client_creds = self.get_cached_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'upn_dns_info_test_upn0@bar'}) >+ self._run_upn_dns_info_ex_test(client_creds) >+ >+ def test_upn_dns_info_ex_upn_mac(self): >+ mach_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'upn_dns_info_test_upn1@bar'}) >+ self._run_upn_dns_info_ex_test(mach_creds) >+ >+ def _run_upn_dns_info_ex_test(self, client_creds): >+ service_creds = self.get_service_creds() >+ >+ samdb = self.get_samdb() >+ dn = client_creds.get_dn() >+ >+ account_name = client_creds.get_username() >+ upn_name = client_creds.get_upn() >+ if upn_name is None: >+ realm = client_creds.get_realm().lower() >+ upn_name = f'{account_name}@{realm}' >+ sid = self.get_objectSid(samdb, dn) >+ >+ tgt = self.get_tgt(client_creds, >+ expected_account_name=account_name, >+ expected_upn_name=upn_name, >+ expected_sid=sid) >+ >+ self._make_tgs_request(client_creds, service_creds, tgt, >+ expected_account_name=account_name, >+ expected_upn_name=upn_name, >+ expected_sid=sid) >+ > # Test making a TGS request. > def test_tgs_req(self): > creds = self._get_creds() >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b5ac393ea67..18ee8738eaa 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1986,6 +1986,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_srealm=None, > expected_sname=None, > expected_account_name=None, >+ expected_upn_name=None, > expected_sid=None, > expected_supported_etypes=None, > expected_flags=None, >@@ -2019,6 +2020,7 @@ class RawKerberosTest(TestCaseInTempDir): > expect_edata=None, > expect_pac=True, > expect_claims=True, >+ expect_upn_dns_info_ex=None, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -2037,6 +2039,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, > 'expected_account_name': expected_account_name, >+ 'expected_upn_name': expected_upn_name, > 'expected_sid': expected_sid, > 'expected_supported_etypes': expected_supported_etypes, > 'expected_flags': expected_flags, >@@ -2070,6 +2073,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expect_edata': expect_edata, > 'expect_pac': expect_pac, > 'expect_claims': expect_claims, >+ 'expect_upn_dns_info_ex': expect_upn_dns_info_ex, > 'to_rodc': to_rodc > } > if callback_dict is None: >@@ -2084,6 +2088,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_srealm=None, > expected_sname=None, > expected_account_name=None, >+ expected_upn_name=None, > expected_sid=None, > expected_supported_etypes=None, > expected_flags=None, >@@ -2116,6 +2121,7 @@ class RawKerberosTest(TestCaseInTempDir): > expect_edata=None, > expect_pac=True, > expect_claims=True, >+ expect_upn_dns_info_ex=None, > expected_proxy_target=None, > expected_transited_services=None, > to_rodc=False): >@@ -2136,6 +2142,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, > 'expected_account_name': expected_account_name, >+ 'expected_upn_name': expected_upn_name, > 'expected_sid': expected_sid, > 'expected_supported_etypes': expected_supported_etypes, > 'expected_flags': expected_flags, >@@ -2168,6 +2175,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expect_edata': expect_edata, > 'expect_pac': expect_pac, > 'expect_claims': expect_claims, >+ 'expect_upn_dns_info_ex': expect_upn_dns_info_ex, > 'expected_proxy_target': expected_proxy_target, > 'expected_transited_services': expected_transited_services, > 'to_rodc': to_rodc >@@ -2584,6 +2592,12 @@ class RawKerberosTest(TestCaseInTempDir): > expected_account_name = kdc_exchange_dict['expected_account_name'] > expected_sid = kdc_exchange_dict['expected_sid'] > >+ expect_upn_dns_info_ex = kdc_exchange_dict['expect_upn_dns_info_ex'] >+ if expect_upn_dns_info_ex is None and ( >+ expected_account_name is not None >+ or expected_sid is not None): >+ expect_upn_dns_info_ex = True >+ > for pac_buffer in pac.buffers: > if pac_buffer.type == krb5pac.PAC_TYPE_CONSTRAINED_DELEGATION: > expected_proxy_target = kdc_exchange_dict[ >@@ -2618,6 +2632,31 @@ class RawKerberosTest(TestCaseInTempDir): > expected_rid = int(expected_sid.rsplit('-', 1)[1]) > self.assertEqual(expected_rid, logon_info.rid) > >+ elif pac_buffer.type == krb5pac.PAC_TYPE_UPN_DNS_INFO: >+ upn_dns_info = pac_buffer.info >+ upn_dns_info_ex = upn_dns_info.ex >+ >+ expected_realm = kdc_exchange_dict['expected_crealm'] >+ self.assertEqual(expected_realm, >+ upn_dns_info.dns_domain_name) >+ >+ expected_upn_name = kdc_exchange_dict['expected_upn_name'] >+ if expected_upn_name is not None: >+ self.assertEqual(expected_upn_name, >+ upn_dns_info.upn_name) >+ >+ if expect_upn_dns_info_ex: >+ self.assertIsNotNone(upn_dns_info_ex) >+ >+ if upn_dns_info_ex is not None: >+ if expected_account_name is not None: >+ self.assertEqual(expected_account_name, >+ upn_dns_info_ex.samaccountname) >+ >+ if expected_sid is not None: >+ self.assertEqual(expected_sid, >+ str(upn_dns_info_ex.objectsid)) >+ > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >@@ -3600,6 +3639,7 @@ class RawKerberosTest(TestCaseInTempDir): > padata, > kdc_options, > expected_account_name=None, >+ expected_upn_name=None, > expected_sid=None, > expected_flags=None, > unexpected_flags=None, >@@ -3634,6 +3674,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_srealm=expected_srealm, > expected_sname=expected_sname, > expected_account_name=expected_account_name, >+ expected_upn_name=expected_upn_name, > expected_sid=expected_sid, > expected_supported_etypes=expected_supported_etypes, > ticket_decryption_key=ticket_decryption_key, >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index a80a7b3427e..5005affd6b3 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -309,6 +309,7 @@ class S4UKerberosTests(KDCBaseTest): > tgt=service_tgt, > authenticator_subkey=authenticator_subkey, > kdc_options=str(kdc_options), >+ expect_upn_dns_info_ex=False, > expect_claims=False) > > self._generic_kdc_exchange(kdc_exchange_dict, >@@ -610,6 +611,7 @@ class S4UKerberosTests(KDCBaseTest): > kdc_options=kdc_options, > pac_options=pac_options, > expect_edata=expect_edata, >+ expect_upn_dns_info_ex=False, > expected_proxy_target=expected_proxy_target, > expected_transited_services=expected_transited_services, > expect_pac=expect_pac) >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 572fbb0e0cd..46866823590 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -317,6 +317,10 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_mac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_mac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_user >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_user > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_host > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_no_host >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 127fcdc425d..d2acc5559ed 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -436,6 +436,10 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_mac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_mac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_user >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_user > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_no_host > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac >-- >2.25.1 > > >From 5b12b4985bbb59f56b62df2f4e44bb78481febb9 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 24 Aug 2021 17:11:24 +0200 >Subject: [PATCH 498/686] CVE-2020-25719 CVE-2020-25717 tests/krb5: Add tests > for connecting to services anonymously and without a PAC > >At the end of the patchset we assume NT_STATUS_NO_IMPERSONATION_TOKEN if >no PAC is available. > >For now we want to look for ACCESS_DENIED as this allows >the test to pass (showing that gensec:require_pac = true >is a useful partial mitigation). > >This will also help others doing backports that do not >take the full patch set. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14799 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/test_ccache.py | 31 +++++++++--- > python/samba/tests/krb5/test_ldap.py | 70 ++++++++++++++++++++++---- > python/samba/tests/krb5/test_rpc.py | 46 ++++++++++++++--- > python/samba/tests/krb5/test_smb.py | 31 +++++++++--- > source4/selftest/tests.py | 17 ++++--- > 5 files changed, 158 insertions(+), 37 deletions(-) > >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >index 040ae5cc9a1..cb5061b92d9 100755 >--- a/python/samba/tests/krb5/test_ccache.py >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -21,10 +21,11 @@ import sys > import os > > from ldb import SCOPE_SUBTREE >-from samba import gensec >+from samba import NTSTATUSError, gensec > from samba.auth import AuthContext > from samba.dcerpc import security > from samba.ndr import ndr_unpack >+from samba.ntstatus import NT_STATUS_ACCESS_DENIED > > from samba.tests.krb5.kdc_base_test import KDCBaseTest > >@@ -41,11 +42,18 @@ class CcacheTests(KDCBaseTest): > """ > > def test_ccache(self): >+ self._run_ccache_test("ccacheusr") >+ >+ def test_ccache_no_pac(self): >+ self._run_ccache_test("ccacheusr_nopac", include_pac=False, >+ expect_anon=True, allow_error=True) >+ >+ def _run_ccache_test(self, user_name, include_pac=True, >+ expect_anon=False, allow_error=False): > # Create a user account and a machine account, along with a Kerberos > # credentials cache file where the service ticket authenticating the > # user are stored. > >- user_name = "ccacheusr" > mach_name = "ccachemac" > service = "host" > >@@ -67,7 +75,10 @@ class CcacheTests(KDCBaseTest): > # ticket, to ensure that the krbtgt ticket doesn't also need to be > # stored. > (creds, cachefile) = self.create_ccache_with_user(user_credentials, >- mach_credentials) >+ mach_credentials, >+ pac=include_pac) >+ # Remove the cached credentials file. >+ self.addCleanup(os.remove, cachefile.name) > > # Authenticate in-process to the machine account using the user's > # cached credentials. >@@ -117,7 +128,16 @@ class CcacheTests(KDCBaseTest): > sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) > > # Retrieve the SIDs from the security token. >- session = gensec_server.session_info() >+ try: >+ session = gensec_server.session_info() >+ except NTSTATUSError as e: >+ if not allow_error: >+ self.fail() >+ >+ enum, _ = e.args >+ self.assertEqual(NT_STATUS_ACCESS_DENIED, enum) >+ return >+ > token = session.security_token > token_sids = token.sids > self.assertGreater(len(token_sids), 0) >@@ -125,9 +145,6 @@ class CcacheTests(KDCBaseTest): > # Ensure that they match. > self.assertEqual(sid, token_sids[0]) > >- # Remove the cached credentials file. >- os.remove(cachefile.name) >- > > if __name__ == "__main__": > global_asn1_print = False >diff --git a/python/samba/tests/krb5/test_ldap.py b/python/samba/tests/krb5/test_ldap.py >index 7d9ffebe298..31e50487338 100755 >--- a/python/samba/tests/krb5/test_ldap.py >+++ b/python/samba/tests/krb5/test_ldap.py >@@ -20,10 +20,11 @@ > import sys > import os > >-from ldb import SCOPE_BASE, SCOPE_SUBTREE >+from ldb import LdbError, ERR_OPERATIONS_ERROR, SCOPE_BASE, SCOPE_SUBTREE > from samba.dcerpc import security > from samba.ndr import ndr_unpack > from samba.samdb import SamDB >+from samba import credentials > > from samba.tests.krb5.kdc_base_test import KDCBaseTest > >@@ -40,13 +41,20 @@ class LdapTests(KDCBaseTest): > """ > > def test_ldap(self): >+ self._run_ldap_test("ldapusr") >+ >+ def test_ldap_no_pac(self): >+ self._run_ldap_test("ldapusr_nopac", include_pac=False, >+ expect_anon=True, allow_error=True) >+ >+ def _run_ldap_test(self, user_name, include_pac=True, >+ expect_anon=False, allow_error=False): > # Create a user account and a machine account, along with a Kerberos > # credentials cache file where the service ticket authenticating the > # user are stored. > > samdb = self.get_samdb() > >- user_name = "ldapusr" > mach_name = samdb.host_dns_name() > service = "ldap" > >@@ -62,7 +70,10 @@ class LdapTests(KDCBaseTest): > (creds, cachefile) = self.create_ccache_with_user(user_credentials, > mach_credentials, > service, >- mach_name) >+ mach_name, >+ pac=include_pac) >+ # Remove the cached credentials file. >+ self.addCleanup(os.remove, cachefile.name) > > # Authenticate in-process to the machine account using the user's > # cached credentials. >@@ -74,22 +85,61 @@ class LdapTests(KDCBaseTest): > self.assertEqual(1, len(ldb_res)) > sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) > >+ # Connect to the machine account and retrieve the user SID. >+ try: >+ ldb_as_user = SamDB(url="ldap://%s" % mach_name, >+ credentials=creds, >+ lp=self.get_lp()) >+ except LdbError as e: >+ if not allow_error: >+ self.fail() >+ >+ enum, estr = e.args >+ self.assertEqual(ERR_OPERATIONS_ERROR, enum) >+ self.assertIn('NT_STATUS_ACCESS_DENIED', estr) >+ return >+ >+ ldb_res = ldb_as_user.search('', >+ scope=SCOPE_BASE, >+ attrs=["tokenGroups"]) >+ self.assertEqual(1, len(ldb_res)) >+ >+ token_groups = ldb_res[0]["tokenGroups"] >+ token_sid = ndr_unpack(security.dom_sid, token_groups[0]) >+ >+ if expect_anon: >+ # Ensure we got an anonymous token. >+ self.assertEqual(security.SID_NT_ANONYMOUS, str(token_sid)) >+ token_sid = ndr_unpack(security.dom_sid, token_groups[1]) >+ self.assertEqual(security.SID_NT_NETWORK, str(token_sid)) >+ if len(token_groups) >= 3: >+ token_sid = ndr_unpack(security.dom_sid, token_groups[2]) >+ self.assertEqual(security.SID_NT_THIS_ORGANISATION, >+ str(token_sid)) >+ else: >+ # Ensure that they match. >+ self.assertEqual(sid, token_sid) >+ >+ def test_ldap_anonymous(self): >+ samdb = self.get_samdb() >+ mach_name = samdb.host_dns_name() >+ >+ anon_creds = credentials.Credentials() >+ anon_creds.set_anonymous() >+ > # Connect to the machine account and retrieve the user SID. > ldb_as_user = SamDB(url="ldap://%s" % mach_name, >- credentials=creds, >+ credentials=anon_creds, > lp=self.get_lp()) > ldb_res = ldb_as_user.search('', > scope=SCOPE_BASE, > attrs=["tokenGroups"]) > self.assertEqual(1, len(ldb_res)) > >+ # Ensure we got an anonymous token. > token_sid = ndr_unpack(security.dom_sid, ldb_res[0]["tokenGroups"][0]) >- >- # Ensure that they match. >- self.assertEqual(sid, token_sid) >- >- # Remove the cached credentials file. >- os.remove(cachefile.name) >+ self.assertEqual(security.SID_NT_ANONYMOUS, str(token_sid)) >+ self.assertEqual(len(ldb_res[0]["tokenGroups"]), 1) > > > if __name__ == "__main__": >diff --git a/python/samba/tests/krb5/test_rpc.py b/python/samba/tests/krb5/test_rpc.py >index ef8dd4dcbf5..54ad7cf0e48 100755 >--- a/python/samba/tests/krb5/test_rpc.py >+++ b/python/samba/tests/krb5/test_rpc.py >@@ -20,7 +20,9 @@ > import sys > import os > >+from samba import NTSTATUSError, credentials > from samba.dcerpc import lsa >+from samba.ntstatus import NT_STATUS_ACCESS_DENIED > > from samba.tests.krb5.kdc_base_test import KDCBaseTest > >@@ -37,13 +39,20 @@ class RpcTests(KDCBaseTest): > """ > > def test_rpc(self): >+ self._run_rpc_test("rpcusr") >+ >+ def test_rpc_no_pac(self): >+ self._run_rpc_test("rpcusr_nopac", include_pac=False, >+ expect_anon=True, allow_error=True) >+ >+ def _run_rpc_test(self, user_name, include_pac=True, >+ expect_anon=False, allow_error=False): > # Create a user account and a machine account, along with a Kerberos > # credentials cache file where the service ticket authenticating the > # user are stored. > > samdb = self.get_samdb() > >- user_name = "rpcusr" > mach_name = samdb.host_dns_name() > service = "cifs" > >@@ -59,20 +68,45 @@ class RpcTests(KDCBaseTest): > (creds, cachefile) = self.create_ccache_with_user(user_credentials, > mach_credentials, > service, >- mach_name) >+ mach_name, >+ pac=include_pac) >+ # Remove the cached credentials file. >+ self.addCleanup(os.remove, cachefile.name) > > # Authenticate in-process to the machine account using the user's > # cached credentials. > > binding_str = "ncacn_np:%s[\\pipe\\lsarpc]" % mach_name >- conn = lsa.lsarpc(binding_str, self.get_lp(), creds) >+ try: >+ conn = lsa.lsarpc(binding_str, self.get_lp(), creds) >+ except NTSTATUSError as e: >+ if not allow_error: >+ self.fail() >+ >+ enum, _ = e.args >+ self.assertEqual(NT_STATUS_ACCESS_DENIED, enum) >+ return > > (account_name, _) = conn.GetUserName(None, None, None) > >- self.assertEqual(user_name, account_name.string) >+ if expect_anon: >+ self.assertNotEqual(user_name, account_name.string) >+ else: >+ self.assertEqual(user_name, account_name.string) > >- # Remove the cached credentials file. >- os.remove(cachefile.name) >+ def test_rpc_anonymous(self): >+ samdb = self.get_samdb() >+ mach_name = samdb.host_dns_name() >+ >+ anon_creds = credentials.Credentials() >+ anon_creds.set_anonymous() >+ >+ binding_str = "ncacn_np:%s[\\pipe\\lsarpc]" % mach_name >+ conn = lsa.lsarpc(binding_str, self.get_lp(), anon_creds) >+ >+ (account_name, _) = conn.GetUserName(None, None, None) >+ >+ self.assertEqual('ANONYMOUS LOGON', account_name.string) > > > if __name__ == "__main__": >diff --git a/python/samba/tests/krb5/test_smb.py b/python/samba/tests/krb5/test_smb.py >index 1e70ed322bf..79ff16ac879 100755 >--- a/python/samba/tests/krb5/test_smb.py >+++ b/python/samba/tests/krb5/test_smb.py >@@ -21,8 +21,10 @@ import sys > import os > > from ldb import SCOPE_SUBTREE >+from samba import NTSTATUSError > from samba.dcerpc import security > from samba.ndr import ndr_unpack >+from samba.ntstatus import NT_STATUS_ACCESS_DENIED > from samba.samba3 import libsmb_samba_internal as libsmb > from samba.samba3 import param as s3param > >@@ -41,13 +43,20 @@ class SmbTests(KDCBaseTest): > """ > > def test_smb(self): >+ self._run_smb_test("smbusr") >+ >+ def test_smb_no_pac(self): >+ self._run_smb_test("smbusr_nopac", include_pac=False, >+ expect_error=True) >+ >+ def _run_smb_test(self, user_name, include_pac=True, >+ expect_error=False): > # Create a user account and a machine account, along with a Kerberos > # credentials cache file where the service ticket authenticating the > # user are stored. > > samdb = self.get_samdb() > >- user_name = "smbusr" > mach_name = samdb.host_dns_name() > service = "cifs" > share = "tmp" >@@ -64,7 +73,10 @@ class SmbTests(KDCBaseTest): > (creds, cachefile) = self.create_ccache_with_user(user_credentials, > mach_credentials, > service, >- mach_name) >+ mach_name, >+ pac=include_pac) >+ # Remove the cached credentials file. >+ self.addCleanup(os.remove, cachefile.name) > > # Set the Kerberos 5 credentials cache environment variable. This is > # required because the codepath that gets run (gse_krb5) looks for it >@@ -95,16 +107,23 @@ class SmbTests(KDCBaseTest): > self.addCleanup(s3_lp.set, "client max protocol", max_protocol) > s3_lp.set("client max protocol", "NT1") > >- conn = libsmb.Conn(mach_name, share, lp=s3_lp, creds=creds) >+ try: >+ conn = libsmb.Conn(mach_name, share, lp=s3_lp, creds=creds) >+ except NTSTATUSError as e: >+ if not expect_error: >+ self.fail() >+ >+ enum, _ = e.args >+ self.assertEqual(NT_STATUS_ACCESS_DENIED, enum) >+ return >+ else: >+ self.assertFalse(expect_error) > > (uid, gid, gids, sids, guest) = conn.posix_whoami() > > # Ensure that they match. > self.assertEqual(sid, sids[0]) > >- # Remove the cached credentials file. >- os.remove(cachefile.name) >- > > if __name__ == "__main__": > global_asn1_print = False >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index ff293dbd580..ce1a42a38ff 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -754,14 +754,15 @@ planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", > 'FAST_SUPPORT': have_fast_support, > 'TKT_SIG_SUPPORT': tkt_sig_support > }) >-planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_rpc", >- environ={ >- 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >- }) >+for env in ['ad_dc_default', 'ad_member']: >+ planoldpythontestsuite(env, "samba.tests.krb5.test_rpc", >+ environ={ >+ 'ADMIN_USERNAME': '$DC_USERNAME', >+ 'ADMIN_PASSWORD': '$DC_PASSWORD', >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support >+ }) > planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >-- >2.25.1 > > >From eb16ab9bbe20301f9bebdaf45ab93cf501efe88f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 22 Oct 2021 16:20:36 +0200 >Subject: [PATCH 499/686] CVE-2020-25719 CVE-2020-25717: selftest: remove > "gensec:require_pac" settings > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14799 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >[jsutton@samba.org Added knownfail entries] > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail.d/no-pac | 4 ++++ > selftest/selftest.pl | 2 -- > selftest/target/Samba4.pm | 2 -- > 3 files changed, 4 insertions(+), 4 deletions(-) > create mode 100644 selftest/knownfail.d/no-pac > >diff --git a/selftest/knownfail.d/no-pac b/selftest/knownfail.d/no-pac >new file mode 100644 >index 00000000000..9723d581c2a >--- /dev/null >+++ b/selftest/knownfail.d/no-pac >@@ -0,0 +1,4 @@ >+^samba.tests.krb5.test_ccache.samba.tests.krb5.test_ccache.CcacheTests.test_ccache_no_pac >+^samba.tests.krb5.test_ldap.samba.tests.krb5.test_ldap.LdapTests.test_ldap_no_pac >+^samba.tests.krb5.test_rpc.samba.tests.krb5.test_rpc.RpcTests.test_rpc_no_pac >+^samba.tests.krb5.test_smb.samba.tests.krb5.test_smb.SmbTests.test_smb_no_pac >diff --git a/selftest/selftest.pl b/selftest/selftest.pl >index f2968139cfd..8c273951ab3 100755 >--- a/selftest/selftest.pl >+++ b/selftest/selftest.pl >@@ -637,8 +637,6 @@ sub write_clientconf($$$) > client lanman auth = Yes > log level = 1 > torture:basedir = $clientdir >-#We don't want to pass our self-tests if the PAC code is wrong >- gensec:require_pac = true > #We don't want to run 'speed' tests for very long > torture:timelimit = 1 > winbind separator = / >diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm >index ae84a3ca89a..1d4de22dee0 100755 >--- a/selftest/target/Samba4.pm >+++ b/selftest/target/Samba4.pm >@@ -777,8 +777,6 @@ sub provision_raw_step1($$) > notify:inotify = false > ldb:nosync = true > ldap server require strong auth = yes >-#We don't want to pass our self-tests if the PAC code is wrong >- gensec:require_pac = true > log file = $ctx->{logdir}/log.\%m > log level = $ctx->{server_loglevel} > lanman auth = Yes >-- >2.25.1 > > >From a7816247f324531df5a58ae1a460dff863f2e010 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 29 Oct 2021 10:27:41 +1300 >Subject: [PATCH 500/686] CVE-2020-25719 CVE-2020-25717 tests/krb5: Adapt tests > for connecting without a PAC to new error codes > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14799 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/test_ccache.py | 5 +++-- > python/samba/tests/krb5/test_ldap.py | 2 +- > python/samba/tests/krb5/test_rpc.py | 4 ++-- > python/samba/tests/krb5/test_smb.py | 4 ++-- > 4 files changed, 8 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >index cb5061b92d9..d21ec84796e 100755 >--- a/python/samba/tests/krb5/test_ccache.py >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -25,7 +25,7 @@ from samba import NTSTATUSError, gensec > from samba.auth import AuthContext > from samba.dcerpc import security > from samba.ndr import ndr_unpack >-from samba.ntstatus import NT_STATUS_ACCESS_DENIED >+from samba.ntstatus import NT_STATUS_NO_IMPERSONATION_TOKEN > > from samba.tests.krb5.kdc_base_test import KDCBaseTest > >@@ -84,6 +84,7 @@ class CcacheTests(KDCBaseTest): > # cached credentials. > > lp = self.get_lp() >+ lp.set('server role', 'active directory domain controller') > > settings = {} > settings["lp_ctx"] = lp >@@ -135,7 +136,7 @@ class CcacheTests(KDCBaseTest): > self.fail() > > enum, _ = e.args >- self.assertEqual(NT_STATUS_ACCESS_DENIED, enum) >+ self.assertEqual(NT_STATUS_NO_IMPERSONATION_TOKEN, enum) > return > > token = session.security_token >diff --git a/python/samba/tests/krb5/test_ldap.py b/python/samba/tests/krb5/test_ldap.py >index 31e50487338..0205bdf6fb7 100755 >--- a/python/samba/tests/krb5/test_ldap.py >+++ b/python/samba/tests/krb5/test_ldap.py >@@ -96,7 +96,7 @@ class LdapTests(KDCBaseTest): > > enum, estr = e.args > self.assertEqual(ERR_OPERATIONS_ERROR, enum) >- self.assertIn('NT_STATUS_ACCESS_DENIED', estr) >+ self.assertIn('NT_STATUS_NO_IMPERSONATION_TOKEN', estr) > return > > ldb_res = ldb_as_user.search('', >diff --git a/python/samba/tests/krb5/test_rpc.py b/python/samba/tests/krb5/test_rpc.py >index 54ad7cf0e48..0f2170a8ded 100755 >--- a/python/samba/tests/krb5/test_rpc.py >+++ b/python/samba/tests/krb5/test_rpc.py >@@ -22,7 +22,7 @@ import os > > from samba import NTSTATUSError, credentials > from samba.dcerpc import lsa >-from samba.ntstatus import NT_STATUS_ACCESS_DENIED >+from samba.ntstatus import NT_STATUS_NO_IMPERSONATION_TOKEN > > from samba.tests.krb5.kdc_base_test import KDCBaseTest > >@@ -84,7 +84,7 @@ class RpcTests(KDCBaseTest): > self.fail() > > enum, _ = e.args >- self.assertEqual(NT_STATUS_ACCESS_DENIED, enum) >+ self.assertEqual(NT_STATUS_NO_IMPERSONATION_TOKEN, enum) > return > > (account_name, _) = conn.GetUserName(None, None, None) >diff --git a/python/samba/tests/krb5/test_smb.py b/python/samba/tests/krb5/test_smb.py >index 79ff16ac879..7408e5dbece 100755 >--- a/python/samba/tests/krb5/test_smb.py >+++ b/python/samba/tests/krb5/test_smb.py >@@ -24,7 +24,7 @@ from ldb import SCOPE_SUBTREE > from samba import NTSTATUSError > from samba.dcerpc import security > from samba.ndr import ndr_unpack >-from samba.ntstatus import NT_STATUS_ACCESS_DENIED >+from samba.ntstatus import NT_STATUS_NO_IMPERSONATION_TOKEN > from samba.samba3 import libsmb_samba_internal as libsmb > from samba.samba3 import param as s3param > >@@ -114,7 +114,7 @@ class SmbTests(KDCBaseTest): > self.fail() > > enum, _ = e.args >- self.assertEqual(NT_STATUS_ACCESS_DENIED, enum) >+ self.assertEqual(NT_STATUS_NO_IMPERSONATION_TOKEN, enum) > return > else: > self.assertFalse(expect_error) >-- >2.25.1 > > >From 0b40662ad40c88e59bfdae4af1cc2cd9db6e721b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 4 Oct 2021 17:29:34 +0200 >Subject: [PATCH 501/686] CVE-2020-25717: s3:winbindd: make sure we default to > r->out.authoritative = true > >We need to make sure that temporary failures don't trigger a fallback >to the local SAM that silently ignores the domain name part for users. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Adapted to remove changes to non-existing calls to > is_allowed_domain() and log_authentication()] >--- > source3/winbindd/winbindd_dual_srv.c | 7 +++++++ > source3/winbindd/winbindd_irpc.c | 7 +++++++ > source3/winbindd/winbindd_pam.c | 13 ++++++++++--- > source3/winbindd/winbindd_pam_auth_crap.c | 9 ++++++++- > source3/winbindd/winbindd_util.c | 7 +++++++ > 5 files changed, 39 insertions(+), 4 deletions(-) > >diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c >index 9f8ff59d914..298ae994d1e 100644 >--- a/source3/winbindd/winbindd_dual_srv.c >+++ b/source3/winbindd/winbindd_dual_srv.c >@@ -934,6 +934,13 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p, > union netr_Validation *validation = NULL; > bool interactive = false; > >+ /* >+ * Make sure we start with authoritative=true, >+ * it will only set to false if we don't know the >+ * domain. >+ */ >+ r->out.authoritative = true; >+ > domain = wb_child_domain(); > if (domain == NULL) { > return NT_STATUS_REQUEST_NOT_ACCEPTED; >diff --git a/source3/winbindd/winbindd_irpc.c b/source3/winbindd/winbindd_irpc.c >index 8cbb0b93086..45615c2dc47 100644 >--- a/source3/winbindd/winbindd_irpc.c >+++ b/source3/winbindd/winbindd_irpc.c >@@ -143,6 +143,13 @@ static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg, > const char *target_domain_name = NULL; > const char *account_name = NULL; > >+ /* >+ * Make sure we start with authoritative=true, >+ * it will only set to false if we don't know the >+ * domain. >+ */ >+ req->out.authoritative = true; >+ > switch (req->in.logon_level) { > case NetlogonInteractiveInformation: > case NetlogonServiceInformation: >diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c >index 35018fbe284..deed81d0a79 100644 >--- a/source3/winbindd/winbindd_pam.c >+++ b/source3/winbindd/winbindd_pam.c >@@ -1703,7 +1703,7 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon( > unsigned char local_nt_response[24]; > fstring name_namespace, name_domain, name_user; > NTSTATUS result; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uint32_t flags = 0; > uint16_t validation_level; > union netr_Validation *validation = NULL; >@@ -2238,6 +2238,13 @@ done: > result = NT_STATUS_NO_LOGON_SERVERS; > } > >+ /* >+ * Here we don't alter >+ * state->response->data.auth.authoritative based >+ * on the servers response >+ * as we don't want a fallback to the local sam >+ * for interactive PAM logons >+ */ > set_auth_errors(state->response, result); > > DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n", >@@ -2420,7 +2427,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, > const char *name_user = NULL; > const char *name_domain = NULL; > const char *workstation; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uint32_t flags = 0; > uint16_t validation_level; > union netr_Validation *validation = NULL; >@@ -2482,7 +2489,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, > &validation_level, > &validation); > if (!NT_STATUS_IS_OK(result)) { >- state->response->data.auth.authoritative = authoritative; > goto done; > } > >@@ -2526,6 +2532,7 @@ done: > } > > set_auth_errors(state->response, result); >+ state->response->data.auth.authoritative = authoritative; > > return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; > } >diff --git a/source3/winbindd/winbindd_pam_auth_crap.c b/source3/winbindd/winbindd_pam_auth_crap.c >index b7912db43df..40cab81b5ea 100644 >--- a/source3/winbindd/winbindd_pam_auth_crap.c >+++ b/source3/winbindd/winbindd_pam_auth_crap.c >@@ -24,6 +24,7 @@ > > struct winbindd_pam_auth_crap_state { > struct winbindd_response *response; >+ bool authoritative; > uint32_t flags; > }; > >@@ -45,7 +46,7 @@ struct tevent_req *winbindd_pam_auth_crap_send( > if (req == NULL) { > return NULL; > } >- >+ state->authoritative = true; > state->flags = request->flags; > > if (state->flags & WBFLAG_PAM_AUTH_PAC) { >@@ -124,6 +125,11 @@ struct tevent_req *winbindd_pam_auth_crap_send( > > domain = find_auth_domain(request->flags, auth_domain); > if (domain == NULL) { >+ /* >+ * We don't know the domain so >+ * we're not authoritative >+ */ >+ state->authoritative = false; > tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); > return tevent_req_post(req, ev); > } >@@ -184,6 +190,7 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req, > > if (tevent_req_is_nterror(req, &status)) { > set_auth_errors(response, status); >+ response->data.auth.authoritative = state->authoritative; > return status; > } > >diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c >index 3245c70bb8e..315eb366a52 100644 >--- a/source3/winbindd/winbindd_util.c >+++ b/source3/winbindd/winbindd_util.c >@@ -2062,6 +2062,13 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain) > > void set_auth_errors(struct winbindd_response *resp, NTSTATUS result) > { >+ /* >+ * Make sure we start with authoritative=true, >+ * it will only set to false if we don't know the >+ * domain. >+ */ >+ resp->data.auth.authoritative = true; >+ > resp->data.auth.nt_status = NT_STATUS_V(result); > fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result)); > >-- >2.25.1 > > >From 2a0191ca36ca53285728120dbfc28acd82978039 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 4 Oct 2021 17:29:34 +0200 >Subject: [PATCH 502/686] CVE-2020-25717: s4:auth/ntlm: make sure > auth_check_password() defaults to r->out.authoritative = true > >We need to make sure that temporary failures don't trigger a fallback >to the local SAM that silently ignores the domain name part for users. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/auth/ntlm/auth.c | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c >index 7cf1be2e1f9..1069a875c30 100644 >--- a/source4/auth/ntlm/auth.c >+++ b/source4/auth/ntlm/auth.c >@@ -169,6 +169,11 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx, > /*TODO: create a new event context here! */ > ev = auth_ctx->event_ctx; > >+ /* >+ * We are authoritative by default >+ */ >+ *pauthoritative = 1; >+ > subreq = auth_check_password_send(mem_ctx, > ev, > auth_ctx, >-- >2.25.1 > > >From b51158e9cc58cfd39320ed6f87543edcd62e5d5b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Oct 2021 17:42:41 +0200 >Subject: [PATCH 503/686] CVE-2020-25717: s4:torture: start with authoritative > = 1 > >This is not strictly needed, but makes it easier to audit >that we don't miss important places. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/torture/rpc/samlogon.c | 4 ++-- > source4/torture/rpc/schannel.c | 2 +- > 2 files changed, 3 insertions(+), 3 deletions(-) > >diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c >index e689dfd5e98..957cb410712 100644 >--- a/source4/torture/rpc/samlogon.c >+++ b/source4/torture/rpc/samlogon.c >@@ -1385,7 +1385,7 @@ static bool test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, > > union netr_LogonLevel logon; > union netr_Validation validation; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uint32_t flags = 0; > > ZERO_STRUCT(logon); >@@ -1498,7 +1498,7 @@ bool test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, > > union netr_LogonLevel logon; > union netr_Validation validation; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > struct dcerpc_binding_handle *b = p->binding_handle; > > ZERO_STRUCT(a); >diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c >index c237c82bbe7..72d0bf28fdd 100644 >--- a/source4/torture/rpc/schannel.c >+++ b/source4/torture/rpc/schannel.c >@@ -50,7 +50,7 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx, > struct netr_NetworkInfo ninfo; > union netr_LogonLevel logon; > union netr_Validation validation; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uint32_t _flags = 0; > DATA_BLOB names_blob, chal, lm_resp, nt_resp; > int i; >-- >2.25.1 > > >From f5d403c53eea6f491429cc2eb2c21c10c99e254b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Oct 2021 17:42:41 +0200 >Subject: [PATCH 504/686] CVE-2020-25717: s4:smb_server: start with > authoritative = 1 > >This is not strictly needed, but makes it easier to audit >that we don't miss important places. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/smb_server/smb/sesssetup.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c >index 13f13934412..5e817eecd4b 100644 >--- a/source4/smb_server/smb/sesssetup.c >+++ b/source4/smb_server/smb/sesssetup.c >@@ -102,7 +102,7 @@ static void sesssetup_old_send(struct tevent_req *subreq) > struct auth_session_info *session_info; > struct smbsrv_session *smb_sess; > NTSTATUS status; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uint32_t flags; > > status = auth_check_password_recv(subreq, req, &user_info_dc, >@@ -243,7 +243,7 @@ static void sesssetup_nt1_send(struct tevent_req *subreq) > struct auth_user_info_dc *user_info_dc = NULL; > struct auth_session_info *session_info; > struct smbsrv_session *smb_sess; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uint32_t flags; > NTSTATUS status; > >-- >2.25.1 > > >From 0351082d6dc69da9c8d85da5bc3b53231847009b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Oct 2021 17:42:41 +0200 >Subject: [PATCH 505/686] CVE-2020-25717: s4:auth_simple: start with > authoritative = 1 > >This is not strictly needed, but makes it easier to audit >that we don't miss important places. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/auth/ntlm/auth_simple.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c >index fcd9050979d..da8f094a838 100644 >--- a/source4/auth/ntlm/auth_simple.c >+++ b/source4/auth/ntlm/auth_simple.c >@@ -150,7 +150,7 @@ static void authenticate_ldap_simple_bind_done(struct tevent_req *subreq) > const struct tsocket_address *local_address = user_info->local_host; > const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE; > struct auth_user_info_dc *user_info_dc = NULL; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uint32_t flags = 0; > NTSTATUS nt_status; > >-- >2.25.1 > > >From 1d1dbe65255e3c31a47879185783b8d400a885d3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Oct 2021 17:42:41 +0200 >Subject: [PATCH 506/686] CVE-2020-25717: s3:ntlm_auth: start with > authoritative = 1 > >This is not strictly needed, but makes it easier to audit >that we don't miss important places. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/utils/ntlm_auth.c | 4 ++-- > source3/utils/ntlm_auth_diagnostics.c | 10 +++++----- > 2 files changed, 7 insertions(+), 7 deletions(-) > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index 36c32e4a3dc..3f70732a837 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -1766,7 +1766,7 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod > TALLOC_FREE(mem_ctx); > > } else { >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > > if (!domain) { > domain = smb_xstrdup(get_winbind_domain()); >@@ -2235,7 +2235,7 @@ static bool check_auth_crap(void) > char *hex_lm_key; > char *hex_user_session_key; > char *error_string; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > > setbuf(stdout, NULL); > >diff --git a/source3/utils/ntlm_auth_diagnostics.c b/source3/utils/ntlm_auth_diagnostics.c >index 41591a8de33..fc0fc19bacb 100644 >--- a/source3/utils/ntlm_auth_diagnostics.c >+++ b/source3/utils/ntlm_auth_diagnostics.c >@@ -54,7 +54,7 @@ static bool test_lm_ntlm_broken(enum ntlm_break break_which) > DATA_BLOB lm_response = data_blob(NULL, 24); > DATA_BLOB nt_response = data_blob(NULL, 24); > DATA_BLOB session_key = data_blob(NULL, 16); >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uchar lm_key[8]; > uchar user_session_key[16]; > uchar lm_hash[16]; >@@ -177,7 +177,7 @@ static bool test_ntlm_in_lm(void) > NTSTATUS nt_status; > uint32_t flags = 0; > DATA_BLOB nt_response = data_blob(NULL, 24); >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uchar lm_key[8]; > uchar lm_hash[16]; > uchar user_session_key[16]; >@@ -245,7 +245,7 @@ static bool test_ntlm_in_both(void) > uint32_t flags = 0; > DATA_BLOB nt_response = data_blob(NULL, 24); > DATA_BLOB session_key = data_blob(NULL, 16); >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uint8_t lm_key[8]; > uint8_t lm_hash[16]; > uint8_t user_session_key[16]; >@@ -322,7 +322,7 @@ static bool test_lmv2_ntlmv2_broken(enum ntlm_break break_which) > DATA_BLOB lmv2_response = data_blob_null; > DATA_BLOB ntlmv2_session_key = data_blob_null; > DATA_BLOB names_blob = NTLMv2_generate_names_blob(NULL, get_winbind_netbios_name(), get_winbind_domain()); >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uchar user_session_key[16]; > DATA_BLOB chall = get_challenge(); > char *error_string; >@@ -452,7 +452,7 @@ static bool test_plaintext(enum ntlm_break break_which) > char *password; > smb_ucs2_t *nt_response_ucs2; > size_t converted_size; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uchar user_session_key[16]; > uchar lm_key[16]; > static const uchar zeros[8] = { 0, }; >-- >2.25.1 > > >From 6081970b334ac00b14dc34d4e6c23b2dacac0349 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Oct 2021 17:42:41 +0200 >Subject: [PATCH 507/686] CVE-2020-25717: s3:torture: start with authoritative > = 1 > >This is not strictly needed, but makes it easier to audit >that we don't miss important places. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Adapted to fix conflicts] >--- > source3/torture/pdbtest.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c >index 64bc45e6a7c..48190e78bf8 100644 >--- a/source3/torture/pdbtest.c >+++ b/source3/torture/pdbtest.c >@@ -277,7 +277,7 @@ static bool test_auth(TALLOC_CTX *mem_ctx, struct samu *pdb_entry) > struct netr_SamInfo6 *info6_wbc = NULL; > NTSTATUS status; > bool ok; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > > SMBOWFencrypt(pdb_get_nt_passwd(pdb_entry), challenge_8, > local_nt_response); >-- >2.25.1 > > >From eb0f79dbbc69659afe18b207f98a2abcca93cbdc Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Oct 2021 17:42:41 +0200 >Subject: [PATCH 508/686] CVE-2020-25717: s3:rpcclient: start with > authoritative = 1 > >This is not strictly needed, but makes it easier to audit >that we don't miss important places. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/rpcclient/cmd_netlogon.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c >index 631740562c6..30fa1ed7816 100644 >--- a/source3/rpcclient/cmd_netlogon.c >+++ b/source3/rpcclient/cmd_netlogon.c >@@ -496,7 +496,7 @@ static NTSTATUS cmd_netlogon_sam_logon(struct rpc_pipe_client *cli, > uint32_t logon_param = 0; > const char *workstation = NULL; > struct netr_SamInfo3 *info3 = NULL; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > uint32_t flags = 0; > uint16_t validation_level; > union netr_Validation *validation = NULL; >-- >2.25.1 > > >From b22c2383fa0f55bffd46a80213c29c3a06dd5c2c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Oct 2021 17:42:41 +0200 >Subject: [PATCH 509/686] CVE-2020-25717: s3:auth: start with authoritative = 1 > >This is not strictly needed, but makes it easier to audit >that we don't miss important places. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Adapted to fix conflicts] >--- > source3/auth/auth_generic.c | 2 +- > source3/auth/auth_samba4.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c >index ec397377ae5..d678961c4b8 100644 >--- a/source3/auth/auth_generic.c >+++ b/source3/auth/auth_generic.c >@@ -415,7 +415,7 @@ NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context, > { > NTSTATUS nt_status; > void *server_info; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > > if (auth_context->check_ntlm_password_send != NULL) { > struct tevent_context *ev = NULL; >diff --git a/source3/auth/auth_samba4.c b/source3/auth/auth_samba4.c >index 02013698cbd..0c7c77d9742 100644 >--- a/source3/auth/auth_samba4.c >+++ b/source3/auth/auth_samba4.c >@@ -119,7 +119,7 @@ static NTSTATUS check_samba4_security( > NTSTATUS nt_status; > struct auth_user_info_dc *user_info_dc; > struct auth4_context *auth4_context; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > struct auth_serversupplied_info *server_info = NULL; > > nt_status = make_auth4_context_s4(auth_context, mem_ctx, &auth4_context); >-- >2.25.1 > > >From 6f1f16d76e6b81f184317da9a1b51b45c4b2bf22 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Oct 2021 17:42:41 +0200 >Subject: [PATCH 510/686] CVE-2020-25717: auth/ntlmssp: start with > authoritative = 1 > >This is not strictly needed, but makes it easier to audit >that we don't miss important places. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > auth/ntlmssp/ntlmssp_server.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c >index 140e89daeb1..eebada670be 100644 >--- a/auth/ntlmssp/ntlmssp_server.c >+++ b/auth/ntlmssp/ntlmssp_server.c >@@ -830,7 +830,7 @@ static void ntlmssp_server_auth_done(struct tevent_req *subreq) > struct gensec_security *gensec_security = state->gensec_security; > struct gensec_ntlmssp_context *gensec_ntlmssp = state->gensec_ntlmssp; > struct auth4_context *auth_context = gensec_security->auth_context; >- uint8_t authoritative = 0; >+ uint8_t authoritative = 1; > NTSTATUS status; > > status = auth_context->check_ntlm_password_recv(subreq, >-- >2.25.1 > > >From ec4af25b00b0265e1cb1634434b4e90374e767ee Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <scabrero@samba.org> >Date: Tue, 28 Sep 2021 10:43:40 +0200 >Subject: [PATCH 511/686] CVE-2020-25717: loadparm: Add new parameter "min > domain uid" > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Samuel Cabrero <scabrero@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> > >[abartlet@samba.org Backported from master/4.15 due to > conflicts with other new parameters] >--- > docs-xml/smbdotconf/security/mindomainuid.xml | 17 +++++++++++++++++ > docs-xml/smbdotconf/winbind/idmapconfig.xml | 4 ++++ > lib/param/loadparm.c | 4 ++++ > source3/param/loadparm.c | 2 ++ > 4 files changed, 27 insertions(+) > create mode 100644 docs-xml/smbdotconf/security/mindomainuid.xml > >diff --git a/docs-xml/smbdotconf/security/mindomainuid.xml b/docs-xml/smbdotconf/security/mindomainuid.xml >new file mode 100644 >index 00000000000..46ae795d730 >--- /dev/null >+++ b/docs-xml/smbdotconf/security/mindomainuid.xml >@@ -0,0 +1,17 @@ >+<samba:parameter name="min domain uid" >+ type="integer" >+ context="G" >+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> >+<description> >+ <para> >+ The integer parameter specifies the minimum uid allowed when mapping a >+ local account to a domain account. >+ </para> >+ >+ <para> >+ Note that this option interacts with the configured <emphasis>idmap ranges</emphasis>! >+ </para> >+</description> >+ >+<value type="default">1000</value> >+</samba:parameter> >diff --git a/docs-xml/smbdotconf/winbind/idmapconfig.xml b/docs-xml/smbdotconf/winbind/idmapconfig.xml >index 1374040fb29..f70f11df757 100644 >--- a/docs-xml/smbdotconf/winbind/idmapconfig.xml >+++ b/docs-xml/smbdotconf/winbind/idmapconfig.xml >@@ -80,6 +80,9 @@ > authoritative for a unix ID to SID mapping, so it must be set > for each individually configured domain and for the default > configuration. The configured ranges must be mutually disjoint. >+ </para> >+ <para> >+ Note that the low value interacts with the <smbconfoption name="min domain uid"/> option! > </para></listitem> > </varlistentry> > >@@ -115,4 +118,5 @@ > </programlisting> > > </description> >+<related>min domain uid</related> > </samba:parameter> >diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c >index 4c3dfff24f3..4aa91f4d404 100644 >--- a/lib/param/loadparm.c >+++ b/lib/param/loadparm.c >@@ -3015,6 +3015,10 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) > lpcfg_do_global_parameter( > lp_ctx, "ldap max search request size", "256000"); > >+ lpcfg_do_global_parameter(lp_ctx, >+ "min domain uid", >+ "1000"); >+ > for (i = 0; parm_table[i].label; i++) { > if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) { > lp_ctx->flags[i] |= FLAG_DEFAULT; >diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c >index 0db44e92d19..57d1d909099 100644 >--- a/source3/param/loadparm.c >+++ b/source3/param/loadparm.c >@@ -963,6 +963,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) > Globals.ldap_max_authenticated_request_size = 16777216; > Globals.ldap_max_search_request_size = 256000; > >+ Globals.min_domain_uid = 1000; >+ > /* Now put back the settings that were set with lp_set_cmdline() */ > apply_lp_set_cmdline(); > } >-- >2.25.1 > > >From 90a25fd8efbd6eaea3f3d010fe791fe69d642b4c Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <scabrero@samba.org> >Date: Tue, 5 Oct 2021 16:56:06 +0200 >Subject: [PATCH 512/686] CVE-2020-25717: selftest: Add a test for the new 'min > domain uid' parameter > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Samuel Cabrero <scabrero@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org Fixed knowfail per instruction from metze] >--- > .../samba/tests/krb5/test_min_domain_uid.py | 121 ++++++++++++++++++ > python/samba/tests/usage.py | 1 + > selftest/knownfail.d/min_domain_uid | 1 + > source4/selftest/tests.py | 7 + > 4 files changed, 130 insertions(+) > create mode 100755 python/samba/tests/krb5/test_min_domain_uid.py > create mode 100644 selftest/knownfail.d/min_domain_uid > >diff --git a/python/samba/tests/krb5/test_min_domain_uid.py b/python/samba/tests/krb5/test_min_domain_uid.py >new file mode 100755 >index 00000000000..77414b239f0 >--- /dev/null >+++ b/python/samba/tests/krb5/test_min_domain_uid.py >@@ -0,0 +1,121 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Samuel Cabrero 2021 >+# >+# 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 <http://www.gnu.org/licenses/>. >+# >+ >+import sys >+import os >+import pwd >+import ctypes >+ >+from samba.tests import env_get_var_value >+from samba.samba3 import libsmb_samba_internal as libsmb >+from samba.samba3 import param as s3param >+from samba import NTSTATUSError, ntstatus >+ >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+from samba.credentials import MUST_USE_KERBEROS, DONT_USE_KERBEROS >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+class SmbMinDomainUid(KDCBaseTest): >+ """Test for SMB authorization without NSS winbind. In such setup domain >+ accounts are mapped to local accounts using the 'username map' option. >+ """ >+ >+ def setUp(self): >+ super(KDCBaseTest, self).setUp() >+ >+ # Create a user account, along with a Kerberos credentials cache file >+ # where the service ticket authenticating the user are stored. >+ self.samdb = self.get_samdb() >+ >+ self.mach_name = env_get_var_value('SERVER') >+ self.user_name = "root" >+ self.service = "cifs" >+ self.share = "tmp" >+ >+ # Create the user account. >+ (self.user_creds, _) = self.create_account(self.samdb, self.user_name) >+ >+ # Build the global inject file path >+ server_conf = env_get_var_value('SMB_CONF_PATH') >+ server_conf_dir = os.path.dirname(server_conf) >+ self.global_inject = os.path.join(server_conf_dir, "global_inject.conf") >+ >+ def _test_min_uid(self, creds): >+ # Assert unix root uid is less than 'idmap config ADDOMAIN' minimum >+ s3_lp = s3param.get_context() >+ s3_lp.load(self.get_lp().configfile) >+ >+ domain_range = s3_lp.get("idmap config * : range").split('-') >+ domain_range_low = int(domain_range[0]) >+ unix_root_pw = pwd.getpwnam(self.user_name) >+ self.assertLess(unix_root_pw.pw_uid, domain_range_low) >+ self.assertLess(unix_root_pw.pw_gid, domain_range_low) >+ >+ conn = libsmb.Conn(self.mach_name, self.share, lp=s3_lp, creds=creds) >+ # Disconnect >+ conn = None >+ >+ # Restrict access to local root account uid >+ with open(self.global_inject, 'w') as f: >+ f.write("min domain uid = %s\n" % (unix_root_pw.pw_uid + 1)) >+ >+ with self.assertRaises(NTSTATUSError) as cm: >+ conn = libsmb.Conn(self.mach_name, >+ self.share, >+ lp=s3_lp, >+ creds=creds) >+ code = ctypes.c_uint32(cm.exception.args[0]).value >+ self.assertEqual(code, ntstatus.NT_STATUS_INVALID_TOKEN) >+ >+ # check that the local root account uid is now allowed >+ with open(self.global_inject, 'w') as f: >+ f.write("min domain uid = %s\n" % unix_root_pw.pw_uid) >+ >+ conn = libsmb.Conn(self.mach_name, self.share, lp=s3_lp, creds=creds) >+ # Disconnect >+ conn = None >+ >+ with open(self.global_inject, 'w') as f: >+ f.truncate() >+ >+ def test_min_domain_uid_krb5(self): >+ krb5_state = self.user_creds.get_kerberos_state() >+ self.user_creds.set_kerberos_state(MUST_USE_KERBEROS) >+ ret = self._test_min_uid(self.user_creds) >+ self.user_creds.set_kerberos_state(krb5_state) >+ return ret >+ >+ def test_min_domain_uid_ntlmssp(self): >+ krb5_state = self.user_creds.get_kerberos_state() >+ self.user_creds.set_kerberos_state(DONT_USE_KERBEROS) >+ ret = self._test_min_uid(self.user_creds) >+ self.user_creds.set_kerberos_state(krb5_state) >+ return ret >+ >+ def tearDown(self): >+ # Ensure no leftovers in global inject file >+ with open(self.global_inject, 'w') as f: >+ f.truncate() >+ >+ super(KDCBaseTest, self).tearDown() >+ >+if __name__ == "__main__": >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index d15e67ba617..d94186ba406 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -104,6 +104,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/salt_tests.py', > 'python/samba/tests/krb5/spn_tests.py', > 'python/samba/tests/krb5/alias_tests.py', >+ 'python/samba/tests/krb5/test_min_domain_uid.py', > } > > >diff --git a/selftest/knownfail.d/min_domain_uid b/selftest/knownfail.d/min_domain_uid >new file mode 100644 >index 00000000000..00bf75cd8af >--- /dev/null >+++ b/selftest/knownfail.d/min_domain_uid >@@ -0,0 +1 @@ >+^samba.tests.krb5.test_min_domain_uid.samba.*.SmbMinDomainUid.test_min_domain_uid_.*\(ad_member_no_nss_wb:local\) >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index ce1a42a38ff..c4e5987f09b 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -771,6 +771,13 @@ planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", > 'FAST_SUPPORT': have_fast_support, > 'TKT_SIG_SUPPORT': tkt_sig_support > }) >+planoldpythontestsuite("ad_member_no_nss_wb:local", >+ "samba.tests.krb5.test_min_domain_uid", >+ environ={ >+ 'ADMIN_USERNAME': '$DC_USERNAME', >+ 'ADMIN_PASSWORD': '$DC_PASSWORD', >+ 'STRICT_CHECKING': '0' >+ }) > > for env in ["ad_dc", smbv1_disabled_testenv]: > planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) >-- >2.25.1 > > >From 6ba330d4963e3f539e60ed234930ef0d2674c2be Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 8 Oct 2021 19:57:18 +0200 >Subject: [PATCH 513/686] CVE-2020-25717: s3:auth: let > auth3_generate_session_info_pac() forward the low level errors > >Mapping everything to ACCESS_DENIED makes it hard to debug problems, >which may happen because of our more restrictive behaviour in future. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/auth/auth_generic.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c >index d678961c4b8..9f8e81b82ab 100644 >--- a/source3/auth/auth_generic.c >+++ b/source3/auth/auth_generic.c >@@ -166,7 +166,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > if (!NT_STATUS_IS_OK(status)) { > DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n", > nt_errstr(status))); >- status = NT_STATUS_ACCESS_DENIED; >+ status = nt_status_squash(status); > goto done; > } > >-- >2.25.1 > > >From 7bf6b894d11f4fb105635a3e30dbf25e425e92a6 Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <scabrero@samba.org> >Date: Tue, 28 Sep 2021 10:45:11 +0200 >Subject: [PATCH 514/686] CVE-2020-25717: s3:auth: Check minimum domain uid > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Samuel Cabrero <scabrero@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org Removed knownfail on advice from metze] >--- > selftest/knownfail.d/min_domain_uid | 1 - > source3/auth/auth_util.c | 16 ++++++++++++++++ > 2 files changed, 16 insertions(+), 1 deletion(-) > delete mode 100644 selftest/knownfail.d/min_domain_uid > >diff --git a/selftest/knownfail.d/min_domain_uid b/selftest/knownfail.d/min_domain_uid >deleted file mode 100644 >index 00bf75cd8af..00000000000 >--- a/selftest/knownfail.d/min_domain_uid >+++ /dev/null >@@ -1 +0,0 @@ >-^samba.tests.krb5.test_min_domain_uid.samba.*.SmbMinDomainUid.test_min_domain_uid_.*\(ad_member_no_nss_wb:local\) >diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c >index 8ff20c33759..8801d3f0f0b 100644 >--- a/source3/auth/auth_util.c >+++ b/source3/auth/auth_util.c >@@ -2078,6 +2078,22 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, > } > } > goto out; >+ } else if ((lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) && >+ !is_myname(domain) && pwd->pw_uid < lp_min_domain_uid()) { >+ /* >+ * !is_myname(domain) because when smbd starts tries to setup >+ * the guest user info, calling this function with nobody >+ * username. Nobody is usually uid 65535 but it can be changed >+ * to a regular user with 'guest account' parameter >+ */ >+ nt_status = NT_STATUS_INVALID_TOKEN; >+ DBG_NOTICE("Username '%s%s%s' is invalid on this system, " >+ "it does not meet 'min domain uid' " >+ "restriction (%u < %u): %s\n", >+ nt_domain, lp_winbind_separator(), nt_username, >+ pwd->pw_uid, lp_min_domain_uid(), >+ nt_errstr(nt_status)); >+ goto out; > } > > result = make_server_info(tmp_ctx); >-- >2.25.1 > > >From 04cbbb67ca72ec1795e847837992a483d25bcebd Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 8 Oct 2021 17:40:30 +0200 >Subject: [PATCH 515/686] CVE-2020-25717: s3:auth: we should not try to > autocreate the guest account > >We should avoid autocreation of users as much as possible. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/auth/user_krb5.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c >index 8998f9c8f8a..074e8c7eb71 100644 >--- a/source3/auth/user_krb5.c >+++ b/source3/auth/user_krb5.c >@@ -155,7 +155,7 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, > if (!fuser) { > return NT_STATUS_NO_MEMORY; > } >- pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true); >+ pw = smb_getpwnam(mem_ctx, fuser, &unixuser, false); > } > > /* extra sanity check that the guest account is valid */ >-- >2.25.1 > > >From 76db20e494d25e628b69cc5ae41ebc7b50d49141 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 8 Oct 2021 18:08:20 +0200 >Subject: [PATCH 516/686] CVE-2020-25717: s3:auth: no longer let > check_account() autocreate local users > >So far we autocreated local user accounts based on just the >account_name (just ignoring any domain part). > >This only happens via a possible 'add user script', >which is not typically defined on domain members >and on NT4 DCs local users already exist in the >local passdb anyway. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/auth/auth_util.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c >index 8801d3f0f0b..6ee500493e6 100644 >--- a/source3/auth/auth_util.c >+++ b/source3/auth/auth_util.c >@@ -1873,7 +1873,7 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain, > return NT_STATUS_NO_MEMORY; > } > >- passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true ); >+ passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false); > if (!passwd) { > DEBUG(3, ("Failed to find authenticated user %s via " > "getpwnam(), denying access.\n", dom_user)); >-- >2.25.1 > > >From d5bc9837d845ad9dace8b372884c0a5fdf61ad60 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 8 Oct 2021 12:33:16 +0200 >Subject: [PATCH 517/686] CVE-2020-25717: s3:auth: remove fallbacks in > smb_getpwnam() > >So far we tried getpwnam("DOMAIN\account") first and >always did a fallback to getpwnam("account") completely >ignoring the domain part, this just causes problems >as we mix "DOMAIN1\account", "DOMAIN2\account", >and "account"! > >As we require a running winbindd for domain member setups >we should no longer do a fallback to just "account" for >users served by winbindd! > >For users of the local SAM don't use this code path, >as check_sam_security() doesn't call check_account(). > >The only case where smb_getpwnam("account") happens is >when map_username() via ("username map [script]") mapped >"DOMAIN\account" to something without '\', but that is >explicitly desired by the admin. > >Note: use 'git show -w' > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Ralph Boehme <slow@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Adapted knownfails to use old command line options > prior to e4474ac0a540c56548b4d15e38f2e234455e19b6] >--- > selftest/knownfail.d/ktest | 26 +++++++++++++ > source3/auth/auth_util.c | 77 +++++++++++++++++++++----------------- > 2 files changed, 68 insertions(+), 35 deletions(-) > create mode 100644 selftest/knownfail.d/ktest > >diff --git a/selftest/knownfail.d/ktest b/selftest/knownfail.d/ktest >new file mode 100644 >index 00000000000..13a45fa743e >--- /dev/null >+++ b/selftest/knownfail.d/ktest >@@ -0,0 +1,26 @@ >+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest >+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest >+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5...rpcclient.ktest:local >+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5...rpcclient.ktest:local >+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest >+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest >+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest >+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest >+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,packet...rpcclient.ktest:local >+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,packet...rpcclient.ktest:local >+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest >+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest >+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,sign...rpcclient.ktest:local >+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,sign...rpcclient.ktest:local >+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest >+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest >+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,seal...rpcclient.ktest:local >+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,seal...rpcclient.ktest:local >+^samba3.blackbox.smbclient_krb5.old.ccache..smbclient.ktest:local >+^samba3.blackbox.smbclient_krb5.new.ccache..smbclient.ktest:local >+^samba3.blackbox.smbclient_large_file..krb5.smbclient.large.posix.write.read.ktest:local >+^samba3.blackbox.smbclient_large_file..krb5.cmp.of.read.and.written.files.ktest:local >+^samba3.blackbox.smbclient_krb5.old.ccache.-e.smbclient.ktest:local >+^samba3.blackbox.smbclient_krb5.new.ccache.-e.smbclient.ktest:local >+^samba3.blackbox.smbclient_large_file.-e.krb5.smbclient.large.posix.write.read.ktest:local >+^samba3.blackbox.smbclient_large_file.-e.krb5.cmp.of.read.and.written.files.ktest:local >diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c >index 6ee500493e6..161e05c2106 100644 >--- a/source3/auth/auth_util.c >+++ b/source3/auth/auth_util.c >@@ -1908,7 +1908,7 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser, > { > struct passwd *pw = NULL; > char *p = NULL; >- char *username = NULL; >+ const char *username = NULL; > > /* we only save a copy of the username it has been mangled > by winbindd use default domain */ >@@ -1927,48 +1927,55 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser, > /* code for a DOMAIN\user string */ > > if ( p ) { >- pw = Get_Pwnam_alloc( mem_ctx, domuser ); >- if ( pw ) { >- /* make sure we get the case of the username correct */ >- /* work around 'winbind use default domain = yes' */ >- >- if ( lp_winbind_use_default_domain() && >- !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) { >- char *domain; >- >- /* split the domain and username into 2 strings */ >- *p = '\0'; >- domain = username; >- >- *p_save_username = talloc_asprintf(mem_ctx, >- "%s%c%s", >- domain, >- *lp_winbind_separator(), >- pw->pw_name); >- if (!*p_save_username) { >- TALLOC_FREE(pw); >- return NULL; >- } >- } else { >- *p_save_username = talloc_strdup(mem_ctx, pw->pw_name); >- } >+ const char *domain = NULL; > >- /* whew -- done! */ >- return pw; >+ /* split the domain and username into 2 strings */ >+ *p = '\0'; >+ domain = username; >+ p++; >+ username = p; >+ >+ if (strequal(domain, get_global_sam_name())) { >+ /* >+ * This typically don't happen >+ * as check_sam_Security() >+ * don't call make_server_info_info3() >+ * and thus check_account(). >+ * >+ * But we better keep this. >+ */ >+ goto username_only; > } > >- /* setup for lookup of just the username */ >- /* remember that p and username are overlapping memory */ >- >- p++; >- username = talloc_strdup(mem_ctx, p); >- if (!username) { >+ pw = Get_Pwnam_alloc( mem_ctx, domuser ); >+ if (pw == NULL) { > return NULL; > } >+ /* make sure we get the case of the username correct */ >+ /* work around 'winbind use default domain = yes' */ >+ >+ if ( lp_winbind_use_default_domain() && >+ !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) { >+ *p_save_username = talloc_asprintf(mem_ctx, >+ "%s%c%s", >+ domain, >+ *lp_winbind_separator(), >+ pw->pw_name); >+ if (!*p_save_username) { >+ TALLOC_FREE(pw); >+ return NULL; >+ } >+ } else { >+ *p_save_username = talloc_strdup(mem_ctx, pw->pw_name); >+ } >+ >+ /* whew -- done! */ >+ return pw; >+ > } > > /* just lookup a plain username */ >- >+username_only: > pw = Get_Pwnam_alloc(mem_ctx, username); > > /* Create local user if requested but only if winbindd >-- >2.25.1 > > >From 2d9eaf7c19f7ec990ed97e0d2a63f328ac5addf2 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 4 Oct 2021 18:03:55 +0200 >Subject: [PATCH 518/686] CVE-2020-25717: s3:auth: don't let create_local_token > depend on !winbind_ping() > >We always require a running winbindd on a domain member, so >we should better fail a request instead of silently alter >the behaviour, which results in a different unix token, just >because winbindd might be restarted. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/auth/auth_util.c | 10 ++++------ > 1 file changed, 4 insertions(+), 6 deletions(-) > >diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c >index 161e05c2106..c0e5cfd7fa8 100644 >--- a/source3/auth/auth_util.c >+++ b/source3/auth/auth_util.c >@@ -551,13 +551,11 @@ NTSTATUS create_local_token(TALLOC_CTX *mem_ctx, > } > > /* >- * If winbind is not around, we can not make much use of the SIDs the >- * domain controller provided us with. Likewise if the user name was >- * mapped to some local unix user. >+ * If the user name was mapped to some local unix user, >+ * we can not make much use of the SIDs the >+ * domain controller provided us with. > */ >- >- if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) || >- (server_info->nss_token)) { >+ if (server_info->nss_token) { > char *found_username = NULL; > status = create_token_from_username(session_info, > server_info->unix_name, >-- >2.25.1 > > >From 9d3c1a34d4f101f16222284cd435d691708832ec Mon Sep 17 00:00:00 2001 >From: Alexander Bokovoy <ab@samba.org> >Date: Wed, 11 Nov 2020 18:50:45 +0200 >Subject: [PATCH 519/686] CVE-2020-25717: Add FreeIPA domain controller role > >As we want to reduce use of 'classic domain controller' role but FreeIPA >relies on it internally, add a separate role to mark FreeIPA domain >controller role. > >It means that role won't result in ROLE_STANDALONE. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Alexander Bokovoy <ab@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > docs-xml/smbdotconf/security/serverrole.xml | 7 ++++ > lib/param/loadparm_server_role.c | 2 ++ > lib/param/param_table.c | 1 + > lib/param/util.c | 1 + > libcli/netlogon/netlogon.c | 2 +- > libds/common/roles.h | 1 + > source3/auth/auth.c | 3 ++ > source3/auth/auth_sam.c | 14 ++++---- > source3/include/smb_macros.h | 2 +- > source3/lib/netapi/joindomain.c | 1 + > source3/param/loadparm.c | 4 ++- > source3/passdb/lookup_sid.c | 2 +- > source3/passdb/machine_account_secrets.c | 7 ++-- > source3/registry/reg_backend_prod_options.c | 1 + > source3/rpc_server/dssetup/srv_dssetup_nt.c | 1 + > source3/smbd/server.c | 2 +- > source3/winbindd/winbindd_misc.c | 2 +- > source3/winbindd/winbindd_util.c | 40 ++++++++++++++++----- > source4/auth/ntlm/auth.c | 1 + > source4/kdc/kdc-heimdal.c | 1 + > source4/rpc_server/samr/dcesrv_samr.c | 2 ++ > 21 files changed, 72 insertions(+), 25 deletions(-) > >diff --git a/docs-xml/smbdotconf/security/serverrole.xml b/docs-xml/smbdotconf/security/serverrole.xml >index 9511c61c96d..b8b83a127b5 100644 >--- a/docs-xml/smbdotconf/security/serverrole.xml >+++ b/docs-xml/smbdotconf/security/serverrole.xml >@@ -78,6 +78,13 @@ > url="http://wiki.samba.org/index.php/Samba4/HOWTO">Samba4 > HOWTO</ulink></para> > >+ <para><anchor id="IPA-DC"/><emphasis>SERVER ROLE = IPA DOMAIN CONTROLLER</emphasis></para> >+ >+ <para>This mode of operation runs Samba in a hybrid mode for IPA >+ domain controller, providing forest trust to Active Directory. >+ This role requires special configuration performed by IPA installers >+ and should not be used manually by any administrator. >+ </para> > </description> > > <related>security</related> >diff --git a/lib/param/loadparm_server_role.c b/lib/param/loadparm_server_role.c >index 7a6bc770723..a78d1ab9cf3 100644 >--- a/lib/param/loadparm_server_role.c >+++ b/lib/param/loadparm_server_role.c >@@ -42,6 +42,7 @@ static const struct srv_role_tab { > { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" }, > { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" }, > { ROLE_ACTIVE_DIRECTORY_DC, "ROLE_ACTIVE_DIRECTORY_DC" }, >+ { ROLE_IPA_DC, "ROLE_IPA_DC"}, > { 0, NULL } > }; > >@@ -140,6 +141,7 @@ bool lp_is_security_and_server_role_valid(int server_role, int security) > case ROLE_DOMAIN_PDC: > case ROLE_DOMAIN_BDC: > case ROLE_ACTIVE_DIRECTORY_DC: >+ case ROLE_IPA_DC: > if (security == SEC_USER) { > valid = true; > } >diff --git a/lib/param/param_table.c b/lib/param/param_table.c >index f9d3b55adf2..aed205d1944 100644 >--- a/lib/param/param_table.c >+++ b/lib/param/param_table.c >@@ -100,6 +100,7 @@ static const struct enum_list enum_server_role[] = { > {ROLE_ACTIVE_DIRECTORY_DC, "active directory domain controller"}, > {ROLE_ACTIVE_DIRECTORY_DC, "domain controller"}, > {ROLE_ACTIVE_DIRECTORY_DC, "dc"}, >+ {ROLE_IPA_DC, "IPA primary domain controller"}, > {-1, NULL} > }; > >diff --git a/lib/param/util.c b/lib/param/util.c >index cd8e74b9d8f..9a0fc102de8 100644 >--- a/lib/param/util.c >+++ b/lib/param/util.c >@@ -255,6 +255,7 @@ const char *lpcfg_sam_name(struct loadparm_context *lp_ctx) > case ROLE_DOMAIN_BDC: > case ROLE_DOMAIN_PDC: > case ROLE_ACTIVE_DIRECTORY_DC: >+ case ROLE_IPA_DC: > return lpcfg_workgroup(lp_ctx); > default: > return lpcfg_netbios_name(lp_ctx); >diff --git a/libcli/netlogon/netlogon.c b/libcli/netlogon/netlogon.c >index 58a331d70ad..838bdf84c87 100644 >--- a/libcli/netlogon/netlogon.c >+++ b/libcli/netlogon/netlogon.c >@@ -93,7 +93,7 @@ NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, > if (ndr->offset < ndr->data_size) { > TALLOC_FREE(ndr); > /* >- * We need to handle a bug in FreeIPA (at least <= 4.1.2). >+ * We need to handle a bug in IPA (at least <= 4.1.2). > * > * They include the ip address information without setting > * NETLOGON_NT_VERSION_5EX_WITH_IP, while using >diff --git a/libds/common/roles.h b/libds/common/roles.h >index 4772c8d7d3f..03ba1915b21 100644 >--- a/libds/common/roles.h >+++ b/libds/common/roles.h >@@ -33,6 +33,7 @@ enum server_role { > > /* not in samr.idl */ > ROLE_ACTIVE_DIRECTORY_DC = 4, >+ ROLE_IPA_DC = 5, > > /* To determine the role automatically, this is not a valid role */ > ROLE_AUTO = 100 >diff --git a/source3/auth/auth.c b/source3/auth/auth.c >index 53daad12ca4..978705ae30d 100644 >--- a/source3/auth/auth.c >+++ b/source3/auth/auth.c >@@ -529,6 +529,7 @@ NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx, > break; > case ROLE_DOMAIN_BDC: > case ROLE_DOMAIN_PDC: >+ case ROLE_IPA_DC: > role = "'DC'"; > methods = "anonymous sam winbind sam_ignoredomain"; > break; >@@ -560,6 +561,7 @@ NTSTATUS make_auth3_context_for_netlogon(TALLOC_CTX *mem_ctx, > switch (lp_server_role()) { > case ROLE_DOMAIN_BDC: > case ROLE_DOMAIN_PDC: >+ case ROLE_IPA_DC: > methods = "sam_netlogon3 winbind"; > break; > >@@ -581,6 +583,7 @@ NTSTATUS make_auth3_context_for_winbind(TALLOC_CTX *mem_ctx, > case ROLE_DOMAIN_MEMBER: > case ROLE_DOMAIN_BDC: > case ROLE_DOMAIN_PDC: >+ case ROLE_IPA_DC: > methods = "sam"; > break; > case ROLE_ACTIVE_DIRECTORY_DC: >diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c >index 8fc552d9242..37b0bd5d1d1 100644 >--- a/source3/auth/auth_sam.c >+++ b/source3/auth/auth_sam.c >@@ -140,12 +140,13 @@ static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context, > break; > case ROLE_DOMAIN_PDC: > case ROLE_DOMAIN_BDC: >+ case ROLE_IPA_DC: > if (!is_local_name && !is_my_domain) { > /* If we are running on a DC that has PASSDB module with domain > * information, check if DNS forest name is matching the domain >- * name. This is the case of FreeIPA domain controller when >- * trusted AD DCs attempt to authenticate FreeIPA users using >- * the forest root domain (which is the only domain in FreeIPA). >+ * name. This is the case of IPA domain controller when >+ * trusted AD DCs attempt to authenticate IPA users using >+ * the forest root domain (which is the only domain in IPA). > */ > struct pdb_domain_info *dom_info = NULL; > >@@ -228,6 +229,7 @@ static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context, > switch (lp_server_role()) { > case ROLE_DOMAIN_PDC: > case ROLE_DOMAIN_BDC: >+ case ROLE_IPA_DC: > break; > default: > DBG_ERR("Invalid server role\n"); >@@ -246,9 +248,9 @@ static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context, > if (!is_my_domain) { > /* If we are running on a DC that has PASSDB module with domain > * information, check if DNS forest name is matching the domain >- * name. This is the case of FreeIPA domain controller when >- * trusted AD DCs attempt to authenticate FreeIPA users using >- * the forest root domain (which is the only domain in FreeIPA). >+ * name. This is the case of IPA domain controller when >+ * trusted AD DCs attempt to authenticate IPA users using >+ * the forest root domain (which is the only domain in IPA). > */ > struct pdb_domain_info *dom_info = NULL; > dom_info = pdb_get_domain_info(mem_ctx); >diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h >index 06d24744960..346401510c2 100644 >--- a/source3/include/smb_macros.h >+++ b/source3/include/smb_macros.h >@@ -213,7 +213,7 @@ copy an IP address from one buffer to another > Check to see if we are a DC for this domain > *****************************************************************************/ > >-#define IS_DC (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC || lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) >+#define IS_DC (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC || lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC || lp_server_role() == ROLE_IPA_DC) > #define IS_AD_DC (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) > > /* >diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c >index 8d0752f4531..0344c0e0416 100644 >--- a/source3/lib/netapi/joindomain.c >+++ b/source3/lib/netapi/joindomain.c >@@ -369,6 +369,7 @@ WERROR NetGetJoinInformation_l(struct libnetapi_ctx *ctx, > case ROLE_DOMAIN_MEMBER: > case ROLE_DOMAIN_PDC: > case ROLE_DOMAIN_BDC: >+ case ROLE_IPA_DC: > *r->out.name_type = NetSetupDomainName; > break; > case ROLE_STANDALONE: >diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c >index 57d1d909099..98e05d13d59 100644 >--- a/source3/param/loadparm.c >+++ b/source3/param/loadparm.c >@@ -4321,6 +4321,7 @@ int lp_default_server_announce(void) > default_server_announce |= SV_TYPE_DOMAIN_MEMBER; > break; > case ROLE_DOMAIN_PDC: >+ case ROLE_IPA_DC: > default_server_announce |= SV_TYPE_DOMAIN_CTRL; > break; > case ROLE_DOMAIN_BDC: >@@ -4346,7 +4347,8 @@ int lp_default_server_announce(void) > bool lp_domain_master(void) > { > if (Globals._domain_master == Auto) >- return (lp_server_role() == ROLE_DOMAIN_PDC); >+ return (lp_server_role() == ROLE_DOMAIN_PDC || >+ lp_server_role() == ROLE_IPA_DC); > > return (bool)Globals._domain_master; > } >diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c >index 9f7891b7d4a..470330342c3 100644 >--- a/source3/passdb/lookup_sid.c >+++ b/source3/passdb/lookup_sid.c >@@ -120,7 +120,7 @@ bool lookup_name(TALLOC_CTX *mem_ctx, > > /* If we are running on a DC that has PASSDB module with domain > * information, check if DNS forest name is matching the domain >- * name. This is the case of FreeIPA domain controller when >+ * name. This is the case of IPA domain controller when > * trusted AD DC looks up users found in a Global Catalog of > * the forest root domain. */ > if (!check_global_sam && (IS_DC)) { >diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c >index daa565c9097..5e1af8a8551 100644 >--- a/source3/passdb/machine_account_secrets.c >+++ b/source3/passdb/machine_account_secrets.c >@@ -198,7 +198,8 @@ bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid) > dyn_guid = (struct GUID *)secrets_fetch(key, &size); > > if (!dyn_guid) { >- if (lp_server_role() == ROLE_DOMAIN_PDC) { >+ if (lp_server_role() == ROLE_DOMAIN_PDC || >+ lp_server_role() == ROLE_IPA_DC) { > new_guid = GUID_random(); > if (!secrets_store_domain_guid(domain, &new_guid)) > return False; >@@ -314,9 +315,7 @@ static const char *trust_keystr(const char *domain) > > enum netr_SchannelType get_default_sec_channel(void) > { >- if (lp_server_role() == ROLE_DOMAIN_BDC || >- lp_server_role() == ROLE_DOMAIN_PDC || >- lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) { >+ if (IS_DC) { > return SEC_CHAN_BDC; > } else { > return SEC_CHAN_WKSTA; >diff --git a/source3/registry/reg_backend_prod_options.c b/source3/registry/reg_backend_prod_options.c >index 655c587ac40..7bd3f324c37 100644 >--- a/source3/registry/reg_backend_prod_options.c >+++ b/source3/registry/reg_backend_prod_options.c >@@ -40,6 +40,7 @@ static int prod_options_fetch_values(const char *key, struct regval_ctr *regvals > switch (lp_server_role()) { > case ROLE_DOMAIN_PDC: > case ROLE_DOMAIN_BDC: >+ case ROLE_IPA_DC: > value_ascii = "LanmanNT"; > break; > case ROLE_STANDALONE: >diff --git a/source3/rpc_server/dssetup/srv_dssetup_nt.c b/source3/rpc_server/dssetup/srv_dssetup_nt.c >index 7e3efa8504e..aa896e15ac4 100644 >--- a/source3/rpc_server/dssetup/srv_dssetup_nt.c >+++ b/source3/rpc_server/dssetup/srv_dssetup_nt.c >@@ -62,6 +62,7 @@ static WERROR fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, > basic->domain = get_global_sam_name(); > break; > case ROLE_DOMAIN_PDC: >+ case ROLE_IPA_DC: > basic->role = DS_ROLE_PRIMARY_DC; > basic->domain = get_global_sam_name(); > break; >diff --git a/source3/smbd/server.c b/source3/smbd/server.c >index 7d96a5762ec..d263507b22f 100644 >--- a/source3/smbd/server.c >+++ b/source3/smbd/server.c >@@ -1969,7 +1969,7 @@ extern void build_options(bool screen); > exit_daemon("smbd can not open secrets.tdb", EACCES); > } > >- if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) { >+ if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC || lp_server_role() == ROLE_IPA_DC) { > struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers()); > if (!open_schannel_session_store(NULL, lp_ctx)) { > exit_daemon("ERROR: Samba cannot open schannel store for secured NETLOGON operations.", EACCES); >diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c >index cc0701e597a..f09b029fd13 100644 >--- a/source3/winbindd/winbindd_misc.c >+++ b/source3/winbindd/winbindd_misc.c >@@ -75,7 +75,7 @@ static char *get_trust_type_string(TALLOC_CTX *mem_ctx, > case SEC_CHAN_BDC: { > int role = lp_server_role(); > >- if (role == ROLE_DOMAIN_PDC) { >+ if (role == ROLE_DOMAIN_PDC || role == ROLE_IPA_DC) { > s = talloc_strdup(mem_ctx, "PDC"); > if (s == NULL) { > return NULL; >diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c >index 315eb366a52..04e79e70f6b 100644 >--- a/source3/winbindd/winbindd_util.c >+++ b/source3/winbindd/winbindd_util.c >@@ -1225,15 +1225,37 @@ bool init_domain_list(void) > secure_channel_type = SEC_CHAN_LOCAL; > } > >- status = add_trusted_domain(get_global_sam_name(), >- NULL, >- get_global_sam_sid(), >- LSA_TRUST_TYPE_DOWNLEVEL, >- trust_flags, >- 0, /* trust_attribs */ >- secure_channel_type, >- NULL, >- &domain); >+ if ((pdb_domain_info != NULL) && (role == ROLE_IPA_DC)) { >+ /* This is IPA DC that presents itself as >+ * an Active Directory domain controller to trusted AD >+ * forests but in fact is a classic domain controller. >+ */ >+ trust_flags = NETR_TRUST_FLAG_PRIMARY; >+ trust_flags |= NETR_TRUST_FLAG_IN_FOREST; >+ trust_flags |= NETR_TRUST_FLAG_NATIVE; >+ trust_flags |= NETR_TRUST_FLAG_OUTBOUND; >+ trust_flags |= NETR_TRUST_FLAG_TREEROOT; >+ status = add_trusted_domain(pdb_domain_info->name, >+ pdb_domain_info->dns_domain, >+ &pdb_domain_info->sid, >+ LSA_TRUST_TYPE_UPLEVEL, >+ trust_flags, >+ LSA_TRUST_ATTRIBUTE_WITHIN_FOREST, >+ secure_channel_type, >+ NULL, >+ &domain); >+ TALLOC_FREE(pdb_domain_info); >+ } else { >+ status = add_trusted_domain(get_global_sam_name(), >+ NULL, >+ get_global_sam_sid(), >+ LSA_TRUST_TYPE_DOWNLEVEL, >+ trust_flags, >+ 0, /* trust_attribs */ >+ secure_channel_type, >+ NULL, >+ &domain); >+ } > if (!NT_STATUS_IS_OK(status)) { > DBG_ERR("Failed to add local SAM to " > "domain to winbindd's internal list\n"); >diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c >index 1069a875c30..e4d87c8be22 100644 >--- a/source4/auth/ntlm/auth.c >+++ b/source4/auth/ntlm/auth.c >@@ -737,6 +737,7 @@ const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context * > case ROLE_DOMAIN_BDC: > case ROLE_DOMAIN_PDC: > case ROLE_ACTIVE_DIRECTORY_DC: >+ case ROLE_IPA_DC: > auth_methods = str_list_make(mem_ctx, "anonymous sam winbind sam_ignoredomain", NULL); > break; > } >diff --git a/source4/kdc/kdc-heimdal.c b/source4/kdc/kdc-heimdal.c >index b5de5a790d4..49aa560470c 100644 >--- a/source4/kdc/kdc-heimdal.c >+++ b/source4/kdc/kdc-heimdal.c >@@ -276,6 +276,7 @@ static NTSTATUS kdc_task_init(struct task_server *task) > return NT_STATUS_INVALID_DOMAIN_ROLE; > case ROLE_DOMAIN_PDC: > case ROLE_DOMAIN_BDC: >+ case ROLE_IPA_DC: > task_server_terminate( > task, "Cannot start KDC as a 'classic Samba' DC", false); > return NT_STATUS_INVALID_DOMAIN_ROLE; >diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c >index 51fed4da62b..1f09b721408 100644 >--- a/source4/rpc_server/samr/dcesrv_samr.c >+++ b/source4/rpc_server/samr/dcesrv_samr.c >@@ -568,6 +568,7 @@ static NTSTATUS dcesrv_samr_info_DomGeneralInformation(struct samr_domain_state > break; > case ROLE_DOMAIN_PDC: > case ROLE_DOMAIN_BDC: >+ case ROLE_IPA_DC: > case ROLE_AUTO: > return NT_STATUS_INTERNAL_ERROR; > case ROLE_DOMAIN_MEMBER: >@@ -675,6 +676,7 @@ static NTSTATUS dcesrv_samr_info_DomInfo7(struct samr_domain_state *state, > break; > case ROLE_DOMAIN_PDC: > case ROLE_DOMAIN_BDC: >+ case ROLE_IPA_DC: > case ROLE_AUTO: > return NT_STATUS_INTERNAL_ERROR; > case ROLE_DOMAIN_MEMBER: >-- >2.25.1 > > >From 081e7d9119aa4a5b2faec9a7a4744a4b8474a897 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 5 Oct 2021 18:11:57 +0200 >Subject: [PATCH 520/686] CVE-2020-25719 CVE-2020-25717: auth/gensec: always > require a PAC in domain mode (DC or member) > >AD domains always provide a PAC unless UF_NO_AUTH_DATA_REQUIRED is set >on the service account, which can only be explicitly configured, >but that's an invalid configuration! > >We still try to support standalone servers in an MIT realm, >as legacy setup. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Removed knownfail entries] >--- > auth/gensec/gensec_util.c | 27 +++++++++++++++++++++++---- > selftest/knownfail.d/no-pac | 4 ---- > 2 files changed, 23 insertions(+), 8 deletions(-) > delete mode 100644 selftest/knownfail.d/no-pac > >diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c >index e185acc0c20..694661b53b5 100644 >--- a/auth/gensec/gensec_util.c >+++ b/auth/gensec/gensec_util.c >@@ -25,6 +25,8 @@ > #include "auth/gensec/gensec_internal.h" > #include "auth/common_auth.h" > #include "../lib/util/asn1.h" >+#include "param/param.h" >+#include "libds/common/roles.h" > > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_AUTH >@@ -46,10 +48,27 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx, > session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS; > > if (!pac_blob) { >- if (gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { >- DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n", >- principal_string)); >- return NT_STATUS_ACCESS_DENIED; >+ enum server_role server_role = >+ lpcfg_server_role(gensec_security->settings->lp_ctx); >+ >+ /* >+ * For any domain setup (DC or member) we require having >+ * a PAC, as the service ticket comes from an AD DC, >+ * which will always provide a PAC, unless >+ * UF_NO_AUTH_DATA_REQUIRED is configured for our >+ * account, but that's just an invalid configuration, >+ * the admin configured for us! >+ * >+ * As a legacy case, we still allow kerberos tickets from an MIT >+ * realm, but only in standalone mode. In that mode we'll only >+ * ever accept a kerberos authentication with a keytab file >+ * being explicitly configured via the 'keytab method' option. >+ */ >+ if (server_role != ROLE_STANDALONE) { >+ DBG_WARNING("Unable to find PAC in ticket from %s, " >+ "failing to allow access\n", >+ principal_string); >+ return NT_STATUS_NO_IMPERSONATION_TOKEN; > } > DBG_NOTICE("Unable to find PAC for %s, resorting to local " > "user lookup\n", principal_string); >diff --git a/selftest/knownfail.d/no-pac b/selftest/knownfail.d/no-pac >deleted file mode 100644 >index 9723d581c2a..00000000000 >--- a/selftest/knownfail.d/no-pac >+++ /dev/null >@@ -1,4 +0,0 @@ >-^samba.tests.krb5.test_ccache.samba.tests.krb5.test_ccache.CcacheTests.test_ccache_no_pac >-^samba.tests.krb5.test_ldap.samba.tests.krb5.test_ldap.LdapTests.test_ldap_no_pac >-^samba.tests.krb5.test_rpc.samba.tests.krb5.test_rpc.RpcTests.test_rpc_no_pac >-^samba.tests.krb5.test_smb.samba.tests.krb5.test_smb.SmbTests.test_smb_no_pac >-- >2.25.1 > > >From 0344964207c7fd1f5371d65aff3f1df24f95e7c7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 11 Oct 2021 23:17:19 +0200 >Subject: [PATCH 521/686] CVE-2020-25719 CVE-2020-25717: s4:auth: remove unused > auth_generate_session_info_principal() > >We'll require a PAC at the main gensec layer already. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/auth/auth.h | 8 ------ > source4/auth/ntlm/auth.c | 49 ++++-------------------------------- > source4/auth/ntlm/auth_sam.c | 12 --------- > 3 files changed, 5 insertions(+), 64 deletions(-) > >diff --git a/source4/auth/auth.h b/source4/auth/auth.h >index 3f9fb1ae3cb..6b7db99cbe2 100644 >--- a/source4/auth/auth.h >+++ b/source4/auth/auth.h >@@ -69,14 +69,6 @@ struct auth_operations { > TALLOC_CTX *mem_ctx, > struct auth_user_info_dc **interim_info, > bool *authoritative); >- >- /* Lookup a 'session info interim' return based only on the principal or DN */ >- NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, >- struct auth4_context *auth_context, >- const char *principal, >- struct ldb_dn *user_dn, >- struct auth_user_info_dc **interim_info); >- uint32_t flags; > }; > > struct auth_method_context { >diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c >index e4d87c8be22..a968bd74448 100644 >--- a/source4/auth/ntlm/auth.c >+++ b/source4/auth/ntlm/auth.c >@@ -86,48 +86,6 @@ _PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t cha > return NT_STATUS_OK; > } > >-/**************************************************************************** >-Used in the gensec_gssapi and gensec_krb5 server-side code, where the >-PAC isn't available, and for tokenGroups in the DSDB stack. >- >- Supply either a principal or a DN >-****************************************************************************/ >-static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_ctx, >- TALLOC_CTX *mem_ctx, >- const char *principal, >- struct ldb_dn *user_dn, >- uint32_t session_info_flags, >- struct auth_session_info **session_info) >-{ >- NTSTATUS nt_status; >- struct auth_method_context *method; >- struct auth_user_info_dc *user_info_dc; >- >- for (method = auth_ctx->methods; method; method = method->next) { >- if (!method->ops->get_user_info_dc_principal) { >- continue; >- } >- >- nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, &user_info_dc); >- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { >- continue; >- } >- if (!NT_STATUS_IS_OK(nt_status)) { >- return nt_status; >- } >- >- nt_status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx, >- user_info_dc, >- user_info_dc->info->account_name, >- session_info_flags, session_info); >- talloc_free(user_info_dc); >- >- return nt_status; >- } >- >- return NT_STATUS_NOT_IMPLEMENTED; >-} >- > /** > * Check a user's Plaintext, LM or NTLM password. > * (sync version) >@@ -627,8 +585,11 @@ static NTSTATUS auth_generate_session_info_pac(struct auth4_context *auth_ctx, > TALLOC_CTX *tmp_ctx; > > if (!pac_blob) { >- return auth_generate_session_info_principal(auth_ctx, mem_ctx, principal_name, >- NULL, session_info_flags, session_info); >+ /* >+ * This should already be catched at the main >+ * gensec layer, but better check twice >+ */ >+ return NT_STATUS_INTERNAL_ERROR; > } > > tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context"); >diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c >index e4ebeae7523..e80b1e82fec 100644 >--- a/source4/auth/ntlm/auth_sam.c >+++ b/source4/auth/ntlm/auth_sam.c >@@ -937,22 +937,11 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx, > return NT_STATUS_OK; > } > >-/* Wrapper for the auth subsystem pointer */ >-static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx, >- struct auth4_context *auth_context, >- const char *principal, >- struct ldb_dn *user_dn, >- struct auth_user_info_dc **user_info_dc) >-{ >- return authsam_get_user_info_dc_principal(mem_ctx, auth_context->lp_ctx, auth_context->sam_ctx, >- principal, user_dn, user_info_dc); >-} > static const struct auth_operations sam_ignoredomain_ops = { > .name = "sam_ignoredomain", > .want_check = authsam_ignoredomain_want_check, > .check_password_send = authsam_check_password_send, > .check_password_recv = authsam_check_password_recv, >- .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, > }; > > static const struct auth_operations sam_ops = { >@@ -960,7 +949,6 @@ static const struct auth_operations sam_ops = { > .want_check = authsam_want_check, > .check_password_send = authsam_check_password_send, > .check_password_recv = authsam_check_password_recv, >- .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, > }; > > _PUBLIC_ NTSTATUS auth4_sam_init(TALLOC_CTX *); >-- >2.25.1 > > >From 3ecc0691e4d4c726c39b60f3c1b149f8a525aa3d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 21 Sep 2021 12:27:28 +0200 >Subject: [PATCH 522/686] CVE-2020-25717: s3:ntlm_auth: fix memory leaks in > ntlm_auth_generate_session_info_pac() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/utils/ntlm_auth.c | 18 ++++++++++++------ > 1 file changed, 12 insertions(+), 6 deletions(-) > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index 3f70732a837..fefdd32bf11 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -827,23 +827,27 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c > if (!p) { > DEBUG(3, ("[%s] Doesn't look like a valid principal\n", > princ_name)); >- return NT_STATUS_LOGON_FAILURE; >+ status = NT_STATUS_LOGON_FAILURE; >+ goto done; > } > > user = talloc_strndup(mem_ctx, princ_name, p - princ_name); > if (!user) { >- return NT_STATUS_NO_MEMORY; >+ status = NT_STATUS_NO_MEMORY; >+ goto done; > } > > realm = talloc_strdup(talloc_tos(), p + 1); > if (!realm) { >- return NT_STATUS_NO_MEMORY; >+ status = NT_STATUS_NO_MEMORY; >+ goto done; > } > > if (!strequal(realm, lp_realm())) { > DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm)); > if (!lp_allow_trusted_domains()) { >- return NT_STATUS_LOGON_FAILURE; >+ status = NT_STATUS_LOGON_FAILURE; >+ goto done; > } > } > >@@ -851,7 +855,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c > domain = talloc_strdup(mem_ctx, > logon_info->info3.base.logon_domain.string); > if (!domain) { >- return NT_STATUS_NO_MEMORY; >+ status = NT_STATUS_NO_MEMORY; >+ goto done; > } > DEBUG(10, ("Domain is [%s] (using PAC)\n", domain)); > } else { >@@ -881,7 +886,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c > domain = talloc_strdup(mem_ctx, realm); > } > if (!domain) { >- return NT_STATUS_NO_MEMORY; >+ status = NT_STATUS_NO_MEMORY; >+ goto done; > } > DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain)); > } >-- >2.25.1 > > >From 11f063986a20e6039bc758ad99af74c1efcb4065 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 21 Sep 2021 12:44:01 +0200 >Subject: [PATCH 523/686] CVE-2020-25717: s3:ntlm_auth: let > ntlm_auth_generate_session_info_pac() base the name on the PAC LOGON_INFO > only > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/utils/ntlm_auth.c | 91 ++++++++++++--------------------------- > 1 file changed, 28 insertions(+), 63 deletions(-) > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index fefdd32bf11..ff2fd30a9ae 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -799,10 +799,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c > struct PAC_LOGON_INFO *logon_info = NULL; > char *unixuser; > NTSTATUS status; >- char *domain = NULL; >- char *realm = NULL; >- char *user = NULL; >- char *p; >+ const char *domain = ""; >+ const char *user = ""; > > tmp_ctx = talloc_new(mem_ctx); > if (!tmp_ctx) { >@@ -819,79 +817,46 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c > if (!NT_STATUS_IS_OK(status)) { > goto done; > } >- } >- >- DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name)); >- >- p = strchr_m(princ_name, '@'); >- if (!p) { >- DEBUG(3, ("[%s] Doesn't look like a valid principal\n", >- princ_name)); >- status = NT_STATUS_LOGON_FAILURE; >+ } else { >+ status = NT_STATUS_ACCESS_DENIED; >+ DBG_WARNING("Kerberos ticket for[%s] has no PAC: %s\n", >+ princ_name, nt_errstr(status)); > goto done; > } > >- user = talloc_strndup(mem_ctx, princ_name, p - princ_name); >- if (!user) { >- status = NT_STATUS_NO_MEMORY; >- goto done; >+ if (logon_info->info3.base.account_name.string != NULL) { >+ user = logon_info->info3.base.account_name.string; >+ } else { >+ user = ""; >+ } >+ if (logon_info->info3.base.logon_domain.string != NULL) { >+ domain = logon_info->info3.base.logon_domain.string; >+ } else { >+ domain = ""; > } > >- realm = talloc_strdup(talloc_tos(), p + 1); >- if (!realm) { >- status = NT_STATUS_NO_MEMORY; >+ if (strlen(user) == 0 || strlen(domain) == 0) { >+ status = NT_STATUS_ACCESS_DENIED; >+ DBG_WARNING("Kerberos ticket for[%s] has invalid " >+ "account_name[%s]/logon_domain[%s]: %s\n", >+ princ_name, >+ logon_info->info3.base.account_name.string, >+ logon_info->info3.base.logon_domain.string, >+ nt_errstr(status)); > goto done; > } > >- if (!strequal(realm, lp_realm())) { >- DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm)); >+ DBG_NOTICE("Kerberos ticket principal name is [%s] " >+ "account_name[%s]/logon_domain[%s]\n", >+ princ_name, user, domain); >+ >+ if (!strequal(domain, lp_workgroup())) { > if (!lp_allow_trusted_domains()) { > status = NT_STATUS_LOGON_FAILURE; > goto done; > } > } > >- if (logon_info && logon_info->info3.base.logon_domain.string) { >- domain = talloc_strdup(mem_ctx, >- logon_info->info3.base.logon_domain.string); >- if (!domain) { >- status = NT_STATUS_NO_MEMORY; >- goto done; >- } >- DEBUG(10, ("Domain is [%s] (using PAC)\n", domain)); >- } else { >- >- /* If we have winbind running, we can (and must) shorten the >- username by using the short netbios name. Otherwise we will >- have inconsistent user names. With Kerberos, we get the >- fully qualified realm, with ntlmssp we get the short >- name. And even w2k3 does use ntlmssp if you for example >- connect to an ip address. */ >- >- wbcErr wbc_status; >- struct wbcDomainInfo *info = NULL; >- >- DEBUG(10, ("Mapping [%s] to short name using winbindd\n", >- realm)); >- >- wbc_status = wbcDomainInfo(realm, &info); >- >- if (WBC_ERROR_IS_OK(wbc_status)) { >- domain = talloc_strdup(mem_ctx, >- info->short_name); >- wbcFreeMemory(info); >- } else { >- DEBUG(3, ("Could not find short name: %s\n", >- wbcErrorString(wbc_status))); >- domain = talloc_strdup(mem_ctx, realm); >- } >- if (!domain) { >- status = NT_STATUS_NO_MEMORY; >- goto done; >- } >- DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain)); >- } >- > unixuser = talloc_asprintf(tmp_ctx, "%s%c%s", domain, winbind_separator(), user); > if (!unixuser) { > status = NT_STATUS_NO_MEMORY; >-- >2.25.1 > > >From 1ef2ab902379387e4232def9b12d611b4149c2d5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 4 Oct 2021 19:42:20 +0200 >Subject: [PATCH 524/686] CVE-2020-25717: s3:auth: let > auth3_generate_session_info_pac() delegate everything to > make_server_info_wbcAuthUserInfo() > >This consolidates the code paths used for NTLMSSP and Kerberos! > >I checked what we were already doing for NTLMSSP, which is this: > >a) source3/auth/auth_winbind.c calls wbcAuthenticateUserEx() >b) as a domain member we require a valid response from winbindd, > otherwise we'll return NT_STATUS_NO_LOGON_SERVERS >c) we call make_server_info_wbcAuthUserInfo(), which internally > calls make_server_info_info3() >d) auth_check_ntlm_password() calls > smb_pam_accountcheck(unix_username, rhost), where rhost > is only an ipv4 or ipv6 address (without reverse dns lookup) >e) from auth3_check_password_send/auth3_check_password_recv() > server_returned_info will be passed to auth3_generate_session_info(), > triggered by gensec_session_info(), which means we'll call into > create_local_token() in order to transform auth_serversupplied_info > into auth_session_info. > >For Kerberos gensec_session_info() will call >auth3_generate_session_info_pac() via the gensec_generate_session_info_pac() >helper function. The current logic is this: > >a) gensec_generate_session_info_pac() is the function that > evaluates the 'gensec:require_pac', which defaulted to 'no' > before. >b) auth3_generate_session_info_pac() called > wbcAuthenticateUserEx() in order to pass the PAC blob > to winbindd, but only to prime its cache, e.g. netsamlogon cache > and others. Most failures were just ignored. >c) If the PAC blob is available, it extracted the PAC_LOGON_INFO > from it. >d) Then we called the horrible get_user_from_kerberos_info() function: > - It uses a first part of the tickets principal name (before the @) > as username and combines that with the 'logon_info->base.logon_domain' > if the logon_info (PAC) is present. > - As a fallback without a PAC it's tries to ask winbindd for a mapping > from realm to netbios domain name. > - Finally is falls back to using the realm as netbios domain name > With this information is builds 'userdomain+winbind_separator+useraccount' > and calls map_username() followed by smb_getpwnam() with create=true, > Note this is similar to the make_server_info_info3() => check_account() > => smb_getpwnam() logic under 3. > - It also calls smb_pam_accountcheck(), but may pass the reverse DNS lookup name > instead of the ip address as rhost. > - It does some MAP_TO_GUEST_ON_BAD_UID logic and auto creates the > guest account. >e) We called create_info3_from_pac_logon_info() >f) make_session_info_krb5() calls gets called and triggers this: > - If get_user_from_kerberos_info() mapped to guest, it calls > make_server_info_guest() > - If create_info3_from_pac_logon_info() created a info3 from logon_info, > it calls make_server_info_info3() > - Without a PAC it tries pdb_getsampwnam()/make_server_info_sam() with > a fallback to make_server_info_pw() > From there it calls create_local_token() > >I tried to change auth3_generate_session_info_pac() to behave similar >to auth_winbind.c together with auth3_generate_session_info() as >a domain member, as we now rely on a PAC: > >a) As domain member we require a PAC and always call wbcAuthenticateUserEx() > and require a valid response! >b) we call make_server_info_wbcAuthUserInfo(), which internally > calls make_server_info_info3(). Note make_server_info_info3() > handles MAP_TO_GUEST_ON_BAD_UID and make_server_info_guest() > internally. >c) Similar to auth_check_ntlm_password() we now call > smb_pam_accountcheck(unix_username, rhost), where rhost > is only an ipv4 or ipv6 address (without reverse dns lookup) >d) From there it calls create_local_token() > >As standalone server (in an MIT realm) we continue >with the already existing code logic, which works without a PAC: >a) we keep smb_getpwnam() with create=true logic as it > also requires an explicit 'add user script' option. >b) In the following commits we assert that there's > actually no PAC in this mode, which means we can > remove unused and confusing code. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14646 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/auth/auth_generic.c | 137 ++++++++++++++++++++++++++++-------- > 1 file changed, 109 insertions(+), 28 deletions(-) > >diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c >index 9f8e81b82ab..3099e8f9057 100644 >--- a/source3/auth/auth_generic.c >+++ b/source3/auth/auth_generic.c >@@ -46,6 +46,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > uint32_t session_info_flags, > struct auth_session_info **session_info) > { >+ enum server_role server_role = lp_server_role(); > TALLOC_CTX *tmp_ctx; > struct PAC_LOGON_INFO *logon_info = NULL; > struct netr_SamInfo3 *info3_copy = NULL; >@@ -54,39 +55,59 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > char *ntuser; > char *ntdomain; > char *username; >- char *rhost; >+ const char *rhost; > struct passwd *pw; > NTSTATUS status; >- int rc; > > tmp_ctx = talloc_new(mem_ctx); > if (!tmp_ctx) { > return NT_STATUS_NO_MEMORY; > } > >- if (pac_blob) { >-#ifdef HAVE_KRB5 >+ if (tsocket_address_is_inet(remote_address, "ip")) { >+ rhost = tsocket_address_inet_addr_string( >+ remote_address, tmp_ctx); >+ if (rhost == NULL) { >+ status = NT_STATUS_NO_MEMORY; >+ goto done; >+ } >+ } else { >+ rhost = "127.0.0.1"; >+ } >+ >+ if (server_role != ROLE_STANDALONE) { > struct wbcAuthUserParams params = { 0 }; > struct wbcAuthUserInfo *info = NULL; > struct wbcAuthErrorInfo *err = NULL; >+ struct auth_serversupplied_info *server_info = NULL; >+ char *original_user_name = NULL; >+ char *p = NULL; > wbcErr wbc_err; > >+ if (pac_blob == NULL) { >+ /* >+ * This should already be catched at the main >+ * gensec layer, but better check twice >+ */ >+ status = NT_STATUS_INTERNAL_ERROR; >+ goto done; >+ } >+ > /* > * Let winbind decode the PAC. > * This will also store the user > * data in the netsamlogon cache. > * >- * We need to do this *before* we >- * call get_user_from_kerberos_info() >- * as that does a user lookup that >- * expects info in the netsamlogon cache. >- * >- * See BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259 >+ * This used to be a cache prime >+ * optimization, but now we delegate >+ * all logic to winbindd, as we require >+ * winbindd as domain member anyway. > */ > params.level = WBC_AUTH_USER_LEVEL_PAC; > params.password.pac.data = pac_blob->data; > params.password.pac.length = pac_blob->length; > >+ /* we are contacting the privileged pipe */ > become_root(); > wbc_err = wbcAuthenticateUserEx(¶ms, &info, &err); > unbecome_root(); >@@ -99,18 +120,90 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > */ > > switch (wbc_err) { >- case WBC_ERR_WINBIND_NOT_AVAILABLE: > case WBC_ERR_SUCCESS: > break; >+ case WBC_ERR_WINBIND_NOT_AVAILABLE: >+ status = NT_STATUS_NO_LOGON_SERVERS; >+ DBG_ERR("winbindd not running - " >+ "but required as domain member: %s\n", >+ nt_errstr(status)); >+ goto done; > case WBC_ERR_AUTH_ERROR: > status = NT_STATUS(err->nt_status); > wbcFreeMemory(err); > goto done; >+ case WBC_ERR_NO_MEMORY: >+ status = NT_STATUS_NO_MEMORY; >+ goto done; > default: > status = NT_STATUS_LOGON_FAILURE; > goto done; > } > >+ status = make_server_info_wbcAuthUserInfo(tmp_ctx, >+ info->account_name, >+ info->domain_name, >+ info, &server_info); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n", >+ nt_errstr(status))); >+ goto done; >+ } >+ >+ /* We skip doing this step if the caller asked us not to */ >+ if (!(server_info->guest)) { >+ const char *unix_username = server_info->unix_name; >+ >+ /* We might not be root if we are an RPC call */ >+ become_root(); >+ status = smb_pam_accountcheck(unix_username, rhost); >+ unbecome_root(); >+ >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] " >+ "FAILED with error %s\n", >+ unix_username, nt_errstr(status))); >+ goto done; >+ } >+ >+ DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] " >+ "succeeded\n", unix_username)); >+ } >+ >+ DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name)); >+ >+ p = strchr_m(princ_name, '@'); >+ if (!p) { >+ DEBUG(3, ("[%s] Doesn't look like a valid principal\n", >+ princ_name)); >+ status = NT_STATUS_LOGON_FAILURE; >+ goto done; >+ } >+ >+ original_user_name = talloc_strndup(tmp_ctx, princ_name, p - princ_name); >+ if (original_user_name == NULL) { >+ status = NT_STATUS_NO_MEMORY; >+ goto done; >+ } >+ >+ status = create_local_token(mem_ctx, >+ server_info, >+ NULL, >+ original_user_name, >+ session_info); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(10, ("create_local_token failed: %s\n", >+ nt_errstr(status))); >+ goto done; >+ } >+ >+ goto session_info_ready; >+ } >+ >+ /* This is the standalone legacy code path */ >+ >+ if (pac_blob != NULL) { >+#ifdef HAVE_KRB5 > status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL, > NULL, NULL, 0, &logon_info); > #else >@@ -121,22 +214,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > } > } > >- rc = get_remote_hostname(remote_address, >- &rhost, >- tmp_ctx); >- if (rc < 0) { >- status = NT_STATUS_NO_MEMORY; >- goto done; >- } >- if (strequal(rhost, "UNKNOWN")) { >- rhost = tsocket_address_inet_addr_string(remote_address, >- tmp_ctx); >- if (rhost == NULL) { >- status = NT_STATUS_NO_MEMORY; >- goto done; >- } >- } >- > status = get_user_from_kerberos_info(tmp_ctx, rhost, > princ_name, logon_info, > &is_mapped, &is_guest, >@@ -170,6 +247,8 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > goto done; > } > >+session_info_ready: >+ > /* setup the string used by %U */ > set_current_user_info((*session_info)->unix_info->sanitized_username, > (*session_info)->unix_info->unix_name, >@@ -179,7 +258,9 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > lp_load_with_shares(get_dyn_CONFIGFILE()); > > DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n", >- ntuser, ntdomain, rhost)); >+ (*session_info)->info->account_name, >+ (*session_info)->info->domain_name, >+ rhost)); > > status = NT_STATUS_OK; > >-- >2.25.1 > > >From 7ee2b3f5ae4259bbf8fbf3ace0b3036bf3b3f00c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 5 Oct 2021 18:12:49 +0200 >Subject: [PATCH 525/686] CVE-2020-25717: s3:auth: let > auth3_generate_session_info_pac() reject a PAC in standalone mode > >We should be strict in standalone mode, that we only support MIT realms >without a PAC in order to keep the code sane. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/auth/auth_generic.c | 29 +++++++++-------------------- > 1 file changed, 9 insertions(+), 20 deletions(-) > >diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c >index 3099e8f9057..23f746c078e 100644 >--- a/source3/auth/auth_generic.c >+++ b/source3/auth/auth_generic.c >@@ -48,8 +48,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > { > enum server_role server_role = lp_server_role(); > TALLOC_CTX *tmp_ctx; >- struct PAC_LOGON_INFO *logon_info = NULL; >- struct netr_SamInfo3 *info3_copy = NULL; > bool is_mapped; > bool is_guest; > char *ntuser; >@@ -203,19 +201,20 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > /* This is the standalone legacy code path */ > > if (pac_blob != NULL) { >-#ifdef HAVE_KRB5 >- status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL, >- NULL, NULL, 0, &logon_info); >-#else >- status = NT_STATUS_ACCESS_DENIED; >-#endif >+ /* >+ * In standalone mode we don't expect a PAC! >+ * we only support MIT realms >+ */ >+ status = NT_STATUS_BAD_TOKEN_TYPE; >+ DBG_WARNING("Unexpected PAC for [%s] in standalone mode - %s\n", >+ princ_name, nt_errstr(status)); > if (!NT_STATUS_IS_OK(status)) { > goto done; > } > } > > status = get_user_from_kerberos_info(tmp_ctx, rhost, >- princ_name, logon_info, >+ princ_name, NULL, > &is_mapped, &is_guest, > &ntuser, &ntdomain, > &username, &pw); >@@ -226,19 +225,9 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > goto done; > } > >- /* Get the info3 from the PAC data if we have it */ >- if (logon_info) { >- status = create_info3_from_pac_logon_info(tmp_ctx, >- logon_info, >- &info3_copy); >- if (!NT_STATUS_IS_OK(status)) { >- goto done; >- } >- } >- > status = make_session_info_krb5(mem_ctx, > ntuser, ntdomain, username, pw, >- info3_copy, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */, >+ NULL, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */, > session_info); > if (!NT_STATUS_IS_OK(status)) { > DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n", >-- >2.25.1 > > >From 55f0e39bc6cf30af165c7d78fd062814888c28ef Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 8 Oct 2021 17:59:59 +0200 >Subject: [PATCH 526/686] CVE-2020-25717: s3:auth: simplify > get_user_from_kerberos_info() by removing the unused logon_info argument > >This code is only every called in standalone mode on a MIT realm, >it means we never have a PAC and we also don't have winbindd arround. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/auth/auth_generic.c | 2 +- > source3/auth/proto.h | 1 - > source3/auth/user_krb5.c | 57 +++++++------------------------------ > 3 files changed, 11 insertions(+), 49 deletions(-) > >diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c >index 23f746c078e..a11aae713f5 100644 >--- a/source3/auth/auth_generic.c >+++ b/source3/auth/auth_generic.c >@@ -214,7 +214,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > } > > status = get_user_from_kerberos_info(tmp_ctx, rhost, >- princ_name, NULL, >+ princ_name, > &is_mapped, &is_guest, > &ntuser, &ntdomain, > &username, &pw); >diff --git a/source3/auth/proto.h b/source3/auth/proto.h >index fcfd1f36ca2..1ed3f4a2f77 100644 >--- a/source3/auth/proto.h >+++ b/source3/auth/proto.h >@@ -416,7 +416,6 @@ struct PAC_LOGON_INFO; > NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, > const char *cli_name, > const char *princ_name, >- struct PAC_LOGON_INFO *logon_info, > bool *is_mapped, > bool *mapped_to_guest, > char **ntuser, >diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c >index 074e8c7eb71..7b69ca6c222 100644 >--- a/source3/auth/user_krb5.c >+++ b/source3/auth/user_krb5.c >@@ -31,7 +31,6 @@ > NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, > const char *cli_name, > const char *princ_name, >- struct PAC_LOGON_INFO *logon_info, > bool *is_mapped, > bool *mapped_to_guest, > char **ntuser, >@@ -40,8 +39,8 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, > struct passwd **_pw) > { > NTSTATUS status; >- char *domain = NULL; >- char *realm = NULL; >+ const char *domain = NULL; >+ const char *realm = NULL; > char *user = NULL; > char *p; > char *fuser = NULL; >@@ -62,55 +61,16 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, > return NT_STATUS_NO_MEMORY; > } > >- realm = talloc_strdup(talloc_tos(), p + 1); >- if (!realm) { >- return NT_STATUS_NO_MEMORY; >- } >+ realm = p + 1; > > if (!strequal(realm, lp_realm())) { > DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm)); > if (!lp_allow_trusted_domains()) { > return NT_STATUS_LOGON_FAILURE; > } >- } >- >- if (logon_info && logon_info->info3.base.logon_domain.string) { >- domain = talloc_strdup(mem_ctx, >- logon_info->info3.base.logon_domain.string); >- if (!domain) { >- return NT_STATUS_NO_MEMORY; >- } >- DEBUG(10, ("Domain is [%s] (using PAC)\n", domain)); >+ domain = realm; > } else { >- >- /* If we have winbind running, we can (and must) shorten the >- username by using the short netbios name. Otherwise we will >- have inconsistent user names. With Kerberos, we get the >- fully qualified realm, with ntlmssp we get the short >- name. And even w2k3 does use ntlmssp if you for example >- connect to an ip address. */ >- >- wbcErr wbc_status; >- struct wbcDomainInfo *info = NULL; >- >- DEBUG(10, ("Mapping [%s] to short name using winbindd\n", >- realm)); >- >- wbc_status = wbcDomainInfo(realm, &info); >- >- if (WBC_ERROR_IS_OK(wbc_status)) { >- domain = talloc_strdup(mem_ctx, >- info->short_name); >- wbcFreeMemory(info); >- } else { >- DEBUG(3, ("Could not find short name: %s\n", >- wbcErrorString(wbc_status))); >- domain = talloc_strdup(mem_ctx, realm); >- } >- if (!domain) { >- return NT_STATUS_NO_MEMORY; >- } >- DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain)); >+ domain = lp_workgroup(); > } > > fuser = talloc_asprintf(mem_ctx, >@@ -175,7 +135,11 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, > return NT_STATUS_NO_MEMORY; > } > *ntuser = user; >- *ntdomain = domain; >+ *ntdomain = talloc_strdup(mem_ctx, domain); >+ if (*ntdomain == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ > *_pw = pw; > > return NT_STATUS_OK; >@@ -282,7 +246,6 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, > NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, > const char *cli_name, > const char *princ_name, >- struct PAC_LOGON_INFO *logon_info, > bool *is_mapped, > bool *mapped_to_guest, > char **ntuser, >-- >2.25.1 > > >From 01eedb26304df9a1e4eec3f0fadcf0dc960ae560 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 8 Oct 2021 18:03:04 +0200 >Subject: [PATCH 527/686] CVE-2020-25717: s3:auth: simplify > make_session_info_krb5() by removing unused arguments > >This is only ever be called in standalone mode with an MIT realm, >so we don't have a PAC/info3 structure. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source3/auth/auth_generic.c | 2 +- > source3/auth/proto.h | 2 -- > source3/auth/user_krb5.c | 20 +------------------- > 3 files changed, 2 insertions(+), 22 deletions(-) > >diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c >index a11aae713f5..4dd1af784bf 100644 >--- a/source3/auth/auth_generic.c >+++ b/source3/auth/auth_generic.c >@@ -227,7 +227,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, > > status = make_session_info_krb5(mem_ctx, > ntuser, ntdomain, username, pw, >- NULL, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */, >+ is_guest, is_mapped, > session_info); > if (!NT_STATUS_IS_OK(status)) { > DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n", >diff --git a/source3/auth/proto.h b/source3/auth/proto.h >index 1ed3f4a2f77..c00ac70fd3f 100644 >--- a/source3/auth/proto.h >+++ b/source3/auth/proto.h >@@ -427,9 +427,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, > char *ntdomain, > char *username, > struct passwd *pw, >- const struct netr_SamInfo3 *info3, > bool mapped_to_guest, bool username_was_mapped, >- DATA_BLOB *session_key, > struct auth_session_info **session_info); > > /* The following definitions come from auth/auth_samba4.c */ >diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c >index 7b69ca6c222..b8f37cbeee0 100644 >--- a/source3/auth/user_krb5.c >+++ b/source3/auth/user_krb5.c >@@ -150,9 +150,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, > char *ntdomain, > char *username, > struct passwd *pw, >- const struct netr_SamInfo3 *info3, > bool mapped_to_guest, bool username_was_mapped, >- DATA_BLOB *session_key, > struct auth_session_info **session_info) > { > NTSTATUS status; >@@ -166,20 +164,6 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, > return status; > } > >- } else if (info3) { >- /* pass the unmapped username here since map_username() >- will be called again in make_server_info_info3() */ >- >- status = make_server_info_info3(mem_ctx, >- ntuser, ntdomain, >- &server_info, >- info3); >- if (!NT_STATUS_IS_OK(status)) { >- DEBUG(1, ("make_server_info_info3 failed: %s!\n", >- nt_errstr(status))); >- return status; >- } >- > } else { > /* > * We didn't get a PAC, we have to make up the user >@@ -231,7 +215,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, > > server_info->nss_token |= username_was_mapped; > >- status = create_local_token(mem_ctx, server_info, session_key, ntuser, session_info); >+ status = create_local_token(mem_ctx, server_info, NULL, ntuser, session_info); > talloc_free(server_info); > if (!NT_STATUS_IS_OK(status)) { > DEBUG(10,("failed to create local token: %s\n", >@@ -261,9 +245,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, > char *ntdomain, > char *username, > struct passwd *pw, >- const struct netr_SamInfo3 *info3, > bool mapped_to_guest, bool username_was_mapped, >- DATA_BLOB *session_key, > struct auth_session_info **session_info) > { > return NT_STATUS_NOT_IMPLEMENTED; >-- >2.25.1 > > >From c729136afc38959050da28fc785a288bfcf1d9e1 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 18 Oct 2021 14:07:41 +1300 >Subject: [PATCH 528/686] CVE-2020-25722 Add test for SPN deletion followed by > addition > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org Removed transaction hooks, these do nothing over > remote LDAP] > >[jsutton@samba.org Adapted to fix conflicts] >--- > selftest/knownfail.d/acl-spn | 1 + > source4/dsdb/tests/python/acl.py | 47 ++++++++++++++++++++++++++++++++ > 2 files changed, 48 insertions(+) > create mode 100644 selftest/knownfail.d/acl-spn > >diff --git a/selftest/knownfail.d/acl-spn b/selftest/knownfail.d/acl-spn >new file mode 100644 >index 00000000000..e68add920a6 >--- /dev/null >+++ b/selftest/knownfail.d/acl-spn >@@ -0,0 +1 @@ >+^samba4.ldap.acl.python.*AclSPNTests.test_delete_add_spn >diff --git a/source4/dsdb/tests/python/acl.py b/source4/dsdb/tests/python/acl.py >index 6c46a6130df..3c0771d0e8d 100755 >--- a/source4/dsdb/tests/python/acl.py >+++ b/source4/dsdb/tests/python/acl.py >@@ -2189,6 +2189,53 @@ class AclSPNTests(AclTests): > def test_spn_rodc(self): > self.dc_spn_test(self.rodcctx) > >+ def test_delete_add_spn(self): >+ # Grant Validated-SPN property. >+ mod = f'(OA;;SW;{security.GUID_DRS_VALIDATE_SPN};;{self.user_sid1})' >+ self.sd_utils.dacl_add_ace(self.computerdn, mod) >+ >+ spn_base = f'HOST/{self.computername}' >+ >+ allowed_spn = f'{spn_base}.{self.dcctx.dnsdomain}' >+ not_allowed_spn = f'{spn_base}/{self.dcctx.get_domain_name()}' >+ >+ # Ensure we are able to add an allowed SPN. >+ msg = Message(Dn(self.ldb_user1, self.computerdn)) >+ msg['servicePrincipalName'] = MessageElement(allowed_spn, >+ FLAG_MOD_ADD, >+ 'servicePrincipalName') >+ self.ldb_user1.modify(msg) >+ >+ # Ensure we are not able to add a disallowed SPN. >+ msg = Message(Dn(self.ldb_user1, self.computerdn)) >+ msg['servicePrincipalName'] = MessageElement(not_allowed_spn, >+ FLAG_MOD_ADD, >+ 'servicePrincipalName') >+ try: >+ self.ldb_user1.modify(msg) >+ except LdbError as e: >+ num, _ = e.args >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail(f'able to add disallowed SPN {not_allowed_spn}') >+ >+ # Ensure that deleting an existing SPN followed by adding a disallowed >+ # SPN fails. >+ msg = Message(Dn(self.ldb_user1, self.computerdn)) >+ msg['0'] = MessageElement([], >+ FLAG_MOD_DELETE, >+ 'servicePrincipalName') >+ msg['1'] = MessageElement(not_allowed_spn, >+ FLAG_MOD_ADD, >+ 'servicePrincipalName') >+ try: >+ self.ldb_user1.modify(msg) >+ except LdbError as e: >+ num, _ = e.args >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail(f'able to add disallowed SPN {not_allowed_spn}') >+ > > # Important unit running information > >-- >2.25.1 > > >From b8c30263543956f7094fa7116433ee565ab38a2a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:49:31 +1300 >Subject: [PATCH 529/686] CVE-2020-25722 s4:dsdb:tests: Add missing self.fail() > calls > >Without these calls the tests could pass if an expected error did not >occur. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14832 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org Included in backport as changing ACLs while > ACL tests are not checking for unexpected success would be bad] >--- > source4/dsdb/tests/python/acl.py | 32 ++++++++++++++++++++++++++++++++ > 1 file changed, 32 insertions(+) > >diff --git a/source4/dsdb/tests/python/acl.py b/source4/dsdb/tests/python/acl.py >index 3c0771d0e8d..9ca66bd1db4 100755 >--- a/source4/dsdb/tests/python/acl.py >+++ b/source4/dsdb/tests/python/acl.py >@@ -1646,6 +1646,8 @@ userPassword: thatsAcomplPASS1 > except LdbError as e31: > (num, _) = e31.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ pass # Not self.fail() as we normally want success. > > def test_reset_password3(self): > """Grant WP and see what happens (unicodePwd)""" >@@ -1707,6 +1709,8 @@ userPassword: thatsAcomplPASS1 > except LdbError as e34: > (num, _) = e34.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ pass # Not self.fail() as we normally want success > > > class AclExtendedTests(AclTests): >@@ -2023,6 +2027,8 @@ class AclSPNTests(AclTests): > except LdbError as e39: > (num, _) = e39.args > self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ else: >+ self.fail() > > mod = "(OA;;SW;f3a64788-5306-11d1-a9c5-0000f80367c1;;%s)" % str(self.user_sid1) > self.sd_utils.dacl_add_ace(ctx.acct_dn, mod) >@@ -2061,29 +2067,39 @@ class AclSPNTests(AclTests): > except LdbError as e40: > (num, _) = e40.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > try: > self.replace_spn(self.ldb_user1, ctx.acct_dn, "ldap/%s.%s/DomainDnsZones.%s" % > (ctx.myname, ctx.dnsdomain, ctx.dnsdomain)) > except LdbError as e41: > (num, _) = e41.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > try: > self.replace_spn(self.ldb_user1, ctx.acct_dn, "nosuchservice/%s/%s" % ("abcd", "abcd")) > except LdbError as e42: > (num, _) = e42.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > try: > self.replace_spn(self.ldb_user1, ctx.acct_dn, "GC/%s.%s/%s" % > (ctx.myname, ctx.dnsdomain, netbiosdomain)) > except LdbError as e43: > (num, _) = e43.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > try: > self.replace_spn(self.ldb_user1, ctx.acct_dn, "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s" % > (ctx.ntds_guid, ctx.dnsdomain)) > except LdbError as e44: > (num, _) = e44.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > > def test_computer_spn(self): > # with WP, any value can be set >@@ -2129,6 +2145,8 @@ class AclSPNTests(AclTests): > except LdbError as e45: > (num, _) = e45.args > self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ else: >+ self.fail() > > mod = "(OA;;SW;f3a64788-5306-11d1-a9c5-0000f80367c1;;%s)" % str(self.user_sid1) > self.sd_utils.dacl_add_ace(self.computerdn, mod) >@@ -2147,41 +2165,55 @@ class AclSPNTests(AclTests): > except LdbError as e46: > (num, _) = e46.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > try: > self.replace_spn(self.ldb_user1, self.computerdn, "HOST/%s.%s/%s" % > (self.computername, self.dcctx.dnsdomain, netbiosdomain)) > except LdbError as e47: > (num, _) = e47.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > try: > self.replace_spn(self.ldb_user1, self.computerdn, "HOST/%s/%s" % > (self.computername, self.dcctx.dnsdomain)) > except LdbError as e48: > (num, _) = e48.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > try: > self.replace_spn(self.ldb_user1, self.computerdn, "HOST/%s.%s/%s" % > (self.computername, self.dcctx.dnsdomain, self.dcctx.dnsdomain)) > except LdbError as e49: > (num, _) = e49.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > try: > self.replace_spn(self.ldb_user1, self.computerdn, "GC/%s.%s/%s" % > (self.computername, self.dcctx.dnsdomain, self.dcctx.dnsforest)) > except LdbError as e50: > (num, _) = e50.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > try: > self.replace_spn(self.ldb_user1, self.computerdn, "ldap/%s/%s" % (self.computername, netbiosdomain)) > except LdbError as e51: > (num, _) = e51.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > try: > self.replace_spn(self.ldb_user1, self.computerdn, "ldap/%s.%s/ForestDnsZones.%s" % > (self.computername, self.dcctx.dnsdomain, self.dcctx.dnsdomain)) > except LdbError as e52: > (num, _) = e52.args > self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() > > def test_spn_rwdc(self): > self.dc_spn_test(self.dcctx) >-- >2.25.1 > > >From c7f78af1d72004897c2f9b1890bda25a755614ea Mon Sep 17 00:00:00 2001 >From: Nadezhda Ivanova <nivanova@symas.com> >Date: Mon, 25 Oct 2021 14:54:56 +0300 >Subject: [PATCH 530/686] CVE-2020-25722: s4-acl: test Control Access Rights > honor the Applies-to attribute > >Validate Writes and Control Access Rights should only grant access if the >object is of the type listed in the Right's appliesTo attribute. >Tests to verify this behavior > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14832 > >Signed-off-by: Nadezhda Ivanova <nivanova@symas.com> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail.d/bug-14832 | 1 + > source4/dsdb/tests/python/acl.py | 17 +++++++++++++++++ > 2 files changed, 18 insertions(+) > create mode 100644 selftest/knownfail.d/bug-14832 > >diff --git a/selftest/knownfail.d/bug-14832 b/selftest/knownfail.d/bug-14832 >new file mode 100644 >index 00000000000..059a1778e65 >--- /dev/null >+++ b/selftest/knownfail.d/bug-14832 >@@ -0,0 +1 @@ >+^samba4.ldap.acl.python\(.*\).__main__.AclSPNTests.test_user_spn\(.*\) >\ No newline at end of file >diff --git a/source4/dsdb/tests/python/acl.py b/source4/dsdb/tests/python/acl.py >index 9ca66bd1db4..245b5fd7737 100755 >--- a/source4/dsdb/tests/python/acl.py >+++ b/source4/dsdb/tests/python/acl.py >@@ -1925,6 +1925,8 @@ class AclSPNTests(AclTests): > self.computername = "testcomp8" > self.test_user = "spn_test_user8" > self.computerdn = "CN=%s,CN=computers,%s" % (self.computername, self.base_dn) >+ self.user_object = "user_with_spn" >+ self.user_object_dn = "CN=%s,CN=Users,%s" % (self.user_object, self.base_dn) > self.dc_dn = "CN=%s,OU=Domain Controllers,%s" % (self.dcname, self.base_dn) > self.site = "Default-First-Site-Name" > self.rodcctx = DCJoinContext(server=host, creds=creds, lp=lp, >@@ -1946,6 +1948,7 @@ class AclSPNTests(AclTests): > self.dcctx.cleanup_old_join() > delete_force(self.ldb_admin, "cn=%s,cn=computers,%s" % (self.computername, self.base_dn)) > delete_force(self.ldb_admin, self.get_user_dn(self.test_user)) >+ delete_force(self.ldb_admin, self.user_object_dn) > > del self.ldb_user1 > >@@ -2221,6 +2224,20 @@ class AclSPNTests(AclTests): > def test_spn_rodc(self): > self.dc_spn_test(self.rodcctx) > >+ def test_user_spn(self): >+ #grant SW to a regular user and try to set the spn on a user object >+ #should get ERR_INSUFFICIENT_ACCESS_RIGHTS, since Validate-SPN only applies to computer >+ self.ldb_admin.newuser(self.user_object, self.user_pass) >+ mod = "(OA;;SW;f3a64788-5306-11d1-a9c5-0000f80367c1;;%s)" % str(self.user_sid1) >+ self.sd_utils.dacl_add_ace(self.user_object_dn, mod) >+ try: >+ self.replace_spn(self.ldb_user1, self.user_object_dn, "nosuchservice/%s/%s" % ("abcd", "abcd")) >+ except LdbError as e60: >+ (num, _) = e60.args >+ self.assertEqual(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) >+ else: >+ self.fail() >+ > def test_delete_add_spn(self): > # Grant Validated-SPN property. > mod = f'(OA;;SW;{security.GUID_DRS_VALIDATE_SPN};;{self.user_sid1})' >-- >2.25.1 > > >From bd6add0f9d5945139c047c62972f5d818e5a64b8 Mon Sep 17 00:00:00 2001 >From: Nadezhda Ivanova <nivanova@symas.com> >Date: Mon, 18 Oct 2021 14:27:59 +0300 >Subject: [PATCH 531/686] CVE-2020-25722: s4-acl: Make sure Control Access > Rights honor the Applies-to attribute > >Validate Writes and Control Access Rights only grant access if the >object is of the type listed in the Right's appliesTo attribute. For >example, even though a Validated-SPN access may be granted to a user >object in the SD, it should only pass if the object is of class >computer This patch enforces the appliesTo attribute classes for >access checks from within the ldb stack. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14832 > >Signed-off-by: Nadezhda Ivanova <nivanova@symas.com> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail.d/bug-14832 | 1 - > source4/dsdb/common/util.c | 11 +++ > source4/dsdb/samdb/ldb_modules/acl.c | 87 +++++++++++++++++++---- > source4/dsdb/samdb/ldb_modules/acl_util.c | 40 +++++++++++ > source4/dsdb/samdb/ldb_modules/dirsync.c | 13 +++- > source4/dsdb/samdb/ldb_modules/samldb.c | 56 ++++++++------- > 6 files changed, 168 insertions(+), 40 deletions(-) > delete mode 100644 selftest/knownfail.d/bug-14832 > >diff --git a/selftest/knownfail.d/bug-14832 b/selftest/knownfail.d/bug-14832 >deleted file mode 100644 >index 059a1778e65..00000000000 >--- a/selftest/knownfail.d/bug-14832 >+++ /dev/null >@@ -1 +0,0 @@ >-^samba4.ldap.acl.python\(.*\).__main__.AclSPNTests.test_user_spn\(.*\) >\ No newline at end of file >diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c >index 0e81a4ec1dc..36bfb42e45d 100644 >--- a/source4/dsdb/common/util.c >+++ b/source4/dsdb/common/util.c >@@ -1199,6 +1199,17 @@ struct ldb_dn *samdb_sites_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx) > return new_dn; > } > >+struct ldb_dn *samdb_extended_rights_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx) >+{ >+ struct ldb_dn *new_dn; >+ >+ new_dn = ldb_dn_copy(mem_ctx, ldb_get_config_basedn(sam_ctx)); >+ if ( ! ldb_dn_add_child_fmt(new_dn, "CN=Extended-Rights")) { >+ talloc_free(new_dn); >+ return NULL; >+ } >+ return new_dn; >+} > /* > work out the domain sid for the current open ldb > */ >diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c >index 5d36f85b173..4724c877b95 100644 >--- a/source4/dsdb/samdb/ldb_modules/acl.c >+++ b/source4/dsdb/samdb/ldb_modules/acl.c >@@ -698,7 +698,12 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, > return LDB_SUCCESS; > } > >- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module), >+ ret = acl_check_extended_right(tmp_ctx, >+ module, >+ req, >+ objectclass, >+ sd, >+ acl_user_token(module), > GUID_DRS_VALIDATE_SPN, > SEC_ADS_SELF_WRITE, > sid); >@@ -911,7 +916,7 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req) > return ldb_next_request(module, req); > } > >-/* ckecks if modifications are allowed on "Member" attribute */ >+/* checks if modifications are allowed on "Member" attribute */ > static int acl_check_self_membership(TALLOC_CTX *mem_ctx, > struct ldb_module *module, > struct ldb_request *req, >@@ -925,6 +930,16 @@ static int acl_check_self_membership(TALLOC_CTX *mem_ctx, > struct ldb_context *ldb = ldb_module_get_ctx(module); > struct ldb_dn *user_dn; > struct ldb_message_element *member_el; >+ const struct ldb_message *msg = NULL; >+ >+ if (req->operation == LDB_MODIFY) { >+ msg = req->op.mod.message; >+ } else if (req->operation == LDB_ADD) { >+ msg = req->op.add.message; >+ } else { >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ > /* if we have wp, we can do whatever we like */ > if (acl_check_access_on_attribute(module, > mem_ctx, >@@ -935,13 +950,13 @@ static int acl_check_self_membership(TALLOC_CTX *mem_ctx, > return LDB_SUCCESS; > } > /* if we are adding/deleting ourselves, check for self membership */ >- ret = dsdb_find_dn_by_sid(ldb, mem_ctx, >- &acl_user_token(module)->sids[PRIMARY_USER_SID_INDEX], >+ ret = dsdb_find_dn_by_sid(ldb, mem_ctx, >+ &acl_user_token(module)->sids[PRIMARY_USER_SID_INDEX], > &user_dn); > if (ret != LDB_SUCCESS) { > return ret; > } >- member_el = ldb_msg_find_element(req->op.mod.message, "member"); >+ member_el = ldb_msg_find_element(msg, "member"); > if (!member_el) { > return ldb_operr(ldb); > } >@@ -955,13 +970,18 @@ static int acl_check_self_membership(TALLOC_CTX *mem_ctx, > return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; > } > } >- ret = acl_check_extended_right(mem_ctx, sd, acl_user_token(module), >+ ret = acl_check_extended_right(mem_ctx, >+ module, >+ req, >+ objectclass, >+ sd, >+ acl_user_token(module), > GUID_DRS_SELF_MEMBERSHIP, > SEC_ADS_SELF_WRITE, > sid); > if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { > dsdb_acl_debug(sd, acl_user_token(module), >- req->op.mod.message->dn, >+ msg->dn, > true, > 10); > } >@@ -1021,6 +1041,9 @@ static int acl_check_password_rights( > * so we don't have to strict verification of the input. > */ > ret = acl_check_extended_right(tmp_ctx, >+ module, >+ req, >+ objectclass, > sd, > acl_user_token(module), > GUID_DRS_USER_CHANGE_PASSWORD, >@@ -1044,7 +1067,12 @@ static int acl_check_password_rights( > * the only caller is samdb_set_password_internal(), > * so we don't have to strict verification of the input. > */ >- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module), >+ ret = acl_check_extended_right(tmp_ctx, >+ module, >+ req, >+ objectclass, >+ sd, >+ acl_user_token(module), > GUID_DRS_FORCE_CHANGE_PASSWORD, > SEC_ADS_CONTROL_ACCESS, > sid); >@@ -1097,7 +1125,12 @@ static int acl_check_password_rights( > if (rep_attr_cnt > 0) { > pav->pwd_reset = true; > >- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module), >+ ret = acl_check_extended_right(tmp_ctx, >+ module, >+ req, >+ objectclass, >+ sd, >+ acl_user_token(module), > GUID_DRS_FORCE_CHANGE_PASSWORD, > SEC_ADS_CONTROL_ACCESS, > sid); >@@ -1107,7 +1140,12 @@ static int acl_check_password_rights( > if (add_attr_cnt != del_attr_cnt) { > pav->pwd_reset = true; > >- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module), >+ ret = acl_check_extended_right(tmp_ctx, >+ module, >+ req, >+ objectclass, >+ sd, >+ acl_user_token(module), > GUID_DRS_FORCE_CHANGE_PASSWORD, > SEC_ADS_CONTROL_ACCESS, > sid); >@@ -1117,7 +1155,12 @@ static int acl_check_password_rights( > if (add_val_cnt == 1 && del_val_cnt == 1) { > pav->pwd_reset = false; > >- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module), >+ ret = acl_check_extended_right(tmp_ctx, >+ module, >+ req, >+ objectclass, >+ sd, >+ acl_user_token(module), > GUID_DRS_USER_CHANGE_PASSWORD, > SEC_ADS_CONTROL_ACCESS, > sid); >@@ -1131,7 +1174,12 @@ static int acl_check_password_rights( > if (add_val_cnt == 1 && del_val_cnt == 0) { > pav->pwd_reset = true; > >- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module), >+ ret = acl_check_extended_right(tmp_ctx, >+ module, >+ req, >+ objectclass, >+ sd, >+ acl_user_token(module), > GUID_DRS_FORCE_CHANGE_PASSWORD, > SEC_ADS_CONTROL_ACCESS, > sid); >@@ -1686,6 +1734,9 @@ static int acl_check_reanimate_tombstone(TALLOC_CTX *mem_ctx, > struct ldb_result *acl_res; > struct security_descriptor *sd = NULL; > struct dom_sid *sid = NULL; >+ const struct dsdb_schema *schema = NULL; >+ const struct dsdb_class *objectclass = NULL; >+ struct ldb_context *ldb = ldb_module_get_ctx(module); > static const char *acl_attrs[] = { > "nTSecurityDescriptor", > "objectClass", >@@ -1706,10 +1757,20 @@ static int acl_check_reanimate_tombstone(TALLOC_CTX *mem_ctx, > > ret = dsdb_get_sd_from_ldb_message(mem_ctx, req, acl_res->msgs[0], &sd); > sid = samdb_result_dom_sid(mem_ctx, acl_res->msgs[0], "objectSid"); >+ schema = dsdb_get_schema(ldb, req); >+ if (!schema) { >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ objectclass = dsdb_get_structural_oc_from_msg(schema, acl_res->msgs[0]); > if (ret != LDB_SUCCESS || !sd) { > return ldb_operr(ldb_module_get_ctx(module)); > } >- return acl_check_extended_right(mem_ctx, sd, acl_user_token(module), >+ return acl_check_extended_right(mem_ctx, >+ module, >+ req, >+ objectclass, >+ sd, >+ acl_user_token(module), > GUID_DRS_REANIMATE_TOMBSTONE, > SEC_ADS_CONTROL_ACCESS, sid); > } >diff --git a/source4/dsdb/samdb/ldb_modules/acl_util.c b/source4/dsdb/samdb/ldb_modules/acl_util.c >index b9931795e19..e38b264ca23 100644 >--- a/source4/dsdb/samdb/ldb_modules/acl_util.c >+++ b/source4/dsdb/samdb/ldb_modules/acl_util.c >@@ -197,6 +197,9 @@ fail: > > /* checks for validated writes */ > int acl_check_extended_right(TALLOC_CTX *mem_ctx, >+ struct ldb_module *module, >+ struct ldb_request *req, >+ const struct dsdb_class *objectclass, > struct security_descriptor *sd, > struct security_token *token, > const char *ext_right, >@@ -208,6 +211,43 @@ int acl_check_extended_right(TALLOC_CTX *mem_ctx, > uint32_t access_granted; > struct object_tree *root = NULL; > TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); >+ static const char *no_attrs[] = { NULL }; >+ struct ldb_result *extended_rights_res = NULL; >+ struct ldb_dn *extended_rights_dn = NULL; >+ struct ldb_context *ldb = ldb_module_get_ctx(module); >+ int ret = 0; >+ >+ /* >+ * Find the extended right and check if applies to >+ * the objectclass of the object >+ */ >+ extended_rights_dn = samdb_extended_rights_dn(ldb, req); >+ if (!extended_rights_dn) { >+ ldb_set_errstring(ldb, >+ "access_check: CN=Extended-Rights dn could not be generated!"); >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ >+ /* Note: we are checking only the structural object class. */ >+ ret = dsdb_module_search(module, req, &extended_rights_res, >+ extended_rights_dn, LDB_SCOPE_ONELEVEL, >+ no_attrs, >+ DSDB_FLAG_NEXT_MODULE | >+ DSDB_FLAG_AS_SYSTEM, >+ req, >+ "(&(rightsGuid=%s)(appliesTo=%s))", >+ ext_right, >+ GUID_string(tmp_ctx, >+ &(objectclass->schemaIDGUID))); >+ >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } else if (extended_rights_res->count == 0 ) { >+ ldb_debug(ldb, LDB_DEBUG_TRACE, >+ "acl_check_extended_right: Could not find appliesTo for %s\n", >+ ext_right); >+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; >+ } > > GUID_from_string(ext_right, &right); > >diff --git a/source4/dsdb/samdb/ldb_modules/dirsync.c b/source4/dsdb/samdb/ldb_modules/dirsync.c >index 2d19c653706..d08f89b9a9e 100644 >--- a/source4/dsdb/samdb/ldb_modules/dirsync.c >+++ b/source4/dsdb/samdb/ldb_modules/dirsync.c >@@ -1050,7 +1050,9 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req > if (!(dirsync_ctl->flags & LDAP_DIRSYNC_OBJECT_SECURITY)) { > struct dom_sid *sid; > struct security_descriptor *sd = NULL; >- const char *acl_attrs[] = { "nTSecurityDescriptor", "objectSid", NULL }; >+ const char *acl_attrs[] = { "nTSecurityDescriptor", "objectSid", "objectClass", NULL }; >+ const struct dsdb_schema *schema = NULL; >+ const struct dsdb_class *objectclass = NULL; > /* > * If we don't have the flag and if we have the "replicate directory change" granted > * then we upgrade ourself to system to not be blocked by the acl >@@ -1080,7 +1082,14 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req > if (ret != LDB_SUCCESS) { > return ret; > } >- ret = acl_check_extended_right(dsc, sd, acl_user_token(module), GUID_DRS_GET_CHANGES, SEC_ADS_CONTROL_ACCESS, sid); >+ schema = dsdb_get_schema(ldb, req); >+ if (!schema) { >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ objectclass = dsdb_get_structural_oc_from_msg(schema, acl_res->msgs[0]); >+ ret = acl_check_extended_right(dsc, module, req, objectclass, >+ sd, acl_user_token(module), >+ GUID_DRS_GET_CHANGES, SEC_ADS_CONTROL_ACCESS, sid); > > if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { > return ret; >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index babcbd26ee7..9a4b7d946d6 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -2192,12 +2192,15 @@ static int samldb_check_user_account_control_objectclass_invariants( > return LDB_SUCCESS; > } > >-static int samldb_get_domain_secdesc(struct samldb_ctx *ac, >- struct security_descriptor **domain_sd) >+static int samldb_get_domain_secdesc_and_oc(struct samldb_ctx *ac, >+ struct security_descriptor **domain_sd, >+ const struct dsdb_class **objectclass) > { >- const char * const sd_attrs[] = {"ntSecurityDescriptor", NULL}; >+ const char * const sd_attrs[] = {"ntSecurityDescriptor", "objectClass", NULL}; > struct ldb_result *res; > struct ldb_dn *domain_dn = ldb_get_default_basedn(ldb_module_get_ctx(ac->module)); >+ const struct dsdb_schema *schema = NULL; >+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module); > int ret = dsdb_module_search_dn(ac->module, ac, &res, > domain_dn, > sd_attrs, >@@ -2210,6 +2213,11 @@ static int samldb_get_domain_secdesc(struct samldb_ctx *ac, > return ldb_module_operr(ac->module); > } > >+ schema = dsdb_get_schema(ldb, ac->req); >+ if (!schema) { >+ return ldb_module_operr(ac->module);; >+ } >+ *objectclass = dsdb_get_structural_oc_from_msg(schema, res->msgs[0]); > return dsdb_get_sd_from_ldb_message(ldb_module_get_ctx(ac->module), > ac, res->msgs[0], domain_sd); > >@@ -2228,6 +2236,7 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac, > bool need_acl_check = false; > struct security_token *user_token; > struct security_descriptor *domain_sd; >+ const struct dsdb_class *objectclass = NULL; > const struct uac_to_guid { > uint32_t uac; > uint32_t priv_to_change_from; >@@ -2313,7 +2322,7 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac, > return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; > } > >- ret = samldb_get_domain_secdesc(ac, &domain_sd); >+ ret = samldb_get_domain_secdesc_and_oc(ac, &domain_sd, &objectclass); > if (ret != LDB_SUCCESS) { > return ret; > } >@@ -2344,7 +2353,11 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac, > ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; > } > } else if (map[i].guid) { >- ret = acl_check_extended_right(ac, domain_sd, >+ ret = acl_check_extended_right(ac, >+ ac->module, >+ ac->req, >+ objectclass, >+ domain_sd, > user_token, > map[i].guid, > SEC_ADS_CONTROL_ACCESS, >@@ -2684,12 +2697,11 @@ static int samldb_check_pwd_last_set_acl(struct samldb_ctx *ac, > { > struct ldb_context *ldb = ldb_module_get_ctx(ac->module); > int ret = 0; >- struct ldb_result *res = NULL; >- const char * const sd_attrs[] = {"ntSecurityDescriptor", NULL}; > struct security_token *user_token = NULL; > struct security_descriptor *domain_sd = NULL; > struct ldb_dn *domain_dn = ldb_get_default_basedn(ldb_module_get_ctx(ac->module)); > const char *operation = ""; >+ const struct dsdb_class *objectclass = NULL; > > if (dsdb_module_am_system(ac->module)) { > return LDB_SUCCESS; >@@ -2711,24 +2723,15 @@ static int samldb_check_pwd_last_set_acl(struct samldb_ctx *ac, > return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; > } > >- ret = dsdb_module_search_dn(ac->module, ac, &res, >- domain_dn, >- sd_attrs, >- DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED, >- ac->req); >- if (ret != LDB_SUCCESS) { >- return ret; >- } >- if (res->count != 1) { >- return ldb_module_operr(ac->module); >- } >- >- ret = dsdb_get_sd_from_ldb_message(ldb, ac, res->msgs[0], &domain_sd); >+ ret = samldb_get_domain_secdesc_and_oc(ac, &domain_sd, &objectclass); > if (ret != LDB_SUCCESS) { > return ret; > } >- >- ret = acl_check_extended_right(ac, domain_sd, >+ ret = acl_check_extended_right(ac, >+ ac->module, >+ ac->req, >+ objectclass, >+ domain_sd, > user_token, > GUID_DRS_UNEXPIRE_PASSWORD, > SEC_ADS_CONTROL_ACCESS, >@@ -3757,16 +3760,21 @@ static int samldb_check_sensitive_attributes(struct samldb_ctx *ac) > el = ldb_msg_find_element(ac->msg, "msDS-SecondaryKrbTgtNumber"); > if (el) { > struct security_descriptor *domain_sd; >+ const struct dsdb_class *objectclass = NULL; > /* > * msDS-SecondaryKrbTgtNumber allows the creator to > * become an RODC, this is trusted as an RODC > * account > */ >- ret = samldb_get_domain_secdesc(ac, &domain_sd); >+ ret = samldb_get_domain_secdesc_and_oc(ac, &domain_sd, &objectclass); > if (ret != LDB_SUCCESS) { > return ret; > } >- ret = acl_check_extended_right(ac, domain_sd, >+ ret = acl_check_extended_right(ac, >+ ac->module, >+ ac->req, >+ objectclass, >+ domain_sd, > user_token, > GUID_DRS_DS_INSTALL_REPLICA, > SEC_ADS_CONTROL_ACCESS, >-- >2.25.1 > > >From 4812c657901228da62a0bb154410dce546704966 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 1 Nov 2021 17:19:29 +1300 >Subject: [PATCH 532/686] CVE-2020-25722 Check all elements in acl_check_spn() > not just the first one > >Thankfully we are aleady in a loop over all the message elements in >acl_modify() so this is an easy and safe change to make. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > selftest/knownfail.d/acl-spn | 1 - > source4/dsdb/samdb/ldb_modules/acl.c | 31 +++++++++++++++++++++------- > 2 files changed, 23 insertions(+), 9 deletions(-) > delete mode 100644 selftest/knownfail.d/acl-spn > >diff --git a/selftest/knownfail.d/acl-spn b/selftest/knownfail.d/acl-spn >deleted file mode 100644 >index e68add920a6..00000000000 >--- a/selftest/knownfail.d/acl-spn >+++ /dev/null >@@ -1 +0,0 @@ >-^samba4.ldap.acl.python.*AclSPNTests.test_delete_add_spn >diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c >index 4724c877b95..e0f572daeb3 100644 >--- a/source4/dsdb/samdb/ldb_modules/acl.c >+++ b/source4/dsdb/samdb/ldb_modules/acl.c >@@ -653,9 +653,14 @@ success: > return LDB_SUCCESS; > } > >+/* >+ * Passing in 'el' is critical, we want to check all the values. >+ * >+ */ > static int acl_check_spn(TALLOC_CTX *mem_ctx, > struct ldb_module *module, > struct ldb_request *req, >+ const struct ldb_message_element *el, > struct security_descriptor *sd, > struct dom_sid *sid, > const struct dsdb_attribute *attr, >@@ -667,7 +672,6 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, > struct ldb_context *ldb = ldb_module_get_ctx(module); > struct ldb_result *acl_res; > struct ldb_result *netbios_res; >- struct ldb_message_element *el; > struct ldb_dn *partitions_dn = samdb_partitions_dn(ldb, tmp_ctx); > uint32_t userAccountControl; > const char *samAccountName; >@@ -717,6 +721,23 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, > return ret; > } > >+ /* >+ * If we have "validated write spn", allow delete of any >+ * existing value (this keeps constrained delete to the same >+ * rules as unconstrained) >+ */ >+ if (req->operation == LDB_MODIFY) { >+ /* >+ * If not add or replace (eg delete), >+ * return success >+ */ >+ if ((el->flags >+ & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE)) == 0) { >+ talloc_free(tmp_ctx); >+ return LDB_SUCCESS; >+ } >+ } >+ > ret = dsdb_module_search_dn(module, tmp_ctx, > &acl_res, req->op.mod.message->dn, > acl_attrs, >@@ -745,13 +766,6 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, > > netbios_name = ldb_msg_find_attr_as_string(netbios_res->msgs[0], "nETBIOSName", NULL); > >- el = ldb_msg_find_element(req->op.mod.message, "servicePrincipalName"); >- if (!el) { >- talloc_free(tmp_ctx); >- return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, >- "Error finding element for servicePrincipalName."); >- } >- > /* NTDSDSA objectGuid of object we are checking SPN for */ > if (userAccountControl & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) { > ret = dsdb_module_find_ntdsguid_for_computer(module, tmp_ctx, >@@ -1510,6 +1524,7 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) > ret = acl_check_spn(tmp_ctx, > module, > req, >+ el, > sd, > sid, > attr, >-- >2.25.1 > > >From 4913703512239a913e496d65243947827d907723 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 1 Nov 2021 17:21:16 +1300 >Subject: [PATCH 533/686] CVE-2020-25722 Check for all errors from > acl_check_extended_right() in acl_check_spn() > >We should not fail open on error. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/dsdb/samdb/ldb_modules/acl.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c >index e0f572daeb3..71b3eaba2e4 100644 >--- a/source4/dsdb/samdb/ldb_modules/acl.c >+++ b/source4/dsdb/samdb/ldb_modules/acl.c >@@ -712,7 +712,7 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, > SEC_ADS_SELF_WRITE, > sid); > >- if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { >+ if (ret != LDB_SUCCESS) { > dsdb_acl_debug(sd, acl_user_token(module), > req->op.mod.message->dn, > true, >-- >2.25.1 > > >From d224d7e0a82c063b2fedf7fb6af8a2136a6d0094 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Mon, 4 Oct 2021 12:56:42 +1300 >Subject: [PATCH 534/686] CVE-2020-25722 pytests: add reverse lookup dict for > LDB error codes > >You can give ldb_err() it a number, an LdbError, or a sequence of >numbers, and it will return the corresponding strings. Examples: > >ldb_err(68) # "LDB_ERR_ENTRY_ALREADY_EXISTS" >LDB_ERR_LUT[68] # "LDB_ERR_ENTRY_ALREADY_EXISTS" > >expected = (ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, > ldb.ERR_INVALID_CREDENTIALS) >try: > foo() >except ldb.LdbError as e: > self.fail(f"got {ldb_err(e)}, expected one of {ldb_err(expected)}") > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/__init__.py | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > >diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py >index 579b21f7f17..7f97563648f 100644 >--- a/python/samba/tests/__init__.py >+++ b/python/samba/tests/__init__.py >@@ -63,6 +63,22 @@ BINDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), > > HEXDUMP_FILTER = bytearray([x if ((len(repr(chr(x))) == 3) and (x < 127)) else ord('.') for x in range(256)]) > >+LDB_ERR_LUT = {v: k for k,v in vars(ldb).items() if k.startswith('ERR_')} >+ >+def ldb_err(v): >+ if isinstance(v, ldb.LdbError): >+ v = v.args[0] >+ >+ if v in LDB_ERR_LUT: >+ return LDB_ERR_LUT[v] >+ >+ try: >+ return f"[{', '.join(LDB_ERR_LUT.get(x, x) for x in v)}]" >+ except TypeError as e: >+ print(e) >+ return v >+ >+ > def DynamicTestCase(cls): > cls.setUpDynamicTestCases() > return cls >-- >2.25.1 > > >From 22f6d8388779f45107f3cd1bc418e6bed3a74230 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Sun, 24 Oct 2021 15:18:05 +1300 >Subject: [PATCH 535/686] CVE-2020-25722 pytest: assertRaisesLdbError invents a > message if you're lazy > >This makes it easier to convert tests that don't have good messages. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/__init__.py | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py >index 7f97563648f..71295c7c403 100644 >--- a/python/samba/tests/__init__.py >+++ b/python/samba/tests/__init__.py >@@ -315,6 +315,8 @@ class TestCase(unittest.TestCase): > > def assertRaisesLdbError(self, errcode, message, f, *args, **kwargs): > """Assert a function raises a particular LdbError.""" >+ if message is None: >+ message = f"{f.__name__}(*{args}, **{kwargs})" > try: > f(*args, **kwargs) > except ldb.LdbError as e: >-- >2.25.1 > > >From 24d852b1a0b0b3ba8444929409fb557a66bb5c4f Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 11 Aug 2021 16:56:07 +1200 >Subject: [PATCH 536/686] CVE-2020-25722 s4/dsdb/cracknames: always free > tmp_ctx in spn_alias > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/cracknames.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > >diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c >index 3360d9a48a5..b319b4232a7 100644 >--- a/source4/dsdb/samdb/cracknames.c >+++ b/source4/dsdb/samdb/cracknames.c >@@ -99,10 +99,12 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, stru > > service_dn = ldb_dn_new(tmp_ctx, ldb_ctx, "CN=Directory Service,CN=Windows NT,CN=Services"); > if ( ! ldb_dn_add_base(service_dn, ldb_get_config_basedn(ldb_ctx))) { >+ talloc_free(tmp_ctx); > return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; > } > service_dn_str = ldb_dn_alloc_linearized(tmp_ctx, service_dn); > if ( ! service_dn_str) { >+ talloc_free(tmp_ctx); > return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; > } > >@@ -111,13 +113,15 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, stru > > if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { > DEBUG(1, ("ldb_search: dn: %s not found: %s\n", service_dn_str, ldb_errstring(ldb_ctx))); >+ talloc_free(tmp_ctx); > return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; > } else if (ret == LDB_ERR_NO_SUCH_OBJECT) { > DEBUG(1, ("ldb_search: dn: %s not found\n", service_dn_str)); >+ talloc_free(tmp_ctx); > return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; > } else if (res->count != 1) { >- talloc_free(res); > DEBUG(1, ("ldb_search: dn: %s not found\n", service_dn_str)); >+ talloc_free(tmp_ctx); > return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; > } > >-- >2.25.1 > > >From 2b34be63edfb950e91f11c35c2122d134d88397d Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Tue, 10 Aug 2021 23:02:36 +0000 >Subject: [PATCH 537/686] CVE-2020-25722 s4/cracknames: lookup_spn_alias > doesn't need krb5 context > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/cracknames.c | 7 +++---- > 1 file changed, 3 insertions(+), 4 deletions(-) > >diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c >index b319b4232a7..582cfba3056 100644 >--- a/source4/dsdb/samdb/cracknames.c >+++ b/source4/dsdb/samdb/cracknames.c >@@ -72,9 +72,9 @@ static WERROR dns_domain_from_principal(TALLOC_CTX *mem_ctx, struct smb_krb5_con > > info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY; > return WERR_OK; >-} >+} > >-static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, struct ldb_context *ldb_ctx, >+static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(struct ldb_context *ldb_ctx, > TALLOC_CTX *mem_ctx, > const char *alias_from, > char **alias_to) >@@ -219,8 +219,7 @@ static WERROR DsCrackNameSPNAlias(struct ldb_context *sam_ctx, TALLOC_CTX *mem_c > dns_name = (const char *)component->data; > > /* MAP it */ >- namestatus = LDB_lookup_spn_alias(smb_krb5_context->krb5_context, >- sam_ctx, mem_ctx, >+ namestatus = LDB_lookup_spn_alias(sam_ctx, mem_ctx, > service, &new_service); > > if (namestatus == DRSUAPI_DS_NAME_STATUS_NOT_FOUND) { >-- >2.25.1 > > >From d9973bb6d16192302c73534d576e2b2acb132f1a Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 28 Jul 2021 05:38:50 +0000 >Subject: [PATCH 538/686] CVE-2020-25722 samba-tool spn: accept -H for database > url > >Following the convention and making testing easier > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/netcmd/spn.py | 33 ++++++++++++++++++++++----------- > 1 file changed, 22 insertions(+), 11 deletions(-) > >diff --git a/python/samba/netcmd/spn.py b/python/samba/netcmd/spn.py >index f0069460e3e..46e9c59272a 100644 >--- a/python/samba/netcmd/spn.py >+++ b/python/samba/netcmd/spn.py >@@ -18,7 +18,6 @@ > > import samba.getopt as options > import ldb >-from samba import provision > from samba.samdb import SamDB > from samba.auth import system_session > from samba.netcmd.common import _get_user_realm_domain >@@ -40,14 +39,20 @@ class cmd_spn_list(Command): > "credopts": options.CredentialsOptions, > "versionopts": options.VersionOptions, > } >+ takes_options = [ >+ Option("-H", "--URL", help="LDB URL for database or target server", >+ type=str, metavar="URL", dest="H"), >+ ] > > takes_args = ["user"] > >- def run(self, user, credopts=None, sambaopts=None, versionopts=None): >+ def run(self, user, H=None, >+ credopts=None, >+ sambaopts=None, >+ versionopts=None): > lp = sambaopts.get_loadparm() > creds = credopts.get_credentials(lp) >- paths = provision.provision_paths_from_lp(lp, lp.get("realm")) >- sam = SamDB(paths.samdb, session_info=system_session(), >+ sam = SamDB(H, session_info=system_session(), > credentials=creds, lp=lp) > # TODO once I understand how, use the domain info to naildown > # to the correct domain >@@ -82,17 +87,20 @@ class cmd_spn_add(Command): > "versionopts": options.VersionOptions, > } > takes_options = [ >+ Option("-H", "--URL", help="LDB URL for database or target server", >+ type=str, metavar="URL", dest="H"), > Option("--force", help="Force the addition of the spn" > " even it exists already", action="store_true"), >- ] >+ ] > takes_args = ["name", "user"] > >- def run(self, name, user, force=False, credopts=None, sambaopts=None, >+ def run(self, name, user, H=None, force=False, >+ credopts=None, >+ sambaopts=None, > versionopts=None): > lp = sambaopts.get_loadparm() > creds = credopts.get_credentials(lp) >- paths = provision.provision_paths_from_lp(lp, lp.get("realm")) >- sam = SamDB(paths.samdb, session_info=system_session(), >+ sam = SamDB(H, session_info=system_session(), > credentials=creds, lp=lp) > res = sam.search( > expression="servicePrincipalName=%s" % ldb.binary_encode(name), >@@ -141,15 +149,18 @@ class cmd_spn_delete(Command): > "credopts": options.CredentialsOptions, > "versionopts": options.VersionOptions, > } >+ takes_options = [ >+ Option("-H", "--URL", help="LDB URL for database or target server", >+ type=str, metavar="URL", dest="H"), >+ ] > > takes_args = ["name", "user?"] > >- def run(self, name, user=None, credopts=None, sambaopts=None, >+ def run(self, name, user=None, H=None, credopts=None, sambaopts=None, > versionopts=None): > lp = sambaopts.get_loadparm() > creds = credopts.get_credentials(lp) >- paths = provision.provision_paths_from_lp(lp, lp.get("realm")) >- sam = SamDB(paths.samdb, session_info=system_session(), >+ sam = SamDB(H, session_info=system_session(), > credentials=creds, lp=lp) > res = sam.search( > expression="servicePrincipalName=%s" % ldb.binary_encode(name), >-- >2.25.1 > > >From 48d6983845142311b025ebe64a593d5a5b78e672 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 27 Aug 2021 11:36:42 +1200 >Subject: [PATCH 539/686] CVE-2020-25722 samba-tool spn add: remove --force > option > >This did not actually *force* the creation of a duplicate SPN, it just >ignored the client-side check for the existing copy. Soon we are going >to enforce SPN uniqueness on the server side, and this --force will not >work. This will make the --force test fail, and if that tests fail, so >will others that depend the duplicate values. So we remove those tests. > >It is wrong-headed to try to make duplicate SPNs in any case, which is >probably why there is no sign of anyone ever having used this option. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/netcmd/spn.py | 6 ++---- > source4/setup/tests/blackbox_spn.sh | 5 +---- > 2 files changed, 3 insertions(+), 8 deletions(-) > >diff --git a/python/samba/netcmd/spn.py b/python/samba/netcmd/spn.py >index 46e9c59272a..2676ff34fac 100644 >--- a/python/samba/netcmd/spn.py >+++ b/python/samba/netcmd/spn.py >@@ -89,12 +89,10 @@ class cmd_spn_add(Command): > takes_options = [ > Option("-H", "--URL", help="LDB URL for database or target server", > type=str, metavar="URL", dest="H"), >- Option("--force", help="Force the addition of the spn" >- " even it exists already", action="store_true"), > ] > takes_args = ["name", "user"] > >- def run(self, name, user, H=None, force=False, >+ def run(self, name, user, H=None, > credopts=None, > sambaopts=None, > versionopts=None): >@@ -105,7 +103,7 @@ class cmd_spn_add(Command): > res = sam.search( > expression="servicePrincipalName=%s" % ldb.binary_encode(name), > scope=ldb.SCOPE_SUBTREE) >- if len(res) != 0 and not force: >+ if len(res) != 0: > raise CommandError("Service principal %s already" > " affected to another user" % name) > >diff --git a/source4/setup/tests/blackbox_spn.sh b/source4/setup/tests/blackbox_spn.sh >index 429ace9494f..764ded4c88b 100755 >--- a/source4/setup/tests/blackbox_spn.sh >+++ b/source4/setup/tests/blackbox_spn.sh >@@ -22,11 +22,8 @@ testit "addspn" $PYTHON $samba_tool spn add FOO/bar Administrator $CONFIG > testit "delspn" $PYTHON $samba_tool spn delete FOO/bar $CONFIG > testit "readdspn" $PYTHON $samba_tool spn add FOO/bar Administrator $CONFIG > testit_expect_failure "failexistingspn" $PYTHON $samba_tool spn add FOO/bar Guest $CONFIG >-testit "existingspnforce" $PYTHON $samba_tool spn add --force FOO/bar Guest $CONFIG > testit_expect_failure "faildelspnnotgooduser" $PYTHON $samba_tool spn delete FOO/bar krbtgt $CONFIG >-testit_expect_failure "faildelspnmoreoneuser" $PYTHON $samba_tool spn delete FOO/bar $CONFIG >-testit "deluserspn" $PYTHON $samba_tool spn delete FOO/bar Guest $CONFIG >-testit "dellastuserspn" $PYTHON $samba_tool spn delete FOO/bar $CONFIG >+testit "deluserspn" $PYTHON $samba_tool spn delete FOO/bar $CONFIG > testit_expect_failure "faildelspn" $PYTHON $samba_tool spn delete FOO/bar $CONFIG > testit_expect_failure "failaddspn" $PYTHON $samba_tool spn add FOO/bar nonexistinguser $CONFIG > >-- >2.25.1 > > >From 3c97ddb2e11d063223eadec7007ede417e3ce9e1 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 1 Sep 2021 18:35:02 +1200 >Subject: [PATCH 540/686] CVE-2020-25722 tests: blackbox samba-tool spn > non-admin test > >It is soon going to be impossible to add duplicate SPNs (short of >going behind DSDB's back on the local filesystem). Our test of adding >SPNs on non-admin users doubled as the test for adding a duplicate (using >--force). As --force is gone, we add these tests on Guest after the SPN >on Administrator is gone. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/setup/tests/blackbox_spn.sh | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/source4/setup/tests/blackbox_spn.sh b/source4/setup/tests/blackbox_spn.sh >index 764ded4c88b..8f0258d0db8 100755 >--- a/source4/setup/tests/blackbox_spn.sh >+++ b/source4/setup/tests/blackbox_spn.sh >@@ -24,6 +24,8 @@ testit "readdspn" $PYTHON $samba_tool spn add FOO/bar Administrator $CONFIG > testit_expect_failure "failexistingspn" $PYTHON $samba_tool spn add FOO/bar Guest $CONFIG > testit_expect_failure "faildelspnnotgooduser" $PYTHON $samba_tool spn delete FOO/bar krbtgt $CONFIG > testit "deluserspn" $PYTHON $samba_tool spn delete FOO/bar $CONFIG >+testit "readd_spn_guest" $PYTHON $samba_tool spn add FOO/bar Guest $CONFIG >+testit "deluserspn_guest" $PYTHON $samba_tool spn delete FOO/bar Guest $CONFIG > testit_expect_failure "faildelspn" $PYTHON $samba_tool spn delete FOO/bar $CONFIG > testit_expect_failure "failaddspn" $PYTHON $samba_tool spn add FOO/bar nonexistinguser $CONFIG > >-- >2.25.1 > > >From c25d1570f9491f116b708eca571e111f7e051bfb Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Thu, 28 Oct 2021 09:45:36 +1300 >Subject: [PATCH 541/686] CVE-2020-25722 s4/provision: add host/ SPNs at the > start > >There are two reasons for this. Firstly, leaving SPNs unclaimed is >dangerous, as someone else could grab them first. Secondly, in some >circumstances (self join) we try to add a DNS/ SPN a little bit later >in provision. Under the rules we are introducing for CVE-2020-25722, >this will make our later attempts to add HOST/ fail. > >This causes a few errors in samba4.blackbox.dbcheck.* tests, which >assert that revivified old domains match stored reference versions. >Now they don't, because they have servicePrincipalNames. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail.d/cve-2020-25722-provision | 4 ++++ > source4/setup/provision_self_join.ldif | 9 +++++++-- > 2 files changed, 11 insertions(+), 2 deletions(-) > create mode 100644 selftest/knownfail.d/cve-2020-25722-provision > >diff --git a/selftest/knownfail.d/cve-2020-25722-provision b/selftest/knownfail.d/cve-2020-25722-provision >new file mode 100644 >index 00000000000..7fd4b4b3763 >--- /dev/null >+++ b/selftest/knownfail.d/cve-2020-25722-provision >@@ -0,0 +1,4 @@ >+samba4.blackbox.dbcheck.release-4-0-0 >+samba4.blackbox.dbcheck.release-4-0-0.quick >+samba4.blackbox.upgradeprovision.release-4-0-0 >+samba4.blackbox.functionalprep.check_databases_same >diff --git a/source4/setup/provision_self_join.ldif b/source4/setup/provision_self_join.ldif >index f77ac5710ec..92bf4d9cf8f 100644 >--- a/source4/setup/provision_self_join.ldif >+++ b/source4/setup/provision_self_join.ldif >@@ -15,11 +15,16 @@ localPolicyFlags: 0 > operatingSystem: Samba > operatingSystemVersion: ${SAMBA_VERSION_STRING} > sAMAccountName: ${NETBIOSNAME}$ >-# The "servicePrincipalName" updates are now handled by the "samba_spnupdate" >-# script > userAccountControl: 532480 > clearTextPassword:: ${MACHINEPASS_B64} > objectSid: ${DOMAINSID}-${DCRID} >+# While some "servicePrincipalName" updates might be handled by the >+# "samba_spnupdate" script, we need to get the basics in here before >+# we add any others. >+servicePrincipalName: HOST/${DNSNAME} >+servicePrincipalName: HOST/${NETBIOSNAME} >+servicePrincipalName: HOST/${DNSNAME}/${DNSNAME} >+ > > dn: CN=RID Set,CN=${NETBIOSNAME},OU=Domain Controllers,${DOMAINDN} > objectClass: rIDSet >-- >2.25.1 > > >From 606fc193aa4fb7bb0e61dbf0b9d19c3b79e89d70 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Thu, 28 Oct 2021 13:07:01 +1300 >Subject: [PATCH 542/686] CVE-2020-25722 blackbox/upgrades tests: ignore SPN > for ldapcmp > >We need to have the SPNs there before someone else nabs them, which >makes the re-provisioned old releases different from the reference >versions that we keep for this comparison. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Adapted to fix conflict with > msDS-SupportedEncryptionTypes] >--- > selftest/knownfail.d/cve-2020-25722-provision | 4 ---- > source4/setup/tests/blackbox_upgradeprovision.sh | 8 ++++---- > testprogs/blackbox/dbcheck-oldrelease.sh | 4 ++-- > testprogs/blackbox/functionalprep.sh | 2 +- > testprogs/blackbox/upgradeprovision-oldrelease.sh | 4 ++-- > 5 files changed, 9 insertions(+), 13 deletions(-) > delete mode 100644 selftest/knownfail.d/cve-2020-25722-provision > >diff --git a/selftest/knownfail.d/cve-2020-25722-provision b/selftest/knownfail.d/cve-2020-25722-provision >deleted file mode 100644 >index 7fd4b4b3763..00000000000 >--- a/selftest/knownfail.d/cve-2020-25722-provision >+++ /dev/null >@@ -1,4 +0,0 @@ >-samba4.blackbox.dbcheck.release-4-0-0 >-samba4.blackbox.dbcheck.release-4-0-0.quick >-samba4.blackbox.upgradeprovision.release-4-0-0 >-samba4.blackbox.functionalprep.check_databases_same >diff --git a/source4/setup/tests/blackbox_upgradeprovision.sh b/source4/setup/tests/blackbox_upgradeprovision.sh >index 85c085fc1c2..b7c55172ef3 100755 >--- a/source4/setup/tests/blackbox_upgradeprovision.sh >+++ b/source4/setup/tests/blackbox_upgradeprovision.sh >@@ -42,19 +42,19 @@ upgradeprovision_full() { > # really doesn't change anything. > > ldapcmp() { >- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX/upgradeprovision/private/sam.ldb tdb://$PREFIX/upgradeprovision_reference/private/sam.ldb --two --skip-missing-dn >+ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX/upgradeprovision/private/sam.ldb tdb://$PREFIX/upgradeprovision_reference/private/sam.ldb --two --skip-missing-dn --filter=servicePrincipalName > } > > ldapcmp_full() { >- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX/upgradeprovision_full/private/sam.ldb tdb://$PREFIX/upgradeprovision_reference/private/sam.ldb --two --skip-missing-dn >+ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX/upgradeprovision_full/private/sam.ldb tdb://$PREFIX/upgradeprovision_reference/private/sam.ldb --two --skip-missing-dn --filter=servicePrincipalName > } > > ldapcmp_sd() { >- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX/upgradeprovision/private/sam.ldb tdb://$PREFIX/upgradeprovision_reference/private/sam.ldb --two --sd --skip-missing-dn >+ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX/upgradeprovision/private/sam.ldb tdb://$PREFIX/upgradeprovision_reference/private/sam.ldb --two --sd --skip-missing-dn --filter=servicePrincipalName > } > > ldapcmp_full_sd() { >- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX/upgradeprovision_full/private/sam.ldb tdb://$PREFIX/upgradeprovision_reference/private/sam.ldb --two --sd --skip-missing-dn >+ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX/upgradeprovision_full/private/sam.ldb tdb://$PREFIX/upgradeprovision_reference/private/sam.ldb --two --sd --skip-missing-dn --filter=servicePrincipalName > } > > testit "upgradeprovision" upgradeprovision >diff --git a/testprogs/blackbox/dbcheck-oldrelease.sh b/testprogs/blackbox/dbcheck-oldrelease.sh >index 3d0ee2c165a..cc7bba3d470 100755 >--- a/testprogs/blackbox/dbcheck-oldrelease.sh >+++ b/testprogs/blackbox/dbcheck-oldrelease.sh >@@ -388,13 +388,13 @@ referenceprovision() { > > ldapcmp() { > if [ x$RELEASE = x"release-4-0-0" ]; then >- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb --two --skip-missing-dn --filter=dnsRecord,displayName >+ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb --two --skip-missing-dn --filter=dnsRecord,displayName,servicePrincipalName > fi > } > > ldapcmp_sd() { > if [ x$RELEASE = x"release-4-0-0" ]; then >- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb --two --sd --skip-missing-dn >+ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb --two --sd --skip-missing-dn --filter=servicePrincipalName > fi > } > >diff --git a/testprogs/blackbox/functionalprep.sh b/testprogs/blackbox/functionalprep.sh >index 80e82252d45..e8683726ae1 100755 >--- a/testprogs/blackbox/functionalprep.sh >+++ b/testprogs/blackbox/functionalprep.sh >@@ -61,7 +61,7 @@ provision_2012r2() { > ldapcmp_ignore() { > # At some point we will need to ignore, but right now, it should be perfect > IGNORE_ATTRS=$1 >- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/$2/private/sam.ldb tdb://$PREFIX_ABS/$3/private/sam.ldb --two --skip-missing-dn >+ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/$2/private/sam.ldb tdb://$PREFIX_ABS/$3/private/sam.ldb --two --skip-missing-dn --filter=servicePrincipalName > } > > ldapcmp() { >diff --git a/testprogs/blackbox/upgradeprovision-oldrelease.sh b/testprogs/blackbox/upgradeprovision-oldrelease.sh >index 76276168011..28a3704d4eb 100755 >--- a/testprogs/blackbox/upgradeprovision-oldrelease.sh >+++ b/testprogs/blackbox/upgradeprovision-oldrelease.sh >@@ -106,12 +106,12 @@ referenceprovision() { > > ldapcmp() { > if [ x$RELEASE != x"alpha13" ]; then >- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_upgrade_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}_upgrade/private/sam.ldb --two --skip-missing-dn --filter=dnsRecord,displayName >+ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_upgrade_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}_upgrade/private/sam.ldb --two --skip-missing-dn --filter=dnsRecord,displayName,servicePrincipalName > fi > } > > ldapcmp_full() { >- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_upgrade_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}_upgrade_full/private/sam.ldb --two --filter=dNSProperty,dnsRecord,cn,displayName,versionNumber,systemFlags,msDS-HasInstantiatedNCs --skip-missing-dn >+ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_upgrade_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}_upgrade_full/private/sam.ldb --two --filter=dNSProperty,dnsRecord,cn,displayName,versionNumber,systemFlags,msDS-HasInstantiatedNCs,servicePrincipalName --skip-missing-dn > } > > ldapcmp_sd() { >-- >2.25.1 > > >From 04151067987439f90d2a08d17b4028aafaf77b43 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Mon, 13 Sep 2021 14:15:09 +1200 >Subject: [PATCH 543/686] CVE-2020-25722 pytest: test > sAMAccountName/userPrincipalName over ldap > >Because the sam account name + the dns host name is used as the >default user principal name, we need to check for collisions between >these. Fixes are coming in upcoming patches. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Adapted to fix conflicts and remove usage of > f-string] >--- > python/samba/tests/ldap_upn_sam_account.py | 510 +++++++++++++++++++++ > selftest/knownfail.d/ldap_upn_sam_account | 16 + > source4/selftest/tests.py | 9 + > 3 files changed, 535 insertions(+) > create mode 100644 python/samba/tests/ldap_upn_sam_account.py > create mode 100644 selftest/knownfail.d/ldap_upn_sam_account > >diff --git a/python/samba/tests/ldap_upn_sam_account.py b/python/samba/tests/ldap_upn_sam_account.py >new file mode 100644 >index 00000000000..cc1cce9b6c3 >--- /dev/null >+++ b/python/samba/tests/ldap_upn_sam_account.py >@@ -0,0 +1,510 @@ >+# Unix SMB/CIFS implementation. >+# >+# Copyright 2021 (C) Catalyst IT Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+ >+ >+import os >+import sys >+from samba.samdb import SamDB >+from samba.auth import system_session >+import ldb >+from samba.tests.subunitrun import SubunitOptions, TestProgram >+from samba.tests import TestCase, ldb_err >+from samba.tests import DynamicTestCase >+import samba.getopt as options >+import optparse >+from samba.colour import c_RED, c_GREEN, c_DARK_YELLOW >+import re >+import pprint >+from samba.dsdb import ( >+ UF_SERVER_TRUST_ACCOUNT, >+ UF_TRUSTED_FOR_DELEGATION, >+) >+ >+ >+# bad sAMAccountName characters from [MS-SAMR] >+# "3.1.1.6 Attribute Constraints for Originating Updates" >+BAD_SAM_CHARS = (''.join(chr(x) for x in range(0, 32)) + >+ '"/\\[]:|<>+=;?,*') >+ >+# 0x7f is *said* to be bad, but turns out to be fine. >+ALLEGED_BAD_SAM_CHARS = chr(127) >+ >+LATIN1_BAD_CHARS = set([chr(x) for x in range(129, 160)] + >+ list("ªºÿ") + >+ [chr(x) for x in range(0xc0, 0xc6)] + >+ [chr(x) for x in range(0xc7, 0xd7)] + >+ [chr(x) for x in range(0xd8, 0xde)] + >+ [chr(x) for x in range(0xe0, 0xe6)] + >+ [chr(x) for x in range(0xe7, 0xf7)] + >+ [chr(x) for x in range(0xf8, 0xfe)]) >+ >+ >+LATIN_EXTENDED_A_NO_CLASH = {306, 307, 330, 331, 338, 339, 358, 359, 383} >+ >+#XXX does '\x00' just truncate the string though? >+#XXX elsewhere we see "[\\\"|,/:<>+=;?*']" with "'" >+ >+ >+## UPN limits >+# max length 1024 UTF-8 bytes, following "rfc822" >+# for o365 sync https://docs.microsoft.com/en-us/microsoft-365/enterprise/prepare-for-directory-synchronization?view=o365-worldwide >+# max length is 113 [64 before @] "@" [48 after @] >+# invalid chars: '\\%&*+/=?{}|<>();:,[]"' >+# allowed chars: A â Z, a - z, 0 â 9, ' . - _ ! # ^ ~ >+# "Letters with diacritical marks, such as umlauts, accents, and tildes, are invalid characters." >+# >+# "@" can't be first >+# "The username cannot end with a period (.), an ampersand (&), a space, or an at sign (@)." >+# >+ >+# per RFC 822, «"a b" @ example.org» is >+ >+ >+ok = True >+bad = False >+report = 'report' >+exists = ldb.ERR_ENTRY_ALREADY_EXISTS >+ >+ >+if sys.stdout.isatty(): >+ c_doc = c_DARK_YELLOW >+else: >+ c_doc = lambda x: x >+ >+ >+def get_samdb(): >+ return SamDB(url=f"ldap://{SERVER}", >+ lp=LP, >+ session_info=system_session(), >+ credentials=CREDS) >+ >+ >+def format(s): >+ if type(s) is str: >+ s = s.format(realm=REALM.upper(), >+ lrealm=REALM.lower(), >+ other_realm=(REALM + ".another.example.net")) >+ return s >+ >+ >+class LdapUpnSamTestBase(TestCase): >+ """Make sure we can't add userPrincipalNames or sAMAccountNames that >+ implicitly collide. >+ """ >+ _disabled = False >+ >+ @classmethod >+ def setUpDynamicTestCases(cls): >+ if getattr(cls, '_disabled', False): >+ return >+ for doc, *rows in cls.cases: >+ name = re.sub(r'\W+', '_', doc) >+ cls.generate_dynamic_test("test_upn_sam", name, rows, doc) >+ >+ def setup_objects(self, rows): >+ objects = set(r[0] for r in rows) >+ for name in objects: >+ if ':' in name: >+ objtype, name = name.split(':', 1) >+ else: >+ objtype = 'user' >+ getattr(self, f'add_{objtype}')(name) >+ self.addCleanup(self.remove_object, name) >+ >+ def _test_upn_sam_with_args(self, rows, doc): >+ self.setup_objects(rows) >+ cdoc = c_doc(doc) >+ >+ for i, row in enumerate(rows): >+ if len(row) == 4: >+ obj, data, expected, op = row >+ else: >+ obj, data, expected = row >+ op = ldb.FLAG_MOD_REPLACE >+ >+ dn, dnsname = self.objects[obj] >+ sam, upn = None, None >+ if isinstance(data, dict): >+ sam = data.get('sam') >+ upn = data.get('upn') >+ elif isinstance(data, str): >+ if '@' in data: >+ upn = data >+ else: >+ sam = data >+ else: # bytes >+ if b'@' in data: >+ upn = data >+ else: >+ sam = data >+ >+ m = {"dn": dn} >+ >+ if upn is not None: >+ m["userPrincipalName"] = format(upn) >+ >+ if sam is not None: >+ m["sAMAccountName"] = format(sam) >+ >+ msg = ldb.Message.from_dict(self.samdb, m, op) >+ >+ if expected is bad: >+ try: >+ self.samdb.modify(msg) >+ except ldb.LdbError as e: >+ print(f"row {i+1} of '{cdoc}' failed as expected with " >+ f"{ldb_err(e)}\n") >+ continue >+ self.fail(f"row {i+1} of '{cdoc}' should have failed:\n" >+ f"{pprint.pformat(m)} on {obj}") >+ elif expected is ok: >+ try: >+ self.samdb.modify(msg) >+ except ldb.LdbError as e: >+ raise AssertionError( >+ f"row {i+1} of '{cdoc}' failed with {ldb_err(e)}:\n" >+ f"{pprint.pformat(m)} on {obj}") from None >+ elif expected is report: >+ try: >+ self.samdb.modify(msg) >+ print(f"row {i+1} of '{cdoc}' SUCCEEDED:\n" >+ f"{pprint.pformat(m)} on {obj}") >+ except ldb.LdbError as e: >+ print(f"row {i+1} of '{cdoc}' FAILED " >+ f"with {ldb_err(e)}:\n" >+ f"{pprint.pformat(m)} on {obj}") >+ >+ else: >+ try: >+ self.samdb.modify(msg) >+ except ldb.LdbError as e: >+ if hasattr(expected, '__contains__'): >+ if e.args[0] in expected: >+ continue >+ >+ if e.args[0] == expected: >+ continue >+ >+ self.fail(f"row {i+1} of '{cdoc}' " >+ f"should have failed with {ldb_err(expected)} " >+ f"but instead failed with {ldb_err(e)}:\n" >+ f"{pprint.pformat(m)} on {obj}") >+ self.fail(f"row {i+1} of '{cdoc}' " >+ f"should have failed with {ldb_err(expected)}:\n" >+ f"{pprint.pformat(m)} on {obj}") >+ >+ def add_dc(self, name): >+ dn = f"CN={name},OU=Domain Controllers,{self.base_dn}" >+ dnsname = f"{name}.{REALM}".lower() >+ self.samdb.add({ >+ "dn": dn, >+ "objectclass": "computer", >+ "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT | >+ UF_TRUSTED_FOR_DELEGATION), >+ "dnsHostName": dnsname, >+ "carLicense": self.id() >+ }) >+ self.objects[name] = (dn, dnsname) >+ >+ def add_user(self, name): >+ dn = f"CN={name},{self.ou}" >+ self.samdb.add({ >+ "dn": dn, >+ "name": name, >+ "objectclass": "user", >+ "carLicense": self.id() >+ }) >+ self.objects[name] = (dn, None) >+ >+ def remove_object(self, name): >+ dn, dnsname = self.objects.pop(name) >+ self.samdb.delete(dn) >+ >+ def setUp(self): >+ super().setUp() >+ self.samdb = get_samdb() >+ self.base_dn = self.samdb.get_default_basedn() >+ self.short_id = self.id().rsplit('.', 1)[1][:63] >+ self.objects = {} >+ self.ou = f"OU={ self.short_id },{ self.base_dn }" >+ self.addCleanup(self.samdb.delete, self.ou, ["tree_delete:1"]) >+ self.samdb.add({"dn": self.ou, "objectclass": "organizationalUnit"}) >+ >+ >+@DynamicTestCase >+class LdapUpnSamTest(LdapUpnSamTestBase): >+ cases = [ >+ # The structure is >+ # ( «documentation/message that becomes test name», >+ # («short object id», «upn or sam or mapping», «expected»), >+ # («short object id», «upn or sam or mapping», «expected»), >+ # ..., >+ # ) >+ # >+ # where the first item is a one line string explaining the >+ # test, and subsequent items describe database modifications, >+ # to be applied in series. >+ # >+ # First is a short ID, which maps to an object DN. Second is >+ # either a string or a dictionary. >+ # >+ # * If a string, if it contains '@', it is a UPN, otherwise a >+ # samaccountname. >+ # >+ # * If a dictionary, it is a mapping of some of ['sam', 'upn'] >+ # to strings (in this way, you can add two attributes in one >+ # mesage, or attempt a samaccountname with '@'). >+ # >+ # expected can be «ok», «bad» (mapped to True and False, >+ # respectively), or a specific LDB error code, if that exact >+ # exception is wanted. >+ ("add good UPN", >+ ('A', 'a@{realm}', ok), >+ ), >+ ("add the same upn to different objects", >+ ('A', 'a@{realm}', ok), >+ ('B', 'a@{realm}', ldb.ERR_CONSTRAINT_VIOLATION), >+ ('B', 'a@{lrealm}', ldb.ERR_CONSTRAINT_VIOLATION), # lowercase realm >+ ), >+ ("replace UPN with itself", >+ ('A', 'a@{realm}', ok), >+ ('A', 'a@{realm}', ok), >+ ('A', 'a@{lrealm}', ok), >+ ), >+ ("replace SAM with itself", >+ ('A', 'a', ok), >+ ('A', 'a', ok), >+ ), >+ ("replace UPN realm", >+ ('A', 'a@{realm}', ok), >+ ('A', 'a@{other_realm}', ok), >+ ), >+ ("matching SAM and UPN", >+ ('A', 'a', ok), >+ ('A', 'a@{realm}', ok), >+ ), >+ ("matching SAM and UPN, other realm", >+ ('A', 'a', ok), >+ ('A', 'a@{other_realm}', ok), >+ ), >+ ("matching SAM and UPN, single message", >+ ('A', {'sam': 'a', 'upn': 'a@{realm}'}, ok), >+ ('A', {'sam': 'a', 'upn': 'a@{other_realm}'}, ok), >+ ), >+ ("different objects, different realms", >+ ('A', 'a@{realm}', ok), >+ ('B', 'a@{other_realm}', ok), >+ ), >+ ("different objects, same UPN, different case", >+ ('A', 'a@{realm}', ok), >+ ('B', 'A@{realm}', ldb.ERR_CONSTRAINT_VIOLATION), >+ ), >+ ("different objects, SAM after UPN", >+ ('A', 'a@{realm}', ok), >+ ('B', 'a', ldb.ERR_CONSTRAINT_VIOLATION), >+ ), >+ ("different objects, SAM before UPN", >+ ('A', 'a', ok), >+ ('B', 'a@{realm}', exists), >+ ), >+ ("different objects, SAM account clash", >+ ('A', 'a', ok), >+ ('B', 'a', exists), >+ ), >+ ("different objects, SAM account clash, different case", >+ ('A', 'a', ok), >+ ('B', 'A', exists), >+ ), >+ ("two way clash", >+ ('A', {'sam': 'x', 'upn': 'y@{realm}'}, ok), >+ # The sam account raises EXISTS while the UPN raises >+ # CONSTRAINT_VIOLATION. We don't really care in which order >+ # they are checked, so either error is ok. >+ ('B', {'sam': 'y', 'upn': 'x@{realm}'}, >+ (exists, ldb.ERR_CONSTRAINT_VIOLATION)), >+ ), >+ ("two way clash, other realm", >+ ('A', {'sam': 'x', 'upn': 'y@{other_realm}'}, ok), >+ ('B', {'sam': 'y', 'upn': 'x@{other_realm}'}, ok), >+ ), >+ # UPN versions of bad sam account names >+ ("UPN clash on other realm", >+ ('A', 'a@x.x', ok), >+ ('B', 'a@x.x', ldb.ERR_CONSTRAINT_VIOLATION), >+ ), >+ ("UPN same but for trailing spaces", >+ ('A', 'a@{realm}', ok), >+ ('B', 'a @{realm}', ok), >+ ), >+ # UPN has no at >+ ("UPN has no at", >+ ('A', {'upn': 'noat'}, ok), >+ ('B', {'upn': 'noat'}, ldb.ERR_CONSTRAINT_VIOLATION), >+ ('C', {'upn': 'NOAT'}, ldb.ERR_CONSTRAINT_VIOLATION), >+ ), >+ # UPN has non-ascii at, followed by real at. >+ ("UPN with non-ascii at vs real at", >+ ('A', {'upn': 'smallat﹫{realm}'}, ok), >+ ('B', {'upn': 'smallat@{realm}'}, ok), >+ ('C', {'upn': 'tagat\U000e0040{realm}'}, ok), >+ ('D', {'upn': 'tagat@{realm}'}, ok), >+ ), >+ ("UPN with unicode at vs real at, real at first", >+ ('B', {'upn': 'smallat@{realm}'}, ok), >+ ('A', {'upn': 'smallat﹫{realm}'}, ok), >+ ('D', {'upn': 'tagat@{realm}'}, ok), >+ ('C', {'upn': 'tagat\U000e0040{realm}'}, ok), >+ ), >+ ("UPN username too long", >+ # SPN soft limit 20; hard limit 256, overall UPN 1024 >+ ('A', 'a' * 25 + '@b.c', ok), >+ ('A', 'a' * 65 + '@b.c', ok), # Azure AD limit is 64 >+ ('A', 'a' * 257 + '@b.c', ok), # 256 is sam account name limit >+ ), >+ ("sam account name 20 long", >+ # SPN soft limit 20 >+ ('A', 'a' * 20, ok), >+ ), >+ ("UPN has two at signs", >+ ('A', 'a@{realm}', ok), >+ ('A', 'a@{realm}@{realm}', ok), >+ ('A', 'a@a.b', ok), >+ ('A', 'a@a@a.b', ok), >+ ), >+ ("SAM has at signs clashing upn second, non-realm", >+ ('A', {'sam': 'a@a.b'}, ok), >+ ('B', 'a@a.b@a.b', ok), # UPN won't clash with SAM, because realm >+ ), >+ ("SAM has at signs clashing upn second", >+ ('A', {'sam': 'a@{realm}'}, ok), >+ ('B', 'a@{realm}@{realm}', bad), # UPN would clashes with SAM >+ ), >+ ("SAM has at signs clashing upn first", >+ ('B', 'a@{realm}@{realm}', ok), >+ ('A', {'sam': 'a@{realm}'}, bad), >+ ), >+ ("spaces around at", >+ ('A', 'a name @ {realm}', ok), >+ ('B', 'a name @ {realm}', ldb.ERR_CONSTRAINT_VIOLATION), >+ ('B', 'a name @{realm}', ok), # because realm looks different >+ ('C', 'a name@{realm}', ok), >+ ('D', 'a name', ldb.ERR_CONSTRAINT_VIOLATION), >+ ('D', 'a name ', (exists, ldb.ERR_CONSTRAINT_VIOLATION)), # matches B >+ ), >+ ("SAM starts with at", >+ ('A', {'sam': '@{realm}'}, ok), >+ ('B', {'sam': '@a'}, ok), >+ ('C', {'sam': '@{realm}'}, exists), >+ ('C', {'sam': '@a'}, exists), >+ ('C', {'upn': '@{realm}@{realm}'}, bad), >+ ('C', {'upn': '@a@{realm}'}, bad), >+ ), >+ ("UPN starts with at", >+ ('A', {'upn': '@{realm}'}, ok), >+ ('B', {'upn': '@a@{realm}'}, ok), >+ ('C', {'upn': '@{realm}'}, bad), >+ ('C', {'sam': '@a'}, bad), >+ ), >+ ("SAM ends with at", >+ ('A', {'sam': '{realm}@'}, ok), >+ ('B', {'sam': 'a@'}, ok), >+ ('C', {'sam': '{realm}@'}, exists), >+ ('C', {'sam': 'a@'}, exists), >+ ('C', {'upn': 'a@@{realm}'}, bad), >+ ('C', {'upn': '{realm}@@{realm}'}, bad), >+ ), >+ ("UPN ends with at", >+ ('A', {'upn': '{realm}@'}, ok), >+ ('B', {'upn': '@a@{realm}@'}, ok), >+ ('C', {'upn': '{realm}@'}, bad), >+ ('C', {'sam': '@a@{realm}'}, ok), # not like B, because other realm >+ ), >+ ] >+ >+ >+@DynamicTestCase >+class LdapUpnSamSambaOnlyTest(LdapUpnSamTestBase): >+ # We don't run these ones outside of selftest, where we are >+ # probably testing against Windows and these are known failures. >+ _disabled = 'SAMBA_SELFTEST' not in os.environ >+ cases = [ >+ ("sam account name too long", >+ # SPN soft limit 20 >+ ('A', 'a' * 19, ok), >+ ('A', 'a' * 20, ok), >+ ('A', 'a' * 65, ok), >+ ('A', 'a' * 255, ok), >+ ('A', 'a' * 256, ok), >+ ('A', 'a' * 257, ldb.ERR_INVALID_ATTRIBUTE_SYNTAX), >+ ), >+ ("UPN username too long", >+ ('A', 'a' * 254 + '@' + 'b.c' * 257, >+ ldb.ERR_INVALID_ATTRIBUTE_SYNTAX), # 1024 is alleged UPN limit >+ ), >+ ("UPN same but for internal spaces", >+ ('A', 'a b@x.x', ok), >+ ('B', 'a b@x.x', ldb.ERR_CONSTRAINT_VIOLATION), >+ ), >+ ("SAM contains delete", >+ # forbidden according to documentation, but works in practice on Windows >+ ('A', 'a\x7f', ldb.ERR_CONSTRAINT_VIOLATION), >+ ('A', 'a\x7f'.encode(), ldb.ERR_CONSTRAINT_VIOLATION), >+ ('A', 'a\x7fb', ldb.ERR_CONSTRAINT_VIOLATION), >+ ('A', 'a\x7fb'.encode(), ldb.ERR_CONSTRAINT_VIOLATION), >+ ('A', '\x7fb', ldb.ERR_CONSTRAINT_VIOLATION), >+ ('A', '\x7fb'.encode(), ldb.ERR_CONSTRAINT_VIOLATION), >+ ), >+ # The wide at symbol ('ï¼ ' U+FF20) does not count as '@' for Samba >+ # so it will look like a string with no @s. >+ ("UPN with unicode wide at vs real at", >+ ('A', {'upn': 'wideatï¼ {realm}'}, ok), >+ ('B', {'upn': 'wideat@{realm}'}, ok), >+ ), >+ ("UPN with real at vs wide at", >+ ('B', {'upn': 'wideat@{realm}'}, ok), >+ ('A', {'upn': 'wideatï¼ {realm}'}, ok) >+ ), >+ ] >+ >+ >+def main(): >+ global LP, CREDS, SERVER, REALM >+ >+ parser = optparse.OptionParser( >+ "python3 ldap_upn_sam_account_name.py <server> [options]") >+ sambaopts = options.SambaOptions(parser) >+ parser.add_option_group(sambaopts) >+ >+ # use command line creds if available >+ credopts = options.CredentialsOptions(parser) >+ parser.add_option_group(credopts) >+ subunitopts = SubunitOptions(parser) >+ parser.add_option_group(subunitopts) >+ >+ opts, args = parser.parse_args() >+ if len(args) != 1: >+ parser.print_usage() >+ sys.exit(1) >+ >+ LP = sambaopts.get_loadparm() >+ CREDS = credopts.get_credentials(LP) >+ SERVER = args[0] >+ REALM = CREDS.get_realm() >+ >+ TestProgram(module=__name__, opts=subunitopts) >+ >+main() >diff --git a/selftest/knownfail.d/ldap_upn_sam_account b/selftest/knownfail.d/ldap_upn_sam_account >new file mode 100644 >index 00000000000..c4d494968b2 >--- /dev/null >+++ b/selftest/knownfail.d/ldap_upn_sam_account >@@ -0,0 +1,16 @@ >+samba.tests.ldap_upn_sam_account.+LdapUpnSamSambaOnlyTest.test_upn_sam_SAM_contains_delete >+samba.tests.ldap_upn_sam_account.+LdapUpnSamSambaOnlyTest.test_upn_sam_UPN_same_but_for_internal_spaces >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_SAM_ends_with_at >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_SAM_has_at_signs_clashing_upn_first >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_SAM_has_at_signs_clashing_upn_second >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_SAM_starts_with_at >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_UPN_clash_on_other_realm >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_UPN_ends_with_at >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_UPN_has_no_at >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_UPN_starts_with_at >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_add_the_same_upn_to_different_objects >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_different_objects_SAM_after_UPN >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_different_objects_SAM_before_UPN >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_different_objects_same_UPN_different_case >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_spaces_around_at >+samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_two_way_clash >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index c4e5987f09b..32db0d109cd 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -946,6 +946,15 @@ planoldpythontestsuite("ad_dc", > extra_args=['-U"$USERNAME%$PASSWORD"'], > environ={'TEST_ENV': 'ad_dc'}) > >+plantestsuite_loadlist("samba.tests.ldap_upn_sam_account", "ad_dc", >+ [python, >+ os.path.join(srcdir(), "python/samba/tests/ldap_upn_sam_account.py"), >+ '$SERVER', >+ '-U"$USERNAME%$PASSWORD"', >+ '--workgroup=$DOMAIN', >+ '$LOADLIST', '$LISTOPT']) >+ >+ > planoldpythontestsuite("none", "samba.tests.blackbox.undoguididx") > > 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']) >-- >2.25.1 > > >From be1486e42c5382c7c8f6c467576fb444d5804d10 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 6 Aug 2021 12:03:18 +1200 >Subject: [PATCH 544/686] CVE-2020-25722 pytest: test setting > servicePrincipalName over ldap > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Adapted to remove f-string] >--- > python/samba/tests/ldap_spn.py | 917 +++++++++++++++++++++++++++++++++ > selftest/knownfail.d/ldap_spn | 26 + > source4/selftest/tests.py | 10 +- > 3 files changed, 952 insertions(+), 1 deletion(-) > create mode 100644 python/samba/tests/ldap_spn.py > create mode 100644 selftest/knownfail.d/ldap_spn > >diff --git a/python/samba/tests/ldap_spn.py b/python/samba/tests/ldap_spn.py >new file mode 100644 >index 00000000000..8a398ffaa49 >--- /dev/null >+++ b/python/samba/tests/ldap_spn.py >@@ -0,0 +1,917 @@ >+# Unix SMB/CIFS implementation. >+# >+# Copyright 2021 (C) Catalyst IT Ltd >+# >+# 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 <http://www.gnu.org/licenses/>. >+ >+ >+import sys >+import os >+import pprint >+import re >+from samba.samdb import SamDB >+from samba.auth import system_session >+import ldb >+from samba.sd_utils import SDUtils >+from samba.credentials import DONT_USE_KERBEROS, Credentials >+from samba.gensec import FEATURE_SEAL >+from samba.tests.subunitrun import SubunitOptions, TestProgram >+from samba.tests import TestCase, ldb_err >+from samba.tests import DynamicTestCase >+import samba.getopt as options >+import optparse >+from samba.colour import c_RED, c_GREEN, c_DARK_YELLOW >+from samba.dsdb import ( >+ UF_SERVER_TRUST_ACCOUNT, >+ UF_TRUSTED_FOR_DELEGATION, >+) >+ >+ >+SPN_GUID = 'f3a64788-5306-11d1-a9c5-0000f80367c1' >+ >+RELEVANT_ATTRS = {'dNSHostName', >+ 'servicePrincipalName', >+ 'sAMAccountName', >+ 'dn'} >+ >+ok = True >+bad = False >+report = 'report' >+ >+operr = ldb.ERR_OPERATIONS_ERROR >+denied = ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS >+constraint = ldb.ERR_CONSTRAINT_VIOLATION >+exists = ldb.ERR_ENTRY_ALREADY_EXISTS >+ >+add = ldb.FLAG_MOD_ADD >+replace = ldb.FLAG_MOD_REPLACE >+delete = ldb.FLAG_MOD_DELETE >+ >+try: >+ breakpoint >+except NameError: >+ # for python <= 3.6 >+ def breakpoint(): >+ import pdb >+ pdb.set_trace() >+ >+ >+def init(): >+ # This needs to happen before the class definition, and we put it >+ # in a function to keep the namespace clean. >+ global LP, CREDS, SERVER, REALM, COLOUR_TEXT, subunitopts, FILTER >+ >+ parser = optparse.OptionParser( >+ "python3 ldap_spn.py <server> [options]") >+ sambaopts = options.SambaOptions(parser) >+ parser.add_option_group(sambaopts) >+ >+ # use command line creds if available >+ credopts = options.CredentialsOptions(parser) >+ parser.add_option_group(credopts) >+ subunitopts = SubunitOptions(parser) >+ parser.add_option_group(subunitopts) >+ >+ parser.add_option('--colour', action="store_true", >+ help="use colour text", >+ default=sys.stdout.isatty()) >+ >+ parser.add_option('--filter', help="only run tests matching this regex") >+ >+ opts, args = parser.parse_args() >+ if len(args) != 1: >+ parser.print_usage() >+ sys.exit(1) >+ >+ LP = sambaopts.get_loadparm() >+ CREDS = credopts.get_credentials(LP) >+ SERVER = args[0] >+ REALM = CREDS.get_realm() >+ COLOUR_TEXT = opts.colour >+ FILTER = opts.filter >+ >+ >+init() >+ >+ >+def colour_text(x, state=None): >+ if not COLOUR_TEXT: >+ return x >+ if state == 'error': >+ return c_RED(x) >+ if state == 'pass': >+ return c_GREEN(x) >+ >+ return c_DARK_YELLOW(x) >+ >+ >+def get_samdb(creds=None): >+ if creds is None: >+ creds = CREDS >+ session = system_session() >+ else: >+ session = None >+ >+ return SamDB(url=f"ldap://{SERVER}", >+ lp=LP, >+ session_info=session, >+ credentials=creds) >+ >+ >+def add_unpriv_user(samdb, ou, username, >+ writeable_objects=None, >+ password="samba123@"): >+ creds = Credentials() >+ creds.set_username(username) >+ creds.set_password(password) >+ creds.set_domain(CREDS.get_domain()) >+ creds.set_realm(CREDS.get_realm()) >+ creds.set_workstation(CREDS.get_workstation()) >+ creds.set_gensec_features(CREDS.get_gensec_features() | FEATURE_SEAL) >+ creds.set_kerberos_state(DONT_USE_KERBEROS) >+ dnstr = f"CN={username},{ou}" >+ >+ # like, WTF, samdb.newuser(), this is what you make us do. >+ short_ou = ou.split(',', 1)[0] >+ >+ samdb.newuser(username, password, userou=short_ou) >+ >+ if writeable_objects: >+ sd_utils = SDUtils(samdb) >+ sid = sd_utils.get_object_sid(dnstr) >+ for obj in writeable_objects: >+ mod = f"(OA;CI;WP;{ SPN_GUID };;{ sid })" >+ sd_utils.dacl_add_ace(obj, mod) >+ >+ unpriv_samdb = get_samdb(creds=creds) >+ return unpriv_samdb >+ >+ >+class LdapSpnTestBase(TestCase): >+ _disabled = False >+ >+ @classmethod >+ def setUpDynamicTestCases(cls): >+ if getattr(cls, '_disabled', False): >+ return >+ for doc, *rows in cls.cases: >+ if FILTER: >+ if not re.search(FILTER, doc): >+ continue >+ name = re.sub(r'\W+', '_', doc) >+ cls.generate_dynamic_test("test_spn", name, rows, doc) >+ >+ def setup_objects(self, rows): >+ objects = set(r[0] for r in rows) >+ for name in objects: >+ if ':' in name: >+ objtype, name = name.split(':', 1) >+ else: >+ objtype = 'dc' >+ getattr(self, f'add_{objtype}')(name) >+ >+ def setup_users(self, rows): >+ # When you are adding an SPN that aliases (or would be aliased >+ # by) another SPN on another object, you need to have write >+ # permission on that other object too. >+ # >+ # To test this negatively and positively, we need to have >+ # users with various combinations of write permission, which >+ # means fiddling with SDs on the objects. >+ # >+ # The syntax is: >+ # '' : user with no special permissions >+ # '*' : admin user >+ # 'A' : user can write to A only >+ # 'A,C' : user can write to A and C >+ # 'C,A' : same, but makes another user >+ self.userdbs = { >+ '*': self.samdb >+ } >+ >+ permissions = set(r[2] for r in rows) >+ for p in permissions: >+ if p == '*': >+ continue >+ if p == '': >+ user = 'nobody' >+ writeable_objects = None >+ else: >+ user = 'writes_' + p.replace(",", '_') >+ writeable_objects = [self.objects[x][0] for x in p.split(',')] >+ >+ self.userdbs[p] = add_unpriv_user(self.samdb, self.ou, user, >+ writeable_objects) >+ >+ def _test_spn_with_args(self, rows, doc): >+ cdoc = colour_text(doc) >+ edoc = colour_text(doc, 'error') >+ pdoc = colour_text(doc, 'pass') >+ >+ if COLOUR_TEXT: >+ sys.stderr.flush() >+ print('\n', c_DARK_YELLOW('#' * 10), f'starting «{cdoc}»\n') >+ sys.stdout.flush() >+ >+ self.samdb = get_samdb() >+ self.base_dn = self.samdb.get_default_basedn() >+ self.short_id = self.id().rsplit('.', 1)[1][:63] >+ self.objects = {} >+ self.ou = f"OU={ self.short_id },{ self.base_dn }" >+ self.addCleanup(self.samdb.delete, self.ou, ["tree_delete:1"]) >+ self.samdb.create_ou(self.ou) >+ >+ self.setup_objects(rows) >+ self.setup_users(rows) >+ >+ for i, row in enumerate(rows): >+ if len(row) == 5: >+ obj, data, rights, expected, op = row >+ else: >+ obj, data, rights, expected = row >+ op = ldb.FLAG_MOD_REPLACE >+ >+ # We use this DB with possibly restricted rights for this row >+ samdb = self.userdbs[rights] >+ >+ if ':' in obj: >+ objtype, obj = obj.split(':', 1) >+ else: >+ objtype = 'dc' >+ >+ dn, dnsname = self.objects[obj] >+ m = {"dn": dn} >+ >+ if isinstance(data, dict): >+ m.update(data) >+ else: >+ m['servicePrincipalName'] = data >+ >+ # for python's sake (and our sanity) we try to ensure we >+ # have consistent canonical case in our attributes >+ keys = set(m.keys()) >+ if not keys.issubset(RELEVANT_ATTRS): >+ raise ValueError(f"unexpected attr {keys - RELEVANT_ATTRS}. " >+ "Casefold typo?") >+ >+ for k in ('dNSHostName', 'servicePrincipalName'): >+ if isinstance(m.get(k), str): >+ m[k] = m[k].format(dnsname=f"x.{REALM}") >+ >+ msg = ldb.Message.from_dict(samdb, m, op) >+ >+ if expected is bad: >+ try: >+ samdb.modify(msg) >+ except ldb.LdbError as e: >+ print(f"row {i+1} of '{pdoc}' failed as expected with " >+ f"{ldb_err(e)}\n") >+ continue >+ self.fail(f"row {i+1}: " >+ f"{rights} {pprint.pformat(m)} on {objtype} {obj} " >+ f"should fail ({edoc})") >+ >+ elif expected is ok: >+ try: >+ samdb.modify(msg) >+ except ldb.LdbError as e: >+ self.fail(f"row {i+1} of {edoc} failed with {ldb_err(e)}:\n" >+ f"{rights} {pprint.pformat(m)} on {objtype} {obj}") >+ >+ elif expected is report: >+ try: >+ self.samdb.modify(msg) >+ print(f"row {i+1} " >+ f"of '{cdoc}' {colour_text('SUCCEEDED', 'pass')}:\n" >+ f"{pprint.pformat(m)} on {obj}") >+ except ldb.LdbError as e: >+ print(f"row {i+1} " >+ f"of '{cdoc}' {colour_text('FAILED', 'error')} " >+ f"with {ldb_err(e)}:\n{pprint.pformat(m)} on {obj}") >+ >+ elif expected is breakpoint: >+ try: >+ breakpoint() >+ samdb.modify(msg) >+ except ldb.LdbError as e: >+ print(f"row {i+1} of '{pdoc}' FAILED with {ldb_err(e)}\n") >+ >+ else: # an ldb error number >+ try: >+ samdb.modify(msg) >+ except ldb.LdbError as e: >+ if e.args[0] == expected: >+ continue >+ self.fail(f"row {i+1} of '{edoc}' " >+ f"should have failed with {ldb_err(expected)}:\n" >+ f"not {ldb_err(e)}:\n" >+ f"{rights} {pprint.pformat(m)} on {objtype} {obj}") >+ self.fail(f"row {i+1} of '{edoc}' " >+ f"should have failed with {ldb_err(expected)}:\n" >+ f"{rights} {pprint.pformat(m)} on {objtype} {obj}") >+ >+ def add_dc(self, name): >+ dn = f"CN={name},OU=Domain Controllers,{self.base_dn}" >+ dnsname = f"{name}.{REALM}".lower() >+ self.samdb.add({ >+ "dn": dn, >+ "objectclass": "computer", >+ "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT | >+ UF_TRUSTED_FOR_DELEGATION), >+ "dnsHostName": dnsname, >+ "carLicense": self.id() >+ }) >+ self.addCleanup(self.remove_object, name) >+ self.objects[name] = (dn, dnsname) >+ >+ def add_user(self, name): >+ dn = f"CN={name},{self.ou}" >+ self.samdb.add({ >+ "dn": dn, >+ "name": name, >+ "samAccountName": name, >+ "objectclass": "user", >+ "carLicense": self.id() >+ }) >+ self.addCleanup(self.remove_object, name) >+ self.objects[name] = (dn, None) >+ >+ def remove_object(self, name): >+ dn, dnsname = self.objects.pop(name) >+ self.samdb.delete(dn) >+ >+ >+@DynamicTestCase >+class LdapSpnTest(LdapSpnTestBase): >+ """Make sure we can't add clashing servicePrincipalNames. >+ >+ This would be possible using sPNMappings aliases â for example, if >+ the mapping maps host/ to cifs/, we should not be able to add >+ different addresses for each. >+ """ >+ >+ # default sPNMappings: host=alerter, appmgmt, cisvc, clipsrv, >+ # browser, dhcp, dnscache, replicator, eventlog, eventsystem, >+ # policyagent, oakley, dmserver, dns, mcsvc, fax, msiserver, ias, >+ # messenger, netlogon, netman, netdde, netddedsm, nmagent, >+ # plugplay, protectedstorage, rasman, rpclocator, rpc, rpcss, >+ # remoteaccess, rsvp, samss, scardsvr, scesrv, seclogon, scm, >+ # dcom, cifs, spooler, snmp, schedule, tapisrv, trksvr, trkwks, >+ # ups, time, wins, www, http, w3svc, iisadmin, msdtc >+ # >+ # I think in practice this is rarely if ever changed or added to. >+ >+ cases = [ >+ ("add one as admin", >+ ('A', 'host/{dnsname}', '*', ok), >+ ), >+ ("add one as rightful user", >+ ('A', 'host/{dnsname}', 'A', ok), >+ ), >+ ("attempt to add one as nobody", >+ ('A', 'host/{dnsname}', '', denied), >+ ), >+ >+ ("add and replace as admin", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', 'host/x.{dnsname}', '*', ok), >+ ), >+ ("replace as rightful user", >+ ('A', 'host/{dnsname}', 'A', ok), >+ ('A', 'host/x.{dnsname}', 'A', ok), >+ ), >+ ("attempt to replace one as nobody", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', 'host/x.{dnsname}', '', denied), >+ ), >+ >+ ("add second as admin", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', 'host/x.{dnsname}', '*', ok, add), >+ ), >+ ("add second as rightful user", >+ ('A', 'host/{dnsname}', 'A', ok), >+ ('A', 'host/x.{dnsname}', 'A', ok, add), >+ ), >+ ("attempt to add second as nobody", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', 'host/x.{dnsname}', '', denied, add), >+ ), >+ >+ ("add the same one twice, simple duplicate error", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', '*', bad, add), >+ ), >+ ("simple duplicate attributes, as non-admin", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', 'A', bad, add), >+ ), >+ >+ ("add the same one twice, identical duplicate", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', '*', bad, add), >+ ), >+ >+ ("add a conflict, host first, as nobody", >+ ('A', 'host/z.{dnsname}', '*', ok), >+ ('B', 'cifs/z.{dnsname}', '', denied), >+ ), >+ >+ ("add a conflict, service first, as nobody", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('B', 'host/{dnsname}', '', denied), >+ ), >+ >+ >+ ("three way conflict, host first, as admin", >+ ('A', 'host/z.{dnsname}', '*', ok), >+ ('B', 'cifs/z.{dnsname}', '*', ok), >+ ('C', 'www/z.{dnsname}', '*', ok), >+ ), >+ ("three way conflict, host first, with sufficient rights", >+ ('A', 'host/z.{dnsname}', 'A', ok), >+ ('B', 'cifs/z.{dnsname}', 'B,A', ok), >+ ('C', 'www/z.{dnsname}', 'C,A', ok), >+ ), >+ ("three way conflict, host first, adding duplicate", >+ ('A', 'host/z.{dnsname}', 'A', ok), >+ ('B', 'cifs/z.{dnsname}', 'B,A', ok), >+ ('C', 'cifs/z.{dnsname}', 'C,A', bad), >+ ), >+ ("three way conflict, host first, adding duplicate, full rights", >+ ('A', 'host/z.{dnsname}', 'A', ok), >+ ('B', 'cifs/z.{dnsname}', 'B,A', ok), >+ ('C', 'cifs/z.{dnsname}', 'C,B,A', bad), >+ ), >+ >+ ("three way conflict, host first, with other write rights", >+ ('A', 'host/z.{dnsname}', '*', ok), >+ ('B', 'cifs/z.{dnsname}', 'A,B', ok), >+ ('C', 'cifs/z.{dnsname}', 'A,B', bad), >+ >+ ), >+ ("three way conflict, host first, as nobody", >+ ('A', 'host/z.{dnsname}', '*', ok), >+ ('B', 'cifs/z.{dnsname}', '*', ok), >+ ('C', 'www/z.{dnsname}', '', denied), >+ ), >+ >+ ("three way conflict, services first, as admin", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('B', 'www/{dnsname}', '*', ok), >+ ('C', 'host/{dnsname}', '*', constraint), >+ ), >+ ("three way conflict, services first, with service write rights", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('B', 'www/{dnsname}', '*', ok), >+ ('C', 'host/{dnsname}', 'A,B', bad), >+ ), >+ >+ ("three way conflict, service first, as nobody", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('B', 'www/{dnsname}', '*', ok), >+ ('C', 'host/{dnsname}', '', denied), >+ ), >+ ("replace host before specific", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ), >+ ("replace host after specific, as nobody", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', '', denied), >+ ), >+ >+ ("non-conflict host before specific", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', 'cifs/{dnsname}', '*', ok, add), >+ ), >+ ("non-conflict host after specific", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', '*', ok, add), >+ ), >+ ("non-conflict host before specific, non-admin", >+ ('A', 'host/{dnsname}', 'A', ok), >+ ('A', 'cifs/{dnsname}', 'A', ok, add), >+ ), >+ ("non-conflict host after specific, as nobody", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', '', denied, add), >+ ), >+ >+ ("add a conflict, host first on user, as admin", >+ ('user:C', 'host/{dnsname}', '*', ok), >+ ('B', 'cifs/{dnsname}', '*', ok), >+ ), >+ ("add a conflict, host first on user, host rights", >+ ('user:C', 'host/{dnsname}', '*', ok), >+ ('B', 'cifs/{dnsname}', 'C', denied), >+ ), >+ ("add a conflict, host first on user, both rights", >+ ('user:C', 'host/{dnsname}', '*', ok), >+ ('B', 'cifs/{dnsname}', 'B,C', ok), >+ ), >+ ("add a conflict, host first both on user", >+ ('user:C', 'host/{dnsname}', '*', ok), >+ ('user:D', 'www/{dnsname}', '*', ok), >+ ), >+ ("add a conflict, host first both on user, host rights", >+ ('user:C', 'host/{dnsname}', '*', ok), >+ ('user:D', 'www/{dnsname}', 'C', denied), >+ ), >+ ("add a conflict, host first both on user, both rights", >+ ('user:C', 'host/{dnsname}', '*', ok), >+ ('user:D', 'www/{dnsname}', 'C,D', ok), >+ ), >+ ("add a conflict, host first both on user, as nobody", >+ ('user:C', 'host/{dnsname}', '*', ok), >+ ('user:D', 'www/{dnsname}', '', denied), >+ ), >+ ("add a conflict, host first, with both write rights", >+ ('A', 'host/z.{dnsname}', '*', ok), >+ ('B', 'cifs/z.{dnsname}', 'A,B', ok), >+ ), >+ >+ ("add a conflict, host first, second on user, as admin", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('user:D', 'cifs/{dnsname}', '*', ok), >+ ), >+ ("add a conflict, host first, second on user, with rights", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('user:D', 'cifs/{dnsname}', 'A,D', ok), >+ ), >+ >+ ("nonsense SPNs, part 1, as admin", >+ ('A', 'a-b-c/{dnsname}', '*', ok), >+ ('A', 'rrrrrrrrrrrrr /{dnsname}', '*', ok), >+ ), >+ ("nonsense SPNs, part 1, as user", >+ ('A', 'a-b-c/{dnsname}', 'A', ok), >+ ('A', 'rrrrrrrrrrrrr /{dnsname}', 'A', ok), >+ ), >+ ("nonsense SPNs, part 1, as nobody", >+ ('A', 'a-b-c/{dnsname}', '', denied), >+ ('A', 'rrrrrrrrrrrrr /{dnsname}', '', denied), >+ ), >+ >+ ("add a conflict, using port", >+ ('A', 'dns/{dnsname}', '*', ok), >+ ('B', 'dns/{dnsname}:53', '*', ok), >+ ), >+ ("add a conflict, using port, port first", >+ ('user:C', 'dns/{dnsname}:53', '*', ok), >+ ('user:D', 'dns/{dnsname}', '*', ok), >+ ), >+ ("three part spns", >+ ('A', {'dNSHostName': '{dnsname}'}, '*', ok), >+ ('A', 'cifs/{dnsname}/DomainDNSZones.{dnsname}', '*', ok), >+ ('B', 'cifs/{dnsname}/DomainDNSZones.{dnsname}', '*', constraint), >+ ('A', {'dNSHostName': 'y.{dnsname}'}, '*', ok), >+ ('B', 'cifs/{dnsname}/DomainDNSZones.{dnsname}', '*', ok), >+ ('B', 'cifs/y.{dnsname}/DomainDNSZones.{dnsname}', '*', constraint), >+ ), >+ ("three part nonsense spns", >+ ('A', {'dNSHostName': 'bean'}, '*', ok), >+ ('A', 'cifs/bean/DomainDNSZones.bean', '*', ok), >+ ('B', 'cifs/bean/DomainDNSZones.bean', '*', constraint), >+ ('A', {'dNSHostName': 'y.bean'}, '*', ok), >+ ('B', 'cifs/bean/DomainDNSZones.bean', '*', ok), >+ ('B', 'cifs/y.bean/DomainDNSZones.bean', '*', constraint), >+ ('C', 'host/bean/bean', '*', ok), >+ ), >+ >+ ("one part spns (no slashes)", >+ ('A', '{dnsname}', '*', constraint), >+ ('B', 'cifs', '*', constraint), >+ ('B', 'cifs/', '*', ok), >+ ('B', ' ', '*', constraint), >+ ('user:C', 'host', '*', constraint), >+ ), >+ >+ ("dodgy spns", >+ # These tests pass on Windows. An SPN must have one or two >+ # slashes, with at least one character before the first one, >+ # UNLESS the first slash is followed by a good enough service >+ # name (e.g. "/host/x.y" rather than "sdfsd/x.y"). >+ ('A', '\\/{dnsname}', '*', ok), >+ ('B', 'cifs/\\\\{dnsname}', '*', ok), >+ ('B', r'cifs/\\\{dnsname}', '*', ok), >+ ('B', r'cifs/\\\{dnsname}/', '*', ok), >+ ('A', r'cÄ«fs/\\\{dnsname}/', '*', constraint), # 'Ä«' maps to 'i' >+ # on the next two, full-width solidus (U+FF0F) does not work >+ # as '/'. >+ ('A', 'cifsï¼sfic', '*', constraint, add), >+ ('A', r'cifsï¼\\\{dnsname}', '*', constraint, add), >+ ('B', '\n', '*', constraint), >+ ('B', '\n/\n', '*', ok), >+ ('B', '\n/\n/\n', '*', ok), >+ ('B', '\n/\n/\n/\n', '*', constraint), >+ ('B', ' /* and so on */ ', '*', ok, add), >+ ('B', r'¯\_(ã)_/¯', '*', ok, add), # ¯\_(ã)_/¯ >+ # 㤠is hiragana for katakana ã, so the next one fails for >+ # something analogous to casefold reasons. >+ ('A', r'¯\_(ã¤)_/¯', '*', constraint), >+ ('A', r'¯\_(ã¡)_/¯', '*', constraint), # circled ã >+ ('B', '//', '*', constraint), # all can't be empty, >+ ('B', ' //', '*', ok), # service can be space >+ ('B', '/host/{dnsname}', '*', ok), # or empty if others aren't >+ ('B', '/host/x.y.z', '*', ok), >+ ('B', '/ /x.y.z', '*', ok), >+ ('B', ' / / ', '*', ok), >+ ('user:C', b'host/', '*', ok), >+ ('user:C', ' /host', '*', ok), # service is ' ' (space) >+ ('B', ' /host', '*', constraint), # already on C >+ ('B', ' /HÅST', '*', constraint), # Å equiv to O >+ ('B', ' /ħÃÅt', '*', constraint), # maps to ' /host' >+ ('B', ' /H0ST', '*', ok), # 0 is zero >+ ('B', ' /ÐoST', '*', ok), # Cyrillic Ð (~N) >+ ('B', ' /host', '*', ok), # two space >+ ('B', '\u00a0/host', '*', ok), # non-breaking space >+ ('B', ' 2/HÅST/â·[ ][]¨(', '*', ok), >+ ('B', ' (//)', '*', ok, add), >+ ('B', ' ///', '*', constraint), >+ ('B', r' /\//', '*', constraint), # escape doesn't help >+ ('B', ' /\\//', '*', constraint), # double escape doesn't help >+ ('B', r'\//', '*', ok), >+ ('A', r'\\/\\/', '*', ok), >+ ('B', '|//|', '*', ok, add), >+ ('B', r'\/\/\\', '*', ok, add), >+ >+ ('A', ':', '*', constraint), >+ ('A', ':/:', '*', ok), >+ ('A', ':/:80', '*', ok), # port number syntax is not special >+ ('A', ':/:( ã', '*', ok), >+ ('A', ':/:/:', '*', ok), >+ ('B', b'cifs/\x11\xaa\xbb\xcc\\example.com', '*', ok), >+ ('A', b':/\xcc\xcc\xcc\xcc', '*', ok), >+ ('A', b':/b\x00/b/b/b', '*', ok), # string handlng truncates at \x00 >+ ('A', b'a@b/a@b/a@b', '*', ok), >+ ('A', b'a/a@b/a@b', '*', ok), >+ ), >+ ("empty part spns (consecutive slashes)", >+ ('A', 'cifs//{dnsname}', '*', ok), >+ ('B', 'cifs//{dnsname}', '*', bad), # should clash with line 1 >+ ('B', 'cifs/zzzy.{dnsname}/', '*', ok), >+ ('B', '/host/zzzy.{dnsname}', '*', ok), >+ ), >+ ("too many spn parts", >+ ('A', 'cifs/{dnsname}/{dnsname}/{dnsname}', '*', bad), >+ ('A', {'dNSHostName': 'y.{dnsname}'}, '*', ok), >+ ('B', 'cifs/{dnsname}/{dnsname}/', '*', bad), >+ ('B', 'cifs/y.{dnsname}/{dnsname}/toop', '*', bad), >+ ('B', 'host/{dnsname}/a/b/c', '*', bad), >+ ), >+ ("add a conflict, host first, as admin", >+ ('A', 'host/z.{dnsname}', '*', ok), >+ ('B', 'cifs/z.{dnsname}', '*', ok), >+ ), >+ ("add a conflict, host first, with host write rights", >+ ('A', 'host/z.{dnsname}', '*', ok), >+ ('B', 'cifs/z.{dnsname}', 'A', denied), >+ ), >+ ("add a conflict, service first, with service write rights", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('B', 'host/{dnsname}', 'A', denied), >+ ), >+ ("adding dNSHostName after cifs with no old dNSHostName", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', {'dNSHostName': 'y.{dnsname}'}, '*', ok), >+ ('B', 'cifs/{dnsname}', '*', constraint), >+ ('B', 'cifs/y.{dnsname}', '*', ok), >+ ('B', 'host/y.{dnsname}', '*', ok), >+ ), >+ ("changing dNSHostName after cifs", >+ ('A', {'dNSHostName': '{dnsname}'}, '*', ok), >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', {'dNSHostName': 'y.{dnsname}'}, '*', ok), >+ ('B', 'cifs/{dnsname}', '*', ok), >+ ('B', 'cifs/y.{dnsname}', '*', bad), >+ ('B', 'host/y.{dnsname}', '*', bad), >+ ), >+ ] >+ >+ >+@DynamicTestCase >+class LdapSpnSambaOnlyTest(LdapSpnTestBase): >+ # We don't run these ones outside of selftest, where we are >+ # probably testing against Windows and these are known failures. >+ _disabled = 'SAMBA_SELFTEST' not in os.environ >+ cases = [ >+ ("add a conflict, host first, with service write rights", >+ ('A', 'host/z.{dnsname}', '*', ok), >+ ('B', 'cifs/z.{dnsname}', 'B', denied), >+ ), >+ ("add a conflict, service first, with host write rights", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('B', 'host/{dnsname}', 'B', constraint), >+ ), >+ ("add a conflict, service first, as admin", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('B', 'host/{dnsname}', '*', constraint), >+ ), >+ ("add a conflict, service first, with both write rights", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('B', 'host/{dnsname}', 'A,B', constraint), >+ ), >+ ("add a conflict, host first both on user, service rights", >+ ('user:C', 'host/{dnsname}', '*', ok), >+ ('user:D', 'www/{dnsname}', 'D', denied), >+ ), >+ >+ ("changing dNSHostName after host", >+ ('A', {'dNSHostName': '{dnsname}'}, '*', ok), >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', {'dNSHostName': 'y.{dnsname}'}, '*', ok), >+ ('B', 'cifs/{dnsname}', 'B', ok), # no clash with A >+ ('B', 'cifs/y.{dnsname}', 'B', bad), # should clash with A >+ ('B', 'host/y.{dnsname}', '*', bad), >+ ), >+ >+ ("mystery dnsname clash, host first", >+ ('user:C', 'host/heeble.example.net', '*', ok), >+ ('user:D', 'www/heeble.example.net', '*', ok), >+ ), >+ ("mystery dnsname clash, www first", >+ ('user:D', 'www/heeble.example.net', '*', ok), >+ ('user:C', 'host/heeble.example.net', '*', constraint), >+ ), >+ ("replace as admin", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ), >+ ("replace as non-admin with rights", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', 'A', ok), >+ ('A', 'cifs/{dnsname}', 'A', ok), >+ ), >+ ("replace vial delete as non-admin with rights", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', 'A', ok), >+ ('A', 'host/{dnsname}', 'A', ok, delete), >+ ('A', 'cifs/{dnsname}', 'A', ok, add), >+ ), >+ ("replace as non-admin without rights", >+ ('B', 'cifs/b', '*', ok), >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', 'B', denied), >+ ('A', 'cifs/{dnsname}', 'B', denied), >+ ), >+ ("replace as nobody", >+ ('B', 'cifs/b', '*', ok), >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', '', denied), >+ ('A', 'cifs/{dnsname}', '', denied), >+ ), >+ ("accumulate and delete as admin", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', '*', ok, add), >+ ('A', 'www/{dnsname}', '*', ok, add), >+ ('A', 'www/...', '*', ok, add), >+ ('A', 'host/...', '*', ok, add), >+ ('A', 'www/{dnsname}', '*', ok, delete), >+ ('A', 'host/{dnsname}', '*', ok, delete), >+ ('A', 'host/{dnsname}', '*', ok, add), >+ ('A', 'www/{dnsname}', '*', ok, add), >+ ('A', 'host/...', '*', ok, delete), >+ ), >+ ("accumulate and delete with user rights", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', 'host/{dnsname}', 'A', ok, add), >+ ('A', 'www/{dnsname}', 'A', ok, add), >+ ('A', 'www/...', 'A', ok, add), >+ ('A', 'host/...', 'A', ok, add), >+ ('A', 'www/{dnsname}', 'A', ok, delete), >+ ('A', 'host/{dnsname}', 'A', ok, delete), >+ ('A', 'host/{dnsname}', 'A', ok, add), >+ ('A', 'www/{dnsname}', 'A', ok, add), >+ ('A', 'host/...', 'A', ok, delete), >+ ), >+ ("three way conflict, host first, with partial write rights", >+ ('A', 'host/z.{dnsname}', 'A', ok), >+ ('B', 'cifs/z.{dnsname}', 'B', denied), >+ ('C', 'www/z.{dnsname}', 'C', denied), >+ ), >+ ("three way conflict, host first, with partial write rights 2", >+ ('A', 'host/z.{dnsname}', 'A', ok), >+ ('B', 'cifs/z.{dnsname}', 'B', bad), >+ ('C', 'www/z.{dnsname}', 'C,A', ok), >+ ), >+ >+ ("three way conflict sandwich, sufficient rights", >+ ('B', 'host/{dnsname}', 'B', ok), >+ ('A', 'cifs/{dnsname}', 'A,B', ok), >+ # the replaces don't fail even though they appear to affect A >+ # and B, because they are effectively no-ops, leaving >+ # everything as it was before. >+ ('A', 'cifs/{dnsname}', 'A', ok), >+ ('B', 'host/{dnsname}', 'B', ok), >+ ('C', 'www/{dnsname}', 'A,B,C', ok), >+ ('C', 'www/{dnsname}', 'B,C', ok), >+ # because B already has host/, C doesn't matter >+ ('B', 'host/{dnsname}', 'A,B', ok), >+ # removing host (via replace) frees others, needs B only >+ ('B', 'ldap/{dnsname}', 'B', ok), >+ ('C', 'www/{dnsname}', 'C', ok), >+ ('A', 'cifs/{dnsname}', 'A', ok), >+ >+ # re-adding host is now impossible while A and C have {dnsname} spns >+ ('B', 'host/{dnsname}', '*', bad), >+ ('B', 'host/{dnsname}', 'A,B,C', bad), >+ # so let's remove those... (not needing B rights) >+ ('C', 'www/{dnsname}', 'C', ok, delete), >+ ('A', 'cifs/{dnsname}', 'A', ok, delete), >+ # and now we can add host/ again >+ ('B', 'host/{dnsname}', 'B', ok), >+ ('C', 'www/{dnsname}', 'B,C', ok, add), >+ ('A', 'cifs/{dnsname}', 'A,B', ok), >+ ), >+ ("three way conflict, service first, with all write rights", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('B', 'www/{dnsname}', 'A,B,C', ok), >+ ('C', 'host/{dnsname}', 'A,B,C', bad), >+ ), >+ ("three way conflict, service first, just sufficient rights", >+ ('A', 'cifs/{dnsname}', 'A', ok), >+ ('B', 'www/{dnsname}', 'B', ok), >+ ('C', 'host/{dnsname}', 'A,B,C', bad), >+ ), >+ >+ ("three way conflict, service first, with host write rights", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('B', 'www/{dnsname}', '*', ok), >+ ('C', 'host/{dnsname}', 'C', bad), >+ ), >+ ("three way conflict, service first, with both write rights", >+ ('A', 'cifs/{dnsname}', '*', ok), >+ ('A', 'cifs/{dnsname}', '*', ok, delete), >+ ('A', 'www/{dnsname}', 'A,B,C', ok), >+ ('B', 'host/{dnsname}', 'A,B', bad), >+ ('A', 'www/{dnsname}', 'A', ok, delete), >+ ('B', 'host/{dnsname}', 'A,B', ok), >+ ('C', 'cifs/{dnsname}', 'C', bad), >+ ('C', 'cifs/{dnsname}', 'B,C', ok), >+ ), >+ ("three way conflict, services first, with partial rights", >+ ('A', 'cifs/{dnsname}', 'A,C', ok), >+ ('B', 'www/{dnsname}', '*', ok), >+ ('C', 'host/{dnsname}', 'A,C', bad), >+ ), >+ ] >+ >+ >+@DynamicTestCase >+class LdapSpnAmbitiousTest(LdapSpnTestBase): >+ _disabled = True >+ cases = [ >+ ("add a conflict with port, host first both on user", >+ ('user:C', 'host/{dnsname}', '*', ok), >+ ('user:D', 'www/{dnsname}:80', '*', bad), >+ ), >+ # see https://bugzilla.samba.org/show_bug.cgi?id=8929 >+ ("add the same one twice, case-insensitive duplicate", >+ ('A', 'host/{dnsname}', '*', ok), >+ ('A', 'Host/{dnsname}', '*', bad, add), >+ ), >+ ("special SPN", >+ # should fail because we don't have all the DSA infrastructure >+ ('A', ("E3514235-4B06-11D1-AB04-00C04FC2DCD2/" >+ "75b84f00-a81b-4a19-8ef2-8e483cccff11/" >+ "{dnsname}"), '*', constraint) >+ ), >+ ("single part SPNs matching sAMAccountName", >+ # setting them both together is allegedly a MacOS behaviour, >+ # but all we get from Windows is a mysterious NO_SUCH_OBJECT. >+ ('user:A', {'sAMAccountName': 'A', >+ 'servicePrincipalName': 'A'}, '*', ldb.ERR_NO_SUCH_OBJECT), >+ ('user:B', {'sAMAccountName': 'B'}, '*', ok), >+ ('user:B', {'servicePrincipalName': 'B'}, '*', constraint), >+ ('user:C', {'servicePrincipalName': 'C'}, '*', constraint), >+ ('user:C', {'sAMAccountName': 'C'}, '*', ok), >+ ), >+ ("three part spns with dnsHostName", >+ ('A', {'dNSHostName': '{dnsname}'}, '*', ok), >+ ('A', 'cifs/{dnsname}/DomainDNSZones.{dnsname}', '*', ok), >+ ('A', {'dNSHostName': 'y.{dnsname}'}, '*', ok), >+ ('B', 'cifs/{dnsname}/DomainDNSZones.{dnsname}', '*', ok), >+ ('B', 'cifs/y.{dnsname}/DomainDNSZones.{dnsname}', '*', constraint), >+ ('C', 'host/{y.dnsname}/{y.dnsname}', '*', constraint), >+ ('A', 'host/y.{dnsname}/{dnsname}', '*', constraint), >+ ), >+ ] >+ >+ >+def main(): >+ TestProgram(module=__name__, opts=subunitopts) >+ >+main() >diff --git a/selftest/knownfail.d/ldap_spn b/selftest/knownfail.d/ldap_spn >new file mode 100644 >index 00000000000..dc768728658 >--- /dev/null >+++ b/selftest/knownfail.d/ldap_spn >@@ -0,0 +1,26 @@ >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_host_first_both_on_user_service_rights >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_host_first_with_service_write_rights >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_service_first_as_admin >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_service_first_with_both_write_rights >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_service_first_with_host_write_rights >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_changing_dNSHostName_after_host >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_mystery_dnsname_clash_www_first >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_host_first_with_partial_write_rights >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_host_first_with_partial_write_rights_2 >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_sandwich_sufficient_rights >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_service_first_just_sufficient_rights >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_service_first_with_all_write_rights >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_service_first_with_both_write_rights >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_service_first_with_host_write_rights >+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_services_first_with_partial_rights >+samba.tests.ldap_spn.+LdapSpnTest.test_spn_adding_dNSHostName_after_cifs_with_no_old_dNSHostName >+samba.tests.ldap_spn.+LdapSpnTest.test_spn_changing_dNSHostName_after_cifs >+samba.tests.ldap_spn.+LdapSpnTest.test_spn_dodgy_spns >+samba.tests.ldap_spn.+LdapSpnTest.test_spn_empty_part_spns_consecutive_slashes_ >+samba.tests.ldap_spn.+LdapSpnTest.test_spn_one_part_spns_no_slashes_ >+samba.tests.ldap_spn.+LdapSpnTest.test_spn_three_part_nonsense_spns >+samba.tests.ldap_spn.+LdapSpnTest.test_spn_three_part_spns >+samba.tests.ldap_spn.+LdapSpnTest.test_spn_three_way_conflict_host_first_adding_duplicate >+samba.tests.ldap_spn.+LdapSpnTest.test_spn_three_way_conflict_host_first_adding_duplicate_full_rights >+samba.tests.ldap_spn.+LdapSpnTest.test_spn_three_way_conflict_services_first_as_admin >+samba.tests.ldap_spn.+LdapSpnTest.test_spn_too_many_spn_parts >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 32db0d109cd..d3ef08ef9e9 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -946,7 +946,15 @@ planoldpythontestsuite("ad_dc", > extra_args=['-U"$USERNAME%$PASSWORD"'], > environ={'TEST_ENV': 'ad_dc'}) > >-plantestsuite_loadlist("samba.tests.ldap_upn_sam_account", "ad_dc", >+plantestsuite_loadlist("samba.tests.ldap_spn", "ad_dc", >+ [python, >+ os.path.join(srcdir(), "python/samba/tests/ldap_spn.py"), >+ '$SERVER', >+ '-U"$USERNAME%$PASSWORD"', >+ '--workgroup=$DOMAIN', >+ '$LOADLIST', '$LISTOPT']) >+ >+plantestsuite_loadlist("samba.tests.ldap_upn_sam_account", "ad_dc_ntvfs", > [python, > os.path.join(srcdir(), "python/samba/tests/ldap_upn_sam_account.py"), > '$SERVER', >-- >2.25.1 > > >From b2baaf31f4563a09ece24afdefbbfd1cccdcd078 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Thu, 12 Aug 2021 21:53:16 +1200 >Subject: [PATCH 545/686] CVE-2020-25722 s4/cracknames: add comment pointing to > samldb spn handling > >These need to stay a little bit in sync. The reverse comment is there. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/cracknames.c | 6 ++++++ > 1 file changed, 6 insertions(+) > >diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c >index 582cfba3056..65a2866de52 100644 >--- a/source4/dsdb/samdb/cracknames.c >+++ b/source4/dsdb/samdb/cracknames.c >@@ -79,6 +79,12 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(struct ldb_context *ldb_ct > const char *alias_from, > char **alias_to) > { >+ /* >+ * Some of the logic of this function is mirrored in find_spn_alias() >+ * in source4/dsdb.samdb/ldb_modules/samldb.c. If you change this to >+ * not return the first matched alias, you will need to rethink that >+ * function too. >+ */ > unsigned int i; > int ret; > struct ldb_result *res; >-- >2.25.1 > > >From d57d7496a1ec405ac35b894dee41f9cb2bc8c9a6 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 22 Oct 2021 14:12:25 +1300 >Subject: [PATCH 546/686] CVE-2020-25722 s4/dsdb/samldb: add > samldb_get_single_valued_attr() helper > >This takes a string of logic out of samldb_unique_attr_check() that we >are going to need in other places, and that would be very tedious to >repeat. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 49 +++++++++++++++++++++++++ > 1 file changed, 49 insertions(+) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 9a4b7d946d6..bbb60ac5492 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -161,6 +161,55 @@ static int samldb_next_step(struct samldb_ctx *ac) > } > } > >+static int samldb_get_single_valued_attr(struct ldb_context *ldb, >+ struct samldb_ctx *ac, >+ const char *attr, >+ const char **value) >+{ >+ /* >+ * The steps we end up going through to get and check a single valued >+ * attribute. >+ */ >+ struct ldb_message_element *el = NULL; >+ >+ *value = NULL; >+ >+ el = dsdb_get_single_valued_attr(ac->msg, attr, >+ ac->req->operation); >+ if (el == NULL) { >+ /* we are not affected */ >+ return LDB_SUCCESS; >+ } >+ >+ if (el->num_values > 1) { >+ ldb_asprintf_errstring( >+ ldb, >+ "samldb: %s has %u values, should be single-valued!", >+ attr, el->num_values); >+ return LDB_ERR_CONSTRAINT_VIOLATION; >+ } else if (el->num_values == 0) { >+ ldb_asprintf_errstring( >+ ldb, >+ "samldb: new value for %s " >+ "not provided for mandatory, single-valued attribute!", >+ attr); >+ return LDB_ERR_OBJECT_CLASS_VIOLATION; >+ } >+ >+ >+ if (el->values[0].length == 0) { >+ ldb_asprintf_errstring( >+ ldb, >+ "samldb: %s is of zero length, should have a value!", >+ attr); >+ return LDB_ERR_OBJECT_CLASS_VIOLATION; >+ } >+ >+ *value = (char *)el->values[0].data; >+ >+ return LDB_SUCCESS; >+} >+ > static int samldb_unique_attr_check(struct samldb_ctx *ac, const char *attr, > const char *attr_conflict, > struct ldb_dn *base_dn) >-- >2.25.1 > > >From c65542b750c087ba6e4030510199a9f3949776d4 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 22 Oct 2021 13:16:30 +1300 >Subject: [PATCH 547/686] CVE-2020-25722 s4/dsdb/samldb: unique_attr_check uses > samldb_get_single_valued_attr() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 36 +++++++------------------ > 1 file changed, 10 insertions(+), 26 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index bbb60ac5492..91929f9f160 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -216,37 +216,21 @@ static int samldb_unique_attr_check(struct samldb_ctx *ac, const char *attr, > { > struct ldb_context *ldb = ldb_module_get_ctx(ac->module); > const char * const no_attrs[] = { NULL }; >- struct ldb_result *res; >- const char *enc_str; >- struct ldb_message_element *el; >+ struct ldb_result *res = NULL; >+ const char *str = NULL; >+ const char *enc_str = NULL; > int ret; > >- el = dsdb_get_single_valued_attr(ac->msg, attr, >- ac->req->operation); >- if (el == NULL) { >- /* we are not affected */ >- return LDB_SUCCESS; >- } >- >- if (el->num_values > 1) { >- ldb_asprintf_errstring(ldb, >- "samldb: %s has %u values, should be single-valued!", >- attr, el->num_values); >- return LDB_ERR_CONSTRAINT_VIOLATION; >- } else if (el->num_values == 0) { >- ldb_asprintf_errstring(ldb, >- "samldb: new value for %s not provided for mandatory, single-valued attribute!", >- attr); >- return LDB_ERR_OBJECT_CLASS_VIOLATION; >+ ret = samldb_get_single_valued_attr(ldb, ac, attr, &str); >+ if (ret != LDB_SUCCESS) { >+ return ret; > } >- if (el->values[0].length == 0) { >- ldb_asprintf_errstring(ldb, >- "samldb: %s is of zero length, should have a value!", >- attr); >- return LDB_ERR_OBJECT_CLASS_VIOLATION; >+ if (str == NULL) { >+ /* the attribute wasn't found */ >+ return LDB_SUCCESS; > } >- enc_str = ldb_binary_encode(ac, el->values[0]); > >+ enc_str = ldb_binary_encode_string(ac, str); > if (enc_str == NULL) { > return ldb_module_oom(ac->module); > } >-- >2.25.1 > > >From fab5efe8ed5cb2a780d9d6f6b2207bf1d69c3b0a Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 22 Oct 2021 13:17:34 +1300 >Subject: [PATCH 548/686] CVE-2020-25722 s4/dsdb/samldb: check for clashes in > UPNs/samaccountnames > >We already know duplicate sAMAccountNames and UserPrincipalNames are bad, >but we also have to check against the values these imply in each other. > >For example, imagine users with SAM account names "Alice" and "Bob" in >the realm "example.com". If they do not have explicit UPNs, by the logic >of MS-ADTS 5.1.1.1.1 they use the implict UPNs "alice@example.com" and >"bob@example.com", respectively. If Bob's UPN gets set to >"alice@example.com", it will clash with Alice's implicit one. > >Therefore we refuse to allow a UPN that implies an existing SAM account >name and vice versa. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail.d/ldap_upn_sam_account | 15 -- > source4/dsdb/samdb/ldb_modules/samldb.c | 206 +++++++++++++++++++++- > 2 files changed, 203 insertions(+), 18 deletions(-) > >diff --git a/selftest/knownfail.d/ldap_upn_sam_account b/selftest/knownfail.d/ldap_upn_sam_account >index c4d494968b2..e53d566816e 100644 >--- a/selftest/knownfail.d/ldap_upn_sam_account >+++ b/selftest/knownfail.d/ldap_upn_sam_account >@@ -1,16 +1 @@ > samba.tests.ldap_upn_sam_account.+LdapUpnSamSambaOnlyTest.test_upn_sam_SAM_contains_delete >-samba.tests.ldap_upn_sam_account.+LdapUpnSamSambaOnlyTest.test_upn_sam_UPN_same_but_for_internal_spaces >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_SAM_ends_with_at >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_SAM_has_at_signs_clashing_upn_first >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_SAM_has_at_signs_clashing_upn_second >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_SAM_starts_with_at >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_UPN_clash_on_other_realm >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_UPN_ends_with_at >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_UPN_has_no_at >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_UPN_starts_with_at >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_add_the_same_upn_to_different_objects >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_different_objects_SAM_after_UPN >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_different_objects_SAM_before_UPN >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_different_objects_same_UPN_different_case >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_spaces_around_at >-samba.tests.ldap_upn_sam_account.+LdapUpnSamTest.test_upn_sam_two_way_clash >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 91929f9f160..a76f456a2ad 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -235,8 +235,9 @@ static int samldb_unique_attr_check(struct samldb_ctx *ac, const char *attr, > return ldb_module_oom(ac->module); > } > >- /* Make sure that attr (eg) "sAMAccountName" is only used once */ >- >+ /* >+ * No other object should have the attribute with this value. >+ */ > if (attr_conflict != NULL) { > ret = dsdb_module_search(ac->module, ac, &res, > base_dn, >@@ -270,6 +271,193 @@ static int samldb_unique_attr_check(struct samldb_ctx *ac, const char *attr, > return LDB_SUCCESS; > } > >+ >+ >+static inline int samldb_sam_account_upn_clash_sub_search( >+ struct samldb_ctx *ac, >+ TALLOC_CTX *mem_ctx, >+ struct ldb_dn *base_dn, >+ const char *attr, >+ const char *value, >+ const char *err_msg >+ ) >+{ >+ /* >+ * A very specific helper function for samldb_sam_account_upn_clash(), >+ * where we end up doing this same thing several times in a row. >+ */ >+ const char * const no_attrs[] = { NULL }; >+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module); >+ struct ldb_result *res = NULL; >+ int ret; >+ char *enc_value = ldb_binary_encode_string(ac, value); >+ if (enc_value == NULL) { >+ return ldb_module_oom(ac->module); >+ } >+ ret = dsdb_module_search(ac->module, mem_ctx, &res, >+ base_dn, >+ LDB_SCOPE_SUBTREE, no_attrs, >+ DSDB_FLAG_NEXT_MODULE, ac->req, >+ "(%s=%s)", >+ attr, enc_value); >+ talloc_free(enc_value); >+ >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } else if (res->count > 1) { >+ return ldb_operr(ldb); >+ } else if (res->count == 1) { >+ if (ldb_dn_compare(res->msgs[0]->dn, ac->msg->dn) != 0){ >+ ldb_asprintf_errstring(ldb, >+ "samldb: %s '%s' " >+ "is already in use %s", >+ attr, value, err_msg); >+ /* different errors for different attrs */ >+ if (strcasecmp("userPrincipalName", attr) == 0) { >+ return LDB_ERR_CONSTRAINT_VIOLATION; >+ } >+ return LDB_ERR_ENTRY_ALREADY_EXISTS; >+ } >+ } >+ return LDB_SUCCESS; >+} >+ >+static int samldb_sam_account_upn_clash(struct samldb_ctx *ac) >+{ >+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module); >+ int ret; >+ struct ldb_dn *base_dn = ldb_get_default_basedn(ldb); >+ TALLOC_CTX *tmp_ctx = NULL; >+ const char *real_sam = NULL; >+ const char *real_upn = NULL; >+ char *implied_sam = NULL; >+ char *implied_upn = NULL; >+ const char *realm = NULL; >+ >+ ret = samldb_get_single_valued_attr(ldb, ac, >+ "sAMAccountName", >+ &real_sam); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ ret = samldb_get_single_valued_attr(ldb, ac, >+ "userPrincipalName", >+ &real_upn); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ if (real_upn == NULL && real_sam == NULL) { >+ /* Not changing these things, so we're done */ >+ return LDB_SUCCESS; >+ } >+ >+ tmp_ctx = talloc_new(ac); >+ realm = samdb_dn_to_dns_domain(tmp_ctx, base_dn); >+ if (realm == NULL) { >+ talloc_free(tmp_ctx); >+ return ldb_operr(ldb); >+ } >+ >+ if (real_upn != NULL) { >+ /* >+ * note we take the last @ in the upn because the first (i.e. >+ * sAMAccountName equivalent) part can contain @. >+ * >+ * It is also OK (per Windows) for a UPN to have zero @s. >+ */ >+ char *at = NULL; >+ char *upn_realm = NULL; >+ implied_sam = talloc_strdup(tmp_ctx, real_upn); >+ if (implied_sam == NULL) { >+ talloc_free(tmp_ctx); >+ return ldb_module_oom(ac->module); >+ } >+ >+ at = strrchr(implied_sam, '@'); >+ if (at == NULL) { >+ /* >+ * there is no @ in this UPN, so we treat the whole >+ * thing as a sAMAccountName for the purposes of a >+ * clash. >+ */ >+ DBG_INFO("samldb: userPrincipalName '%s' contains " >+ "no '@' character\n", implied_sam); >+ } else { >+ /* >+ * Now, this upn only implies a sAMAccountName if the >+ * realm is our realm. So we need to compare the tail >+ * of the upn to the realm. >+ */ >+ *at = '\0'; >+ upn_realm = at + 1; >+ if (strcasecmp(upn_realm, realm) != 0) { >+ /* implied_sam is not the implied >+ * sAMAccountName after all, because it is >+ * from a different realm. */ >+ TALLOC_FREE(implied_sam); >+ } >+ } >+ } >+ >+ if (real_sam != NULL) { >+ implied_upn = talloc_asprintf(tmp_ctx, "%s@%s", >+ real_sam, realm); >+ if (implied_upn == NULL) { >+ talloc_free(tmp_ctx); >+ return ldb_module_oom(ac->module); >+ } >+ } >+ >+ /* >+ * Now we have all of the actual and implied names, in which to search >+ * for conflicts. >+ */ >+ if (real_sam != NULL) { >+ ret = samldb_sam_account_upn_clash_sub_search( >+ ac, tmp_ctx, base_dn, "sAMAccountName", >+ real_sam, ""); >+ >+ if (ret != LDB_SUCCESS) { >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ } >+ if (implied_upn != NULL) { >+ ret = samldb_sam_account_upn_clash_sub_search( >+ ac, tmp_ctx, base_dn, "userPrincipalName", implied_upn, >+ "(implied by sAMAccountName)"); >+ >+ if (ret != LDB_SUCCESS) { >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ } >+ if (real_upn != NULL) { >+ ret = samldb_sam_account_upn_clash_sub_search( >+ ac, tmp_ctx, base_dn, "userPrincipalName", >+ real_upn, ""); >+ >+ if (ret != LDB_SUCCESS) { >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ } >+ if (implied_sam != NULL) { >+ ret = samldb_sam_account_upn_clash_sub_search( >+ ac, tmp_ctx, base_dn, "sAMAccountName", implied_sam, >+ "(implied by userPrincipalName)"); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ } >+ >+ talloc_free(tmp_ctx); >+ return LDB_SUCCESS; >+} >+ >+ >+/* This is run during an add or modify */ > static int samldb_sam_accountname_valid_check(struct samldb_ctx *ac) > { > int ret = 0; >@@ -303,7 +491,11 @@ static int samldb_sam_accountname_valid_check(struct samldb_ctx *ac) > } else if (ret == LDB_ERR_OBJECT_CLASS_VIOLATION) { > ret = LDB_ERR_CONSTRAINT_VIOLATION; > } >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } > >+ ret = samldb_sam_account_upn_clash(ac); > if (ret != LDB_SUCCESS) { > return ret; > } >@@ -4174,7 +4366,6 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) > if (ret != LDB_SUCCESS) { > return ret; > } >- > user_account_control > = ldb_msg_find_attr_as_uint(res->msgs[0], > "userAccountControl", >@@ -4198,6 +4389,15 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) > } > } > >+ el = ldb_msg_find_element(ac->msg, "userPrincipalName"); >+ if (el != NULL) { >+ ret = samldb_sam_account_upn_clash(ac); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(ac); >+ return ret; >+ } >+ } >+ > el = ldb_msg_find_element(ac->msg, "ldapDisplayName"); > if (el != NULL) { > ret = samldb_schema_ldapdisplayname_valid_check(ac); >-- >2.25.1 > > >From 21e2064495d4fa625117ba9aba1f453d53a1d3d9 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 22 Oct 2021 15:27:25 +1300 >Subject: [PATCH 549/686] CVE-2020-25722 s4/dsdb/samldb: check sAMAccountName > for illegal characters > >This only for the real account name, not the account name implicit in >a UPN. It doesn't matter if a UPN implies an illegal sAMAccountName, >since that is not going to conflict with a real one. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail.d/ldap_upn_sam_account | 1 - > source4/dsdb/samdb/ldb_modules/samldb.c | 58 +++++++++++++++++++++++ > 2 files changed, 58 insertions(+), 1 deletion(-) > delete mode 100644 selftest/knownfail.d/ldap_upn_sam_account > >diff --git a/selftest/knownfail.d/ldap_upn_sam_account b/selftest/knownfail.d/ldap_upn_sam_account >deleted file mode 100644 >index e53d566816e..00000000000 >--- a/selftest/knownfail.d/ldap_upn_sam_account >+++ /dev/null >@@ -1 +0,0 @@ >-samba.tests.ldap_upn_sam_account.+LdapUpnSamSambaOnlyTest.test_upn_sam_SAM_contains_delete >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index a76f456a2ad..b69c1fa4030 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -322,6 +322,59 @@ static inline int samldb_sam_account_upn_clash_sub_search( > return LDB_SUCCESS; > } > >+static int samaccountname_bad_chars_check(struct samldb_ctx *ac, >+ const char *name) >+{ >+ /* >+ * The rules here are based on >+ * >+ * https://social.technet.microsoft.com/wiki/contents/articles/11216.active-directory-requirements-for-creating-objects.aspx >+ * >+ * Windows considers UTF-8 sequences that map to "similar" characters >+ * (e.g. 'a', 'Ä') to be the same sAMAccountName, and we don't. Names >+ * that are not valid UTF-8 *are* allowed. >+ * >+ * Additionally, Samba collapses multiple spaces, and Windows doesn't. >+ */ >+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module); >+ size_t i; >+ >+ for (i = 0; name[i] != '\0'; i++) { >+ uint8_t c = name[i]; >+ char *p = NULL; >+ if (c < 32 || c == 127) { >+ ldb_asprintf_errstring( >+ ldb, >+ "samldb: sAMAccountName contains invalid " >+ "0x%.2x character\n", c); >+ return LDB_ERR_CONSTRAINT_VIOLATION; >+ } >+ p = strchr("\"[]:;|=+*?<>/\\,", c); >+ if (p != NULL) { >+ ldb_asprintf_errstring( >+ ldb, >+ "samldb: sAMAccountName contains invalid " >+ "'%c' character\n", c); >+ return LDB_ERR_CONSTRAINT_VIOLATION; >+ } >+ } >+ >+ if (i == 0) { >+ ldb_asprintf_errstring( >+ ldb, >+ "samldb: sAMAccountName is empty\n"); >+ return LDB_ERR_CONSTRAINT_VIOLATION; >+ } >+ >+ if (name[i - 1] == '.') { >+ ldb_asprintf_errstring( >+ ldb, >+ "samldb: sAMAccountName ends with '.'"); >+ return LDB_ERR_CONSTRAINT_VIOLATION; >+ } >+ return LDB_SUCCESS; >+} >+ > static int samldb_sam_account_upn_clash(struct samldb_ctx *ac) > { > struct ldb_context *ldb = ldb_module_get_ctx(ac->module); >@@ -421,6 +474,11 @@ static int samldb_sam_account_upn_clash(struct samldb_ctx *ac) > talloc_free(tmp_ctx); > return ret; > } >+ ret = samaccountname_bad_chars_check(ac, real_sam); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(tmp_ctx); >+ return ret; >+ } > } > if (implied_upn != NULL) { > ret = samldb_sam_account_upn_clash_sub_search( >-- >2.25.1 > > >From 6fe69a5ef52860e746437704b7188e0f0c315b72 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 22 Oct 2021 13:14:32 +1300 >Subject: [PATCH 550/686] CVE-2020-25722 s4/dsdb/samldb: check for SPN > uniqueness, including aliases > >Not only should it not be possible to add a servicePrincipalName that >is already present in the domain, it should not be possible to add one >that is implied by an entry in sPNMappings, unless the user is adding >an alias to another SPN and has rights to alter that one. > >For example, with the default sPNMappings, cifs/ is an alias pointing to >host/, meaning if there is no cifs/example.com SPN, the host/example.com >one will be used instead. A user can add the cifs/example.com SPN only >if they can also change the host/example.com one (because adding the >cifs/ effectively changes the host/). The reverse is refused in all cases, >unless they happen to be on the same object. That is, if there is a >cifs/example.com SPN, there is no way to add host/example.com elsewhere. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail.d/ldap_spn | 23 - > source4/dsdb/samdb/ldb_modules/samldb.c | 588 +++++++++++++++++++++++- > 2 files changed, 585 insertions(+), 26 deletions(-) > >diff --git a/selftest/knownfail.d/ldap_spn b/selftest/knownfail.d/ldap_spn >index dc768728658..b7eb6f30e7a 100644 >--- a/selftest/knownfail.d/ldap_spn >+++ b/selftest/knownfail.d/ldap_spn >@@ -1,26 +1,3 @@ >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_host_first_both_on_user_service_rights >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_host_first_with_service_write_rights >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_service_first_as_admin >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_service_first_with_both_write_rights >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_service_first_with_host_write_rights >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_changing_dNSHostName_after_host >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_mystery_dnsname_clash_www_first >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_host_first_with_partial_write_rights >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_host_first_with_partial_write_rights_2 >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_sandwich_sufficient_rights >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_service_first_just_sufficient_rights >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_service_first_with_all_write_rights >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_service_first_with_both_write_rights >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_service_first_with_host_write_rights >-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_three_way_conflict_services_first_with_partial_rights >-samba.tests.ldap_spn.+LdapSpnTest.test_spn_adding_dNSHostName_after_cifs_with_no_old_dNSHostName >-samba.tests.ldap_spn.+LdapSpnTest.test_spn_changing_dNSHostName_after_cifs > samba.tests.ldap_spn.+LdapSpnTest.test_spn_dodgy_spns >-samba.tests.ldap_spn.+LdapSpnTest.test_spn_empty_part_spns_consecutive_slashes_ > samba.tests.ldap_spn.+LdapSpnTest.test_spn_one_part_spns_no_slashes_ >-samba.tests.ldap_spn.+LdapSpnTest.test_spn_three_part_nonsense_spns >-samba.tests.ldap_spn.+LdapSpnTest.test_spn_three_part_spns >-samba.tests.ldap_spn.+LdapSpnTest.test_spn_three_way_conflict_host_first_adding_duplicate >-samba.tests.ldap_spn.+LdapSpnTest.test_spn_three_way_conflict_host_first_adding_duplicate_full_rights >-samba.tests.ldap_spn.+LdapSpnTest.test_spn_three_way_conflict_services_first_as_admin > samba.tests.ldap_spn.+LdapSpnTest.test_spn_too_many_spn_parts >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index b69c1fa4030..8faf0e04fb5 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -3383,6 +3383,546 @@ static int samldb_description_check(struct samldb_ctx *ac, bool *modified) > return LDB_SUCCESS; > } > >+#define SPN_ALIAS_NONE 0 >+#define SPN_ALIAS_LINK 1 >+#define SPN_ALIAS_TARGET 2 >+ >+static int find_spn_aliases(struct ldb_context *ldb, >+ TALLOC_CTX *mem_ctx, >+ const char *service_class, >+ char ***aliases, >+ size_t *n_aliases, >+ int *direction) >+{ >+ /* >+ * If you change the way this works, you should also look at changing >+ * LDB_lookup_spn_alias() in source4/dsdb/samdb/cracknames.c, which >+ * does some of the same work. >+ * >+ * In particular, note that sPNMappings are resolved on a first come, >+ * first served basis. For example, if we have >+ * >+ * host=ldap,cifs >+ * foo=ldap >+ * cifs=host,alerter >+ * >+ * then 'ldap', 'cifs', and 'host' will resolve to 'host', and >+ * 'alerter' will resolve to 'cifs'. >+ * >+ * If this resolution method is made more complicated, then the >+ * cracknames function should also be changed. >+ */ >+ size_t i, j; >+ int ret; >+ bool ok; >+ struct ldb_result *res = NULL; >+ struct ldb_message_element *spnmappings = NULL; >+ TALLOC_CTX *tmp_ctx = NULL; >+ struct ldb_dn *service_dn = NULL; >+ >+ const char *attrs[] = { >+ "sPNMappings", >+ NULL >+ }; >+ >+ *direction = SPN_ALIAS_NONE; >+ >+ tmp_ctx = talloc_new(mem_ctx); >+ if (tmp_ctx == NULL) { >+ return ldb_oom(ldb); >+ } >+ >+ service_dn = ldb_dn_new( >+ tmp_ctx, ldb, >+ "CN=Directory Service,CN=Windows NT,CN=Services"); >+ if (service_dn == NULL) { >+ talloc_free(tmp_ctx); >+ return ldb_oom(ldb); >+ } >+ >+ ok = ldb_dn_add_base(service_dn, ldb_get_config_basedn(ldb)); >+ if (! ok) { >+ talloc_free(tmp_ctx); >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ >+ ret = ldb_search(ldb, tmp_ctx, &res, service_dn, LDB_SCOPE_BASE, >+ attrs, "(objectClass=nTDSService)"); >+ >+ if (ret != LDB_SUCCESS || res->count != 1) { >+ DBG_WARNING("sPNMappings not found.\n"); >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ >+ spnmappings = ldb_msg_find_element(res->msgs[0], "sPNMappings"); >+ if (spnmappings == NULL || spnmappings->num_values == 0) { >+ DBG_WARNING("no sPNMappings attribute\n"); >+ talloc_free(tmp_ctx); >+ return LDB_ERR_NO_SUCH_OBJECT; >+ } >+ *n_aliases = 0; >+ >+ for (i = 0; i < spnmappings->num_values; i++) { >+ char *p = NULL; >+ char *mapping = talloc_strndup( >+ tmp_ctx, >+ (char *)spnmappings->values[i].data, >+ spnmappings->values[i].length); >+ if (mapping == NULL) { >+ talloc_free(tmp_ctx); >+ return ldb_oom(ldb); >+ } >+ >+ p = strchr(mapping, '='); >+ if (p == NULL) { >+ talloc_free(tmp_ctx); >+ return LDB_ERR_ALIAS_PROBLEM; >+ } >+ p[0] = '\0'; >+ p++; >+ >+ if (strcasecmp(mapping, service_class) == 0) { >+ /* >+ * We need to return the reverse aliases for this one. >+ * >+ * typically, this means the service_class is "host" >+ * and the mapping is "host=alerter,appmgmt,cisvc,..", >+ * so we get "alerter", "appmgmt", etc in the list of >+ * aliases. >+ */ >+ >+ /* There is one more field than there are commas */ >+ size_t n = 1; >+ >+ for (j = 0; p[j] != '\0'; j++) { >+ if (p[j] == ',') { >+ n++; >+ p[j] = '\0'; >+ } >+ } >+ *aliases = talloc_array(mem_ctx, char*, n); >+ if (*aliases == NULL) { >+ talloc_free(tmp_ctx); >+ return ldb_oom(ldb); >+ } >+ *n_aliases = n; >+ talloc_steal(mem_ctx, mapping); >+ for (j = 0; j < n; j++) { >+ (*aliases)[j] = p; >+ p += strlen(p) + 1; >+ } >+ talloc_free(tmp_ctx); >+ *direction = SPN_ALIAS_LINK; >+ return LDB_SUCCESS; >+ } >+ /* >+ * We need to look along the list to see if service_class is >+ * there; if so, we return a list of one item (probably "host"). >+ */ >+ do { >+ char *str = p; >+ p = strchr(p, ','); >+ if (p != NULL) { >+ p[0] = '\0'; >+ p++; >+ } >+ if (strcasecmp(str, service_class) == 0) { >+ *aliases = talloc_array(mem_ctx, char*, 1); >+ if (*aliases == NULL) { >+ talloc_free(tmp_ctx); >+ return ldb_oom(ldb); >+ } >+ *n_aliases = 1; >+ (*aliases)[0] = mapping; >+ talloc_steal(mem_ctx, mapping); >+ talloc_free(tmp_ctx); >+ *direction = SPN_ALIAS_TARGET; >+ return LDB_SUCCESS; >+ } >+ } while (p != NULL); >+ } >+ DBG_INFO("no sPNMappings alias for '%s'\n", service_class); >+ talloc_free(tmp_ctx); >+ *aliases = NULL; >+ *n_aliases = 0; >+ return LDB_SUCCESS; >+} >+ >+ >+static int get_spn_dn(struct ldb_context *ldb, >+ TALLOC_CTX *tmp_ctx, >+ const char *candidate, >+ struct ldb_dn **dn) >+{ >+ int ret; >+ const char *empty_attrs[] = { NULL }; >+ struct ldb_message *msg = NULL; >+ struct ldb_dn *base_dn = ldb_get_default_basedn(ldb); >+ >+ const char *enc_candidate = NULL; >+ >+ *dn = NULL; >+ >+ enc_candidate = ldb_binary_encode_string(tmp_ctx, candidate); >+ if (enc_candidate == NULL) { >+ return ldb_operr(ldb); >+ } >+ >+ ret = dsdb_search_one(ldb, >+ tmp_ctx, >+ &msg, >+ base_dn, >+ LDB_SCOPE_SUBTREE, >+ empty_attrs, >+ 0, >+ "(servicePrincipalName=%s)", >+ enc_candidate); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ *dn = msg->dn; >+ return LDB_SUCCESS; >+} >+ >+ >+static int check_spn_write_rights(struct ldb_context *ldb, >+ TALLOC_CTX *mem_ctx, >+ const char *spn, >+ struct ldb_dn *dn) >+{ >+ int ret; >+ struct ldb_message *msg = NULL; >+ struct ldb_message_element *del_el = NULL; >+ struct ldb_message_element *add_el = NULL; >+ struct ldb_val val = { >+ .data = discard_const_p(uint8_t, spn), >+ .length = strlen(spn) >+ }; >+ >+ msg = ldb_msg_new(mem_ctx); >+ if (msg == NULL) { >+ return ldb_oom(ldb); >+ } >+ msg->dn = dn; >+ >+ ret = ldb_msg_add_empty(msg, >+ "servicePrincipalName", >+ LDB_FLAG_MOD_DELETE, >+ &del_el); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(msg); >+ return ret; >+ } >+ >+ del_el->values = talloc_array(msg->elements, struct ldb_val, 1); >+ if (del_el->values == NULL) { >+ talloc_free(msg); >+ return ret; >+ } >+ >+ del_el->values[0] = val; >+ del_el->num_values = 1; >+ >+ ret = ldb_msg_add_empty(msg, >+ "servicePrincipalName", >+ LDB_FLAG_MOD_ADD, >+ &add_el); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(msg); >+ return ret; >+ } >+ >+ add_el->values = talloc_array(msg->elements, struct ldb_val, 1); >+ if (add_el->values == NULL) { >+ talloc_free(msg); >+ return ret; >+ } >+ >+ add_el->values[0] = val; >+ add_el->num_values = 1; >+ >+ ret = ldb_modify(ldb, msg); >+ if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { >+ DBG_ERR("hmm I think we're OK, but not sure\n"); >+ } else if (ret != LDB_SUCCESS) { >+ DBG_ERR("SPN write rights check failed with %d\n", ret); >+ talloc_free(msg); >+ return ret; >+ } >+ talloc_free(msg); >+ return LDB_SUCCESS; >+} >+ >+ >+static int check_spn_alias_collision(struct ldb_context *ldb, >+ TALLOC_CTX *mem_ctx, >+ const char *spn, >+ struct ldb_dn *target_dn) >+{ >+ int ret; >+ char *service_class = NULL; >+ char *spn_tail = NULL; >+ char *p = NULL; >+ char **aliases = NULL; >+ size_t n_aliases = 0; >+ size_t i, len; >+ TALLOC_CTX *tmp_ctx = NULL; >+ const char *target_dnstr = ldb_dn_get_linearized(target_dn); >+ int link_direction; >+ >+ tmp_ctx = talloc_new(mem_ctx); >+ if (tmp_ctx == NULL) { >+ return ldb_oom(ldb); >+ } >+ >+ /* >+ * "dns/example.com/xxx" gives >+ * service_class = "dns" >+ * spn_tail = "example.com/xxx" >+ */ >+ p = strchr(spn, '/'); >+ if (p == NULL) { >+ /* bad SPN */ >+ talloc_free(tmp_ctx); >+ return ldb_error(ldb, >+ LDB_ERR_OPERATIONS_ERROR, >+ "malformed servicePrincipalName"); >+ } >+ len = p - spn; >+ >+ service_class = talloc_strndup(tmp_ctx, spn, len); >+ if (service_class == NULL) { >+ talloc_free(tmp_ctx); >+ return ldb_oom(ldb); >+ } >+ spn_tail = p + 1; >+ >+ ret = find_spn_aliases(ldb, >+ tmp_ctx, >+ service_class, >+ &aliases, >+ &n_aliases, >+ &link_direction); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ >+ /* >+ * we have the list of aliases, and now we need to combined them with >+ * spn_tail and see if we can find the SPN. >+ */ >+ for (i = 0; i < n_aliases; i++) { >+ struct ldb_dn *colliding_dn = NULL; >+ const char *colliding_dnstr = NULL; >+ >+ char *candidate = talloc_asprintf(tmp_ctx, >+ "%s/%s", >+ aliases[i], >+ spn_tail); >+ if (candidate == NULL) { >+ talloc_free(tmp_ctx); >+ return ldb_oom(ldb); >+ } >+ >+ ret = get_spn_dn(ldb, tmp_ctx, candidate, &colliding_dn); >+ if (ret == LDB_ERR_NO_SUCH_OBJECT) { >+ DBG_DEBUG("SPN alias '%s' not found (good)\n", >+ candidate); >+ talloc_free(candidate); >+ continue; >+ } >+ if (ret != LDB_SUCCESS) { >+ DBG_ERR("SPN '%s' search error %d\n", candidate, ret); >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ >+ target_dnstr = ldb_dn_get_linearized(target_dn); >+ /* >+ * We have found an existing SPN that matches the alias. That >+ * is OK only if it is on the object we are trying to add to, >+ * or if the SPN on the other side is a more generic alias for >+ * this one and we also have rights to modify it. >+ * >+ * That is, we can put "host/X" and "cifs/X" on the same >+ * object, but not on different objects, unless we put the >+ * host/X on first, and could also change that object when we >+ * add cifs/X. It is forbidden to add the objects in the other >+ * order. >+ * >+ * The rationale for this is that adding "cifs/X" effectively >+ * changes "host/X" by diverting traffic. If "host/X" can be >+ * added after "cifs/X", a sneaky person could get "cifs/X" in >+ * first, making "host/X" have less effect than intended. >+ * >+ * Note: we also can't have "host/X" and "Host/X" on the same >+ * object, but that is not relevant here. >+ */ >+ >+ ret = ldb_dn_compare(colliding_dn, target_dn); >+ if (ret != 0) { >+ colliding_dnstr = ldb_dn_get_linearized(colliding_dn); >+ DBG_ERR("trying to add SPN '%s' on '%s' when '%s' is " >+ "on '%s'\n", >+ spn, >+ target_dnstr, >+ candidate, >+ colliding_dnstr); >+ >+ if (link_direction == SPN_ALIAS_LINK) { >+ /* we don't allow host/X if there is a >+ * cifs/X */ >+ talloc_free(tmp_ctx); >+ return LDB_ERR_CONSTRAINT_VIOLATION; >+ } >+ ret = check_spn_write_rights(ldb, >+ tmp_ctx, >+ candidate, >+ colliding_dn); >+ if (ret != LDB_SUCCESS) { >+ DBG_ERR("SPN '%s' is on '%s' so '%s' can't be " >+ "added to '%s'\n", >+ candidate, >+ colliding_dnstr, >+ spn, >+ target_dnstr); >+ talloc_free(tmp_ctx); >+ ldb_asprintf_errstring(ldb, >+ "samldb: spn[%s] would cause a conflict", >+ spn); >+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; >+ } >+ } else { >+ DBG_INFO("SPNs '%s' and '%s' alias both on '%s'\n", >+ candidate, spn, target_dnstr); >+ } >+ talloc_free(candidate); >+ } >+ >+ talloc_free(tmp_ctx); >+ return LDB_SUCCESS; >+} >+ >+static int check_spn_direct_collision(struct ldb_context *ldb, >+ TALLOC_CTX *mem_ctx, >+ const char *spn, >+ struct ldb_dn *target_dn) >+{ >+ int ret; >+ TALLOC_CTX *tmp_ctx = NULL; >+ struct ldb_dn *colliding_dn = NULL; >+ const char *target_dnstr = NULL; >+ const char *colliding_dnstr = NULL; >+ >+ tmp_ctx = talloc_new(mem_ctx); >+ if (tmp_ctx == NULL) { >+ return ldb_oom(ldb); >+ } >+ >+ ret = get_spn_dn(ldb, tmp_ctx, spn, &colliding_dn); >+ if (ret == LDB_ERR_NO_SUCH_OBJECT) { >+ DBG_DEBUG("SPN '%s' not found (good)\n", spn); >+ talloc_free(tmp_ctx); >+ return LDB_SUCCESS; >+ } >+ if (ret != LDB_SUCCESS) { >+ DBG_ERR("SPN '%s' search error %d\n", spn, ret); >+ talloc_free(tmp_ctx); >+ if (ret == LDB_ERR_COMPARE_TRUE) { >+ /* >+ * COMPARE_TRUE has special meaning here and we don't >+ * want to return it by mistake. >+ */ >+ ret = LDB_ERR_OPERATIONS_ERROR; >+ } >+ return ret; >+ } >+ /* >+ * We have found this exact SPN. This is mostly harmless (depend on >+ * ADD vs REPLACE) when the spn is being put on the object that >+ * already has, so we let it through to succeed or fail as some other >+ * module sees fit. >+ */ >+ target_dnstr = ldb_dn_get_linearized(target_dn); >+ ret = ldb_dn_compare(colliding_dn, target_dn); >+ if (ret != 0) { >+ colliding_dnstr = ldb_dn_get_linearized(colliding_dn); >+ DBG_ERR("SPN '%s' is on '%s' so it can't be " >+ "added to '%s'\n", >+ spn, >+ colliding_dnstr, >+ target_dnstr); >+ ldb_asprintf_errstring(ldb, >+ "samldb: spn[%s] would cause a conflict", >+ spn); >+ talloc_free(tmp_ctx); >+ return LDB_ERR_CONSTRAINT_VIOLATION; >+ } >+ >+ DBG_INFO("SPN '%s' is already on '%s'\n", >+ spn, target_dnstr); >+ talloc_free(tmp_ctx); >+ return LDB_ERR_COMPARE_TRUE; >+} >+ >+ >+/* Check that "servicePrincipalName" changes do not introduce a collision >+ * globally. */ >+static int samldb_spn_uniqueness_check(struct samldb_ctx *ac, >+ struct ldb_message_element *spn_el) >+{ >+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module); >+ int ret; >+ const char *spn = NULL; >+ size_t i; >+ TALLOC_CTX *tmp_ctx = talloc_new(ac->msg); >+ if (tmp_ctx == NULL) { >+ return ldb_oom(ldb); >+ } >+ >+ for (i = 0; i < spn_el->num_values; i++) { >+ spn = (char *)spn_el->values[i].data; >+ >+ ret = check_spn_direct_collision(ldb, >+ tmp_ctx, >+ spn, >+ ac->msg->dn); >+ if (ret == LDB_ERR_COMPARE_TRUE) { >+ DBG_INFO("SPN %s re-added to the same object\n", spn); >+ talloc_free(tmp_ctx); >+ return LDB_SUCCESS; >+ } >+ if (ret != LDB_SUCCESS) { >+ DBG_ERR("SPN %s failed direct uniqueness check\n", spn); >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ >+ ret = check_spn_alias_collision(ldb, >+ tmp_ctx, >+ spn, >+ ac->msg->dn); >+ >+ if (ret == LDB_ERR_NO_SUCH_OBJECT) { >+ /* we have no sPNMappings, hence no aliases */ >+ break; >+ } >+ if (ret != LDB_SUCCESS) { >+ DBG_ERR("SPN %s failed alias uniqueness check\n", spn); >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ DBG_INFO("SPN %s seems to be unique\n", spn); >+ } >+ >+ talloc_free(tmp_ctx); >+ return LDB_SUCCESS; >+} >+ >+ >+ > /* This trigger adapts the "servicePrincipalName" attributes if the > * "dNSHostName" and/or "sAMAccountName" attribute change(s) */ > static int samldb_service_principal_names_change(struct samldb_ctx *ac) >@@ -3498,8 +4038,14 @@ static int samldb_service_principal_names_change(struct samldb_ctx *ac) > return LDB_SUCCESS; > } > >- /* Potential "servicePrincipalName" changes in the same request have to >- * be handled before the update (Windows behaviour). */ >+ /* >+ * Potential "servicePrincipalName" changes in the same request have >+ * to be handled before the update (Windows behaviour). >+ * >+ * We extract the SPN changes into a new message and run it through >+ * the stack from this module, so that it subjects them to the SPN >+ * checks we have here. >+ */ > el = ldb_msg_find_element(ac->msg, "servicePrincipalName"); > if (el != NULL) { > msg = ldb_msg_new(ac->msg); >@@ -3521,7 +4067,7 @@ static int samldb_service_principal_names_change(struct samldb_ctx *ac) > } while (el != NULL); > > ret = dsdb_module_modify(ac->module, msg, >- DSDB_FLAG_NEXT_MODULE, ac->req); >+ DSDB_FLAG_OWN_MODULE, ac->req); > if (ret != LDB_SUCCESS) { > return ret; > } >@@ -4254,6 +4800,19 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req) > return samldb_fill_object(ac); > } > >+ >+ el = ldb_msg_find_element(ac->msg, "servicePrincipalName"); >+ if ((el != NULL)) { >+ /* >+ * We need to check whether the SPN collides with an existing >+ * one (anywhere) including via aliases. >+ */ >+ ret = samldb_spn_uniqueness_check(ac, el); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ } >+ > if (samdb_find_attribute(ldb, ac->msg, > "objectclass", "subnet") != NULL) { > ret = samldb_verify_subnet(ac, ac->msg->dn); >@@ -4504,12 +5063,35 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) > el2 = ldb_msg_find_element(ac->msg, "sAMAccountName"); > if ((el != NULL) || (el2 != NULL)) { > modified = true; >+ /* >+ * samldb_service_principal_names_change() might add SPN >+ * changes to the request, so this must come before the SPN >+ * uniqueness check below. >+ * >+ * Note we ALSO have to do the SPN uniqueness check inside >+ * samldb_service_principal_names_change(), because it does a >+ * subrequest to do requested SPN modifications *before* its >+ * automatic ones are added. >+ */ > ret = samldb_service_principal_names_change(ac); > if (ret != LDB_SUCCESS) { > return ret; > } > } > >+ el = ldb_msg_find_element(ac->msg, "servicePrincipalName"); >+ if ((el != NULL)) { >+ /* >+ * We need to check whether the SPN collides with an existing >+ * one (anywhere) including via aliases. >+ */ >+ modified = true; >+ ret = samldb_spn_uniqueness_check(ac, el); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ } >+ > el = ldb_msg_find_element(ac->msg, "fSMORoleOwner"); > if (el != NULL) { > ret = samldb_fsmo_role_owner_check(ac); >-- >2.25.1 > > >From 625cd7ff7153819c869d7fc26b11d2cccf62d14d Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 22 Oct 2021 16:03:18 +1300 >Subject: [PATCH 551/686] CVE-2020-25722 s4/dsdb/samldb: reject SPN with too > few/many components > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail.d/ldap_spn | 2 -- > source4/dsdb/samdb/ldb_modules/samldb.c | 41 +++++++++++++++++++++++++ > 2 files changed, 41 insertions(+), 2 deletions(-) > >diff --git a/selftest/knownfail.d/ldap_spn b/selftest/knownfail.d/ldap_spn >index b7eb6f30e7a..63f9fe02ef7 100644 >--- a/selftest/knownfail.d/ldap_spn >+++ b/selftest/knownfail.d/ldap_spn >@@ -1,3 +1 @@ > samba.tests.ldap_spn.+LdapSpnTest.test_spn_dodgy_spns >-samba.tests.ldap_spn.+LdapSpnTest.test_spn_one_part_spns_no_slashes_ >-samba.tests.ldap_spn.+LdapSpnTest.test_spn_too_many_spn_parts >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 8faf0e04fb5..7ea0bb2ceef 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -3868,6 +3868,37 @@ static int check_spn_direct_collision(struct ldb_context *ldb, > } > > >+static int count_spn_components(struct ldb_val val) >+{ >+ /* >+ * a 3 part servicePrincipalName has two slashes, like >+ * ldap/example.com/DomainDNSZones.example.com. >+ * >+ * In krb5_parse_name_flags() we don't count "\/" as a slash (i.e. >+ * escaped by a backslash), but this is not the behaviour of Windows >+ * on setting a servicePrincipalName -- slashes are counted regardless >+ * of backslashes. >+ * >+ * Accordingly, here we ignore backslashes. This will reject >+ * multi-slash SPNs that krb5_parse_name_flags() would accept, and >+ * allow ones in the form "a\/b" that it won't parse. >+ */ >+ size_t i; >+ int slashes = 0; >+ for (i = 0; i < val.length; i++) { >+ char c = val.data[i]; >+ if (c == '/') { >+ slashes++; >+ if (slashes == 3) { >+ /* at this point we don't care */ >+ return 4; >+ } >+ } >+ } >+ return slashes + 1; >+} >+ >+ > /* Check that "servicePrincipalName" changes do not introduce a collision > * globally. */ > static int samldb_spn_uniqueness_check(struct samldb_ctx *ac, >@@ -3883,8 +3914,18 @@ static int samldb_spn_uniqueness_check(struct samldb_ctx *ac, > } > > for (i = 0; i < spn_el->num_values; i++) { >+ int n_components; > spn = (char *)spn_el->values[i].data; > >+ n_components = count_spn_components(spn_el->values[i]); >+ if (n_components > 3 || n_components < 2) { >+ ldb_asprintf_errstring(ldb, >+ "samldb: spn[%s] invalid with %u components", >+ spn, n_components); >+ talloc_free(tmp_ctx); >+ return LDB_ERR_CONSTRAINT_VIOLATION; >+ } >+ > ret = check_spn_direct_collision(ldb, > tmp_ctx, > spn, >-- >2.25.1 > > >From 727baee77a1aab4ad6b102e91a169809a19e6a62 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:09:21 +1300 >Subject: [PATCH 552/686] CVE-2020-25722 s4/dsdb modules: add > dsdb_get_expected_new_values() > >This function collects a superset of all the new values for the specified >attribute that could result from an ldb add or modify message. > >In most cases -- where there is a single add or modify -- the exact set >of added values is returned, and this is done reasonably efficiently >using the existing element. Where it gets complicated is when there are >multiple elements for the same attribute in a message. Anything added >before a replace or delete will be included in these results but may not >end up in the database if the message runs its course. Examples: > > sequence result >1. ADD the element is returned (exact) >2. REPLACE the element is returned (exact) >3. ADD, ADD both elements are concatenated together (exact) >4. ADD, REPLACE both elements are concatenated together (superset) >5. REPLACE, ADD both elements are concatenated together (exact) >6. ADD, DEL, ADD adds are concatenated together (superset) >7. REPLACE, REPLACE both concatenated (superset) >8. DEL, ADD last element is returned (exact) > >Why this? In the past we have treated dsdb_get_single_valued_attr() as if >it returned the complete set of possible database changes, when in fact it >only returned the last non-delete. That is, it could have missed values >in examples 3-7 above. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/util.c | 121 ++++++++++++++++++++++++++ > 1 file changed, 121 insertions(+) > >diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c >index ba1cfffe574..57b370f40b6 100644 >--- a/source4/dsdb/samdb/ldb_modules/util.c >+++ b/source4/dsdb/samdb/ldb_modules/util.c >@@ -1373,6 +1373,127 @@ void dsdb_req_chain_debug(struct ldb_request *req, int level) > talloc_free(s); > } > >+/* >+ * Get all the values that *might* be added by an ldb message, as a composite >+ * ldb element. >+ * >+ * This is useful when we need to check all the possible values against some >+ * criteria. >+ * >+ * In cases where a modify message mixes multiple ADDs, DELETEs, and REPLACES, >+ * the returned element might contain more values than would actually end up >+ * in the database if the message was run to its conclusion. >+ * >+ * If the operation is not LDB_ADD or LDB_MODIFY, an operations error is >+ * returned. >+ * >+ * The returned element might not be new, and should not be modified or freed >+ * before the message is finished. >+ */ >+ >+int dsdb_get_expected_new_values(TALLOC_CTX *mem_ctx, >+ const struct ldb_message *msg, >+ const char *attr_name, >+ struct ldb_message_element **el, >+ enum ldb_request_type operation) >+{ >+ unsigned int i; >+ unsigned int el_count = 0; >+ unsigned int val_count = 0; >+ struct ldb_val *v = NULL; >+ struct ldb_message_element *_el = NULL; >+ *el = NULL; >+ >+ if (operation != LDB_ADD && operation != LDB_MODIFY) { >+ DBG_ERR("inapplicable operation type: %d\n", operation); >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ >+ /* count the adding or replacing elements */ >+ for (i = 0; i < msg->num_elements; i++) { >+ if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { >+ unsigned int tmp; >+ if ((operation == LDB_MODIFY) && >+ (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) >+ == LDB_FLAG_MOD_DELETE)) { >+ continue; >+ } >+ el_count++; >+ tmp = val_count + msg->elements[i].num_values; >+ if (unlikely(tmp < val_count)) { >+ DBG_ERR("too many values for one element!"); >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ val_count = tmp; >+ } >+ } >+ if (el_count == 0) { >+ /* nothing to see here */ >+ return LDB_SUCCESS; >+ } >+ >+ if (el_count == 1 || val_count == 0) { >+ /* >+ * There is one effective element, which we can return as-is, >+ * OR there are only elements with zero values -- any of which >+ * will do. >+ */ >+ for (i = 0; i < msg->num_elements; i++) { >+ if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { >+ if ((operation == LDB_MODIFY) && >+ (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) >+ == LDB_FLAG_MOD_DELETE)) { >+ continue; >+ } >+ *el = &msg->elements[i]; >+ return LDB_SUCCESS; >+ } >+ } >+ } >+ >+ _el = talloc_zero(mem_ctx, struct ldb_message_element); >+ if (_el == NULL) { >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ _el->name = attr_name; >+ >+ if (val_count == 0) { >+ /* >+ * Seems unlikely, but sometimes we might be adding zero >+ * values in multiple separate elements. The talloc zero has >+ * already set the expected values = NULL, num_values = 0. >+ */ >+ *el = _el; >+ return LDB_SUCCESS; >+ } >+ >+ _el->values = talloc_array(_el, struct ldb_val, val_count); >+ if (_el->values == NULL) { >+ talloc_free(_el); >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ _el->num_values = val_count; >+ >+ v = _el->values; >+ >+ for (i = 0; i < val_count; i++) { >+ if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { >+ if ((operation == LDB_MODIFY) && >+ (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) >+ == LDB_FLAG_MOD_DELETE)) { >+ continue; >+ } >+ memcpy(v, >+ msg->elements[i].values, >+ msg->elements[i].num_values); >+ v += msg->elements[i].num_values; >+ } >+ } >+ >+ *el = _el; >+ return LDB_SUCCESS; >+} >+ > /* > * Gets back a single-valued attribute by the rules of the DSDB triggers when > * performing a modify operation. >-- >2.25.1 > > >From 1419a63748279c54dcd785d1355205ac76e1fb3f Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:10:44 +1300 >Subject: [PATCH 553/686] CVE-2020-25722 s4/dsdb/samldb: > samldb_get_single_valued_attr() check all values > >using dsdb_get_expected_new_values(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 12 ++++++++++-- > 1 file changed, 10 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 7ea0bb2ceef..c763cd33634 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -171,11 +171,19 @@ static int samldb_get_single_valued_attr(struct ldb_context *ldb, > * attribute. > */ > struct ldb_message_element *el = NULL; >+ int ret; > > *value = NULL; > >- el = dsdb_get_single_valued_attr(ac->msg, attr, >- ac->req->operation); >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ attr, >+ &el, >+ ac->req->operation); >+ >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } > if (el == NULL) { > /* we are not affected */ > return LDB_SUCCESS; >-- >2.25.1 > > >From 906d7c12d3692a8108d2f8b35e15d45fad5af175 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 22 Oct 2021 14:52:49 +1300 >Subject: [PATCH 554/686] CVE-2020-25722 s4/dsdb/samldb: > samldb_sam_accountname_valid_check() check all values > >Using dsdb_get_expected_new_values(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 13 +++++++++++-- > 1 file changed, 11 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index c763cd33634..9d8ab88929e 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -530,8 +530,17 @@ static int samldb_sam_accountname_valid_check(struct samldb_ctx *ac) > bool is_admin; > struct security_token *user_token = NULL; > struct ldb_context *ldb = ldb_module_get_ctx(ac->module); >- struct ldb_message_element *el = dsdb_get_single_valued_attr(ac->msg, "samAccountName", >- ac->req->operation); >+ struct ldb_message_element *el = NULL; >+ >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ "samAccountName", >+ &el, >+ ac->req->operation); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ > if (el == NULL || el->num_values == 0) { > ldb_asprintf_errstring(ldb, > "%08X: samldb: 'samAccountName' can't be deleted/empty!", >-- >2.25.1 > > >From fe71626c00a45dfd7b35a8188a35df1f3a7bca52 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:12:49 +1300 >Subject: [PATCH 555/686] CVE-2020-25722 s4/dsdb/samldb: > samldb_schema_add_handle_linkid() checks all values > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 9d8ab88929e..99051718529 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -739,8 +739,15 @@ static int samldb_schema_add_handle_linkid(struct samldb_ctx *ac) > schema = dsdb_get_schema(ldb, ac); > schema_dn = ldb_get_schema_basedn(ldb); > >- el = dsdb_get_single_valued_attr(ac->msg, "linkID", >- ac->req->operation); >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ "linkID", >+ &el, >+ ac->req->operation); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ > if (el == NULL) { > return LDB_SUCCESS; > } >-- >2.25.1 > > >From 58a5c2cc0a37b53490f0345fe964f5b0613f21ee Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:13:35 +1300 >Subject: [PATCH 556/686] CVE-2020-25722 s4/dsdb/samldb: > samldb_schema_add_handle_mapiid() checks all values > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 99051718529..f31def32e9a 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -907,8 +907,15 @@ static int samldb_schema_add_handle_mapiid(struct samldb_ctx *ac) > schema = dsdb_get_schema(ldb, ac); > schema_dn = ldb_get_schema_basedn(ldb); > >- el = dsdb_get_single_valued_attr(ac->msg, "mAPIID", >- ac->req->operation); >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ "mAPIID", >+ &el, >+ ac->req->operation); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ > if (el == NULL) { > return LDB_SUCCESS; > } >-- >2.25.1 > > >From d81d834f0f44f80b739440f9096aed853c7cca50 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:14:05 +1300 >Subject: [PATCH 557/686] CVE-2020-25722 s4/dsdb/samldb: > samldb_prim_group_change() checks all values > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index f31def32e9a..337fb778e70 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -2121,8 +2121,15 @@ static int samldb_prim_group_change(struct samldb_ctx *ac) > int ret; > const char * const noattrs[] = { NULL }; > >- el = dsdb_get_single_valued_attr(ac->msg, "primaryGroupID", >- ac->req->operation); >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ "primaryGroupID", >+ &el, >+ ac->req->operation); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ > if (el == NULL) { > /* we are not affected */ > return LDB_SUCCESS; >-- >2.25.1 > > >From 0647bf815c590870ae1ab18eab39079dfbccb3e6 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:15:00 +1300 >Subject: [PATCH 558/686] CVE-2020-25722 s4/dsdb/samldb: > samldb_user_account_control_change() checks all values > >There is another call to dsdb_get_expected_new_values() in this function >that we change in the next commit. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 337fb778e70..6ee7cd44634 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -2807,8 +2807,15 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) > bool old_is_critical = false; > bool new_is_critical = false; > >- el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl", >- ac->req->operation); >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ "userAccountControl", >+ &el, >+ ac->req->operation); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ > if (el == NULL || el->num_values == 0) { > ldb_asprintf_errstring(ldb, > "%08X: samldb: 'userAccountControl' can't be deleted!", >-- >2.25.1 > > >From 1a2e2e9d0176a5c31ea55ec262af3064155d5b29 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:15:43 +1300 >Subject: [PATCH 559/686] CVE-2020-25722 s4/dsdb/samldb > _user_account_control_change() always add final value > >dsdb_get_single_valued_attr() was finding the last non-delete element for >userAccountControl and changing its value to the computed value. >Unfortunately, the last non-delete element might not be the last element, >and a subsequent delete might remove it. > >Instead we just add a replace on the end. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 6ee7cd44634..45407c4e05b 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -3008,9 +3008,12 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) > return ldb_module_oom(ac->module); > } > >- /* Overwrite "userAccountControl" correctly */ >- el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl", >- ac->req->operation); >+ ret = ldb_msg_add_empty(ac->msg, >+ "userAccountControl", >+ LDB_FLAG_MOD_REPLACE, >+ &el); >+ el->values = talloc(ac->msg, struct ldb_val); >+ el->num_values = 1; > el->values[0].data = (uint8_t *) tempstr; > el->values[0].length = strlen(tempstr); > } else { >-- >2.25.1 > > >From ea759dfaaa34a0b75fee1f8d899c1764c251c869 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:16:34 +1300 >Subject: [PATCH 560/686] CVE-2020-25722 s4/dsdb/samldb: > samldb_pwd_last_set_change() checks all values > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 45407c4e05b..747275d331a 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -3102,8 +3102,15 @@ static int samldb_pwd_last_set_change(struct samldb_ctx *ac) > NULL > }; > >- el = dsdb_get_single_valued_attr(ac->msg, "pwdLastSet", >- ac->req->operation); >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ "pwdLastSet", >+ &el, >+ ac->req->operation); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ > if (el == NULL || el->num_values == 0) { > ldb_asprintf_errstring(ldb, > "%08X: samldb: 'pwdLastSet' can't be deleted!", >-- >2.25.1 > > >From cdf2c7533cf5b57ca7d73fb99b75349a0573c33b Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:17:31 +1300 >Subject: [PATCH 561/686] CVE-2020-25722 s4/dsdb/samldb: samldb_lockout_time() > checks all values > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 747275d331a..eddbe741d26 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -3164,8 +3164,15 @@ static int samldb_lockout_time(struct samldb_ctx *ac) > struct ldb_message *tmp_msg; > int ret; > >- el = dsdb_get_single_valued_attr(ac->msg, "lockoutTime", >- ac->req->operation); >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ "lockoutTime", >+ &el, >+ ac->req->operation); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ > if (el == NULL || el->num_values == 0) { > ldb_asprintf_errstring(ldb, > "%08X: samldb: 'lockoutTime' can't be deleted!", >-- >2.25.1 > > >From 28235f692b81721c5f00572d274dad0e2db762a9 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:17:50 +1300 >Subject: [PATCH 562/686] CVE-2020-25722 s4/dsdb/samldb: > samldb_group_type_change() checks all values > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index eddbe741d26..ea9121be3a2 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -3221,8 +3221,15 @@ static int samldb_group_type_change(struct samldb_ctx *ac) > struct ldb_result *res; > const char * const attrs[] = { "groupType", NULL }; > >- el = dsdb_get_single_valued_attr(ac->msg, "groupType", >- ac->req->operation); >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ "groupType", >+ &el, >+ ac->req->operation); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ > if (el == NULL) { > /* we are not affected */ > return LDB_SUCCESS; >-- >2.25.1 > > >From 2e719f187a0a88895385434ab7266c07d643e139 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:18:10 +1300 >Subject: [PATCH 563/686] CVE-2020-25722 s4/dsdb/samldb: > samldb_service_principal_names_change checks values > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 20 ++++++++++++++++---- > 1 file changed, 16 insertions(+), 4 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index ea9121be3a2..1b617836e62 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -4047,10 +4047,22 @@ static int samldb_service_principal_names_change(struct samldb_ctx *ac) > unsigned int i, j; > int ret; > >- el = dsdb_get_single_valued_attr(ac->msg, "dNSHostName", >- ac->req->operation); >- el2 = dsdb_get_single_valued_attr(ac->msg, "sAMAccountName", >- ac->req->operation); >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ "dNSHostName", >+ &el, >+ ac->req->operation); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ "sAMAccountName", >+ &el2, >+ ac->req->operation); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } > if ((el == NULL) && (el2 == NULL)) { > /* we are not affected */ > return LDB_SUCCESS; >-- >2.25.1 > > >From 6b918dd4acb957bee2a91128cd3ebbc17b2d4d25 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:18:21 +1300 >Subject: [PATCH 564/686] CVE-2020-25722 s4/dsdb/samldb: > samldb_fsmo_role_owner_check checks values > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 1b617836e62..1c9c2883704 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -4302,9 +4302,15 @@ static int samldb_fsmo_role_owner_check(struct samldb_ctx *ac) > struct ldb_dn *res_dn; > struct ldb_result *res; > int ret; >+ ret = dsdb_get_expected_new_values(ac, >+ ac->msg, >+ "fSMORoleOwner", >+ &el, >+ ac->req->operation); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } > >- el = dsdb_get_single_valued_attr(ac->msg, "fSMORoleOwner", >- ac->req->operation); > if (el == NULL) { > /* we are not affected */ > return LDB_SUCCESS; >-- >2.25.1 > > >From 8d580b620e37ecb107da357d8632cee0cb79b15c Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Thu, 21 Oct 2021 12:52:07 +1300 >Subject: [PATCH 565/686] CVE-2020-25722 s4/dsdb/samldb: > samldb_fsmo_role_owner_check() wants one value > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/samldb.c | 17 ++++++++++++----- > 1 file changed, 12 insertions(+), 5 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 1c9c2883704..75b0933d479 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -4315,6 +4315,9 @@ static int samldb_fsmo_role_owner_check(struct samldb_ctx *ac) > /* we are not affected */ > return LDB_SUCCESS; > } >+ if (el->num_values != 1) { >+ goto choose_error_code; >+ } > > /* Create a temporary message for fetching the "fSMORoleOwner" */ > tmp_msg = ldb_msg_new(ac->msg); >@@ -4331,11 +4334,7 @@ static int samldb_fsmo_role_owner_check(struct samldb_ctx *ac) > if (res_dn == NULL) { > ldb_set_errstring(ldb, > "samldb: 'fSMORoleOwner' attributes have to reference 'nTDSDSA' entries!"); >- if (ac->req->operation == LDB_ADD) { >- return LDB_ERR_CONSTRAINT_VIOLATION; >- } else { >- return LDB_ERR_UNWILLING_TO_PERFORM; >- } >+ goto choose_error_code; > } > > /* Fetched DN has to reference a "nTDSDSA" entry */ >@@ -4355,6 +4354,14 @@ static int samldb_fsmo_role_owner_check(struct samldb_ctx *ac) > talloc_free(res); > > return LDB_SUCCESS; >+ >+choose_error_code: >+ /* this is just how it is */ >+ if (ac->req->operation == LDB_ADD) { >+ return LDB_ERR_CONSTRAINT_VIOLATION; >+ } else { >+ return LDB_ERR_UNWILLING_TO_PERFORM; >+ } > } > > /* >-- >2.25.1 > > >From afb8632613caf1d43e8bd445a286b4347d26c965 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:19:42 +1300 >Subject: [PATCH 566/686] CVE-2020-25722 s4/dsdb/pwd_hash: password_hash_bypass > gets all values > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > .../dsdb/samdb/ldb_modules/password_hash.c | 30 ++++++++++++------- > 1 file changed, 20 insertions(+), 10 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c >index 9f1fcb996f1..7169e0df3df 100644 >--- a/source4/dsdb/samdb/ldb_modules/password_hash.c >+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c >@@ -188,6 +188,7 @@ static int password_hash_bypass(struct ldb_module *module, struct ldb_request *r > struct ldb_message_element *nthe; > struct ldb_message_element *lmhe; > struct ldb_message_element *sce; >+ int ret; > > switch (request->operation) { > case LDB_ADD: >@@ -201,17 +202,26 @@ static int password_hash_bypass(struct ldb_module *module, struct ldb_request *r > } > > /* nobody must touch password histories and 'supplementalCredentials' */ >- nte = dsdb_get_single_valued_attr(msg, "unicodePwd", >- request->operation); >- lme = dsdb_get_single_valued_attr(msg, "dBCSPwd", >- request->operation); >- nthe = dsdb_get_single_valued_attr(msg, "ntPwdHistory", >- request->operation); >- lmhe = dsdb_get_single_valued_attr(msg, "lmPwdHistory", >- request->operation); >- sce = dsdb_get_single_valued_attr(msg, "supplementalCredentials", >- request->operation); > >+#define GET_VALUES(el, attr) do { \ >+ ret = dsdb_get_expected_new_values(request, \ >+ msg, \ >+ attr, \ >+ &el, \ >+ request->operation); \ >+ \ >+ if (ret != LDB_SUCCESS) { \ >+ return ret; \ >+ } \ >+} while(0) >+ >+ GET_VALUES(nte, "unicodePwd"); >+ GET_VALUES(lme, "dBCSPwd"); >+ GET_VALUES(nthe, "ntPwdHistory"); >+ GET_VALUES(lmhe, "lmPwdHistory"); >+ GET_VALUES(sce, "supplementalCredentials"); >+ >+#undef GET_VALUES > #define CHECK_HASH_ELEMENT(e, min, max) do {\ > if (e && e->num_values) { \ > unsigned int _count; \ >-- >2.25.1 > > >From fd8f622071fbdbf50ff14575747344a37acc38dc Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 20 Oct 2021 17:20:54 +1300 >Subject: [PATCH 567/686] CVE-2020-25722 s4/dsdb/pwd_hash: rework pwdLastSet > bypass > >This tightens the logic a bit, in that a message with trailing DELETE >elements is no longer accepted when the bypass flag is set. In any case >this is an unlikely scenario as this is an internal flag set by a private >control in pdb_samba_dsdb_replace_by_sam(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > .../dsdb/samdb/ldb_modules/password_hash.c | 28 ++++++++++++------- > 1 file changed, 18 insertions(+), 10 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c >index 7169e0df3df..160b26a12b8 100644 >--- a/source4/dsdb/samdb/ldb_modules/password_hash.c >+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c >@@ -2164,23 +2164,31 @@ static int setup_last_set_field(struct setup_password_fields_io *io) > } > > if (io->ac->pwd_last_set_bypass) { >- struct ldb_message_element *el1 = NULL; >- struct ldb_message_element *el2 = NULL; >- >+ struct ldb_message_element *el = NULL; >+ size_t i; >+ size_t count = 0; >+ /* >+ * This is a message from pdb_samba_dsdb_replace_by_sam() >+ * >+ * We want to ensure there is only one pwdLastSet element, and >+ * it isn't deleting. >+ */ > if (msg == NULL) { > return LDB_ERR_CONSTRAINT_VIOLATION; > } > >- el1 = dsdb_get_single_valued_attr(msg, "pwdLastSet", >- io->ac->req->operation); >- if (el1 == NULL) { >- return LDB_ERR_CONSTRAINT_VIOLATION; >+ for (i = 0; i < msg->num_elements; i++) { >+ if (ldb_attr_cmp(msg->elements[i].name, >+ "pwdLastSet") == 0) { >+ count++; >+ el = &msg->elements[i]; >+ } > } >- el2 = ldb_msg_find_element(msg, "pwdLastSet"); >- if (el2 == NULL) { >+ if (count != 1) { > return LDB_ERR_CONSTRAINT_VIOLATION; > } >- if (el1 != el2) { >+ >+ if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) { > return LDB_ERR_CONSTRAINT_VIOLATION; > } > >-- >2.25.1 > > >From 31a2a6646096948940d40e625525b0dbf890e123 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Thu, 21 Oct 2021 13:49:28 +1300 >Subject: [PATCH 568/686] CVE-2020-25722 s4/dsdb/util: remove unused > dsdb_get_single_valued_attr() > >Nobody uses it now. It never really did what it said it did. Almost >every use was wrong. It was a trap. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/dsdb/samdb/ldb_modules/util.c | 34 --------------------------- > 1 file changed, 34 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c >index 57b370f40b6..d14f0bcbf51 100644 >--- a/source4/dsdb/samdb/ldb_modules/util.c >+++ b/source4/dsdb/samdb/ldb_modules/util.c >@@ -1494,40 +1494,6 @@ int dsdb_get_expected_new_values(TALLOC_CTX *mem_ctx, > return LDB_SUCCESS; > } > >-/* >- * Gets back a single-valued attribute by the rules of the DSDB triggers when >- * performing a modify operation. >- * >- * In order that the constraint checking by the "objectclass_attrs" LDB module >- * does work properly, the change request should remain similar or only be >- * enhanced (no other modifications as deletions, variations). >- */ >-struct ldb_message_element *dsdb_get_single_valued_attr(const struct ldb_message *msg, >- const char *attr_name, >- enum ldb_request_type operation) >-{ >- struct ldb_message_element *el = NULL; >- unsigned int i; >- >- /* We've to walk over all modification entries and consider the last >- * non-delete one which belongs to "attr_name". >- * >- * If "el" is NULL afterwards then that means there was no interesting >- * change entry. */ >- for (i = 0; i < msg->num_elements; i++) { >- if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { >- if ((operation == LDB_MODIFY) && >- (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) >- == LDB_FLAG_MOD_DELETE)) { >- continue; >- } >- el = &msg->elements[i]; >- } >- } >- >- return el; >-} >- > /* > * This function determines the (last) structural or 88 object class of a passed > * "objectClass" attribute - per MS-ADTS 3.1.1.1.4 this is the last value. >-- >2.25.1 > > >From dac3d3150a729c4d33911e64ed7025c94f1c9e9b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 29 Oct 2021 12:20:49 +1300 >Subject: [PATCH 569/686] CVE-2020-25722 selftest: Adapt ldap.py tests to new > objectClass restrictions > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Adapted to add missing knownfail file] >--- > selftest/knownfail.d/ldap | 1 + > source4/dsdb/tests/python/ldap.py | 36 +++++++++++++++++++------------ > 2 files changed, 23 insertions(+), 14 deletions(-) > create mode 100644 selftest/knownfail.d/ldap > >diff --git a/selftest/knownfail.d/ldap b/selftest/knownfail.d/ldap >new file mode 100644 >index 00000000000..2773a7f1a23 >--- /dev/null >+++ b/selftest/knownfail.d/ldap >@@ -0,0 +1 @@ >+^samba4.ldap.python.+test_objectclasses >diff --git a/source4/dsdb/tests/python/ldap.py b/source4/dsdb/tests/python/ldap.py >index d6113e3345d..905d58f446b 100755 >--- a/source4/dsdb/tests/python/ldap.py >+++ b/source4/dsdb/tests/python/ldap.py >@@ -436,33 +436,41 @@ class BasicTests(samba.tests.TestCase): > (num, _) = e18.args > self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > >- # Add a new top-most structural class "inetOrgPerson" and remove it >- # afterwards >+ # Try to add a new top-most structural class "inetOrgPerson" > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > m["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_ADD, > "objectClass") >- ldb.modify(m) >+ try: >+ ldb.modify(m) >+ self.fail() >+ except LdbError as e: >+ (num, _) = e.args >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > >+ # Try to remove the structural class "user" > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >- m["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_DELETE, >+ m["objectClass"] = MessageElement("user", FLAG_MOD_DELETE, > "objectClass") >- ldb.modify(m) >+ try: >+ ldb.modify(m) >+ self.fail() >+ except LdbError as e: >+ (num, _) = e.args >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > >- # Replace top-most structural class to "inetOrgPerson" and reset it >- # back to "user" >+ # Try to replace top-most structural class to "inetOrgPerson" > m = Message() > m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) > m["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_REPLACE, > "objectClass") >- ldb.modify(m) >- >- m = Message() >- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) >- m["objectClass"] = MessageElement("user", FLAG_MOD_REPLACE, >- "objectClass") >- ldb.modify(m) >+ try: >+ ldb.modify(m) >+ self.fail() >+ except LdbError as e: >+ (num, _) = e.args >+ self.assertEqual(num, ERR_OBJECT_CLASS_VIOLATION) > > # Add a new auxiliary object class "posixAccount" to "ldaptestuser" > m = Message() >-- >2.25.1 > > >From 1082c0069a6aa0c7541d507ba269f5773f3559b0 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:56:10 +1300 >Subject: [PATCH 570/686] CVE-2020-25718 tests/krb5: Fix indentation > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 5313dbc6045..480e3d8264d 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -667,7 +667,7 @@ class KdcTgsTests(KDCBaseTest): > creds = self._get_creds(replication_allowed=True, > revealed_to_rodc=True) > existing_rid = self._get_existing_rid(replication_allowed=True, >- revealed_to_rodc=True) >+ revealed_to_rodc=True) > tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid) > self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) > >@@ -675,7 +675,7 @@ class KdcTgsTests(KDCBaseTest): > creds = self._get_creds(replication_allowed=True, > revealed_to_rodc=True) > existing_rid = self._get_existing_rid(replication_allowed=True, >- revealed_to_rodc=True) >+ revealed_to_rodc=True) > tgt = self._get_tgt(creds, renewable=True, from_rodc=True, > new_rid=existing_rid) > self._renew_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >@@ -693,7 +693,7 @@ class KdcTgsTests(KDCBaseTest): > creds = self._get_creds(replication_allowed=True, > revealed_to_rodc=True) > existing_rid = self._get_existing_rid(replication_allowed=True, >- revealed_to_rodc=True) >+ revealed_to_rodc=True) > tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid) > self._s4u2self(tgt, creds, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) > >@@ -701,7 +701,7 @@ class KdcTgsTests(KDCBaseTest): > creds = self._get_creds(replication_allowed=True, > revealed_to_rodc=True) > existing_rid = self._get_existing_rid(replication_allowed=True, >- revealed_to_rodc=True) >+ revealed_to_rodc=True) > tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid) > self._user2user(tgt, creds, > expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >-- >2.25.1 > > >From bf4e79bcf823952c2b018119d6e55deb828a627b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:33:38 +1300 >Subject: [PATCH 571/686] CVE-2020-25719 krb5pac.idl: Add PAC_ATTRIBUTES_INFO > PAC buffer type > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > librpc/idl/krb5pac.idl | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) > >diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl >index 475890bac76..5e6c4df1a3e 100644 >--- a/librpc/idl/krb5pac.idl >+++ b/librpc/idl/krb5pac.idl >@@ -111,6 +111,16 @@ interface krb5pac > [switch_is(flags & PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID)] PAC_UPN_DNS_INFO_EX ex; > } PAC_UPN_DNS_INFO; > >+ typedef [bitmap32bit] bitmap { >+ PAC_ATTRIBUTE_FLAG_PAC_WAS_REQUESTED = 0x00000001, >+ PAC_ATTRIBUTE_FLAG_PAC_WAS_GIVEN_IMPLICITLY = 0x00000002 >+ } PAC_ATTRIBUTE_INFO_FLAGS; >+ >+ typedef struct { >+ uint32 flags_length; /* length in bits */ >+ PAC_ATTRIBUTE_INFO_FLAGS flags; >+ } PAC_ATTRIBUTES_INFO; >+ > typedef [public] struct { > PAC_LOGON_INFO *info; > } PAC_LOGON_INFO_CTR; >@@ -130,7 +140,8 @@ interface krb5pac > PAC_TYPE_CLIENT_CLAIMS_INFO = 13, > PAC_TYPE_DEVICE_INFO = 14, > PAC_TYPE_DEVICE_CLAIMS_INFO = 15, >- PAC_TYPE_TICKET_CHECKSUM = 16 >+ PAC_TYPE_TICKET_CHECKSUM = 16, >+ PAC_TYPE_ATTRIBUTES_INFO = 17 > } PAC_TYPE; > > typedef struct { >@@ -147,6 +158,7 @@ interface krb5pac > PAC_CONSTRAINED_DELEGATION_CTR constrained_delegation; > [case(PAC_TYPE_UPN_DNS_INFO)] PAC_UPN_DNS_INFO upn_dns_info; > [case(PAC_TYPE_TICKET_CHECKSUM)] PAC_SIGNATURE_DATA ticket_checksum; >+ [case(PAC_TYPE_ATTRIBUTES_INFO)] PAC_ATTRIBUTES_INFO attributes_info; > /* when new PAC info types are added they are supposed to be done > in such a way that they are backwards compatible with existing > servers. This makes it safe to just use a [default] for >-- >2.25.1 > > >From 2937dbf8d7cfcabc57872032489ccc618fa7c532 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:33:49 +1300 >Subject: [PATCH 572/686] CVE-2020-25719 krb5pac.idl: Add PAC_REQUESTER_SID PAC > buffer type > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > librpc/idl/krb5pac.idl | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > >diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl >index 5e6c4df1a3e..94b9160d6eb 100644 >--- a/librpc/idl/krb5pac.idl >+++ b/librpc/idl/krb5pac.idl >@@ -121,6 +121,10 @@ interface krb5pac > PAC_ATTRIBUTE_INFO_FLAGS flags; > } PAC_ATTRIBUTES_INFO; > >+ typedef struct { >+ dom_sid sid; >+ } PAC_REQUESTER_SID; >+ > typedef [public] struct { > PAC_LOGON_INFO *info; > } PAC_LOGON_INFO_CTR; >@@ -141,7 +145,8 @@ interface krb5pac > PAC_TYPE_DEVICE_INFO = 14, > PAC_TYPE_DEVICE_CLAIMS_INFO = 15, > PAC_TYPE_TICKET_CHECKSUM = 16, >- PAC_TYPE_ATTRIBUTES_INFO = 17 >+ PAC_TYPE_ATTRIBUTES_INFO = 17, >+ PAC_TYPE_REQUESTER_SID = 18 > } PAC_TYPE; > > typedef struct { >@@ -159,6 +164,7 @@ interface krb5pac > [case(PAC_TYPE_UPN_DNS_INFO)] PAC_UPN_DNS_INFO upn_dns_info; > [case(PAC_TYPE_TICKET_CHECKSUM)] PAC_SIGNATURE_DATA ticket_checksum; > [case(PAC_TYPE_ATTRIBUTES_INFO)] PAC_ATTRIBUTES_INFO attributes_info; >+ [case(PAC_TYPE_REQUESTER_SID)] PAC_REQUESTER_SID requester_sid; > /* when new PAC info types are added they are supposed to be done > in such a way that they are backwards compatible with existing > servers. This makes it safe to just use a [default] for >-- >2.25.1 > > >From 08a42d18f505d2c8c61d4612854bf93ede003b64 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:44:45 +1300 >Subject: [PATCH 573/686] CVE-2020-25719 tests/krb5: Provide expected > parameters for both AS-REQs in get_tgt() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 9be6cbab30b..6d6dcc21607 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1389,6 +1389,8 @@ class KDCBaseTest(RawKerberosTest): > ticket_decryption_key = ( > self.TicketDecryptionKey_from_creds(krbtgt_creds)) > >+ expected_etypes = krbtgt_creds.tgs_supported_enctypes >+ > if kdc_options is None: > kdc_options = ('forwardable,' > 'renewable,' >@@ -1415,6 +1417,7 @@ class KDCBaseTest(RawKerberosTest): > expected_salt=salt, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, >+ expected_supported_etypes=expected_etypes, > etypes=etype, > padata=None, > kdc_options=kdc_options, >@@ -1422,6 +1425,7 @@ class KDCBaseTest(RawKerberosTest): > ticket_decryption_key=ticket_decryption_key, > pac_request=pac_request, > pac_options=pac_options, >+ expect_pac=expect_pac, > to_rodc=to_rodc) > self.check_pre_authentication(rep) > >@@ -1440,8 +1444,6 @@ class KDCBaseTest(RawKerberosTest): > expected_sname = self.PrincipalName_create( > name_type=NT_SRV_INST, names=['krbtgt', realm.upper()]) > >- expected_etypes = krbtgt_creds.tgs_supported_enctypes >- > rep, kdc_exchange_dict = self._test_as_exchange( > cname=cname, > realm=realm, >@@ -1453,6 +1455,9 @@ class KDCBaseTest(RawKerberosTest): > expected_cname=cname, > expected_srealm=expected_realm, > expected_sname=expected_sname, >+ expected_account_name=expected_account_name, >+ expected_upn_name=expected_upn_name, >+ expected_sid=expected_sid, > expected_salt=salt, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, >-- >2.25.1 > > >From 992e2605aeadbfb705114177ca4c504da385f821 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:47:53 +1300 >Subject: [PATCH 574/686] CVE-2020-25719 tests/krb5: Allow > update_pac_checksums=True if the PAC is not present > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/raw_testcase.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 18ee8738eaa..39ca4a69e1c 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3293,7 +3293,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertFalse(checksum_keys) > self.assertFalse(include_checksums) > >- expect_pac = update_pac_checksums or modify_pac_fn is not None >+ expect_pac = modify_pac_fn is not None > > key = ticket.decryption_key > >-- >2.25.1 > > >From d7a9a3e192fe86514c44fcffede07b17b4cc1cb0 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:51:34 +1300 >Subject: [PATCH 575/686] CVE-2020-25719 tests/krb5: Don't expect a kvno for > user-to-user > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14873 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/raw_testcase.py | 16 +++++++++++++--- > 1 file changed, 13 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 39ca4a69e1c..f39e57c8189 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2225,9 +2225,19 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(ticket_encpart) > if ticket_encpart is not None: # Never None, but gives indentation > self.assertElementPresent(ticket_encpart, 'etype') >- # 'unspecified' means present, with any value != 0 >- self.assertElementKVNO(ticket_encpart, 'kvno', >- self.unspecified_kvno) >+ >+ kdc_options = kdc_exchange_dict['kdc_options'] >+ pos = len(tuple(krb5_asn1.KDCOptions('enc-tkt-in-skey'))) - 1 >+ expect_kvno = (pos >= len(kdc_options) >+ or kdc_options[pos] != '1') >+ if expect_kvno: >+ # 'unspecified' means present, with any value != 0 >+ self.assertElementKVNO(ticket_encpart, 'kvno', >+ self.unspecified_kvno) >+ else: >+ # For user-to-user, don't expect a kvno. >+ self.assertElementMissing(ticket_encpart, 'kvno') >+ > self.assertElementPresent(ticket_encpart, 'cipher') > ticket_cipher = self.getElementValue(ticket_encpart, 'cipher') > self.assertElementPresent(rep, 'enc-part') >-- >2.25.1 > > >From 054e76488bf6fad09a63c426b1f658b858a17a65 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:51:46 +1300 >Subject: [PATCH 576/686] CVE-2020-25719 tests/krb5: Expect 'renew-till' > element when renewing a TGT > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/raw_testcase.py | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index f39e57c8189..79fe9ec4620 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2369,6 +2369,10 @@ class RawKerberosTest(TestCaseInTempDir): > renewable_pos = len(tuple(krb5_asn1.KDCOptions('renewable'))) - 1 > renewable = (renewable_pos < len(kdc_options) > and kdc_options[renewable_pos] == '1') >+ renew_pos = len(tuple(krb5_asn1.KDCOptions('renew'))) - 1 >+ renew = (renew_pos < len(kdc_options) >+ and kdc_options[renew_pos] == '1') >+ expect_renew_till = renewable or renew > > expected_crealm = kdc_exchange_dict['expected_crealm'] > expected_cname = kdc_exchange_dict['expected_cname'] >@@ -2425,7 +2429,7 @@ class RawKerberosTest(TestCaseInTempDir): > if self.strict_checking: > self.assertElementPresent(ticket_private, 'starttime') > self.assertElementPresent(ticket_private, 'endtime') >- if renewable: >+ if expect_renew_till: > if self.strict_checking: > self.assertElementPresent(ticket_private, 'renew-till') > else: >@@ -2461,7 +2465,7 @@ class RawKerberosTest(TestCaseInTempDir): > if self.strict_checking: > self.assertElementPresent(encpart_private, 'starttime') > self.assertElementPresent(encpart_private, 'endtime') >- if renewable: >+ if expect_renew_till: > if self.strict_checking: > self.assertElementPresent(encpart_private, 'renew-till') > else: >-- >2.25.1 > > >From 40b87b433e2a2b1147cc3da4eebe7851918e8392 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 21:05:08 +1300 >Subject: [PATCH 577/686] CVE-2020-25719 tests/krb5: Return ticket from > _tgs_req() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 18 ++++++++++++------ > 1 file changed, 12 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 480e3d8264d..11bf38766ae 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -1302,12 +1302,18 @@ class KdcTgsTests(KDCBaseTest): > expect_edata=False, > expect_claims=expect_claims) > >- self._generic_kdc_exchange(kdc_exchange_dict, >- cname=None, >- realm=srealm, >- sname=sname, >- etypes=etypes, >- additional_tickets=additional_tickets) >+ rep = self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=None, >+ realm=srealm, >+ sname=sname, >+ etypes=etypes, >+ additional_tickets=additional_tickets) >+ if expected_error: >+ self.check_error_rep(rep, expected_error) >+ return None >+ else: >+ self.check_reply(rep, KRB_TGS_REP) >+ return kdc_exchange_dict['rep_ticket_creds'] > > > if __name__ == "__main__": >-- >2.25.1 > > >From 611ff663ee2af43be0ce07c37720ff1dc6fcad44 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 21:14:45 +1300 >Subject: [PATCH 578/686] CVE-2020-25719 tests/krb5: Use correct credentials > for user-to-user tests > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14873 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 9 ++++----- > selftest/knownfail_heimdal_kdc | 1 - > selftest/knownfail_mit_kdc | 1 - > 3 files changed, 4 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 11bf38766ae..2787185f04a 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -949,7 +949,7 @@ class KdcTgsTests(KDCBaseTest): > creds = self._get_creds() > tgt = self._get_tgt(creds) > >- user_name = self._get_mach_creds().get_username() >+ user_name = creds.get_username() > sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, > names=['host', user_name]) > >@@ -960,18 +960,17 @@ class KdcTgsTests(KDCBaseTest): > creds = self._get_creds() > tgt = self._get_tgt(creds) > >- user_name = self._get_mach_creds().get_username() >+ user_name = creds.get_username() > sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, > names=[user_name]) > >- self._user2user(tgt, creds, sname=sname, >- expected_error=KDC_ERR_BADMATCH) >+ self._user2user(tgt, creds, sname=sname, expected_error=0) > > def test_user2user_wrong_sname(self): > creds = self._get_creds() > tgt = self._get_tgt(creds) > >- other_creds = self.get_service_creds() >+ other_creds = self._get_mach_creds() > user_name = other_creds.get_username() > sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, > names=[user_name]) >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 46866823590..42f02473272 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -323,7 +323,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_user > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_host >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_no_host > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_non_existent_sname > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index d2acc5559ed..daf8012be43 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -441,7 +441,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_user > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_user > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_no_host > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_allowed_denied >-- >2.25.1 > > >From 188a89c1b5c902d4ad0f815df64c6900f68e6b83 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 21:15:53 +1300 >Subject: [PATCH 579/686] CVE-2020-25719 tests/krb5: Adjust PAC tests to > prepare for new PAC_ATTRIBUTES_INFO buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 10 +++++----- > selftest/knownfail_heimdal_kdc | 1 - > selftest/knownfail_mit_kdc | 1 - > 3 files changed, 5 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 2787185f04a..10a146a5e59 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -324,10 +324,10 @@ class KdcTgsTests(KDCBaseTest): > self.assertIsNotNone(pac) > > ticket = self._make_tgs_request(client_creds, service_creds, tgt, >- pac_request=False) >+ pac_request=False, expect_pac=False) > >- pac = self.get_ticket_pac(ticket) >- self.assertIsNotNone(pac) >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) > > def test_client_no_auth_data_required(self): > client_creds = self.get_cached_creds( >@@ -351,13 +351,13 @@ class KdcTgsTests(KDCBaseTest): > opts={'no_auth_data_required': True}) > service_creds = self.get_service_creds() > >- tgt = self.get_tgt(client_creds, pac_request=False) >+ tgt = self.get_tgt(client_creds) > > pac = self.get_ticket_pac(tgt) > self.assertIsNotNone(pac) > > ticket = self._make_tgs_request(client_creds, service_creds, tgt, >- pac_request=False) >+ pac_request=False, expect_pac=True) > > pac = self.get_ticket_pac(ticket) > self.assertIsNotNone(pac) >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 42f02473272..1ddf812da25 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -265,7 +265,6 @@ > # > # KDC TGS PAC tests > # >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_no_pac_client_no_auth_data_required > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_no_pac_service_no_auth_data_required > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_client_no_auth_data_required >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index daf8012be43..720d243e05c 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -278,7 +278,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > # > # KDC TGS PAC tests > # >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_no_pac_client_no_auth_data_required\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_no_pac_service_no_auth_data_required\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_client_no_auth_data_required\(ad_dc\) >-- >2.25.1 > > >From 4754993de7bd6f35ed1918b7c8d48828648d159f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 21:20:51 +1300 >Subject: [PATCH 580/686] CVE-2020-25719 tests/krb5: Adjust expected error > codes for user-to-user tests > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14873 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 10a146a5e59..3a60b9cafb9 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -40,6 +40,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_BADMATCH, > KDC_ERR_BADOPTION, > KDC_ERR_CLIENT_NAME_MISMATCH, >+ KDC_ERR_MODIFIED, > KDC_ERR_POLICY, > KDC_ERR_S_PRINCIPAL_UNKNOWN, > KDC_ERR_TGT_REVOKED, >@@ -996,7 +997,8 @@ class KdcTgsTests(KDCBaseTest): > service_creds = self.get_service_creds() > service_ticket = self.get_service_ticket(tgt, service_creds) > >- self._user2user(service_ticket, creds, expected_error=KDC_ERR_POLICY) >+ self._user2user(service_ticket, creds, >+ expected_error=(KDC_ERR_MODIFIED, KDC_ERR_POLICY)) > > def _get_tgt(self, > client_creds, >-- >2.25.1 > > >From 9bbaf7bff345fb4ddffae16c590785a4158c0810 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 21:08:34 +1300 >Subject: [PATCH 581/686] CVE-2020-25719 tests/krb5: tests/krb5: Adjust > expected error code for S4U2Self no-PAC tests > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 32 ++++++++++++++++-------- > 1 file changed, 22 insertions(+), 10 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 3a60b9cafb9..3fd6fc1a7b1 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -23,7 +23,7 @@ import os > import ldb > > >-from samba import dsdb >+from samba import dsdb, ntstatus > > from samba.dcerpc import krb5pac > >@@ -40,6 +40,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_BADMATCH, > KDC_ERR_BADOPTION, > KDC_ERR_CLIENT_NAME_MISMATCH, >+ KDC_ERR_GENERIC, > KDC_ERR_MODIFIED, > KDC_ERR_POLICY, > KDC_ERR_S_PRINCIPAL_UNKNOWN, >@@ -528,7 +529,10 @@ class KdcTgsTests(KDCBaseTest): > def test_s4u2self_no_pac(self): > creds = self._get_creds() > tgt = self._get_tgt(creds, remove_pac=True) >- self._s4u2self(tgt, creds, expected_error=KDC_ERR_BADOPTION) >+ self._s4u2self(tgt, creds, >+ expected_error=(KDC_ERR_GENERIC, KDC_ERR_BADOPTION), >+ expected_status=ntstatus.NT_STATUS_INVALID_PARAMETER, >+ expect_edata=True) > > def test_user2user_no_pac(self): > creds = self._get_creds() >@@ -556,7 +560,10 @@ class KdcTgsTests(KDCBaseTest): > def test_s4u2self_authdata_no_pac(self): > creds = self._get_creds() > tgt = self._get_tgt(creds, remove_pac=True, allow_empty_authdata=True) >- self._s4u2self(tgt, creds, expected_error=KDC_ERR_BADOPTION) >+ self._s4u2self(tgt, creds, >+ expected_error=(KDC_ERR_GENERIC, KDC_ERR_BADOPTION), >+ expected_status=ntstatus.NT_STATUS_INVALID_PARAMETER, >+ expect_edata=True) > > def test_user2user_authdata_no_pac(self): > creds = self._get_creds() >@@ -1210,7 +1217,8 @@ class KdcTgsTests(KDCBaseTest): > self._tgs_req(tgt, expected_error, krbtgt_creds, > kdc_options=kdc_options) > >- def _s4u2self(self, tgt, tgt_creds, expected_error): >+ def _s4u2self(self, tgt, tgt_creds, expected_error, >+ expect_edata=False, expected_status=None): > user_creds = self._get_mach_creds() > > user_name = user_creds.get_username() >@@ -1229,10 +1237,11 @@ class KdcTgsTests(KDCBaseTest): > > return [padata], req_body > >- self._tgs_req(tgt, expected_error, tgt_creds, >- expected_cname=user_cname, >- generate_padata_fn=generate_s4u2self_padata, >- expect_claims=False) >+ return self._tgs_req(tgt, expected_error, tgt_creds, >+ expected_cname=user_cname, >+ generate_padata_fn=generate_s4u2self_padata, >+ expect_claims=False, expect_edata=expect_edata, >+ expected_status=expected_status) > > def _user2user(self, tgt, tgt_creds, expected_error, sname=None): > user_creds = self._get_mach_creds() >@@ -1250,7 +1259,9 @@ class KdcTgsTests(KDCBaseTest): > additional_ticket=None, > generate_padata_fn=None, > sname=None, >- expect_claims=True): >+ expect_claims=True, >+ expect_edata=False, >+ expected_status=None): > srealm = target_creds.get_realm() > > if sname is None: >@@ -1297,10 +1308,11 @@ class KdcTgsTests(KDCBaseTest): > check_rep_fn=check_rep_fn, > check_kdc_private_fn=self.generic_check_kdc_private, > expected_error_mode=expected_error, >+ expected_status=expected_status, > tgt=tgt, > authenticator_subkey=subkey, > kdc_options=kdc_options, >- expect_edata=False, >+ expect_edata=expect_edata, > expect_claims=expect_claims) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >-- >2.25.1 > > >From acd4e61052f15963fd2662cdb80c1bfa9aaf29d4 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 21:12:12 +1300 >Subject: [PATCH 582/686] CVE-2020-25719 tests/krb5: Extend _get_tgt() method > to allow more modifications to tickets > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 55 ++++++++++++++++-------- > 1 file changed, 37 insertions(+), 18 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 3fd6fc1a7b1..4cb32c96250 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -25,7 +25,7 @@ import ldb > > from samba import dsdb, ntstatus > >-from samba.dcerpc import krb5pac >+from samba.dcerpc import krb5pac, security > > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" >@@ -1014,7 +1014,11 @@ class KdcTgsTests(KDCBaseTest): > from_rodc=False, > new_rid=None, > remove_pac=False, >- allow_empty_authdata=False): >+ allow_empty_authdata=False, >+ can_modify_logon_info=True, >+ can_modify_requester_sid=True, >+ remove_pac_attrs=False, >+ remove_requester_sid=False): > self.assertFalse(renewable and invalid) > > if remove_pac: >@@ -1027,19 +1031,38 @@ class KdcTgsTests(KDCBaseTest): > else: > krbtgt_creds = self.get_krbtgt_creds() > >- if new_rid is not None: >+ if new_rid is not None or remove_requester_sid or remove_pac_attrs: > def change_sid_fn(pac): >- for pac_buffer in pac.buffers: >+ pac_buffers = pac.buffers >+ for pac_buffer in pac_buffers: > if pac_buffer.type == krb5pac.PAC_TYPE_LOGON_INFO: >- logon_info = pac_buffer.info.info >+ if new_rid is not None and can_modify_logon_info: >+ logon_info = pac_buffer.info.info > >- logon_info.info3.base.rid = new_rid >+ logon_info.info3.base.rid = new_rid >+ elif pac_buffer.type == krb5pac.PAC_TYPE_REQUESTER_SID: >+ if remove_requester_sid: >+ pac.num_buffers -= 1 >+ pac_buffers.remove(pac_buffer) >+ elif new_rid is not None and can_modify_requester_sid: >+ requester_sid = pac_buffer.info > >- return pac >+ samdb = self.get_samdb() >+ domain_sid = samdb.get_domain_sid() >+ >+ new_sid = f'{domain_sid}-{new_rid}' >+ >+ requester_sid.sid = security.dom_sid(new_sid) >+ elif pac_buffer.type == krb5pac.PAC_TYPE_ATTRIBUTES_INFO: >+ if remove_pac_attrs: >+ pac.num_buffers -= 1 >+ pac_buffers.remove(pac_buffer) >+ >+ pac.buffers = pac_buffers > >- modify_pac_fn = change_sid_fn >+ return pac > else: >- modify_pac_fn = None >+ change_sid_fn = None > > krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) > >@@ -1051,7 +1074,7 @@ class KdcTgsTests(KDCBaseTest): > } > > if renewable: >- def set_renewable(enc_part): >+ def flags_modify_fn(enc_part): > # Set the renewable flag. > renewable_flag = krb5_asn1.TicketFlags('renewable') > pos = len(tuple(renewable_flag)) - 1 >@@ -1067,10 +1090,8 @@ class KdcTgsTests(KDCBaseTest): > enc_part['renew-till'] = renew_till > > return enc_part >- >- modify_fn = set_renewable > elif invalid: >- def set_invalid(enc_part): >+ def flags_modify_fn(enc_part): > # Set the invalid flag. > invalid_flag = krb5_asn1.TicketFlags('invalid') > pos = len(tuple(invalid_flag)) - 1 >@@ -1086,16 +1107,14 @@ class KdcTgsTests(KDCBaseTest): > enc_part['starttime'] = past_time > > return enc_part >- >- modify_fn = set_invalid > else: >- modify_fn = None >+ flags_modify_fn = None > > return self.modified_ticket( > tgt, > new_ticket_key=krbtgt_key, >- modify_fn=modify_fn, >- modify_pac_fn=modify_pac_fn, >+ modify_fn=flags_modify_fn, >+ modify_pac_fn=change_sid_fn, > exclude_pac=remove_pac, > allow_empty_authdata=allow_empty_authdata, > update_pac_checksums=not remove_pac, >-- >2.25.1 > > >From 59463cee097a0bebe2b27afcfb5132f1942a67a3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 27 Oct 2021 10:25:08 +1300 >Subject: [PATCH 583/686] CVE-2020-25719 tests/krb5: Add _modify_tgt() method > for modifying already obtained tickets > >https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 62 +++++++++++++++++++++++- > 1 file changed, 60 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 4cb32c96250..52a347b9ed4 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -1026,6 +1026,33 @@ class KdcTgsTests(KDCBaseTest): > > tgt = self.get_tgt(client_creds) > >+ return self._modify_tgt( >+ tgt=tgt, >+ renewable=renewable, >+ invalid=invalid, >+ from_rodc=from_rodc, >+ new_rid=new_rid, >+ remove_pac=remove_pac, >+ allow_empty_authdata=allow_empty_authdata, >+ can_modify_logon_info=can_modify_logon_info, >+ can_modify_requester_sid=can_modify_requester_sid, >+ remove_pac_attrs=remove_pac_attrs, >+ remove_requester_sid=remove_requester_sid) >+ >+ def _modify_tgt(self, >+ tgt, >+ renewable=False, >+ invalid=False, >+ from_rodc=False, >+ new_rid=None, >+ remove_pac=False, >+ allow_empty_authdata=False, >+ cname=None, >+ crealm=None, >+ can_modify_logon_info=True, >+ can_modify_requester_sid=True, >+ remove_pac_attrs=False, >+ remove_requester_sid=False): > if from_rodc: > krbtgt_creds = self.get_mock_rodc_krbtgt_creds() > else: >@@ -1110,11 +1137,42 @@ class KdcTgsTests(KDCBaseTest): > else: > flags_modify_fn = None > >+ if cname is not None or crealm is not None: >+ def modify_fn(enc_part): >+ if flags_modify_fn is not None: >+ enc_part = flags_modify_fn(enc_part) >+ >+ if cname is not None: >+ enc_part['cname'] = cname >+ >+ if crealm is not None: >+ enc_part['crealm'] = crealm >+ >+ return enc_part >+ else: >+ modify_fn = flags_modify_fn >+ >+ if cname is not None: >+ def modify_pac_fn(pac): >+ if change_sid_fn is not None: >+ pac = change_sid_fn(pac) >+ >+ for pac_buffer in pac.buffers: >+ if pac_buffer.type == krb5pac.PAC_TYPE_LOGON_NAME: >+ logon_info = pac_buffer.info >+ >+ logon_info.account_name = ( >+ cname['name-string'][0].decode('utf-8')) >+ >+ return pac >+ else: >+ modify_pac_fn = change_sid_fn >+ > return self.modified_ticket( > tgt, > new_ticket_key=krbtgt_key, >- modify_fn=flags_modify_fn, >- modify_pac_fn=change_sid_fn, >+ modify_fn=modify_fn, >+ modify_pac_fn=modify_pac_fn, > exclude_pac=remove_pac, > allow_empty_authdata=allow_empty_authdata, > update_pac_checksums=not remove_pac, >-- >2.25.1 > > >From 554494305ce22174e621fee3e0161da4fdf73acf Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:50:09 +1300 >Subject: [PATCH 584/686] CVE-2020-25719 tests/krb5: Add testing for > PAC_TYPE_ATTRIBUTES_INFO PAC buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 8 ++++- > python/samba/tests/krb5/raw_testcase.py | 37 ++++++++++++++++++++++++ > 2 files changed, 44 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 6d6dcc21607..dc1ba629b41 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1360,7 +1360,9 @@ class KDCBaseTest(RawKerberosTest): > expected_flags=None, unexpected_flags=None, > expected_account_name=None, expected_upn_name=None, > expected_sid=None, >- pac_request=True, expect_pac=True, fresh=False): >+ pac_request=True, expect_pac=True, >+ expect_pac_attrs=None, expect_pac_attrs_pac_request=None, >+ fresh=False): > user_name = creds.get_username() > cache_key = (user_name, to_rodc, kdc_options, pac_request) > >@@ -1426,6 +1428,8 @@ class KDCBaseTest(RawKerberosTest): > pac_request=pac_request, > pac_options=pac_options, > expect_pac=expect_pac, >+ expect_pac_attrs=expect_pac_attrs, >+ expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, > to_rodc=to_rodc) > self.check_pre_authentication(rep) > >@@ -1470,6 +1474,8 @@ class KDCBaseTest(RawKerberosTest): > pac_request=pac_request, > pac_options=pac_options, > expect_pac=expect_pac, >+ expect_pac_attrs=expect_pac_attrs, >+ expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, > to_rodc=to_rodc) > self.check_as_reply(rep) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 79fe9ec4620..d63366318be 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2021,6 +2021,8 @@ class RawKerberosTest(TestCaseInTempDir): > expect_pac=True, > expect_claims=True, > expect_upn_dns_info_ex=None, >+ expect_pac_attrs=None, >+ expect_pac_attrs_pac_request=None, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -2074,6 +2076,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'expect_pac': expect_pac, > 'expect_claims': expect_claims, > 'expect_upn_dns_info_ex': expect_upn_dns_info_ex, >+ 'expect_pac_attrs': expect_pac_attrs, >+ 'expect_pac_attrs_pac_request': expect_pac_attrs_pac_request, > 'to_rodc': to_rodc > } > if callback_dict is None: >@@ -2122,6 +2126,8 @@ class RawKerberosTest(TestCaseInTempDir): > expect_pac=True, > expect_claims=True, > expect_upn_dns_info_ex=None, >+ expect_pac_attrs=None, >+ expect_pac_attrs_pac_request=None, > expected_proxy_target=None, > expected_transited_services=None, > to_rodc=False): >@@ -2176,6 +2182,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'expect_pac': expect_pac, > 'expect_claims': expect_claims, > 'expect_upn_dns_info_ex': expect_upn_dns_info_ex, >+ 'expect_pac_attrs': expect_pac_attrs, >+ 'expect_pac_attrs_pac_request': expect_pac_attrs_pac_request, > 'expected_proxy_target': expected_proxy_target, > 'expected_transited_services': expected_transited_services, > 'to_rodc': to_rodc >@@ -2596,6 +2604,12 @@ class RawKerberosTest(TestCaseInTempDir): > if not self.tkt_sig_support: > require_strict.add(krb5pac.PAC_TYPE_TICKET_CHECKSUM) > >+ expect_pac_attrs = kdc_exchange_dict['expect_pac_attrs'] >+ if expect_pac_attrs: >+ expected_types.append(krb5pac.PAC_TYPE_ATTRIBUTES_INFO) >+ elif expect_pac_attrs is None: >+ require_strict.add(krb5pac.PAC_TYPE_ATTRIBUTES_INFO) >+ > buffer_types = [pac_buffer.type > for pac_buffer in pac.buffers] > self.assertSequenceElementsEqual( >@@ -2671,6 +2685,25 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertEqual(expected_sid, > str(upn_dns_info_ex.objectsid)) > >+ elif (pac_buffer.type == krb5pac.PAC_TYPE_ATTRIBUTES_INFO >+ and expect_pac_attrs): >+ attr_info = pac_buffer.info >+ >+ self.assertEqual(2, attr_info.flags_length) >+ >+ flags = attr_info.flags >+ >+ requested_pac = bool(flags & 1) >+ given_pac = bool(flags & 2) >+ >+ expect_pac_attrs_pac_request = kdc_exchange_dict[ >+ 'expect_pac_attrs_pac_request'] >+ >+ self.assertEqual(expect_pac_attrs_pac_request is True, >+ requested_pac) >+ self.assertEqual(expect_pac_attrs_pac_request is None, >+ given_pac) >+ > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >@@ -3663,6 +3696,8 @@ class RawKerberosTest(TestCaseInTempDir): > pac_request=None, > pac_options=None, > expect_pac=True, >+ expect_pac_attrs=None, >+ expect_pac_attrs_pac_request=None, > to_rodc=False): > > def _generate_padata_copy(_kdc_exchange_dict, >@@ -3706,6 +3741,8 @@ class RawKerberosTest(TestCaseInTempDir): > pac_request=pac_request, > pac_options=pac_options, > expect_pac=expect_pac, >+ expect_pac_attrs=expect_pac_attrs, >+ expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, > to_rodc=to_rodc) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >-- >2.25.1 > > >From 9f7f6ccba70d7b148ebbed6ac71f92281d7bf9c9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:51:13 +1300 >Subject: [PATCH 585/686] CVE-2020-25719 tests/krb5: Add testing for > PAC_TYPE_REQUESTER_SID PAC buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 3 +++ > python/samba/tests/krb5/raw_testcase.py | 19 +++++++++++++++++++ > 2 files changed, 22 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index dc1ba629b41..61eeb2333f9 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1362,6 +1362,7 @@ class KDCBaseTest(RawKerberosTest): > expected_sid=None, > pac_request=True, expect_pac=True, > expect_pac_attrs=None, expect_pac_attrs_pac_request=None, >+ expect_requester_sid=None, > fresh=False): > user_name = creds.get_username() > cache_key = (user_name, to_rodc, kdc_options, pac_request) >@@ -1430,6 +1431,7 @@ class KDCBaseTest(RawKerberosTest): > expect_pac=expect_pac, > expect_pac_attrs=expect_pac_attrs, > expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, >+ expect_requester_sid=expect_requester_sid, > to_rodc=to_rodc) > self.check_pre_authentication(rep) > >@@ -1476,6 +1478,7 @@ class KDCBaseTest(RawKerberosTest): > expect_pac=expect_pac, > expect_pac_attrs=expect_pac_attrs, > expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, >+ expect_requester_sid=expect_requester_sid, > to_rodc=to_rodc) > self.check_as_reply(rep) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index d63366318be..8779d0f7869 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2023,6 +2023,7 @@ class RawKerberosTest(TestCaseInTempDir): > expect_upn_dns_info_ex=None, > expect_pac_attrs=None, > expect_pac_attrs_pac_request=None, >+ expect_requester_sid=None, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -2078,6 +2079,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expect_upn_dns_info_ex': expect_upn_dns_info_ex, > 'expect_pac_attrs': expect_pac_attrs, > 'expect_pac_attrs_pac_request': expect_pac_attrs_pac_request, >+ 'expect_requester_sid': expect_requester_sid, > 'to_rodc': to_rodc > } > if callback_dict is None: >@@ -2128,6 +2130,7 @@ class RawKerberosTest(TestCaseInTempDir): > expect_upn_dns_info_ex=None, > expect_pac_attrs=None, > expect_pac_attrs_pac_request=None, >+ expect_requester_sid=None, > expected_proxy_target=None, > expected_transited_services=None, > to_rodc=False): >@@ -2184,6 +2187,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expect_upn_dns_info_ex': expect_upn_dns_info_ex, > 'expect_pac_attrs': expect_pac_attrs, > 'expect_pac_attrs_pac_request': expect_pac_attrs_pac_request, >+ 'expect_requester_sid': expect_requester_sid, > 'expected_proxy_target': expected_proxy_target, > 'expected_transited_services': expected_transited_services, > 'to_rodc': to_rodc >@@ -2610,6 +2614,12 @@ class RawKerberosTest(TestCaseInTempDir): > elif expect_pac_attrs is None: > require_strict.add(krb5pac.PAC_TYPE_ATTRIBUTES_INFO) > >+ expect_requester_sid = kdc_exchange_dict['expect_requester_sid'] >+ if expect_requester_sid: >+ expected_types.append(krb5pac.PAC_TYPE_REQUESTER_SID) >+ elif expect_requester_sid is None: >+ require_strict.add(krb5pac.PAC_TYPE_REQUESTER_SID) >+ > buffer_types = [pac_buffer.type > for pac_buffer in pac.buffers] > self.assertSequenceElementsEqual( >@@ -2704,6 +2714,13 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertEqual(expect_pac_attrs_pac_request is None, > given_pac) > >+ elif (pac_buffer.type == krb5pac.PAC_TYPE_REQUESTER_SID >+ and expect_requester_sid): >+ requester_sid = pac_buffer.info.sid >+ >+ self.assertIsNotNone(expected_sid) >+ self.assertEqual(expected_sid, str(requester_sid)) >+ > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >@@ -3698,6 +3715,7 @@ class RawKerberosTest(TestCaseInTempDir): > expect_pac=True, > expect_pac_attrs=None, > expect_pac_attrs_pac_request=None, >+ expect_requester_sid=None, > to_rodc=False): > > def _generate_padata_copy(_kdc_exchange_dict, >@@ -3743,6 +3761,7 @@ class RawKerberosTest(TestCaseInTempDir): > expect_pac=expect_pac, > expect_pac_attrs=expect_pac_attrs, > expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, >+ expect_requester_sid=expect_requester_sid, > to_rodc=to_rodc) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >-- >2.25.1 > > >From 13b4ed35eacb4218ebc12ffa594121ad9862e829 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:47:24 +1300 >Subject: [PATCH 586/686] CVE-2020-25719 tests/krb5: Add EXPECT_PAC environment > variable to expect pac from all TGS tickets > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/raw_testcase.py | 25 ++++++++--- > source4/selftest/tests.py | 55 +++++++++++++++++-------- > 2 files changed, 56 insertions(+), 24 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 8779d0f7869..42f2e94f5aa 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -596,6 +596,12 @@ class RawKerberosTest(TestCaseInTempDir): > tkt_sig_support = '0' > cls.tkt_sig_support = bool(int(tkt_sig_support)) > >+ expect_pac = samba.tests.env_get_var_value('EXPECT_PAC', >+ allow_missing=True) >+ if expect_pac is None: >+ expect_pac = '1' >+ cls.expect_pac = bool(int(expect_pac)) >+ > def setUp(self): > super().setUp() > self.do_asn1_print = False >@@ -2417,7 +2423,10 @@ class RawKerberosTest(TestCaseInTempDir): > etype=kcrypto.Enctype.RC4) > krbtgt_keys.append(krbtgt_key_rc4) > >- expect_pac = kdc_exchange_dict['expect_pac'] >+ if self.expect_pac and self.is_tgs(expected_sname): >+ expect_pac = True >+ else: >+ expect_pac = kdc_exchange_dict['expect_pac'] > > ticket_session_key = None > if ticket_private is not None: >@@ -2448,8 +2457,9 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementMissing(ticket_private, 'renew-till') > if self.strict_checking: > self.assertElementEqual(ticket_private, 'caddr', []) >- self.assertElementPresent(ticket_private, 'authorization-data', >- expect_empty=not expect_pac) >+ if expect_pac is not None: >+ self.assertElementPresent(ticket_private, 'authorization-data', >+ expect_empty=not expect_pac) > > encpart_session_key = None > if encpart_private is not None: >@@ -2554,11 +2564,14 @@ class RawKerberosTest(TestCaseInTempDir): > > if ticket_private is not None: > pac_data = self.get_ticket_pac(ticket_creds, expect_pac=expect_pac) >- if expect_pac: >- self.check_pac_buffers(pac_data, kdc_exchange_dict) >- else: >+ if expect_pac is True: >+ self.assertIsNotNone(pac_data) >+ elif expect_pac is False: > self.assertIsNone(pac_data) > >+ if pac_data is not None: >+ self.check_pac_buffers(pac_data, kdc_exchange_dict) >+ > expect_ticket_checksum = kdc_exchange_dict['expect_ticket_checksum'] > if expect_ticket_checksum: > self.assertIsNotNone(ticket_decryption_key) >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index d3ef08ef9e9..8f8d4c1611f 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -715,28 +715,33 @@ planoldpythontestsuite("ad_dc:local", "samba.tests.dckeytab", extra_args=['-U"$U > > have_fast_support = int('SAMBA_USES_MITKDC' in config_hash) > tkt_sig_support = int('SAMBA4_USES_HEIMDAL' in config_hash) >+expect_pac = 0 > planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", > environ={'SERVICE_USERNAME':'$SERVER', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support}) >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac}) > planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", > environ={'ADMIN_USERNAME':'$USERNAME', > 'ADMIN_PASSWORD':'$PASSWORD', > 'FOR_USER':'$USERNAME', > 'STRICT_CHECKING':'0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support}) >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac}) > planoldpythontestsuite("rodc:local", "samba.tests.krb5.rodc_tests", > environ={'ADMIN_USERNAME':'$USERNAME', > 'ADMIN_PASSWORD':'$PASSWORD', > 'STRICT_CHECKING':'0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support}) >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac}) > > planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests", > environ={'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support}) >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac}) > > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", > environ={ >@@ -744,7 +749,8 @@ planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", > environ={ >@@ -752,7 +758,8 @@ planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > for env in ['ad_dc_default', 'ad_member']: > planoldpythontestsuite(env, "samba.tests.krb5.test_rpc", >@@ -761,7 +768,8 @@ for env in ['ad_dc_default', 'ad_member']: > 'ADMIN_PASSWORD': '$DC_PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", > environ={ >@@ -769,7 +777,8 @@ planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > planoldpythontestsuite("ad_member_no_nss_wb:local", > "samba.tests.krb5.test_min_domain_uid", >@@ -1294,7 +1303,8 @@ for env in ["fl2008r2dc", "fl2003dc"]: > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > > planoldpythontestsuite('fl2008r2dc', 'samba.tests.krb5.salt_tests', >@@ -1303,7 +1313,8 @@ planoldpythontestsuite('fl2008r2dc', 'samba.tests.krb5.salt_tests', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > > for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: >@@ -1325,7 +1336,8 @@ planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests", > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", > environ={ >@@ -1333,11 +1345,13 @@ planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests", > environ={'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support}) >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac}) > planpythontestsuite( > "ad_dc", > "samba.tests.krb5.kdc_tgs_tests", >@@ -1346,7 +1360,8 @@ planpythontestsuite( > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > planpythontestsuite( > "ad_dc", >@@ -1356,7 +1371,8 @@ planpythontestsuite( > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > planpythontestsuite( > "ad_dc", >@@ -1366,7 +1382,8 @@ planpythontestsuite( > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > planpythontestsuite( > "ad_dc", >@@ -1376,7 +1393,8 @@ planpythontestsuite( > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > planpythontestsuite( > "ad_dc", >@@ -1386,7 +1404,8 @@ planpythontestsuite( > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >- 'TKT_SIG_SUPPORT': tkt_sig_support >+ 'TKT_SIG_SUPPORT': tkt_sig_support, >+ 'EXPECT_PAC': expect_pac > }) > > for env in [ >-- >2.25.1 > > >From 2547fe56276b7a339f3457dc3c4875cd89e4b04e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 27 Oct 2021 11:18:36 +1300 >Subject: [PATCH 587/686] CVE-2020-25719 tests/krb5: Add expected parameters to > cache key for obtaining tickets > >If multiple calls to get_tgt() or get_service_ticket() specify different >expected parameters, we want to perform the request again so that the >checking can be performed, rather than reusing a previously obtained >ticket and potentially skipping checks. > >It should be fine to cache tickets with the same expected parameters, as >tickets that fail to be obtained will not be stored in the cache, so the >checking will happen for every call. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 61eeb2333f9..4b4f1486f60 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1294,7 +1294,8 @@ class KDCBaseTest(RawKerberosTest): > if target_name is None: > target_name = target_creds.get_username()[:-1] > cache_key = (user_name, target_name, service, to_rodc, kdc_options, >- pac_request) >+ pac_request, str(expected_flags), str(unexpected_flags), >+ expect_pac) > > if not fresh: > ticket = self.tkt_cache.get(cache_key) >@@ -1365,7 +1366,11 @@ class KDCBaseTest(RawKerberosTest): > expect_requester_sid=None, > fresh=False): > user_name = creds.get_username() >- cache_key = (user_name, to_rodc, kdc_options, pac_request) >+ cache_key = (user_name, to_rodc, kdc_options, pac_request, >+ str(expected_flags), str(unexpected_flags), >+ expected_account_name, expected_upn_name, expected_sid, >+ expect_pac, expect_pac_attrs, >+ expect_pac_attrs_pac_request, expect_requester_sid) > > if not fresh: > tgt = self.tkt_cache.get(cache_key) >-- >2.25.1 > > >From bad6a9539821ab86d4b15ca6f0c8a98e4a9a2bf7 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 21:02:08 +1300 >Subject: [PATCH 588/686] CVE-2020-25719 tests/krb5: Add tests for PAC > attributes buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 281 +++++++++++++++++++++-- > selftest/knownfail_heimdal_kdc | 21 ++ > selftest/knownfail_mit_kdc | 22 ++ > 3 files changed, 308 insertions(+), 16 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 52a347b9ed4..40291677819 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -510,6 +510,20 @@ class KdcTgsTests(KDCBaseTest): > tgt = self._get_tgt(creds) > self._user2user(tgt, creds, expected_error=0) > >+ def test_tgs_req_no_pac_attrs(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, remove_pac_attrs=True) >+ >+ self._run_tgs(tgt, expected_error=0, expect_pac=True, >+ expect_pac_attrs=False) >+ >+ def test_tgs_req_from_rodc_no_pac_attrs(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True, remove_pac_attrs=True) >+ self._run_tgs(tgt, expected_error=0, expect_pac=True, >+ expect_pac_attrs=False) >+ > # Test making a request without a PAC. > def test_tgs_no_pac(self): > creds = self._get_creds() >@@ -1007,6 +1021,221 @@ class KdcTgsTests(KDCBaseTest): > self._user2user(service_ticket, creds, > expected_error=(KDC_ERR_MODIFIED, KDC_ERR_POLICY)) > >+ def test_pac_attrs_none(self): >+ creds = self._get_creds() >+ self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=None) >+ >+ def test_pac_attrs_false(self): >+ creds = self._get_creds() >+ self.get_tgt(creds, pac_request=False, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=False) >+ >+ def test_pac_attrs_true(self): >+ creds = self._get_creds() >+ self.get_tgt(creds, pac_request=True, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=True) >+ >+ def test_pac_attrs_renew_none(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=None) >+ tgt = self._modify_tgt(tgt, renewable=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=None) >+ >+ def test_pac_attrs_renew_false(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=False, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=False) >+ tgt = self._modify_tgt(tgt, renewable=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=False) >+ >+ def test_pac_attrs_renew_true(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=True, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=True) >+ tgt = self._modify_tgt(tgt, renewable=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=True) >+ >+ def test_pac_attrs_rodc_renew_none(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=None) >+ tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=None) >+ >+ def test_pac_attrs_rodc_renew_false(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self.get_tgt(creds, pac_request=False, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=False) >+ tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=False) >+ >+ def test_pac_attrs_rodc_renew_true(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self.get_tgt(creds, pac_request=True, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=True) >+ tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=True) >+ >+ def test_pac_attrs_missing_renew_none(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=None) >+ tgt = self._modify_tgt(tgt, renewable=True, >+ remove_pac_attrs=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=False) >+ >+ def test_pac_attrs_missing_renew_false(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=False, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=False) >+ tgt = self._modify_tgt(tgt, renewable=True, >+ remove_pac_attrs=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=False) >+ >+ def test_pac_attrs_missing_renew_true(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=True, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=True) >+ tgt = self._modify_tgt(tgt, renewable=True, >+ remove_pac_attrs=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=False) >+ >+ def test_pac_attrs_missing_rodc_renew_none(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=None) >+ tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True, >+ remove_pac_attrs=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=False) >+ >+ def test_pac_attrs_missing_rodc_renew_false(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self.get_tgt(creds, pac_request=False, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=False) >+ tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True, >+ remove_pac_attrs=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=False) >+ >+ def test_pac_attrs_missing_rodc_renew_true(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self.get_tgt(creds, pac_request=True, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=True) >+ tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True, >+ remove_pac_attrs=True) >+ >+ self._renew_tgt(tgt, expected_error=0, >+ expect_pac=True, >+ expect_pac_attrs=False) >+ >+ def test_tgs_pac_attrs_none(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=None) >+ >+ self._run_tgs(tgt, expected_error=0, expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=None) >+ >+ def test_tgs_pac_attrs_false(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=False, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=False) >+ >+ self._run_tgs(tgt, expected_error=0, expect_pac=False) >+ >+ def test_tgs_pac_attrs_true(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=True, >+ expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=True) >+ >+ self._run_tgs(tgt, expected_error=0, expect_pac=True, >+ expect_pac_attrs=True, >+ expect_pac_attrs_pac_request=True) >+ >+ > def _get_tgt(self, > client_creds, > renewable=False, >@@ -1278,23 +1507,34 @@ class KdcTgsTests(KDCBaseTest): > def _get_non_existent_rid(self): > return (1 << 30) - 1 > >- def _run_tgs(self, tgt, expected_error): >+ def _run_tgs(self, tgt, expected_error, expect_pac=True, >+ expect_pac_attrs=None, expect_pac_attrs_pac_request=None): > target_creds = self.get_service_creds() >- self._tgs_req(tgt, expected_error, target_creds) >- >- def _renew_tgt(self, tgt, expected_error): >+ return self._tgs_req( >+ tgt, expected_error, target_creds, >+ expect_pac=expect_pac, >+ expect_pac_attrs=expect_pac_attrs, >+ expect_pac_attrs_pac_request=expect_pac_attrs_pac_request) >+ >+ def _renew_tgt(self, tgt, expected_error, expect_pac=True, >+ expect_pac_attrs=None, expect_pac_attrs_pac_request=None): > krbtgt_creds = self.get_krbtgt_creds() > kdc_options = str(krb5_asn1.KDCOptions('renew')) >- self._tgs_req(tgt, expected_error, krbtgt_creds, >- kdc_options=kdc_options) >+ return self._tgs_req( >+ tgt, expected_error, krbtgt_creds, >+ kdc_options=kdc_options, >+ expect_pac=expect_pac, >+ expect_pac_attrs=expect_pac_attrs, >+ expect_pac_attrs_pac_request=expect_pac_attrs_pac_request) > >- def _validate_tgt(self, tgt, expected_error): >+ def _validate_tgt(self, tgt, expected_error, expect_pac=True): > krbtgt_creds = self.get_krbtgt_creds() > kdc_options = str(krb5_asn1.KDCOptions('validate')) >- self._tgs_req(tgt, expected_error, krbtgt_creds, >- kdc_options=kdc_options) >+ return self._tgs_req(tgt, expected_error, krbtgt_creds, >+ kdc_options=kdc_options, >+ expect_pac=expect_pac) > >- def _s4u2self(self, tgt, tgt_creds, expected_error, >+ def _s4u2self(self, tgt, tgt_creds, expected_error, expect_pac=True, > expect_edata=False, expected_status=None): > user_creds = self._get_mach_creds() > >@@ -1318,17 +1558,20 @@ class KdcTgsTests(KDCBaseTest): > expected_cname=user_cname, > generate_padata_fn=generate_s4u2self_padata, > expect_claims=False, expect_edata=expect_edata, >- expected_status=expected_status) >+ expected_status=expected_status, >+ expect_pac=expect_pac) > >- def _user2user(self, tgt, tgt_creds, expected_error, sname=None): >+ def _user2user(self, tgt, tgt_creds, expected_error, sname=None, >+ expect_pac=True): > user_creds = self._get_mach_creds() > user_tgt = self.get_tgt(user_creds) > > kdc_options = str(krb5_asn1.KDCOptions('enc-tkt-in-skey')) >- self._tgs_req(user_tgt, expected_error, tgt_creds, >- kdc_options=kdc_options, >- additional_ticket=tgt, >- sname=sname) >+ return self._tgs_req(user_tgt, expected_error, tgt_creds, >+ kdc_options=kdc_options, >+ additional_ticket=tgt, >+ sname=sname, >+ expect_pac=expect_pac) > > def _tgs_req(self, tgt, expected_error, target_creds, > kdc_options='0', >@@ -1337,6 +1580,9 @@ class KdcTgsTests(KDCBaseTest): > generate_padata_fn=None, > sname=None, > expect_claims=True, >+ expect_pac=True, >+ expect_pac_attrs=None, >+ expect_pac_attrs_pac_request=None, > expect_edata=False, > expected_status=None): > srealm = target_creds.get_realm() >@@ -1390,6 +1636,9 @@ class KdcTgsTests(KDCBaseTest): > authenticator_subkey=subkey, > kdc_options=kdc_options, > expect_edata=expect_edata, >+ expect_pac=expect_pac, >+ expect_pac_attrs=expect_pac_attrs, >+ expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, > expect_claims=expect_claims) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 1ddf812da25..e9b510e0f09 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -349,3 +349,24 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_nonexisting >+# >+# PAC attributes tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 720d243e05c..cf0eb2495b2 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -467,3 +467,25 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_nonexisting >+# >+# PAC attributes tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_pac_attrs >-- >2.25.1 > > >From 3fec9edbea4ecf9e1c64f11e48f0f239981ababf Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 21:19:44 +1300 >Subject: [PATCH 589/686] CVE-2020-25719 tests/krb5: Add tests for PAC-REQUEST > padata > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 232 ++++++++++++++++++++++- > selftest/knownfail_heimdal_kdc | 9 + > selftest/knownfail_mit_kdc | 18 ++ > 3 files changed, 256 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 40291677819..53d7dd4effb 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -1235,6 +1235,231 @@ class KdcTgsTests(KDCBaseTest): > expect_pac_attrs=True, > expect_pac_attrs_pac_request=True) > >+ def test_tgs_pac_request_none(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=None) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_tgs_pac_request_false(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ def test_tgs_pac_request_true(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=True) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_renew_pac_request_none(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=None) >+ tgt = self._modify_tgt(tgt, renewable=True) >+ >+ tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_renew_pac_request_false(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) >+ tgt = self._modify_tgt(tgt, renewable=True) >+ >+ tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ def test_renew_pac_request_true(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=True) >+ tgt = self._modify_tgt(tgt, renewable=True) >+ >+ tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_validate_pac_request_none(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=None) >+ tgt = self._modify_tgt(tgt, invalid=True) >+ >+ tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_validate_pac_request_false(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) >+ tgt = self._modify_tgt(tgt, invalid=True) >+ >+ tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ def test_validate_pac_request_true(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=True) >+ tgt = self._modify_tgt(tgt, invalid=True) >+ >+ tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_s4u2self_pac_request_none(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=None) >+ >+ ticket = self._s4u2self(tgt, creds, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_s4u2self_pac_request_false(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) >+ >+ ticket = self._s4u2self(tgt, creds, expected_error=0, expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ def test_s4u2self_pac_request_true(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=True) >+ >+ ticket = self._s4u2self(tgt, creds, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_user2user_pac_request_none(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=None) >+ >+ ticket = self._user2user(tgt, creds, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_user2user_pac_request_false(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) >+ >+ ticket = self._user2user(tgt, creds, expected_error=0, >+ expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=True) >+ self.assertIsNotNone(pac) >+ >+ def test_user2user_pac_request_true(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds, pac_request=True) >+ >+ ticket = self._user2user(tgt, creds, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_user2user_user_pac_request_none(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds) >+ >+ user_creds = self._get_mach_creds() >+ user_tgt = self.get_tgt(user_creds, pac_request=None) >+ >+ ticket = self._user2user(tgt, creds, expected_error=0, >+ user_tgt=user_tgt, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_user2user_user_pac_request_false(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds) >+ >+ user_creds = self._get_mach_creds() >+ user_tgt = self.get_tgt(user_creds, pac_request=False, expect_pac=None) >+ >+ ticket = self._user2user(tgt, creds, expected_error=0, >+ user_tgt=user_tgt, expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ def test_user2user_user_pac_request_true(self): >+ creds = self._get_creds() >+ tgt = self.get_tgt(creds) >+ >+ user_creds = self._get_mach_creds() >+ user_tgt = self.get_tgt(user_creds, pac_request=True) >+ >+ ticket = self._user2user(tgt, creds, expected_error=0, >+ user_tgt=user_tgt, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_tgs_rodc_pac_request_none(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self.get_tgt(creds, pac_request=None) >+ tgt = self._modify_tgt(tgt, from_rodc=True) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_tgs_rodc_pac_request_false(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) >+ tgt = self._modify_tgt(tgt, from_rodc=True) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ def test_tgs_rodc_pac_request_true(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self.get_tgt(creds, pac_request=True) >+ tgt = self._modify_tgt(tgt, from_rodc=True) >+ >+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) > > def _get_tgt(self, > client_creds, >@@ -1562,9 +1787,10 @@ class KdcTgsTests(KDCBaseTest): > expect_pac=expect_pac) > > def _user2user(self, tgt, tgt_creds, expected_error, sname=None, >- expect_pac=True): >- user_creds = self._get_mach_creds() >- user_tgt = self.get_tgt(user_creds) >+ user_tgt=None, expect_pac=True): >+ if user_tgt is None: >+ user_creds = self._get_mach_creds() >+ user_tgt = self.get_tgt(user_creds) > > kdc_options = str(krb5_asn1.KDCOptions('enc-tkt-in-skey')) > return self._tgs_req(user_tgt, expected_error, tgt_creds, >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index e9b510e0f09..e6fad91b402 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -370,3 +370,12 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_false > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true >+# >+# PAC request tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index cf0eb2495b2..17a9792c619 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -489,3 +489,21 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_pac_attrs >+# >+# PAC request tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_pac_request_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_request_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_false >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_none >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_pac_request_false >-- >2.25.1 > > >From b79476487317889192a2c5d6b0bbc8046a5f00fd Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 21:04:25 +1300 >Subject: [PATCH 590/686] CVE-2020-25719 tests/krb5: Add tests for requester > SID PAC buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 222 ++++++++++++++++++++++- > selftest/knownfail_heimdal_kdc | 18 ++ > selftest/knownfail_mit_kdc | 20 ++ > 3 files changed, 256 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 53d7dd4effb..2005d71fa81 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -510,6 +510,13 @@ class KdcTgsTests(KDCBaseTest): > tgt = self._get_tgt(creds) > self._user2user(tgt, creds, expected_error=0) > >+ def test_tgs_req_no_requester_sid(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds, remove_requester_sid=True) >+ >+ self._run_tgs(tgt, expected_error=0, expect_pac=True, >+ expect_requester_sid=False) # Note: not expected >+ > def test_tgs_req_no_pac_attrs(self): > creds = self._get_creds() > tgt = self._get_tgt(creds, remove_pac_attrs=True) >@@ -517,6 +524,17 @@ class KdcTgsTests(KDCBaseTest): > self._run_tgs(tgt, expected_error=0, expect_pac=True, > expect_pac_attrs=False) > >+ def test_tgs_req_from_rodc_no_requester_sid(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True, remove_requester_sid=True) >+ >+ samdb = self.get_samdb() >+ sid = self.get_objectSid(samdb, creds.get_dn()) >+ >+ self._run_tgs(tgt, expected_error=0, expect_pac=True, >+ expect_requester_sid=True, expected_sid=sid) >+ > def test_tgs_req_from_rodc_no_pac_attrs(self): > creds = self._get_creds(replication_allowed=True, > revealed_to_rodc=True) >@@ -617,6 +635,27 @@ class KdcTgsTests(KDCBaseTest): > self._user2user(tgt, creds, > expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) > >+ def test_requester_sid_mismatch_existing(self): >+ creds = self._get_creds() >+ existing_rid = self._get_existing_rid() >+ tgt = self._get_tgt(creds, new_rid=existing_rid, >+ can_modify_logon_info=False) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_logon_info_sid_mismatch_existing(self): >+ creds = self._get_creds() >+ existing_rid = self._get_existing_rid() >+ tgt = self._get_tgt(creds, new_rid=existing_rid, >+ can_modify_requester_sid=False) >+ self._run_tgs(tgt, expected_error=0) >+ >+ def test_logon_info_only_sid_mismatch_existing(self): >+ creds = self._get_creds() >+ existing_rid = self._get_existing_rid() >+ tgt = self._get_tgt(creds, new_rid=existing_rid, >+ remove_requester_sid=True) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ > # Test changing the SID in the PAC to a non-existent one. > def test_tgs_sid_mismatch_nonexisting(self): > creds = self._get_creds() >@@ -652,6 +691,27 @@ class KdcTgsTests(KDCBaseTest): > self._user2user(tgt, creds, > expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) > >+ def test_requester_sid_mismatch_nonexisting(self): >+ creds = self._get_creds() >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, new_rid=nonexistent_rid, >+ can_modify_logon_info=False) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_logon_info_sid_mismatch_nonexisting(self): >+ creds = self._get_creds() >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, new_rid=nonexistent_rid, >+ can_modify_requester_sid=False) >+ self._run_tgs(tgt, expected_error=0) >+ >+ def test_logon_info_only_sid_mismatch_nonexisting(self): >+ creds = self._get_creds() >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, new_rid=nonexistent_rid, >+ remove_requester_sid=True) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ > # Test with an RODC-issued ticket where the client is revealed to the RODC. > def test_tgs_rodc_revealed(self): > creds = self._get_creds(replication_allowed=True, >@@ -728,6 +788,33 @@ class KdcTgsTests(KDCBaseTest): > self._user2user(tgt, creds, > expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) > >+ def test_tgs_rodc_requester_sid_mismatch_existing(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ existing_rid = self._get_existing_rid(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid, >+ can_modify_logon_info=False) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_tgs_rodc_logon_info_sid_mismatch_existing(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ existing_rid = self._get_existing_rid(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid, >+ can_modify_requester_sid=False) >+ self._run_tgs(tgt, expected_error=0) >+ >+ def test_tgs_rodc_logon_info_only_sid_mismatch_existing(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ existing_rid = self._get_existing_rid(replication_allowed=True, >+ revealed_to_rodc=True) >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid, >+ remove_requester_sid=True) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ > # Test with an RODC-issued ticket where the SID in the PAC is changed to a > # non-existent one. > def test_tgs_rodc_sid_mismatch_nonexisting(self): >@@ -768,6 +855,30 @@ class KdcTgsTests(KDCBaseTest): > self._user2user(tgt, creds, > expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) > >+ def test_tgs_rodc_requester_sid_mismatch_nonexisting(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid, >+ can_modify_logon_info=False) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ >+ def test_tgs_rodc_logon_info_sid_mismatch_nonexisting(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid, >+ can_modify_requester_sid=False) >+ self._run_tgs(tgt, expected_error=0) >+ >+ def test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ nonexistent_rid = self._get_non_existent_rid() >+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid, >+ remove_requester_sid=True) >+ self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) >+ > # Test with an RODC-issued ticket where the client is not revealed to the > # RODC. > def test_tgs_rodc_not_revealed(self): >@@ -1235,6 +1346,99 @@ class KdcTgsTests(KDCBaseTest): > expect_pac_attrs=True, > expect_pac_attrs_pac_request=True) > >+ def test_as_requester_sid(self): >+ creds = self._get_creds() >+ >+ samdb = self.get_samdb() >+ sid = self.get_objectSid(samdb, creds.get_dn()) >+ >+ self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expected_sid=sid, >+ expect_requester_sid=True) >+ >+ def test_tgs_requester_sid(self): >+ creds = self._get_creds() >+ >+ samdb = self.get_samdb() >+ sid = self.get_objectSid(samdb, creds.get_dn()) >+ >+ tgt = self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expected_sid=sid, >+ expect_requester_sid=True) >+ >+ self._run_tgs(tgt, expected_error=0, expect_pac=True, >+ expected_sid=sid, >+ expect_requester_sid=True) >+ >+ def test_tgs_requester_sid_renew(self): >+ creds = self._get_creds() >+ >+ samdb = self.get_samdb() >+ sid = self.get_objectSid(samdb, creds.get_dn()) >+ >+ tgt = self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expected_sid=sid, >+ expect_requester_sid=True) >+ tgt = self._modify_tgt(tgt, renewable=True) >+ >+ self._renew_tgt(tgt, expected_error=0, expect_pac=True, >+ expected_sid=sid, >+ expect_requester_sid=True) >+ >+ def test_tgs_requester_sid_rodc_renew(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ >+ samdb = self.get_samdb() >+ sid = self.get_objectSid(samdb, creds.get_dn()) >+ >+ tgt = self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expected_sid=sid, >+ expect_requester_sid=True) >+ tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True) >+ >+ self._renew_tgt(tgt, expected_error=0, expect_pac=True, >+ expected_sid=sid, >+ expect_requester_sid=True) >+ >+ def test_tgs_requester_sid_missing_renew(self): >+ creds = self._get_creds() >+ >+ samdb = self.get_samdb() >+ sid = self.get_objectSid(samdb, creds.get_dn()) >+ >+ tgt = self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expected_sid=sid, >+ expect_requester_sid=True) >+ tgt = self._modify_tgt(tgt, renewable=True, >+ remove_requester_sid=True) >+ >+ self._renew_tgt(tgt, expected_error=0, expect_pac=True, >+ expect_requester_sid=False) # Note: not expected >+ >+ def test_tgs_requester_sid_missing_rodc_renew(self): >+ creds = self._get_creds(replication_allowed=True, >+ revealed_to_rodc=True) >+ >+ samdb = self.get_samdb() >+ sid = self.get_objectSid(samdb, creds.get_dn()) >+ >+ tgt = self.get_tgt(creds, pac_request=None, >+ expect_pac=True, >+ expected_sid=sid, >+ expect_requester_sid=True) >+ tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True, >+ remove_requester_sid=True) >+ >+ self._renew_tgt(tgt, expected_error=0, expect_pac=True, >+ expected_sid=sid, >+ expect_requester_sid=True) >+ > def test_tgs_pac_request_none(self): > creds = self._get_creds() > tgt = self.get_tgt(creds, pac_request=None) >@@ -1733,16 +1937,20 @@ class KdcTgsTests(KDCBaseTest): > return (1 << 30) - 1 > > def _run_tgs(self, tgt, expected_error, expect_pac=True, >- expect_pac_attrs=None, expect_pac_attrs_pac_request=None): >+ expect_pac_attrs=None, expect_pac_attrs_pac_request=None, >+ expect_requester_sid=None, expected_sid=None): > target_creds = self.get_service_creds() > return self._tgs_req( > tgt, expected_error, target_creds, > expect_pac=expect_pac, > expect_pac_attrs=expect_pac_attrs, >- expect_pac_attrs_pac_request=expect_pac_attrs_pac_request) >+ expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, >+ expect_requester_sid=expect_requester_sid, >+ expected_sid=expected_sid) > > def _renew_tgt(self, tgt, expected_error, expect_pac=True, >- expect_pac_attrs=None, expect_pac_attrs_pac_request=None): >+ expect_pac_attrs=None, expect_pac_attrs_pac_request=None, >+ expect_requester_sid=None, expected_sid=None): > krbtgt_creds = self.get_krbtgt_creds() > kdc_options = str(krb5_asn1.KDCOptions('renew')) > return self._tgs_req( >@@ -1750,7 +1958,9 @@ class KdcTgsTests(KDCBaseTest): > kdc_options=kdc_options, > expect_pac=expect_pac, > expect_pac_attrs=expect_pac_attrs, >- expect_pac_attrs_pac_request=expect_pac_attrs_pac_request) >+ expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, >+ expect_requester_sid=expect_requester_sid, >+ expected_sid=expected_sid) > > def _validate_tgt(self, tgt, expected_error, expect_pac=True): > krbtgt_creds = self.get_krbtgt_creds() >@@ -1809,7 +2019,9 @@ class KdcTgsTests(KDCBaseTest): > expect_pac=True, > expect_pac_attrs=None, > expect_pac_attrs_pac_request=None, >+ expect_requester_sid=None, > expect_edata=False, >+ expected_sid=None, > expected_status=None): > srealm = target_creds.get_realm() > >@@ -1865,6 +2077,8 @@ class KdcTgsTests(KDCBaseTest): > expect_pac=expect_pac, > expect_pac_attrs=expect_pac_attrs, > expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, >+ expect_requester_sid=expect_requester_sid, >+ expected_sid=expected_sid, > expect_claims=expect_claims) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index e6fad91b402..41ad710d2f2 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -379,3 +379,21 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_false > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_none > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true >+# >+# PAC requester SID tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_as_requester_sid >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_renew >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 17a9792c619..cf3fc5abbaf 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -507,3 +507,23 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_none > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_pac_request_false >+# >+# PAC requester SID tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_as_requester_sid >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_renew >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting >-- >2.25.1 > > >From 1b33d5edbf2faa4182e5ec6bf01e124251b31b86 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 21:06:58 +1300 >Subject: [PATCH 591/686] CVE-2020-25719 tests/krb5: Add test for user-to-user > with no sname > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14873 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 38 +++++++++++++++++------- > selftest/knownfail_heimdal_kdc | 1 + > selftest/knownfail_mit_kdc | 1 + > 3 files changed, 29 insertions(+), 11 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 2005d71fa81..b0f60c0a8ce 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -1122,6 +1122,14 @@ class KdcTgsTests(KDCBaseTest): > self._user2user(tgt, creds, sname=sname, > expected_error=KDC_ERR_S_PRINCIPAL_UNKNOWN) > >+ def test_user2user_no_sname(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ self._user2user(tgt, creds, sname=False, >+ expected_error=(KDC_ERR_GENERIC, >+ KDC_ERR_S_PRINCIPAL_UNKNOWN)) >+ > def test_user2user_service_ticket(self): > creds = self._get_creds() > tgt = self._get_tgt(creds) >@@ -2025,16 +2033,24 @@ class KdcTgsTests(KDCBaseTest): > expected_status=None): > srealm = target_creds.get_realm() > >- if sname is None: >- target_name = target_creds.get_username() >- if target_name == 'krbtgt': >- sname = self.PrincipalName_create(name_type=NT_SRV_INST, >- names=[target_name, srealm]) >- else: >- if target_name[-1] == '$': >- target_name = target_name[:-1] >- sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >- names=['host', target_name]) >+ if sname is False: >+ sname = None >+ expected_sname = self.get_krbtgt_sname() >+ else: >+ if sname is None: >+ target_name = target_creds.get_username() >+ if target_name == 'krbtgt': >+ sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, >+ names=[target_name, srealm]) >+ else: >+ if target_name[-1] == '$': >+ target_name = target_name[:-1] >+ sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, >+ names=['host', target_name]) >+ >+ expected_sname = sname > > if additional_ticket is not None: > additional_tickets = [additional_ticket.ticket] >@@ -2062,7 +2078,7 @@ class KdcTgsTests(KDCBaseTest): > expected_crealm=tgt.crealm, > expected_cname=expected_cname, > expected_srealm=srealm, >- expected_sname=sname, >+ expected_sname=expected_sname, > ticket_decryption_key=decryption_key, > generate_padata_fn=generate_padata_fn, > check_error_fn=check_error_fn, >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 41ad710d2f2..fc2917761a1 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -323,6 +323,7 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_host > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_sname > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_non_existent_sname > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_allowed_denied >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index cf3fc5abbaf..aa66f4cb0fc 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -441,6 +441,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_user > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_sname > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_denied >-- >2.25.1 > > >From e8d856bcb87563eefd83c4996c88a2f3979ba685 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 21:09:32 +1300 >Subject: [PATCH 592/686] CVE-2020-25719 tests/krb5: Add tests for mismatched > names with user-to-user > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14873 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 105 ++++++++++++++++++- > python/samba/tests/krb5/rfc4120_constants.py | 1 + > selftest/knownfail_heimdal_kdc | 8 ++ > selftest/knownfail_mit_kdc | 8 ++ > 4 files changed, 120 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index b0f60c0a8ce..cfe1ad42d61 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -43,8 +43,10 @@ from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_GENERIC, > KDC_ERR_MODIFIED, > KDC_ERR_POLICY, >+ KDC_ERR_C_PRINCIPAL_UNKNOWN, > KDC_ERR_S_PRINCIPAL_UNKNOWN, > KDC_ERR_TGT_REVOKED, >+ KDC_ERR_WRONG_REALM, > NT_PRINCIPAL, > NT_SRV_INST, > ) >@@ -1112,6 +1114,100 @@ class KdcTgsTests(KDCBaseTest): > expected_error=(KDC_ERR_BADMATCH, > KDC_ERR_BADOPTION)) > >+ def test_user2user_other_sname(self): >+ other_name = self.get_new_username() >+ spn = f'host/{other_name}' >+ creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'spn': spn}) >+ tgt = self._get_tgt(creds) >+ >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=['host', other_name]) >+ >+ self._user2user(tgt, creds, sname=sname, expected_error=0) >+ >+ def test_user2user_wrong_sname_krbtgt(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ sname = self.get_krbtgt_sname() >+ >+ self._user2user(tgt, creds, sname=sname, >+ expected_error=(KDC_ERR_BADMATCH, >+ KDC_ERR_BADOPTION)) >+ >+ def test_user2user_wrong_srealm(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ self._user2user(tgt, creds, srealm='OTHER.REALM', >+ expected_error=(KDC_ERR_WRONG_REALM, >+ KDC_ERR_S_PRINCIPAL_UNKNOWN)) >+ >+ def test_user2user_tgt_correct_realm(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ realm = creds.get_realm().encode('utf-8') >+ tgt = self._modify_tgt(tgt, realm) >+ >+ self._user2user(tgt, creds, >+ expected_error=0) >+ >+ def test_user2user_tgt_wrong_realm(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ tgt = self._modify_tgt(tgt, b'OTHER.REALM') >+ >+ self._user2user(tgt, creds, >+ expected_error=0) >+ >+ def test_user2user_tgt_correct_cname(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ user_name = creds.get_username() >+ user_name = user_name.encode('utf-8') >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ >+ tgt = self._modify_tgt(tgt, cname=cname) >+ >+ self._user2user(tgt, creds, expected_error=0) >+ >+ def test_user2user_tgt_other_cname(self): >+ samdb = self.get_samdb() >+ >+ other_name = self.get_new_username() >+ upn = f'{other_name}@{samdb.domain_dns_name()}' >+ >+ creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': upn}) >+ tgt = self._get_tgt(creds) >+ >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[other_name.encode('utf-8')]) >+ >+ tgt = self._modify_tgt(tgt, cname=cname) >+ >+ self._user2user(tgt, creds, expected_error=0) >+ >+ def test_user2user_tgt_cname_host(self): >+ creds = self._get_creds() >+ tgt = self._get_tgt(creds) >+ >+ user_name = creds.get_username() >+ user_name = user_name.encode('utf-8') >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[b'host', user_name]) >+ >+ tgt = self._modify_tgt(tgt, cname=cname) >+ >+ self._user2user(tgt, creds, expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN) >+ > def test_user2user_non_existent_sname(self): > creds = self._get_creds() > tgt = self._get_tgt(creds) >@@ -2005,7 +2101,7 @@ class KdcTgsTests(KDCBaseTest): > expect_pac=expect_pac) > > def _user2user(self, tgt, tgt_creds, expected_error, sname=None, >- user_tgt=None, expect_pac=True): >+ srealm=None, user_tgt=None, expect_pac=True): > if user_tgt is None: > user_creds = self._get_mach_creds() > user_tgt = self.get_tgt(user_creds) >@@ -2015,6 +2111,7 @@ class KdcTgsTests(KDCBaseTest): > kdc_options=kdc_options, > additional_ticket=tgt, > sname=sname, >+ srealm=srealm, > expect_pac=expect_pac) > > def _tgs_req(self, tgt, expected_error, target_creds, >@@ -2023,6 +2120,7 @@ class KdcTgsTests(KDCBaseTest): > additional_ticket=None, > generate_padata_fn=None, > sname=None, >+ srealm=None, > expect_claims=True, > expect_pac=True, > expect_pac_attrs=None, >@@ -2031,7 +2129,10 @@ class KdcTgsTests(KDCBaseTest): > expect_edata=False, > expected_sid=None, > expected_status=None): >- srealm = target_creds.get_realm() >+ if srealm is False: >+ srealm = None >+ elif srealm is None: >+ srealm = target_creds.get_realm() > > if sname is False: > sname = None >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index 490cd255ec3..5251e291fde 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -82,6 +82,7 @@ KDC_ERR_SKEW = 37 > KDC_ERR_MODIFIED = 41 > KDC_ERR_INAPP_CKSUM = 50 > KDC_ERR_GENERIC = 60 >+KDC_ERR_WRONG_REALM = 68 > KDC_ERR_CLIENT_NAME_MISMATCH = 75 > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS = 93 > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index fc2917761a1..d1fb5f210af 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -325,6 +325,7 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_sname > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_non_existent_sname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_other_sname > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_denied >@@ -337,7 +338,14 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_cname_host >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_correct_cname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_correct_realm >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_other_cname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_wrong_realm > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_srealm > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_allowed_denied >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index aa66f4cb0fc..04efccf4a59 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -442,6 +442,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_sname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_other_sname > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_denied >@@ -454,7 +455,14 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_cname_host >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_correct_cname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_correct_realm >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_other_cname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_wrong_realm > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_srealm > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_allowed_denied >-- >2.25.1 > > >From 21518b819be32059439355a734d3c3580441eb88 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 29 Oct 2021 11:00:38 +1300 >Subject: [PATCH 593/686] CVE-2020-25719 s4/torture: Expect additional PAC > buffers > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[jsutton@samba.org Backported to adapt to missing netlogon_validate_pac > from d6a4eea5fd284755d181426dba84ddd5c1ba9769 and test_S4U2Proxy from > 90bdaaf09d9c5595170272bd0bfebaac0a90ae01 and re-added MIT knownfails] >--- > selftest/knownfail_heimdal_kdc | 39 ++++++++++++++++++++++++++++++++ > selftest/knownfail_mit_kdc | 39 ++++++++++++++++++++++++++++++++ > source4/torture/rpc/remote_pac.c | 14 +++++++++++- > 3 files changed, 91 insertions(+), 1 deletion(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index d1fb5f210af..850346940ad 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -406,3 +406,42 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting >+# >+# PAC tests >+# >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc:local >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc_ntvfs:local >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 04efccf4a59..abaf316b3d8 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -536,3 +536,42 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting >+# >+# PAC tests >+# >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc:local >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc_ntvfs:local >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c >index 3e02245d7ba..5da82b630bb 100644 >--- a/source4/torture/rpc/remote_pac.c >+++ b/source4/torture/rpc/remote_pac.c >@@ -280,7 +280,7 @@ static bool test_PACVerify(struct torture_context *tctx, > (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); > torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_pull_struct_blob of PAC_DATA structure failed"); > >- num_pac_buffers = 5; >+ num_pac_buffers = 7; > if (expect_pac_upn_dns_info) { > num_pac_buffers += 1; > } >@@ -337,6 +337,18 @@ static bool test_PACVerify(struct torture_context *tctx, > pac_buf->info != NULL, > "PAC_TYPE_TICKET_CHECKSUM info"); > >+ pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_ATTRIBUTES_INFO); >+ torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_ATTRIBUTES_INFO"); >+ torture_assert(tctx, >+ pac_buf->info != NULL, >+ "PAC_TYPE_ATTRIBUTES_INFO info"); >+ >+ pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_REQUESTER_SID); >+ torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_REQUESTER_SID"); >+ torture_assert(tctx, >+ pac_buf->info != NULL, >+ "PAC_TYPE_REQUESTER_SID info"); >+ > pac_wrapped_struct.ChecksumLength = pac_data->pac_srv_sig->signature.length; > pac_wrapped_struct.SignatureType = pac_data->pac_kdc_sig->type; > pac_wrapped_struct.SignatureLength = pac_data->pac_kdc_sig->signature.length; >-- >2.25.1 > > >From 0c6b95d0d0734217c956d09d2c9d45c22f15c0a5 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 27 Oct 2021 19:18:20 +1300 >Subject: [PATCH 594/686] CVE-2020-25722 pytest: Raise an error when adding a > dynamic test that would overwrite an existing test > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/__init__.py | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py >index 71295c7c403..d5be84ea297 100644 >--- a/python/samba/tests/__init__.py >+++ b/python/samba/tests/__init__.py >@@ -101,7 +101,10 @@ class TestCase(unittest.TestCase): > def fn(self): > getattr(self, "_%s_with_args" % fnname)(*args) > fn.__doc__ = doc >- setattr(cls, "%s_%s" % (fnname, suffix), fn) >+ attr = "%s_%s" % (fnname, suffix) >+ if hasattr(cls, attr): >+ raise RuntimeError(f"Dynamic test {attr} already exists!") >+ setattr(cls, attr, fn) > > @classmethod > def setUpDynamicTestCases(cls): >-- >2.25.1 > > >From ab1abcfd0763bf6eedbdbb7009d0e674e25e2c4d Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 12 Jul 2021 12:32:12 +0200 >Subject: [PATCH 595/686] CVE-2020-25719 mit-samba: Make ks_get_principal() > internally public > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/kdc/mit-kdb/kdb_samba.h | 5 +++++ > source4/kdc/mit-kdb/kdb_samba_principals.c | 8 ++++---- > 2 files changed, 9 insertions(+), 4 deletions(-) > >diff --git a/source4/kdc/mit-kdb/kdb_samba.h b/source4/kdc/mit-kdb/kdb_samba.h >index b9c571f26cb..ea414aad815 100644 >--- a/source4/kdc/mit-kdb/kdb_samba.h >+++ b/source4/kdc/mit-kdb/kdb_samba.h >@@ -48,6 +48,11 @@ > > struct mit_samba_context *ks_get_context(krb5_context kcontext); > >+krb5_error_code ks_get_principal(krb5_context context, >+ krb5_const_principal principal, >+ unsigned int kflags, >+ krb5_db_entry **kentry); >+ > bool ks_data_eq_string(krb5_data d, const char *s); > > krb5_data ks_make_data(void *data, unsigned int len); >diff --git a/source4/kdc/mit-kdb/kdb_samba_principals.c b/source4/kdc/mit-kdb/kdb_samba_principals.c >index 8b67436dc47..79219e5a274 100644 >--- a/source4/kdc/mit-kdb/kdb_samba_principals.c >+++ b/source4/kdc/mit-kdb/kdb_samba_principals.c >@@ -33,10 +33,10 @@ > #define ADMIN_LIFETIME 60*60*3 /* 3 hours */ > #define CHANGEPW_LIFETIME 60*5 /* 5 minutes */ > >-static krb5_error_code ks_get_principal(krb5_context context, >- krb5_const_principal principal, >- unsigned int kflags, >- krb5_db_entry **kentry) >+krb5_error_code ks_get_principal(krb5_context context, >+ krb5_const_principal principal, >+ unsigned int kflags, >+ krb5_db_entry **kentry) > { > struct mit_samba_context *mit_ctx; > krb5_error_code code; >-- >2.25.1 > > >From 7ad161840785928ecc783548bdcfea0654dc8c66 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Wed, 14 Jul 2021 14:51:34 +0200 >Subject: [PATCH 596/686] CVE-2020-25719 mit-samba: Add ks_free_principal() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >[abartlet@samba.org As submitted in patch to Samba bugzilla > to address this issue as https://attachments.samba.org/attachment.cgi?id=16724 > on overall bug https://bugzilla.samba.org/show_bug.cgi?id=14725] > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > source4/kdc/mit-kdb/kdb_samba.h | 2 + > source4/kdc/mit-kdb/kdb_samba_principals.c | 52 ++++++++++++++++++++++ > 2 files changed, 54 insertions(+) > >diff --git a/source4/kdc/mit-kdb/kdb_samba.h b/source4/kdc/mit-kdb/kdb_samba.h >index ea414aad815..85579cad2c3 100644 >--- a/source4/kdc/mit-kdb/kdb_samba.h >+++ b/source4/kdc/mit-kdb/kdb_samba.h >@@ -53,6 +53,8 @@ krb5_error_code ks_get_principal(krb5_context context, > unsigned int kflags, > krb5_db_entry **kentry); > >+void ks_free_principal(krb5_context context, krb5_db_entry *entry); >+ > bool ks_data_eq_string(krb5_data d, const char *s); > > krb5_data ks_make_data(void *data, unsigned int len); >diff --git a/source4/kdc/mit-kdb/kdb_samba_principals.c b/source4/kdc/mit-kdb/kdb_samba_principals.c >index 79219e5a274..cc67c2392be 100644 >--- a/source4/kdc/mit-kdb/kdb_samba_principals.c >+++ b/source4/kdc/mit-kdb/kdb_samba_principals.c >@@ -59,6 +59,58 @@ cleanup: > return code; > } > >+static void ks_free_principal_e_data(krb5_context context, krb5_octet *e_data) >+{ >+ struct samba_kdc_entry *skdc_entry; >+ >+ skdc_entry = talloc_get_type_abort(e_data, >+ struct samba_kdc_entry); >+ talloc_set_destructor(skdc_entry, NULL); >+ TALLOC_FREE(skdc_entry); >+} >+ >+void ks_free_principal(krb5_context context, krb5_db_entry *entry) >+{ >+ krb5_tl_data *tl_data_next = NULL; >+ krb5_tl_data *tl_data = NULL; >+ size_t i, j; >+ >+ if (entry != NULL) { >+ krb5_free_principal(context, entry->princ); >+ >+ for (tl_data = entry->tl_data; tl_data; tl_data = tl_data_next) { >+ tl_data_next = tl_data->tl_data_next; >+ if (tl_data->tl_data_contents != NULL) { >+ free(tl_data->tl_data_contents); >+ } >+ free(tl_data); >+ } >+ >+ if (entry->key_data != NULL) { >+ for (i = 0; i < entry->n_key_data; i++) { >+ for (j = 0; j < entry->key_data[i].key_data_ver; j++) { >+ if (entry->key_data[i].key_data_length[j] != 0) { >+ if (entry->key_data[i].key_data_contents[j] != NULL) { >+ memset(entry->key_data[i].key_data_contents[j], 0, entry->key_data[i].key_data_length[j]); >+ free(entry->key_data[i].key_data_contents[j]); >+ } >+ } >+ entry->key_data[i].key_data_contents[j] = NULL; >+ entry->key_data[i].key_data_length[j] = 0; >+ entry->key_data[i].key_data_type[j] = 0; >+ } >+ } >+ free(entry->key_data); >+ } >+ >+ if (entry->e_data) { >+ ks_free_principal_e_data(context, entry->e_data); >+ } >+ >+ free(entry); >+ } >+} >+ > static krb5_boolean ks_is_master_key_principal(krb5_context context, > krb5_const_principal princ) > { >-- >2.25.1 > > >From 8f02682ff14d017269caf1a52eaa80547b189fb4 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 12 Jul 2021 11:20:29 +0200 >Subject: [PATCH 597/686] CVE-2020-25719 mit-samba: If we use client_princ, > always lookup the db entry > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org backported due to support for MIT KDB < 10 > in Samba 4.14] > >[jsutton@samba.org Adapted to fix conflicts] >--- > source4/kdc/mit-kdb/kdb_samba_policies.c | 78 ++++++++++++++++++++++-- > 1 file changed, 73 insertions(+), 5 deletions(-) > >diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c >index fc80329f221..237f4a94132 100644 >--- a/source4/kdc/mit-kdb/kdb_samba_policies.c >+++ b/source4/kdc/mit-kdb/kdb_samba_policies.c >@@ -301,7 +301,8 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, > krb5_authdata **tgt_auth_data, > krb5_authdata ***signed_auth_data) > { >- krb5_const_principal ks_client_princ; >+ krb5_const_principal ks_client_princ = NULL; >+ krb5_db_entry *client_entry = NULL; > krb5_authdata **authdata = NULL; > krb5_boolean is_as_req; > krb5_error_code code; >@@ -317,8 +318,72 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, > > is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0); > >+ /* >+ * When using s4u2proxy client_princ actually refers to the proxied user >+ * while client->princ to the proxy service asking for the TGS on behalf >+ * of the proxied user. So always use client_princ in preference. >+ * >+ * Note that when client principal is not NULL, client entry might be >+ * NULL for cross-realm case, so we need to make sure to not >+ * dereference NULL pointer here. >+ */ >+ if (client_princ != NULL) { >+ ks_client_princ = client_princ; >+ if (!is_as_req) { >+ krb5_boolean is_equal = false; >+ >+ if (client != NULL && client->princ != NULL) { >+ is_equal = >+ krb5_principal_compare(context, >+ client_princ, >+ client->princ); >+ } >+ >+ /* >+ * When client principal is the same as supplied client >+ * entry, don't fetch it. >+ */ >+ if (!is_equal) { >+ code = ks_get_principal(context, >+ ks_client_princ, >+ 0, >+ &client_entry); >+ if (code != 0) { >+ char *client_name = NULL; >+ >+ (void)krb5_unparse_name(context, >+ ks_client_princ, >+ &client_name); >+ >+ DBG_DEBUG("We didn't find the client " >+ "principal [%s] in our " >+ "database.\n", >+ client_name); >+ SAFE_FREE(client_name); >+ >+ /* >+ * If we didn't find client_princ in our >+ * database it might be from another >+ * realm. >+ */ >+ client_entry = NULL; >+ } >+ } >+ } >+ } else { >+ if (client == NULL) { >+ *signed_auth_data = NULL; >+ return 0; >+ } >+ ks_client_princ = client->princ; >+ } >+ >+ if (client_entry == NULL) { >+ client_entry = client; >+ } >+ > if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) { >- code = ks_get_pac(context, client, client_key, &pac); >+ code = ks_get_pac(context, client_entry, client_key, &pac); > if (code != 0) { > goto done; > } >@@ -328,7 +393,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, > code = ks_verify_pac(context, > flags, > ks_client_princ, >- client, >+ client_entry, > server, > krbtgt, > server_key, >@@ -341,9 +406,9 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, > } > } > >- if (pac == NULL && client != NULL) { >+ if (pac == NULL) { > >- code = ks_get_pac(context, client, client_key, &pac); >+ code = ks_get_pac(context, client_entry, client_key, &pac); > if (code != 0) { > goto done; > } >@@ -388,6 +453,9 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, > code = 0; > > done: >+ if (client_entry != NULL && client_entry != client) { >+ ks_free_principal(context, client_entry); >+ } > krb5_pac_free(context, pac); > krb5_free_authdata(context, authdata); > >-- >2.25.1 > > >From e738194c18e1d405fbb43701ade978ed708cb99a Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 12 Jul 2021 13:12:00 +0200 >Subject: [PATCH 598/686] CVE-2020-25719 mit-samba: Add > mit_samba_princ_needs_pac() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/kdc/mit_samba.c | 8 ++++++++ > source4/kdc/mit_samba.h | 2 ++ > 2 files changed, 10 insertions(+) > >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index 689e14e1c38..6aed3134544 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -1153,3 +1153,11 @@ void mit_samba_update_bad_password_count(krb5_db_entry *db_entry) > p->msg, > ldb_get_default_basedn(p->kdc_db_ctx->samdb)); > } >+ >+bool mit_samba_princ_needs_pac(krb5_db_entry *db_entry) >+{ >+ struct samba_kdc_entry *skdc_entry = >+ talloc_get_type_abort(db_entry->e_data, struct samba_kdc_entry); >+ >+ return samba_princ_needs_pac(skdc_entry); >+} >diff --git a/source4/kdc/mit_samba.h b/source4/kdc/mit_samba.h >index ba824557bd5..636c77ec97c 100644 >--- a/source4/kdc/mit_samba.h >+++ b/source4/kdc/mit_samba.h >@@ -85,4 +85,6 @@ void mit_samba_zero_bad_password_count(krb5_db_entry *db_entry); > > void mit_samba_update_bad_password_count(krb5_db_entry *db_entry); > >+bool mit_samba_princ_needs_pac(krb5_db_entry *db_entry); >+ > #endif /* _MIT_SAMBA_H */ >-- >2.25.1 > > >From 7873c1da64670590eb6b5759e8bdb77f410bfbf0 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 12 Jul 2021 13:58:57 +0200 >Subject: [PATCH 599/686] CVE-2020-25719 mit-samba: Handle no DB entry in > mit_samba_get_pac() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/kdc/mit_samba.c | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index 6aed3134544..be6ea83c042 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -437,6 +437,10 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, > &upn_dns_info_blob); > if (!NT_STATUS_IS_OK(nt_status)) { > talloc_free(tmp_ctx); >+ if (NT_STATUS_EQUAL(nt_status, >+ NT_STATUS_OBJECT_NAME_NOT_FOUND)) { >+ return ENOENT; >+ } > return EINVAL; > } > >-- >2.25.1 > > >From 45af5ec3a65436fd2a4f057e6b177a77846dc554 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 12 Jul 2021 14:00:19 +0200 >Subject: [PATCH 600/686] CVE-2020-25719 mit-samba: Rework PAC handling in > kdb_samba_db_sign_auth_data() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail_mit_kdc | 6 +- > source4/kdc/mit-kdb/kdb_samba_policies.c | 116 ++++++++++++++++++----- > 2 files changed, 93 insertions(+), 29 deletions(-) > >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index abaf316b3d8..7788ae60ad9 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -278,12 +278,13 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > # > # KDC TGS PAC tests > # >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_client_no_auth_data_required\(ad_dc\) >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_no_pac_client_no_auth_data_required\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_no_pac_service_no_auth_data_required\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_client_no_auth_data_required\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_service_no_auth_data_required\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_request_no_pac\(ad_dc\) >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required\(ad_dc\) > # > # MIT currently fails the following MS-KILE tests. > # >@@ -501,11 +502,9 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > # > # PAC request tests > # >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_pac_request_false > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_false > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_none > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_true >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_request_false > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_false > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_none > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_true >@@ -515,7 +514,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_false > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_none > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_pac_request_false > # > # PAC requester SID tests > # >diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c >index 237f4a94132..5440cf66f41 100644 >--- a/source4/kdc/mit-kdb/kdb_samba_policies.c >+++ b/source4/kdc/mit-kdb/kdb_samba_policies.c >@@ -4,7 +4,7 @@ > Samba KDB plugin for MIT Kerberos > > Copyright (c) 2010 Simo Sorce <idra@samba.org>. >- Copyright (c) 2014 Andreas Schneider <asn@samba.org> >+ Copyright (c) 2014-2021 Andreas Schneider <asn@samba.org> > > 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 >@@ -303,11 +303,16 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, > { > krb5_const_principal ks_client_princ = NULL; > krb5_db_entry *client_entry = NULL; >+ krb5_authdata **pac_auth_data = NULL; > krb5_authdata **authdata = NULL; > krb5_boolean is_as_req; > krb5_error_code code; > krb5_pac pac = NULL; > krb5_data pac_data; >+ bool with_pac = false; >+ bool generate_pac = false; >+ char *client_name = NULL; >+ > > /* Prefer canonicalised name from client entry */ > if (client != NULL) { >@@ -349,8 +354,6 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, > 0, > &client_entry); > if (code != 0) { >- char *client_name = NULL; >- > (void)krb5_unparse_name(context, > ks_client_princ, > &client_name); >@@ -382,43 +385,105 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, > client_entry = client; > } > >- if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) { >+ if (is_as_req) { >+ with_pac = mit_samba_princ_needs_pac(client_entry); >+ } else { >+ with_pac = mit_samba_princ_needs_pac(server); >+ } >+ >+ code = krb5_unparse_name(context, >+ client_princ, >+ &client_name); >+ if (code != 0) { >+ goto done; >+ } >+ >+ if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC) != 0) { >+ generate_pac = true; >+ } >+ >+ DBG_DEBUG("*** Sign data for client principal: %s [%s %s%s]\n", >+ client_name, >+ is_as_req ? "AS-REQ" : "TGS_REQ", >+ with_pac ? is_as_req ? "WITH_PAC" : "FIND_PAC" : "NO_PAC", >+ generate_pac ? " GENERATE_PAC" : ""); >+ >+ /* >+ * Generate PAC for the AS-REQ or check or generate one for the TGS if >+ * needed. >+ */ >+ if (with_pac && generate_pac) { >+ DBG_DEBUG("Generate PAC for AS-REQ [%s]\n", client_name); > code = ks_get_pac(context, client_entry, client_key, &pac); > if (code != 0) { > goto done; > } >- } >- >- if (!is_as_req) { >- code = ks_verify_pac(context, >- flags, >- ks_client_princ, >- client_entry, >- server, >- krbtgt, >- server_key, >- krbtgt_key, >- authtime, >- tgt_auth_data, >- &pac); >+ } else if (with_pac && !is_as_req) { >+ /* >+ * Find the PAC in the TGS, if one exists. >+ */ >+ code = krb5_find_authdata(context, >+ tgt_auth_data, >+ NULL, >+ KRB5_AUTHDATA_WIN2K_PAC, >+ &pac_auth_data); > if (code != 0) { >+ DBG_ERR("krb5_find_authdata failed: %d\n", code); > goto done; > } >- } >+ DBG_DEBUG("Found PAC data for TGS-REQ [%s]\n", client_name); > >- if (pac == NULL) { >+ if (pac_auth_data != NULL && pac_auth_data[0] != NULL) { >+ if (pac_auth_data[1] != NULL) { >+ DBG_ERR("Invalid PAC data!\n"); >+ code = KRB5KDC_ERR_BADOPTION; >+ goto done; >+ } > >- code = ks_get_pac(context, client_entry, client_key, &pac); >- if (code != 0) { >- goto done; >+ DBG_DEBUG("Verify PAC for TGS [%s]\n", >+ client_name); >+ >+ code = ks_verify_pac(context, >+ flags, >+ ks_client_princ, >+ client_entry, >+ server, >+ krbtgt, >+ server_key, >+ krbtgt_key, >+ authtime, >+ tgt_auth_data, >+ &pac); >+ if (code != 0) { >+ goto done; >+ } >+ } else { >+ if (flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) { >+ DBG_DEBUG("Generate PAC for constrained" >+ "delegation TGS [%s]\n", >+ client_name); >+ >+ code = ks_get_pac(context, >+ client_entry, >+ client_key, >+ &pac); >+ if (code != 0 && code != ENOENT) { >+ goto done; >+ } >+ } > } > } > > if (pac == NULL) { >- code = KRB5_KDB_DBTYPE_NOSUP; >+ DBG_DEBUG("No PAC data - we're done [%s]\n", client_name); >+ *signed_auth_data = NULL; >+ code = 0; > goto done; > } > >+ DBG_DEBUG("Signing PAC for %s [%s]\n", >+ is_as_req ? "AS-REQ" : "TGS-REQ", >+ client_name); > code = krb5_pac_sign(context, pac, authtime, ks_client_princ, > server_key, krbtgt_key, &pac_data); > if (code != 0) { >@@ -456,8 +521,9 @@ done: > if (client_entry != NULL && client_entry != client) { > ks_free_principal(context, client_entry); > } >- krb5_pac_free(context, pac); >+ SAFE_FREE(client_name); > krb5_free_authdata(context, authdata); >+ krb5_pac_free(context, pac); > > return code; > } >-- >2.25.1 > > >From 34e7de6028da9c799f487ca8ab931dcf85a62937 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 9 Aug 2021 17:22:52 +0200 >Subject: [PATCH 601/686] CVE-2020-25719 mit_samba: The samba_princ_needs_pac > check should be on the server entry > >This does the same check as the hdb plugin now. The client check is already >done earlier. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/kdc/mit_samba.c | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index be6ea83c042..d11e1640ee9 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -486,6 +486,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > DATA_BLOB *deleg_blob = NULL; > struct samba_kdc_entry *client_skdc_entry = NULL; > struct samba_kdc_entry *krbtgt_skdc_entry = NULL; >+ struct samba_kdc_entry *server_skdc_entry = NULL; > bool is_in_db = false; > bool is_untrusted = false; > size_t num_types = 0; >@@ -499,6 +500,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > ssize_t srv_checksum_idx = -1; > ssize_t kdc_checksum_idx = -1; > krb5_pac new_pac = NULL; >+ bool ok; > > if (client != NULL) { > client_skdc_entry = >@@ -510,6 +512,16 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > return EINVAL; > } > >+ server_skdc_entry = >+ talloc_get_type_abort(server->e_data, >+ struct samba_kdc_entry); >+ >+ /* The account may be set not to want the PAC */ >+ ok = samba_princ_needs_pac(server_skdc_entry); >+ if (!ok) { >+ return EINVAL; >+ } >+ > if (krbtgt == NULL) { > return EINVAL; > } >-- >2.25.1 > > >From 7fd71be6ce73f657cdbd7131a95952450492f983 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 9 Aug 2021 17:25:53 +0200 >Subject: [PATCH 602/686] CVE-2020-25719 mit_samba: Create the talloc context > earlier > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/kdc/mit_samba.c | 20 ++++++++++++-------- > 1 file changed, 12 insertions(+), 8 deletions(-) > >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index d11e1640ee9..d0e68ec8ea4 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -502,6 +502,12 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > krb5_pac new_pac = NULL; > bool ok; > >+ /* Create a memory context early so code can use talloc_stackframe() */ >+ tmp_ctx = talloc_named(ctx, 0, "mit_samba_reget_pac context"); >+ if (tmp_ctx == NULL) { >+ return ENOMEM; >+ } >+ > if (client != NULL) { > client_skdc_entry = > talloc_get_type_abort(client->e_data, >@@ -509,7 +515,8 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > } > > if (server == NULL) { >- return EINVAL; >+ code = EINVAL; >+ goto done; > } > > server_skdc_entry = >@@ -519,21 +526,18 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > /* The account may be set not to want the PAC */ > ok = samba_princ_needs_pac(server_skdc_entry); > if (!ok) { >- return EINVAL; >+ code = EINVAL; >+ goto done; > } > > if (krbtgt == NULL) { >- return EINVAL; >+ code = EINVAL; >+ goto done; > } > krbtgt_skdc_entry = > talloc_get_type_abort(krbtgt->e_data, > struct samba_kdc_entry); > >- tmp_ctx = talloc_named(ctx, 0, "mit_samba_reget_pac context"); >- if (tmp_ctx == NULL) { >- return ENOMEM; >- } >- > code = samba_krbtgt_is_in_db(krbtgt_skdc_entry, > &is_in_db, > &is_untrusted); >-- >2.25.1 > > >From de27145bc2f5d58dc888785269869e4afc982147 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Fri, 6 Aug 2021 12:03:49 +0200 >Subject: [PATCH 603/686] CVE-2020-25719 s4:kdc: Remove trailing spaces in > pac-glue.c > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/kdc/pac-glue.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index 34518e14233..b0d6959d199 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -575,12 +575,12 @@ int samba_krbtgt_is_in_db(struct samba_kdc_entry *p, > if (!mem_ctx) { > return ENOMEM; > } >- >+ > trust_direction = ldb_msg_find_attr_as_int(p->msg, "trustDirection", 0); > > if (trust_direction != 0) { > /* Domain trust - we cannot check the sig, but we trust it for a correct PAC >- >+ > This is exactly where we should flag for SID > validation when we do inter-foreest trusts > */ >@@ -768,7 +768,7 @@ NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > return nt_status; > } > >- nt_status = samba_get_logon_info_pac_blob(mem_ctx, >+ nt_status = samba_get_logon_info_pac_blob(mem_ctx, > user_info_dc, pac_blob); > > return nt_status; >-- >2.25.1 > > >From e25215a45fdb65a539a66a8f15973e56dff55cb4 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 9 Aug 2021 17:19:45 +0200 >Subject: [PATCH 604/686] CVE-2020-25719 s4:kdc: Add > samba_kdc_validate_pac_blob() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/kdc/pac-glue.c | 56 ++++++++++++++++++++++++++++++++++++++++++ > source4/kdc/pac-glue.h | 5 ++++ > 2 files changed, 61 insertions(+) > >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index b0d6959d199..94b047d0640 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -918,3 +918,59 @@ NTSTATUS samba_kdc_check_client_access(struct samba_kdc_entry *kdc_entry, > talloc_free(tmp_ctx); > return nt_status; > } >+ >+/* Does a parse and SID check, but no crypto. */ >+krb5_error_code samba_kdc_validate_pac_blob( >+ krb5_context context, >+ struct samba_kdc_entry *client_skdc_entry, >+ const krb5_pac pac) >+{ >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct auth_user_info_dc *pac_user_info = NULL; >+ struct dom_sid *client_sid = NULL; >+ struct dom_sid pac_sid; >+ krb5_error_code code; >+ bool ok; >+ >+ code = kerberos_pac_to_user_info_dc(frame, >+ pac, >+ context, >+ &pac_user_info, >+ NULL, >+ NULL); >+ if (code != 0) { >+ goto out; >+ } >+ >+ if (pac_user_info->num_sids == 0) { >+ code = EINVAL; >+ goto out; >+ } >+ >+ pac_sid = pac_user_info->sids[0]; >+ client_sid = samdb_result_dom_sid(frame, >+ client_skdc_entry->msg, >+ "objectSid"); >+ >+ ok = dom_sid_equal(&pac_sid, client_sid); >+ if (!ok) { >+ struct dom_sid_buf buf1; >+ struct dom_sid_buf buf2; >+ >+ DBG_ERR("SID mismatch between PAC and looked up client: " >+ "PAC[%s] != CLI[%s]\n", >+ dom_sid_str_buf(&pac_sid, &buf1), >+ dom_sid_str_buf(client_sid, &buf2)); >+#if defined(KRB5KDC_ERR_CLIENT_NAME_MISMATCH) /* MIT */ >+ code = KRB5KDC_ERR_CLIENT_NAME_MISMATCH; >+#else /* Heimdal (where this is an enum) */ >+ code = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH; >+#endif >+ goto out; >+ } >+ >+ code = 0; >+out: >+ TALLOC_FREE(frame); >+ return code; >+} >diff --git a/source4/kdc/pac-glue.h b/source4/kdc/pac-glue.h >index 7b51b0389f5..e83446647b3 100644 >--- a/source4/kdc/pac-glue.h >+++ b/source4/kdc/pac-glue.h >@@ -69,3 +69,8 @@ NTSTATUS samba_kdc_check_client_access(struct samba_kdc_entry *kdc_entry, > const char *client_name, > const char *workstation, > bool password_change); >+ >+krb5_error_code samba_kdc_validate_pac_blob( >+ krb5_context context, >+ struct samba_kdc_entry *client_skdc_entry, >+ const krb5_pac pac); >-- >2.25.1 > > >From 83cb7d0a0ad141ad462b295cbaefbf5b06154182 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 9 Aug 2021 17:20:31 +0200 >Subject: [PATCH 605/686] CVE-2020-25719 s4:kdc: Check if the pac is valid > before updating it > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail_heimdal_kdc | 31 ++++--------------------------- > selftest/knownfail_mit_kdc | 10 ++-------- > source4/kdc/mit_samba.c | 9 +++++++++ > source4/kdc/wdc-samba4.c | 17 +++++++++++++++++ > 4 files changed, 32 insertions(+), 35 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 850346940ad..75ca4bba8c4 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -271,13 +271,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_service_no_auth_data_required > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_request_no_pac > # >-# Alias tests >-# >-^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_delete >-^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_rename >-^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_delete >-^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_rename >-# > # KDC TGT tests > # > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac >@@ -288,10 +281,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_no_partial_secrets > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_revealed >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_allowed_denied >@@ -300,10 +289,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_no_partial_secrets > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_revealed >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied >@@ -312,10 +297,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_partial_secrets > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_revealed >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_mac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_mac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_user >@@ -354,10 +335,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_no_partial_secrets > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_nonexisting > # > # PAC attributes tests > # >@@ -392,8 +369,8 @@ > # PAC requester SID tests > # > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_as_requester_sid >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid >@@ -402,8 +379,8 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_renew > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting > # >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 7788ae60ad9..d01b792eb94 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -407,8 +407,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_req >@@ -434,8 +432,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_mac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_mac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_user >@@ -475,8 +471,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_nonexisting > # > # PAC attributes tests > # >@@ -518,8 +512,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > # PAC requester SID tests > # > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_as_requester_sid >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_existing >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index d0e68ec8ea4..592f6a3bac4 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -512,6 +512,15 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > client_skdc_entry = > talloc_get_type_abort(client->e_data, > struct samba_kdc_entry); >+ >+ /* >+ * Check the objectSID of the client and pac data are the same. >+ * Does a parse and SID check, but no crypto. >+ */ >+ code = samba_kdc_validate_pac_blob(context, client_skdc_entry, *pac); >+ if (code != 0) { >+ goto done; >+ } > } > > if (server == NULL) { >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index ac9d7d51733..ed6e9fb9b63 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -137,6 +137,23 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > return ENOMEM; > } > >+ if (client != NULL) { >+ struct samba_kdc_entry *client_skdc_entry = NULL; >+ >+ client_skdc_entry = talloc_get_type_abort(client->ctx, >+ struct samba_kdc_entry); >+ >+ /* >+ * Check the objectSID of the client and pac data are the same. >+ * Does a parse and SID check, but no crypto. >+ */ >+ ret = samba_kdc_validate_pac_blob(context, client_skdc_entry, *pac); >+ if (ret != 0) { >+ talloc_free(mem_ctx); >+ return ret; >+ } >+ } >+ > /* If the krbtgt was generated by an RODC, and we are not that > * RODC, then we need to regenerate the PAC - we can't trust > * it */ >-- >2.25.1 > > >From de9fafc7d364b8164c2c525a05a157aaa5f1f424 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:41:31 +1300 >Subject: [PATCH 606/686] CVE-2020-25719 s4:kdc: Add KDC support for > PAC_ATTRIBUTES_INFO PAC buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail_heimdal_kdc | 23 ----- > source4/heimdal/kdc/kerberos5.c | 23 +++-- > source4/heimdal/kdc/krb5tgs.c | 2 +- > source4/heimdal/kdc/windc.c | 7 +- > source4/heimdal/kdc/windc_plugin.h | 2 + > source4/kdc/mit_samba.c | 7 +- > source4/kdc/pac-glue.c | 147 ++++++++++++++++++++++++++++- > source4/kdc/pac-glue.h | 10 +- > source4/kdc/wdc-samba4.c | 45 ++++++++- > 9 files changed, 223 insertions(+), 43 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 75ca4bba8c4..0f03e17c242 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -265,11 +265,9 @@ > # > # KDC TGS PAC tests > # >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_no_pac_service_no_auth_data_required > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_client_no_auth_data_required > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_service_no_auth_data_required >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_request_no_pac > # > # KDC TGT tests > # >@@ -336,27 +334,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed > # >-# PAC attributes tests >-# >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_false >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_false >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_none >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_true >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_false >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_none >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_true >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_none >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_false >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_none >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_true >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_false >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_none >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_true >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_true >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_false >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true >-# > # PAC request tests > # > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_false >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index a131f1af08e..c1d4cb1d4aa 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -913,27 +913,30 @@ _kdc_check_addresses(krb5_context context, > */ > > static krb5_boolean >-send_pac_p(krb5_context context, KDC_REQ *req) >+send_pac_p(krb5_context context, KDC_REQ *req, krb5_boolean *pac_request) > { > krb5_error_code ret; > PA_PAC_REQUEST pacreq; > const PA_DATA *pa; > int i = 0; > >+ *pac_request = TRUE; >+ > pa = _kdc_find_padata(req, &i, KRB5_PADATA_PA_PAC_REQUEST); > if (pa == NULL) >- return TRUE; >+ return FALSE; > > ret = decode_PA_PAC_REQUEST(pa->padata_value.data, > pa->padata_value.length, > &pacreq, > NULL); > if (ret) >- return TRUE; >+ return FALSE; > i = pacreq.include_pac; > free_PA_PAC_REQUEST(&pacreq); >- if (i == 0) >- return FALSE; >+ if (i == 0) { >+ *pac_request = FALSE; >+ } > return TRUE; > } > >@@ -1757,13 +1760,19 @@ _kdc_as_rep(krb5_context context, > } > > /* Add the PAC */ >- if (send_pac_p(context, req)) { >+ { > krb5_pac p = NULL; > krb5_data data; > uint16_t rodc_id; > krb5_principal client_pac; >+ krb5_boolean sent_pac_request; >+ krb5_boolean pac_request; >+ >+ sent_pac_request = send_pac_p(context, req, &pac_request); > >- ret = _kdc_pac_generate(context, client, pk_reply_key, &p); >+ ret = _kdc_pac_generate(context, client, pk_reply_key, >+ sent_pac_request ? &pac_request : NULL, >+ &p); > if (ret) { > kdc_log(context, config, 0, "PAC generation failed for -- %s", > client_name); >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index b0c873a4ffb..cff35fc2a65 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -1739,7 +1739,7 @@ server_lookup: > if (mspac) { > krb5_pac_free(context, mspac); > mspac = NULL; >- ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, &mspac); >+ ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, NULL, &mspac); > if (ret) { > kdc_log(context, config, 0, "PAC generation failed for -- %s", > tpn); >diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c >index 43dc89e2bc0..93b973f576b 100644 >--- a/source4/heimdal/kdc/windc.c >+++ b/source4/heimdal/kdc/windc.c >@@ -74,6 +74,7 @@ krb5_error_code > _kdc_pac_generate(krb5_context context, > hdb_entry_ex *client, > const krb5_keyblock *pk_reply_key, >+ const krb5_boolean *pac_request, > krb5_pac *pac) > { > *pac = NULL; >@@ -87,8 +88,10 @@ _kdc_pac_generate(krb5_context context, > > if (windcft->pac_pk_generate != NULL && pk_reply_key != NULL) > return (windcft->pac_pk_generate)(windcctx, context, >- client, pk_reply_key, pac); >- return (windcft->pac_generate)(windcctx, context, client, pac); >+ client, pk_reply_key, >+ pac_request, pac); >+ return (windcft->pac_generate)(windcctx, context, client, >+ pac_request, pac); > } > > krb5_error_code >diff --git a/source4/heimdal/kdc/windc_plugin.h b/source4/heimdal/kdc/windc_plugin.h >index dda258da3d1..c7f2bcb5ed9 100644 >--- a/source4/heimdal/kdc/windc_plugin.h >+++ b/source4/heimdal/kdc/windc_plugin.h >@@ -55,12 +55,14 @@ struct hdb_entry_ex; > typedef krb5_error_code > (*krb5plugin_windc_pac_generate)(void *, krb5_context, > struct hdb_entry_ex *, /* client */ >+ const krb5_boolean *, /* pac_request */ > krb5_pac *); > > typedef krb5_error_code > (*krb5plugin_windc_pac_pk_generate)(void *, krb5_context, > struct hdb_entry_ex *, /* client */ > const krb5_keyblock *, /* pk_replykey */ >+ const krb5_boolean *, /* pac_request */ > krb5_pac *); > > typedef krb5_error_code >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index 592f6a3bac4..69cdbfba929 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -434,7 +434,8 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, > skdc_entry, > &logon_info_blob, > cred_ndr_ptr, >- &upn_dns_info_blob); >+ &upn_dns_info_blob, >+ NULL, NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > talloc_free(tmp_ctx); > if (NT_STATUS_EQUAL(nt_status, >@@ -462,6 +463,7 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, > pcred_blob, > upn_dns_info_blob, > NULL, >+ NULL, > pac); > > talloc_free(tmp_ctx); >@@ -564,7 +566,8 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > client_skdc_entry, > &pac_blob, > NULL, >- &upn_blob); >+ &upn_blob, >+ NULL, NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > code = EINVAL; > goto done; >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index 94b047d0640..8aa0ae33f73 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -113,6 +113,43 @@ NTSTATUS samba_get_upn_info_pac_blob(TALLOC_CTX *mem_ctx, > return NT_STATUS_OK; > } > >+static >+NTSTATUS samba_get_pac_attrs_blob(TALLOC_CTX *mem_ctx, >+ const krb5_boolean *pac_request, >+ DATA_BLOB *pac_attrs_data) >+{ >+ union PAC_INFO pac_attrs; >+ enum ndr_err_code ndr_err; >+ NTSTATUS nt_status; >+ >+ ZERO_STRUCT(pac_attrs); >+ >+ *pac_attrs_data = data_blob_null; >+ >+ /* Set the length of the flags in bits. */ >+ pac_attrs.attributes_info.flags_length = 2; >+ >+ if (pac_request == NULL) { >+ pac_attrs.attributes_info.flags >+ |= PAC_ATTRIBUTE_FLAG_PAC_WAS_GIVEN_IMPLICITLY; >+ } else if (*pac_request) { >+ pac_attrs.attributes_info.flags >+ |= PAC_ATTRIBUTE_FLAG_PAC_WAS_REQUESTED; >+ } >+ >+ ndr_err = ndr_push_union_blob(pac_attrs_data, mem_ctx, &pac_attrs, >+ PAC_TYPE_ATTRIBUTES_INFO, >+ (ndr_push_flags_fn_t)ndr_push_PAC_INFO); >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >+ nt_status = ndr_map_error2ntstatus(ndr_err); >+ DEBUG(1, ("PAC ATTRIBUTES_INFO (presig) push failed: %s\n", >+ nt_errstr(nt_status))); >+ return nt_status; >+ } >+ >+ return NT_STATUS_OK; >+} >+ > static > NTSTATUS samba_get_cred_info_ndr_blob(TALLOC_CTX *mem_ctx, > const struct ldb_message *msg, >@@ -413,12 +450,14 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > const DATA_BLOB *logon_blob, > const DATA_BLOB *cred_blob, > const DATA_BLOB *upn_blob, >+ const DATA_BLOB *pac_attrs_blob, > const DATA_BLOB *deleg_blob, > krb5_pac *pac) > { > krb5_data logon_data; > krb5_data cred_data; > krb5_data upn_data; >+ krb5_data pac_attrs_data; > krb5_data deleg_data; > krb5_error_code ret; > #ifdef SAMBA4_USES_HEIMDAL >@@ -463,6 +502,19 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > } > } > >+ ZERO_STRUCT(pac_attrs_data); >+ if (pac_attrs_blob != NULL) { >+ ret = smb_krb5_copy_data_contents(&pac_attrs_data, >+ pac_attrs_blob->data, >+ pac_attrs_blob->length); >+ if (ret != 0) { >+ smb_krb5_free_data_contents(context, &logon_data); >+ smb_krb5_free_data_contents(context, &cred_data); >+ smb_krb5_free_data_contents(context, &upn_data); >+ return ret; >+ } >+ } >+ > ZERO_STRUCT(deleg_data); > if (deleg_blob != NULL) { > ret = smb_krb5_copy_data_contents(&deleg_data, >@@ -472,6 +524,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > smb_krb5_free_data_contents(context, &logon_data); > smb_krb5_free_data_contents(context, &cred_data); > smb_krb5_free_data_contents(context, &upn_data); >+ smb_krb5_free_data_contents(context, &pac_attrs_data); > return ret; > } > } >@@ -481,6 +534,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > smb_krb5_free_data_contents(context, &logon_data); > smb_krb5_free_data_contents(context, &cred_data); > smb_krb5_free_data_contents(context, &upn_data); >+ smb_krb5_free_data_contents(context, &pac_attrs_data); > smb_krb5_free_data_contents(context, &deleg_data); > return ret; > } >@@ -488,8 +542,9 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > ret = krb5_pac_add_buffer(context, *pac, PAC_TYPE_LOGON_INFO, &logon_data); > smb_krb5_free_data_contents(context, &logon_data); > if (ret != 0) { >- smb_krb5_free_data_contents(context, &upn_data); > smb_krb5_free_data_contents(context, &cred_data); >+ smb_krb5_free_data_contents(context, &upn_data); >+ smb_krb5_free_data_contents(context, &pac_attrs_data); > smb_krb5_free_data_contents(context, &deleg_data); > return ret; > } >@@ -501,6 +556,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > smb_krb5_free_data_contents(context, &cred_data); > if (ret != 0) { > smb_krb5_free_data_contents(context, &upn_data); >+ smb_krb5_free_data_contents(context, &pac_attrs_data); > smb_krb5_free_data_contents(context, &deleg_data); > return ret; > } >@@ -519,6 +575,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > &null_data); > if (ret != 0) { > smb_krb5_free_data_contents(context, &upn_data); >+ smb_krb5_free_data_contents(context, &pac_attrs_data); > smb_krb5_free_data_contents(context, &deleg_data); > return ret; > } >@@ -529,6 +586,18 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > PAC_TYPE_UPN_DNS_INFO, > &upn_data); > smb_krb5_free_data_contents(context, &upn_data); >+ if (ret != 0) { >+ smb_krb5_free_data_contents(context, &pac_attrs_data); >+ smb_krb5_free_data_contents(context, &deleg_data); >+ return ret; >+ } >+ } >+ >+ if (pac_attrs_blob != NULL) { >+ ret = krb5_pac_add_buffer(context, *pac, >+ PAC_TYPE_ATTRIBUTES_INFO, >+ &pac_attrs_data); >+ smb_krb5_free_data_contents(context, &pac_attrs_data); > if (ret != 0) { > smb_krb5_free_data_contents(context, &deleg_data); > return ret; >@@ -562,6 +631,48 @@ bool samba_princ_needs_pac(struct samba_kdc_entry *skdc_entry) > return true; > } > >+int samba_client_requested_pac(krb5_context context, >+ krb5_pac *pac, >+ TALLOC_CTX *mem_ctx, >+ bool *requested_pac) >+{ >+ enum ndr_err_code ndr_err; >+ krb5_data k5pac_attrs_in; >+ DATA_BLOB pac_attrs_in; >+ union PAC_INFO pac_attrs; >+ int ret; >+ >+ *requested_pac = true; >+ >+ ret = krb5_pac_get_buffer(context, *pac, PAC_TYPE_ATTRIBUTES_INFO, >+ &k5pac_attrs_in); >+ if (ret != 0) { >+ return ret == ENOENT ? 0 : ret; >+ } >+ >+ pac_attrs_in = data_blob_const(k5pac_attrs_in.data, >+ k5pac_attrs_in.length); >+ >+ ndr_err = ndr_pull_union_blob(&pac_attrs_in, mem_ctx, &pac_attrs, >+ PAC_TYPE_ATTRIBUTES_INFO, >+ (ndr_pull_flags_fn_t)ndr_pull_PAC_INFO); >+ smb_krb5_free_data_contents(context, &k5pac_attrs_in); >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >+ NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err); >+ DEBUG(0,("can't parse the PAC ATTRIBUTES_INFO: %s\n", nt_errstr(nt_status))); >+ return EINVAL; >+ } >+ >+ if (pac_attrs.attributes_info.flags & (PAC_ATTRIBUTE_FLAG_PAC_WAS_GIVEN_IMPLICITLY >+ | PAC_ATTRIBUTE_FLAG_PAC_WAS_REQUESTED)) { >+ *requested_pac = true; >+ } else { >+ *requested_pac = false; >+ } >+ >+ return 0; >+} >+ > /* Was the krbtgt in this DB (ie, should we check the incoming signature) and was it an RODC */ > int samba_krbtgt_is_in_db(struct samba_kdc_entry *p, > bool *is_in_db, >@@ -637,12 +748,15 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > struct samba_kdc_entry *p, > DATA_BLOB **_logon_info_blob, > DATA_BLOB **_cred_ndr_blob, >- DATA_BLOB **_upn_info_blob) >+ DATA_BLOB **_upn_info_blob, >+ DATA_BLOB **_pac_attrs_blob, >+ const krb5_boolean *pac_request) > { > struct auth_user_info_dc *user_info_dc; > DATA_BLOB *logon_blob = NULL; > DATA_BLOB *cred_blob = NULL; > DATA_BLOB *upn_blob = NULL; >+ DATA_BLOB *pac_attrs_blob = NULL; > NTSTATUS nt_status; > > *_logon_info_blob = NULL; >@@ -650,6 +764,9 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > *_cred_ndr_blob = NULL; > } > *_upn_info_blob = NULL; >+ if (_pac_attrs_blob != NULL) { >+ *_pac_attrs_blob = NULL; >+ } > > logon_blob = talloc_zero(mem_ctx, DATA_BLOB); > if (logon_blob == NULL) { >@@ -668,6 +785,13 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > return NT_STATUS_NO_MEMORY; > } > >+ if (_pac_attrs_blob != NULL) { >+ pac_attrs_blob = talloc_zero(mem_ctx, DATA_BLOB); >+ if (pac_attrs_blob == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ } >+ > nt_status = authsam_make_user_info_dc(mem_ctx, p->kdc_db_ctx->samdb, > lpcfg_netbios_name(p->kdc_db_ctx->lp_ctx), > lpcfg_sam_name(p->kdc_db_ctx->lp_ctx), >@@ -712,12 +836,27 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > return nt_status; > } > >+ if (pac_attrs_blob != NULL) { >+ nt_status = samba_get_pac_attrs_blob(pac_attrs_blob, >+ pac_request, >+ pac_attrs_blob); >+ >+ if (!NT_STATUS_IS_OK(nt_status)) { >+ DEBUG(0, ("Building PAC ATTRIBUTES failed: %s\n", >+ nt_errstr(nt_status))); >+ return nt_status; >+ } >+ } >+ > TALLOC_FREE(user_info_dc); > *_logon_info_blob = logon_blob; > if (_cred_ndr_blob != NULL) { > *_cred_ndr_blob = cred_blob; > } > *_upn_info_blob = upn_blob; >+ if (_pac_attrs_blob != NULL) { >+ *_pac_attrs_blob = pac_attrs_blob; >+ } > return NT_STATUS_OK; > } > >@@ -731,7 +870,9 @@ NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx, > nt_status = samba_kdc_get_pac_blobs(mem_ctx, p, > _logon_info_blob, > NULL, /* cred_blob */ >- &upn_blob); >+ &upn_blob, >+ NULL, >+ NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > return nt_status; > } >diff --git a/source4/kdc/pac-glue.h b/source4/kdc/pac-glue.h >index e83446647b3..1b6264cb2c3 100644 >--- a/source4/kdc/pac-glue.h >+++ b/source4/kdc/pac-glue.h >@@ -31,11 +31,17 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > const DATA_BLOB *logon_blob, > const DATA_BLOB *cred_blob, > const DATA_BLOB *upn_blob, >+ const DATA_BLOB *pac_attrs_blob, > const DATA_BLOB *deleg_blob, > krb5_pac *pac); > > bool samba_princ_needs_pac(struct samba_kdc_entry *skdc_entry); > >+int samba_client_requested_pac(krb5_context context, >+ krb5_pac *pac, >+ TALLOC_CTX *mem_ctx, >+ bool *requested_pac); >+ > int samba_krbtgt_is_in_db(struct samba_kdc_entry *skdc_entry, > bool *is_in_db, > bool *is_untrusted); >@@ -44,7 +50,9 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > struct samba_kdc_entry *skdc_entry, > DATA_BLOB **_logon_info_blob, > DATA_BLOB **_cred_ndr_blob, >- DATA_BLOB **_upn_info_blob); >+ DATA_BLOB **_upn_info_blob, >+ DATA_BLOB **_pac_attrs_blob, >+ const krb5_boolean *pac_request); > NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx, > struct samba_kdc_entry *skdc_entry, > DATA_BLOB **_logon_info_blob); >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index ed6e9fb9b63..11d9ff84f04 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -37,6 +37,7 @@ > static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, > struct hdb_entry_ex *client, > const krb5_keyblock *pk_reply_key, >+ const krb5_boolean *pac_request, > krb5_pac *pac) > { > TALLOC_CTX *mem_ctx; >@@ -46,6 +47,7 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, > DATA_BLOB _cred_blob = data_blob_null; > DATA_BLOB *cred_blob = NULL; > DATA_BLOB *upn_blob = NULL; >+ DATA_BLOB *pac_attrs_blob = NULL; > krb5_error_code ret; > NTSTATUS nt_status; > struct samba_kdc_entry *skdc_entry = >@@ -64,7 +66,9 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, > nt_status = samba_kdc_get_pac_blobs(mem_ctx, skdc_entry, > &logon_blob, > cred_ndr_ptr, >- &upn_blob); >+ &upn_blob, >+ &pac_attrs_blob, >+ pac_request); > if (!NT_STATUS_IS_OK(nt_status)) { > talloc_free(mem_ctx); > return EINVAL; >@@ -84,7 +88,8 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, > } > > ret = samba_make_krb5_pac(context, logon_blob, cred_blob, >- upn_blob, NULL, pac); >+ upn_blob, pac_attrs_blob, >+ NULL, pac); > > talloc_free(mem_ctx); > return ret; >@@ -92,9 +97,10 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, > > static krb5_error_code samba_wdc_get_pac_compat(void *priv, krb5_context context, > struct hdb_entry_ex *client, >+ const krb5_boolean *pac_request, > krb5_pac *pac) > { >- return samba_wdc_get_pac(priv, context, client, NULL, pac); >+ return samba_wdc_get_pac(priv, context, client, NULL, pac_request, pac); > } > > static krb5_error_code samba_wdc_reget_pac2(krb5_context context, >@@ -132,6 +138,7 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > ssize_t srv_checksum_idx = -1; > ssize_t kdc_checksum_idx = -1; > ssize_t tkt_checksum_idx = -1; >+ ssize_t attrs_info_idx = -1; > > if (!mem_ctx) { > return ENOMEM; >@@ -239,7 +246,8 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > struct samba_kdc_entry); > > nt_status = samba_kdc_get_pac_blobs(mem_ctx, client_skdc_entry, >- &pac_blob, NULL, &upn_blob); >+ &pac_blob, NULL, &upn_blob, >+ NULL, NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > talloc_free(mem_ctx); > return EINVAL; >@@ -356,6 +364,18 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > } > tkt_checksum_idx = i; > break; >+ case PAC_TYPE_ATTRIBUTES_INFO: >+ if (attrs_info_idx != -1) { >+ DEBUG(1, ("attributes info type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ attrs_info_idx, >+ i)); >+ SAFE_FREE(types); >+ talloc_free(mem_ctx); >+ return EINVAL; >+ } >+ attrs_info_idx = i; >+ break; > default: > continue; > } >@@ -403,6 +423,20 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > goto out; > } > >+ if (!server_skdc_entry->is_krbtgt) { >+ /* >+ * The client may have requested no PAC when obtaining the >+ * TGT. >+ */ >+ bool requested_pac; >+ ret = samba_client_requested_pac(context, pac, mem_ctx, >+ &requested_pac); >+ if (ret != 0 || !requested_pac) { >+ new_pac = NULL; >+ goto out; >+ } >+ } >+ > /* Otherwise build an updated PAC */ > ret = krb5_pac_init(context, &new_pac); > if (ret != 0) { >@@ -488,6 +522,9 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > */ > type_blob = data_blob_const(&zero_byte, 1); > break; >+ case PAC_TYPE_ATTRIBUTES_INFO: >+ /* just copy... */ >+ break; > default: > /* just copy... */ > break; >-- >2.25.1 > > >From 75891820da846c769805daf7cf01a026b470ecdd Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 18 Oct 2021 15:07:58 +1300 >Subject: [PATCH 607/686] CVE-2020-25719 heimdal:kdc: Require authdata to be > present > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14686 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail_heimdal_kdc | 11 ----------- > source4/heimdal/lib/krb5/pac.c | 2 +- > 2 files changed, 1 insertion(+), 12 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 0f03e17c242..c315446386d 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -243,7 +243,6 @@ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_service_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_forwardable >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_no_pac > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_empty_allowed > # > # The lack of KRB5SignedPath means we no longer return >@@ -263,16 +262,9 @@ > ^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_domain_spn_computer > ^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_realm_spn_computer > # >-# KDC TGS PAC tests >-# >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_client_no_auth_data_required >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_service_no_auth_data_required >-# > # KDC TGT tests > # > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_no_krbtgt_link >@@ -280,7 +272,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_no_krbtgt_link >@@ -288,7 +279,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_krbtgt_link >@@ -326,7 +316,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_srealm > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_no_krbtgt_link >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 05bcc523080..749d0fdb4eb 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -1369,7 +1369,7 @@ _krb5_kdc_pac_ticket_parse(krb5_context context, > *ppac = NULL; > > if (ad == NULL || ad->len == 0) >- return 0; >+ return KRB5KDC_ERR_BADOPTION; > > for (i = 0; i < ad->len; i++) { > AuthorizationData child; >-- >2.25.1 > > >From 3e720113c750ff8a53aab9c6cc3aca51f4500309 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 30 Sep 2021 14:55:06 +1300 >Subject: [PATCH 608/686] CVE-2020-25718 kdc: Remove unused > samba_kdc_get_pac_blob() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/kdc/pac-glue.c | 21 --------------------- > source4/kdc/pac-glue.h | 3 --- > 2 files changed, 24 deletions(-) > >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index 8aa0ae33f73..b2e8a6762cb 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -860,27 +860,6 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > return NT_STATUS_OK; > } > >-NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx, >- struct samba_kdc_entry *p, >- DATA_BLOB **_logon_info_blob) >-{ >- NTSTATUS nt_status; >- DATA_BLOB *upn_blob = NULL; >- >- nt_status = samba_kdc_get_pac_blobs(mem_ctx, p, >- _logon_info_blob, >- NULL, /* cred_blob */ >- &upn_blob, >- NULL, >- NULL); >- if (!NT_STATUS_IS_OK(nt_status)) { >- return nt_status; >- } >- >- TALLOC_FREE(upn_blob); >- return NT_STATUS_OK; >-} >- > NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > krb5_context context, > struct ldb_context *samdb, >diff --git a/source4/kdc/pac-glue.h b/source4/kdc/pac-glue.h >index 1b6264cb2c3..2a7cb68f274 100644 >--- a/source4/kdc/pac-glue.h >+++ b/source4/kdc/pac-glue.h >@@ -53,9 +53,6 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > DATA_BLOB **_upn_info_blob, > DATA_BLOB **_pac_attrs_blob, > const krb5_boolean *pac_request); >-NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx, >- struct samba_kdc_entry *skdc_entry, >- DATA_BLOB **_logon_info_blob); > > NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > krb5_context context, >-- >2.25.1 > > >From 4c23d5f449f5ba015bd9767180ebdb75d7ce6f11 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 1 Oct 2021 10:47:29 +1300 >Subject: [PATCH 609/686] CVE-2020-25718 s4-rpc_server: Change sid list > functions to operate on a array of struct dom_sid > >This is instead of an array of struct dom_sid *. > >The reason is that auth_user_info_dc has an array of struct dom_sid >(the user token) and for checking if an RODC should be allowed >to print a particular ticket, we want to reuse that a rather >then reconstruct it via tokenGroups. > >This also avoids a lot of memory allocation. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/rpc_server/common/sid_helper.c | 44 +++++++++---------- > source4/rpc_server/drsuapi/getncchanges.c | 33 +++++++++----- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 33 +++++++++----- > 3 files changed, 67 insertions(+), 43 deletions(-) > >diff --git a/source4/rpc_server/common/sid_helper.c b/source4/rpc_server/common/sid_helper.c >index 698249391ef..65d7e7c7271 100644 >--- a/source4/rpc_server/common/sid_helper.c >+++ b/source4/rpc_server/common/sid_helper.c >@@ -29,13 +29,16 @@ > /* > see if any SIDs in list1 are in list2 > */ >-bool sid_list_match(const struct dom_sid **list1, const struct dom_sid **list2) >+bool sid_list_match(uint32_t num_sids1, >+ const struct dom_sid *list1, >+ uint32_t num_sids2, >+ const struct dom_sid *list2) > { > unsigned int i, j; > /* do we ever have enough SIDs here to worry about O(n^2) ? */ >- for (i=0; list1[i]; i++) { >- for (j=0; list2[j]; j++) { >- if (dom_sid_equal(list1[i], list2[j])) { >+ for (i=0; i < num_sids1; i++) { >+ for (j=0; j < num_sids2; j++) { >+ if (dom_sid_equal(&list1[i], &list2[j])) { > return true; > } > } >@@ -51,9 +54,10 @@ WERROR samdb_result_sid_array_ndr(struct ldb_context *sam_ctx, > struct ldb_message *msg, > TALLOC_CTX *mem_ctx, > const char *attr, >- const struct dom_sid ***sids, >- const struct dom_sid **additional_sids, >- unsigned int num_additional) >+ uint32_t *num_sids, >+ struct dom_sid **sids, >+ const struct dom_sid *additional_sids, >+ unsigned int num_additional) > { > struct ldb_message_element *el; > unsigned int i, j; >@@ -65,30 +69,25 @@ WERROR samdb_result_sid_array_ndr(struct ldb_context *sam_ctx, > } > > /* Make array long enough for NULL and additional SID */ >- (*sids) = talloc_array(mem_ctx, const struct dom_sid *, >- el->num_values + num_additional + 1); >+ (*sids) = talloc_array(mem_ctx, struct dom_sid, >+ el->num_values + num_additional); > W_ERROR_HAVE_NO_MEMORY(*sids); > > for (i=0; i<el->num_values; i++) { > enum ndr_err_code ndr_err; >- struct dom_sid *sid; > >- sid = talloc(*sids, struct dom_sid); >- W_ERROR_HAVE_NO_MEMORY(sid); >- >- ndr_err = ndr_pull_struct_blob(&el->values[i], sid, sid, >+ ndr_err = ndr_pull_struct_blob_all_noalloc(&el->values[i], &(*sids)[i], > (ndr_pull_flags_fn_t)ndr_pull_dom_sid); > if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { > return WERR_INTERNAL_DB_CORRUPTION; > } >- (*sids)[i] = sid; > } > > for (j = 0; j < num_additional; j++) { > (*sids)[i++] = additional_sids[j]; > } > >- (*sids)[i] = NULL; >+ *num_sids = i; > > return WERR_OK; > } >@@ -101,7 +100,8 @@ WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx, > struct ldb_message *msg, > TALLOC_CTX *mem_ctx, > const char *attr, >- const struct dom_sid ***sids) >+ uint32_t *num_sids, >+ struct dom_sid **sids) > { > struct ldb_message_element *el; > unsigned int i; >@@ -112,23 +112,21 @@ WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx, > return WERR_OK; > } > >- (*sids) = talloc_array(mem_ctx, const struct dom_sid *, el->num_values + 1); >+ (*sids) = talloc_array(mem_ctx, struct dom_sid, el->num_values + 1); > W_ERROR_HAVE_NO_MEMORY(*sids); > > for (i=0; i<el->num_values; i++) { > struct ldb_dn *dn = ldb_dn_from_ldb_val(mem_ctx, sam_ctx, &el->values[i]); > NTSTATUS status; >- struct dom_sid *sid; >+ struct dom_sid sid = { 0, }; > >- sid = talloc(*sids, struct dom_sid); >- W_ERROR_HAVE_NO_MEMORY(sid); >- status = dsdb_get_extended_dn_sid(dn, sid, "SID"); >+ status = dsdb_get_extended_dn_sid(dn, &sid, "SID"); > if (!NT_STATUS_IS_OK(status)) { > return WERR_INTERNAL_DB_CORRUPTION; > } > (*sids)[i] = sid; > } >- (*sids)[i] = NULL; >+ *num_sids = i; > > return WERR_OK; > } >diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c >index 9c6b9801d7f..9aaffda91d2 100644 >--- a/source4/rpc_server/drsuapi/getncchanges.c >+++ b/source4/rpc_server/drsuapi/getncchanges.c >@@ -1196,10 +1196,10 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", "objectGUID", NULL }; > const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL }; > struct ldb_result *rodc_res = NULL, *obj_res = NULL; >- const struct dom_sid **never_reveal_sids, **reveal_sids, **token_sids; >+ uint32_t num_never_reveal_sids, num_reveal_sids, num_token_sids; >+ struct dom_sid *never_reveal_sids, *reveal_sids, *token_sids; > const struct dom_sid *object_sid = NULL; > WERROR werr; >- const struct dom_sid *additional_sids[] = { NULL, NULL }; > > DEBUG(3,(__location__ ": DRSUAPI_EXOP_REPL_SECRET extended op on %s\n", > drs_ObjectIdentifier_to_string(mem_ctx, ncRoot))); >@@ -1284,12 +1284,13 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > > /* if the object SID is equal to the user_sid, allow */ > object_sid = samdb_result_dom_sid(mem_ctx, obj_res->msgs[0], "objectSid"); >+ if (object_sid == NULL) { >+ goto failed; >+ } > if (dom_sid_equal(user_sid, object_sid)) { > goto allowed; > } > >- additional_sids[0] = object_sid; >- > /* > * Must be an RODC account at this point, verify machine DN matches the > * SID account >@@ -1319,13 +1320,17 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > } > > werr = samdb_result_sid_array_dn(b_state->sam_ctx_system, rodc_res->msgs[0], >- mem_ctx, "msDS-NeverRevealGroup", &never_reveal_sids); >+ mem_ctx, "msDS-NeverRevealGroup", >+ &num_never_reveal_sids, >+ &never_reveal_sids); > if (!W_ERROR_IS_OK(werr)) { > goto denied; > } > > werr = samdb_result_sid_array_dn(b_state->sam_ctx_system, rodc_res->msgs[0], >- mem_ctx, "msDS-RevealOnDemandGroup", &reveal_sids); >+ mem_ctx, "msDS-RevealOnDemandGroup", >+ &num_reveal_sids, >+ &reveal_sids); > if (!W_ERROR_IS_OK(werr)) { > goto denied; > } >@@ -1336,19 +1341,27 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > * TODO determine if sIDHistory is required for this check > */ > werr = samdb_result_sid_array_ndr(b_state->sam_ctx_system, obj_res->msgs[0], >- mem_ctx, "tokenGroups", &token_sids, >- additional_sids, 1); >+ mem_ctx, "tokenGroups", >+ &num_token_sids, >+ &token_sids, >+ object_sid, 1); > if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { > goto denied; > } > > if (never_reveal_sids && >- sid_list_match(token_sids, never_reveal_sids)) { >+ sid_list_match(num_token_sids, >+ token_sids, >+ num_never_reveal_sids, >+ never_reveal_sids)) { > goto denied; > } > > if (reveal_sids && >- sid_list_match(token_sids, reveal_sids)) { >+ sid_list_match(num_token_sids, >+ token_sids, >+ num_reveal_sids, >+ reveal_sids)) { > goto allowed; > } > >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index 7668a9eb923..6b773e54c33 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -2818,10 +2818,10 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > struct ldb_dn *rodc_dn; > int ret; > struct ldb_result *rodc_res = NULL, *obj_res = NULL; >- const struct dom_sid *additional_sids[] = { NULL, NULL }; > WERROR werr; > struct dom_sid *object_sid; >- const struct dom_sid **never_reveal_sids, **reveal_sids, **token_sids; >+ uint32_t num_never_reveal_sids, num_reveal_sids, num_token_sids; >+ struct dom_sid *never_reveal_sids, *reveal_sids, *token_sids; > > rodc_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>", > dom_sid_string(mem_ctx, user_sid)); >@@ -2836,17 +2836,22 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > if (ret != LDB_SUCCESS || obj_res->count != 1) goto denied; > > object_sid = samdb_result_dom_sid(mem_ctx, obj_res->msgs[0], "objectSid"); >- >- additional_sids[0] = object_sid; >+ if (object_sid == NULL) { >+ goto denied; >+ } > > werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0], >- mem_ctx, "msDS-NeverRevealGroup", &never_reveal_sids); >+ mem_ctx, "msDS-NeverRevealGroup", >+ &num_never_reveal_sids, >+ &never_reveal_sids); > if (!W_ERROR_IS_OK(werr)) { > goto denied; > } > > werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0], >- mem_ctx, "msDS-RevealOnDemandGroup", &reveal_sids); >+ mem_ctx, "msDS-RevealOnDemandGroup", >+ &num_reveal_sids, >+ &reveal_sids); > if (!W_ERROR_IS_OK(werr)) { > goto denied; > } >@@ -2857,19 +2862,27 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > * TODO determine if sIDHistory is required for this check > */ > werr = samdb_result_sid_array_ndr(sam_ctx, obj_res->msgs[0], >- mem_ctx, "tokenGroups", &token_sids, >- additional_sids, 1); >+ mem_ctx, "tokenGroups", >+ &num_token_sids, >+ &token_sids, >+ object_sid, 1); > if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { > goto denied; > } > > if (never_reveal_sids && >- sid_list_match(token_sids, never_reveal_sids)) { >+ sid_list_match(num_token_sids, >+ token_sids, >+ num_never_reveal_sids, >+ never_reveal_sids)) { > goto denied; > } > > if (reveal_sids && >- sid_list_match(token_sids, reveal_sids)) { >+ sid_list_match(num_token_sids, >+ token_sids, >+ num_reveal_sids, >+ reveal_sids)) { > goto allowed; > } > >-- >2.25.1 > > >From d0a43dbb5f875dbe96e94633a0cb2c79541aab13 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 1 Oct 2021 11:09:48 +1300 >Subject: [PATCH 610/686] CVE-2020-25718 s4-rpc_server: Obtain the user > tokenGroups earlier > >This will allow the creation of a common helper routine that >takes the token SID list (from tokenGroups or struct auth_user_info_dc) >and returns the allowed/denied result. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/rpc_server/drsuapi/getncchanges.c | 28 +++++++++---------- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 28 +++++++++---------- > 2 files changed, 28 insertions(+), 28 deletions(-) > >diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c >index 9aaffda91d2..3eb46ae9830 100644 >--- a/source4/rpc_server/drsuapi/getncchanges.c >+++ b/source4/rpc_server/drsuapi/getncchanges.c >@@ -1307,6 +1307,20 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > goto allowed; > } > >+ /* >+ * The SID list needs to include itself as well as the tokenGroups. >+ * >+ * TODO determine if sIDHistory is required for this check >+ */ >+ werr = samdb_result_sid_array_ndr(b_state->sam_ctx_system, obj_res->msgs[0], >+ mem_ctx, "tokenGroups", >+ &num_token_sids, >+ &token_sids, >+ object_sid, 1); >+ if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { >+ goto denied; >+ } >+ > /* but it isn't allowed to get anyone elses krbtgt secrets */ > if (samdb_result_dn(b_state->sam_ctx_system, mem_ctx, > obj_res->msgs[0], "msDS-KrbTgtLinkBL", NULL)) { >@@ -1335,20 +1349,6 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > goto denied; > } > >- /* >- * The SID list needs to include itself as well as the tokenGroups. >- * >- * TODO determine if sIDHistory is required for this check >- */ >- werr = samdb_result_sid_array_ndr(b_state->sam_ctx_system, obj_res->msgs[0], >- mem_ctx, "tokenGroups", >- &num_token_sids, >- &token_sids, >- object_sid, 1); >- if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { >- goto denied; >- } >- > if (never_reveal_sids && > sid_list_match(num_token_sids, > token_sids, >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index 6b773e54c33..3d003af68be 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -2840,6 +2840,20 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > goto denied; > } > >+ /* >+ * The SID list needs to include itself as well as the tokenGroups. >+ * >+ * TODO determine if sIDHistory is required for this check >+ */ >+ werr = samdb_result_sid_array_ndr(sam_ctx, obj_res->msgs[0], >+ mem_ctx, "tokenGroups", >+ &num_token_sids, >+ &token_sids, >+ object_sid, 1); >+ if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { >+ goto denied; >+ } >+ > werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0], > mem_ctx, "msDS-NeverRevealGroup", > &num_never_reveal_sids, >@@ -2856,20 +2870,6 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > goto denied; > } > >- /* >- * The SID list needs to include itself as well as the tokenGroups. >- * >- * TODO determine if sIDHistory is required for this check >- */ >- werr = samdb_result_sid_array_ndr(sam_ctx, obj_res->msgs[0], >- mem_ctx, "tokenGroups", >- &num_token_sids, >- &token_sids, >- object_sid, 1); >- if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { >- goto denied; >- } >- > if (never_reveal_sids && > sid_list_match(num_token_sids, > token_sids, >-- >2.25.1 > > >From cac8723f7ca7b91ad1a099217073e322f2c73c7c Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 1 Oct 2021 11:38:16 +1300 >Subject: [PATCH 611/686] CVE-2020-25718 s4-rpc_server: Put RODC reveal/never > reveal logic into a single helper function > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/rpc_server/common/sid_helper.c | 49 +++++++++++++++++++ > source4/rpc_server/drsuapi/getncchanges.c | 37 +++----------- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 38 +++----------- > 3 files changed, 63 insertions(+), 61 deletions(-) > >diff --git a/source4/rpc_server/common/sid_helper.c b/source4/rpc_server/common/sid_helper.c >index 65d7e7c7271..eaeab236fc0 100644 >--- a/source4/rpc_server/common/sid_helper.c >+++ b/source4/rpc_server/common/sid_helper.c >@@ -130,3 +130,52 @@ WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx, > > return WERR_OK; > } >+ >+WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ctx, >+ struct ldb_message *rodc_msg, >+ uint32_t num_token_sids, >+ struct dom_sid *token_sids) >+{ >+ uint32_t num_never_reveal_sids, num_reveal_sids; >+ struct dom_sid *never_reveal_sids, *reveal_sids; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ WERROR werr = samdb_result_sid_array_dn(sam_ctx, rodc_msg, >+ frame, "msDS-NeverRevealGroup", >+ &num_never_reveal_sids, >+ &never_reveal_sids); >+ if (!W_ERROR_IS_OK(werr)) { >+ TALLOC_FREE(frame); >+ return WERR_DS_DRA_SECRETS_DENIED; >+ } >+ >+ werr = samdb_result_sid_array_dn(sam_ctx, rodc_msg, >+ frame, "msDS-RevealOnDemandGroup", >+ &num_reveal_sids, >+ &reveal_sids); >+ if (!W_ERROR_IS_OK(werr)) { >+ TALLOC_FREE(frame); >+ return WERR_DS_DRA_SECRETS_DENIED; >+ } >+ >+ if (never_reveal_sids && >+ sid_list_match(num_token_sids, >+ token_sids, >+ num_never_reveal_sids, >+ never_reveal_sids)) { >+ TALLOC_FREE(frame); >+ return WERR_DS_DRA_SECRETS_DENIED; >+ } >+ >+ if (reveal_sids && >+ sid_list_match(num_token_sids, >+ token_sids, >+ num_reveal_sids, >+ reveal_sids)) { >+ TALLOC_FREE(frame); >+ return WERR_OK; >+ } >+ >+ TALLOC_FREE(frame); >+ return WERR_DS_DRA_SECRETS_DENIED; >+ >+} >diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c >index 3eb46ae9830..66566474c4d 100644 >--- a/source4/rpc_server/drsuapi/getncchanges.c >+++ b/source4/rpc_server/drsuapi/getncchanges.c >@@ -1196,8 +1196,8 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", "objectGUID", NULL }; > const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL }; > struct ldb_result *rodc_res = NULL, *obj_res = NULL; >- uint32_t num_never_reveal_sids, num_reveal_sids, num_token_sids; >- struct dom_sid *never_reveal_sids, *reveal_sids, *token_sids; >+ uint32_t num_token_sids; >+ struct dom_sid *token_sids; > const struct dom_sid *object_sid = NULL; > WERROR werr; > >@@ -1333,35 +1333,12 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > goto denied; > } > >- werr = samdb_result_sid_array_dn(b_state->sam_ctx_system, rodc_res->msgs[0], >- mem_ctx, "msDS-NeverRevealGroup", >- &num_never_reveal_sids, >- &never_reveal_sids); >- if (!W_ERROR_IS_OK(werr)) { >- goto denied; >- } >- >- werr = samdb_result_sid_array_dn(b_state->sam_ctx_system, rodc_res->msgs[0], >- mem_ctx, "msDS-RevealOnDemandGroup", >- &num_reveal_sids, >- &reveal_sids); >- if (!W_ERROR_IS_OK(werr)) { >- goto denied; >- } >- >- if (never_reveal_sids && >- sid_list_match(num_token_sids, >- token_sids, >- num_never_reveal_sids, >- never_reveal_sids)) { >- goto denied; >- } >+ werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(b_state->sam_ctx_system, >+ rodc_res->msgs[0], >+ num_token_sids, >+ token_sids); > >- if (reveal_sids && >- sid_list_match(num_token_sids, >- token_sids, >- num_reveal_sids, >- reveal_sids)) { >+ if (W_ERROR_IS_OK(werr)) { > goto allowed; > } > >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index 3d003af68be..a49be95735f 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -2820,8 +2820,8 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > struct ldb_result *rodc_res = NULL, *obj_res = NULL; > WERROR werr; > struct dom_sid *object_sid; >- uint32_t num_never_reveal_sids, num_reveal_sids, num_token_sids; >- struct dom_sid *never_reveal_sids, *reveal_sids, *token_sids; >+ uint32_t num_token_sids; >+ struct dom_sid *token_sids; > > rodc_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>", > dom_sid_string(mem_ctx, user_sid)); >@@ -2854,38 +2854,14 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > goto denied; > } > >- werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0], >- mem_ctx, "msDS-NeverRevealGroup", >- &num_never_reveal_sids, >- &never_reveal_sids); >- if (!W_ERROR_IS_OK(werr)) { >- goto denied; >- } >- >- werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0], >- mem_ctx, "msDS-RevealOnDemandGroup", >- &num_reveal_sids, >- &reveal_sids); >- if (!W_ERROR_IS_OK(werr)) { >- goto denied; >- } >+ werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(sam_ctx, >+ rodc_res->msgs[0], >+ num_token_sids, >+ token_sids); > >- if (never_reveal_sids && >- sid_list_match(num_token_sids, >- token_sids, >- num_never_reveal_sids, >- never_reveal_sids)) { >- goto denied; >- } >- >- if (reveal_sids && >- sid_list_match(num_token_sids, >- token_sids, >- num_reveal_sids, >- reveal_sids)) { >+ if (W_ERROR_IS_OK(werr)) { > goto allowed; > } >- > denied: > return false; > allowed: >-- >2.25.1 > > >From 936da47e457cfb7e48cb5bbf621b873e87c16eec Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 1 Oct 2021 11:55:11 +1300 >Subject: [PATCH 612/686] CVE-2020-25718 s4-rpc_server: Put msDS-KrbTgtLinkBL > and UF_INTERDOMAIN_TRUST_ACCOUNT RODC checks in common > >While these checks were not in the NETLOGON case, there is no sense where >an RODC should be resetting a bad password count on either a >UF_INTERDOMAIN_TRUST_ACCOUNT nor a RODC krbtgt account. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/rpc_server/common/sid_helper.c | 29 ++++++++++++++++--- > source4/rpc_server/drsuapi/getncchanges.c | 13 +-------- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 1 + > 3 files changed, 27 insertions(+), 16 deletions(-) > >diff --git a/source4/rpc_server/common/sid_helper.c b/source4/rpc_server/common/sid_helper.c >index eaeab236fc0..ab2b4373b47 100644 >--- a/source4/rpc_server/common/sid_helper.c >+++ b/source4/rpc_server/common/sid_helper.c >@@ -133,16 +133,37 @@ WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx, > > WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ctx, > struct ldb_message *rodc_msg, >+ struct ldb_message *obj_msg, > uint32_t num_token_sids, > struct dom_sid *token_sids) > { > uint32_t num_never_reveal_sids, num_reveal_sids; > struct dom_sid *never_reveal_sids, *reveal_sids; > TALLOC_CTX *frame = talloc_stackframe(); >- WERROR werr = samdb_result_sid_array_dn(sam_ctx, rodc_msg, >- frame, "msDS-NeverRevealGroup", >- &num_never_reveal_sids, >- &never_reveal_sids); >+ WERROR werr; >+ >+ /* >+ * We are not allowed to get anyone elses krbtgt secrets (and >+ * in callers that don't shortcut before this, the RODC should >+ * not deal with any krbtgt) >+ */ >+ if (samdb_result_dn(sam_ctx, frame, >+ obj_msg, "msDS-KrbTgtLinkBL", NULL)) { >+ TALLOC_FREE(frame); >+ return WERR_DS_DRA_SECRETS_DENIED; >+ } >+ >+ if (ldb_msg_find_attr_as_uint(obj_msg, >+ "userAccountControl", 0) & >+ UF_INTERDOMAIN_TRUST_ACCOUNT) { >+ TALLOC_FREE(frame); >+ return WERR_DS_DRA_SECRETS_DENIED; >+ } >+ >+ werr = samdb_result_sid_array_dn(sam_ctx, rodc_msg, >+ frame, "msDS-NeverRevealGroup", >+ &num_never_reveal_sids, >+ &never_reveal_sids); > if (!W_ERROR_IS_OK(werr)) { > TALLOC_FREE(frame); > return WERR_DS_DRA_SECRETS_DENIED; >diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c >index 66566474c4d..422782cade8 100644 >--- a/source4/rpc_server/drsuapi/getncchanges.c >+++ b/source4/rpc_server/drsuapi/getncchanges.c >@@ -1321,20 +1321,9 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > goto denied; > } > >- /* but it isn't allowed to get anyone elses krbtgt secrets */ >- if (samdb_result_dn(b_state->sam_ctx_system, mem_ctx, >- obj_res->msgs[0], "msDS-KrbTgtLinkBL", NULL)) { >- goto denied; >- } >- >- if (ldb_msg_find_attr_as_uint(obj_res->msgs[0], >- "userAccountControl", 0) & >- UF_INTERDOMAIN_TRUST_ACCOUNT) { >- goto denied; >- } >- > werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(b_state->sam_ctx_system, > rodc_res->msgs[0], >+ obj_res->msgs[0], > num_token_sids, > token_sids); > >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index a49be95735f..26b79a95cb1 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -2856,6 +2856,7 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > > werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(sam_ctx, > rodc_res->msgs[0], >+ obj_res->msgs[0], > num_token_sids, > token_sids); > >-- >2.25.1 > > >From f18558a19e6e93f620408af2dea7b14ab4c65eda Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 1 Oct 2021 12:01:12 +1300 >Subject: [PATCH 613/686] CVE-2020-25718 s4-rpc_server: Confirm that the RODC > has the UF_PARTIAL_SECRETS_ACCOUNT bit > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/rpc_server/common/sid_helper.c | 13 +++++++++++++ > source4/rpc_server/drsuapi/getncchanges.c | 7 ++++++- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 7 ++++++- > 3 files changed, 25 insertions(+), 2 deletions(-) > >diff --git a/source4/rpc_server/common/sid_helper.c b/source4/rpc_server/common/sid_helper.c >index ab2b4373b47..99c5fc20d9d 100644 >--- a/source4/rpc_server/common/sid_helper.c >+++ b/source4/rpc_server/common/sid_helper.c >@@ -141,6 +141,7 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct > struct dom_sid *never_reveal_sids, *reveal_sids; > TALLOC_CTX *frame = talloc_stackframe(); > WERROR werr; >+ uint32_t rodc_uac; > > /* > * We are not allowed to get anyone elses krbtgt secrets (and >@@ -160,6 +161,18 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct > return WERR_DS_DRA_SECRETS_DENIED; > } > >+ /* Be very sure the RODC is really an RODC */ >+ rodc_uac = ldb_msg_find_attr_as_uint(rodc_msg, >+ "userAccountControl", >+ 0); >+ if ((rodc_uac & UF_PARTIAL_SECRETS_ACCOUNT) >+ != UF_PARTIAL_SECRETS_ACCOUNT) { >+ TALLOC_FREE(frame); >+ DBG_ERR("Attempt to use an RODC account that is not an RODC: %s\n", >+ ldb_dn_get_linearized(rodc_msg->dn)); >+ return WERR_DS_DRA_SECRETS_DENIED; >+ } >+ > werr = samdb_result_sid_array_dn(sam_ctx, rodc_msg, > frame, "msDS-NeverRevealGroup", > &num_never_reveal_sids, >diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c >index 422782cade8..3051a1b659e 100644 >--- a/source4/rpc_server/drsuapi/getncchanges.c >+++ b/source4/rpc_server/drsuapi/getncchanges.c >@@ -1193,7 +1193,12 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > struct ldb_dn *ntds_dn = NULL, *server_dn = NULL; > struct ldb_dn *rodc_dn, *krbtgt_link_dn; > int ret; >- const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", "objectGUID", NULL }; >+ const char *rodc_attrs[] = { "msDS-KrbTgtLink", >+ "msDS-NeverRevealGroup", >+ "msDS-RevealOnDemandGroup", >+ "objectGUID", >+ "userAccountControl", >+ NULL }; > const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL }; > struct ldb_result *rodc_res = NULL, *obj_res = NULL; > uint32_t num_token_sids; >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index 26b79a95cb1..381bdafd1fa 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -2813,7 +2813,12 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > struct dom_sid *user_sid, > struct ldb_dn *obj_dn) > { >- const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", "objectGUID", NULL }; >+ const char *rodc_attrs[] = { "msDS-KrbTgtLink", >+ "msDS-NeverRevealGroup", >+ "msDS-RevealOnDemandGroup", >+ "objectGUID", >+ "userAccountControl", >+ NULL }; > const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL }; > struct ldb_dn *rodc_dn; > int ret; >-- >2.25.1 > > >From 2d7511ffd0ab1c29071d2a03059c085a847874fa Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 1 Oct 2021 12:25:30 +1300 >Subject: [PATCH 614/686] CVE-2020-25718 s4-rpc_server: Provide wrapper > samdb_confirm_rodc_allowed_to_repl_to() > >This shares the lookup of the tokenGroups attribute. > >There will be a new caller that does not want to do this step, >so this is a wrapper of samdb_confirm_rodc_allowed_to_repl_to_sid_list() >rather than part of it > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/rpc_server/common/sid_helper.c | 45 +++++++++++++++++++ > source4/rpc_server/drsuapi/getncchanges.c | 24 ++-------- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 30 ++----------- > 3 files changed, 51 insertions(+), 48 deletions(-) > >diff --git a/source4/rpc_server/common/sid_helper.c b/source4/rpc_server/common/sid_helper.c >index 99c5fc20d9d..78cb35d3fc1 100644 >--- a/source4/rpc_server/common/sid_helper.c >+++ b/source4/rpc_server/common/sid_helper.c >@@ -213,3 +213,48 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct > return WERR_DS_DRA_SECRETS_DENIED; > > } >+ >+/* >+ * This is a wrapper for the above that pulls in the tokenGroups >+ * rather than relying on the caller providing those >+ */ >+WERROR samdb_confirm_rodc_allowed_to_repl_to(struct ldb_context *sam_ctx, >+ struct ldb_message *rodc_msg, >+ struct ldb_message *obj_msg) >+{ >+ TALLOC_CTX *frame = talloc_stackframe(); >+ WERROR werr; >+ uint32_t num_token_sids; >+ struct dom_sid *token_sids; >+ const struct dom_sid *object_sid = NULL; >+ >+ object_sid = samdb_result_dom_sid(frame, >+ obj_msg, >+ "objectSid"); >+ if (object_sid == NULL) { >+ return WERR_DS_DRA_BAD_DN; >+ } >+ >+ /* >+ * The SID list needs to include itself as well as the tokenGroups. >+ * >+ * TODO determine if sIDHistory is required for this check >+ */ >+ werr = samdb_result_sid_array_ndr(sam_ctx, >+ obj_msg, >+ frame, "tokenGroups", >+ &num_token_sids, >+ &token_sids, >+ object_sid, 1); >+ if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { >+ return WERR_DS_DRA_SECRETS_DENIED; >+ } >+ >+ werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(sam_ctx, >+ rodc_msg, >+ obj_msg, >+ num_token_sids, >+ token_sids); >+ TALLOC_FREE(frame); >+ return werr; >+} >diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c >index 3051a1b659e..783d5979ccf 100644 >--- a/source4/rpc_server/drsuapi/getncchanges.c >+++ b/source4/rpc_server/drsuapi/getncchanges.c >@@ -1201,8 +1201,6 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > NULL }; > const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL }; > struct ldb_result *rodc_res = NULL, *obj_res = NULL; >- uint32_t num_token_sids; >- struct dom_sid *token_sids; > const struct dom_sid *object_sid = NULL; > WERROR werr; > >@@ -1312,25 +1310,9 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > goto allowed; > } > >- /* >- * The SID list needs to include itself as well as the tokenGroups. >- * >- * TODO determine if sIDHistory is required for this check >- */ >- werr = samdb_result_sid_array_ndr(b_state->sam_ctx_system, obj_res->msgs[0], >- mem_ctx, "tokenGroups", >- &num_token_sids, >- &token_sids, >- object_sid, 1); >- if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { >- goto denied; >- } >- >- werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(b_state->sam_ctx_system, >- rodc_res->msgs[0], >- obj_res->msgs[0], >- num_token_sids, >- token_sids); >+ werr = samdb_confirm_rodc_allowed_to_repl_to(b_state->sam_ctx_system, >+ rodc_res->msgs[0], >+ obj_res->msgs[0]); > > if (W_ERROR_IS_OK(werr)) { > goto allowed; >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index 381bdafd1fa..c44ff811932 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -2824,9 +2824,6 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > int ret; > struct ldb_result *rodc_res = NULL, *obj_res = NULL; > WERROR werr; >- struct dom_sid *object_sid; >- uint32_t num_token_sids; >- struct dom_sid *token_sids; > > rodc_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>", > dom_sid_string(mem_ctx, user_sid)); >@@ -2840,30 +2837,9 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > ret = dsdb_search_dn(sam_ctx, mem_ctx, &obj_res, obj_dn, obj_attrs, 0); > if (ret != LDB_SUCCESS || obj_res->count != 1) goto denied; > >- object_sid = samdb_result_dom_sid(mem_ctx, obj_res->msgs[0], "objectSid"); >- if (object_sid == NULL) { >- goto denied; >- } >- >- /* >- * The SID list needs to include itself as well as the tokenGroups. >- * >- * TODO determine if sIDHistory is required for this check >- */ >- werr = samdb_result_sid_array_ndr(sam_ctx, obj_res->msgs[0], >- mem_ctx, "tokenGroups", >- &num_token_sids, >- &token_sids, >- object_sid, 1); >- if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { >- goto denied; >- } >- >- werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(sam_ctx, >- rodc_res->msgs[0], >- obj_res->msgs[0], >- num_token_sids, >- token_sids); >+ werr = samdb_confirm_rodc_allowed_to_repl_to(sam_ctx, >+ rodc_res->msgs[0], >+ obj_res->msgs[0]); > > if (W_ERROR_IS_OK(werr)) { > goto allowed; >-- >2.25.1 > > >From 3332717462c39f4368bfd9dc3691015a2c7cc727 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 1 Oct 2021 12:29:49 +1300 >Subject: [PATCH 615/686] CVE-2020-25718 s4-rpc_server: Remove unused > attributes in RODC check > >In particular the objectGUID is no longer used, and in the NETLOGON case >the special case for msDS-KrbTgtLink does not apply. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/rpc_server/drsuapi/getncchanges.c | 1 - > source4/rpc_server/netlogon/dcerpc_netlogon.c | 4 +--- > 2 files changed, 1 insertion(+), 4 deletions(-) > >diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c >index 783d5979ccf..2ec3026f22d 100644 >--- a/source4/rpc_server/drsuapi/getncchanges.c >+++ b/source4/rpc_server/drsuapi/getncchanges.c >@@ -1196,7 +1196,6 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > const char *rodc_attrs[] = { "msDS-KrbTgtLink", > "msDS-NeverRevealGroup", > "msDS-RevealOnDemandGroup", >- "objectGUID", > "userAccountControl", > NULL }; > const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL }; >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index c44ff811932..f12eda01b4a 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -2813,10 +2813,8 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > struct dom_sid *user_sid, > struct ldb_dn *obj_dn) > { >- const char *rodc_attrs[] = { "msDS-KrbTgtLink", >- "msDS-NeverRevealGroup", >+ const char *rodc_attrs[] = { "msDS-NeverRevealGroup", > "msDS-RevealOnDemandGroup", >- "objectGUID", > "userAccountControl", > NULL }; > const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL }; >-- >2.25.1 > > >From 2a9265433b16d75d2a9382208cc0dec0786fcb41 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 1 Oct 2021 14:31:00 +1300 >Subject: [PATCH 616/686] CVE-2020-25718 s4-rpc_server: Explain why we use > DSDB_SEARCH_SHOW_EXTENDED_DN in RODC access check > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/rpc_server/drsuapi/getncchanges.c | 6 +++++- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 6 +++++- > 2 files changed, 10 insertions(+), 2 deletions(-) > >diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c >index 2ec3026f22d..1465c139656 100644 >--- a/source4/rpc_server/drsuapi/getncchanges.c >+++ b/source4/rpc_server/drsuapi/getncchanges.c >@@ -1276,7 +1276,11 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > dom_sid_string(mem_ctx, user_sid)); > if (!ldb_dn_validate(rodc_dn)) goto failed; > >- /* do the two searches we need */ >+ /* >+ * do the two searches we need >+ * We need DSDB_SEARCH_SHOW_EXTENDED_DN as we get a SID lists >+ * out of the extended DNs >+ */ > ret = dsdb_search_dn(b_state->sam_ctx_system, mem_ctx, &rodc_res, rodc_dn, rodc_attrs, > DSDB_SEARCH_SHOW_EXTENDED_DN); > if (ret != LDB_SUCCESS || rodc_res->count != 1) goto failed; >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index f12eda01b4a..f8f24d782ff 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -2827,7 +2827,11 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > dom_sid_string(mem_ctx, user_sid)); > if (!ldb_dn_validate(rodc_dn)) goto denied; > >- /* do the two searches we need */ >+ /* >+ * do the two searches we need >+ * We need DSDB_SEARCH_SHOW_EXTENDED_DN as we get a SID list >+ * out of the extended DNs >+ */ > ret = dsdb_search_dn(sam_ctx, mem_ctx, &rodc_res, rodc_dn, rodc_attrs, > DSDB_SEARCH_SHOW_EXTENDED_DN); > if (ret != LDB_SUCCESS || rodc_res->count != 1) goto denied; >-- >2.25.1 > > >From 91f8a70a9c74ebe80955aee32fda94dc4f736049 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 1 Oct 2021 15:57:41 +1300 >Subject: [PATCH 617/686] CVE-2020-25718 s4-rpc_server: Add in debug messages > into RODC processing > >These are added for the uncommon cases. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/rpc_server/common/sid_helper.c | 18 +++++++++++++++++- > 1 file changed, 17 insertions(+), 1 deletion(-) > >diff --git a/source4/rpc_server/common/sid_helper.c b/source4/rpc_server/common/sid_helper.c >index 78cb35d3fc1..c6e7fbeb7ab 100644 >--- a/source4/rpc_server/common/sid_helper.c >+++ b/source4/rpc_server/common/sid_helper.c >@@ -151,12 +151,18 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct > if (samdb_result_dn(sam_ctx, frame, > obj_msg, "msDS-KrbTgtLinkBL", NULL)) { > TALLOC_FREE(frame); >+ DBG_INFO("Denied attempt to replicate to/act as a RODC krbtgt trust account %s using RODC: %s\n", >+ ldb_dn_get_linearized(obj_msg->dn), >+ ldb_dn_get_linearized(rodc_msg->dn)); > return WERR_DS_DRA_SECRETS_DENIED; > } > > if (ldb_msg_find_attr_as_uint(obj_msg, > "userAccountControl", 0) & > UF_INTERDOMAIN_TRUST_ACCOUNT) { >+ DBG_INFO("Denied attempt to replicate to/act as a inter-domain trust account %s using RODC: %s\n", >+ ldb_dn_get_linearized(obj_msg->dn), >+ ldb_dn_get_linearized(rodc_msg->dn)); > TALLOC_FREE(frame); > return WERR_DS_DRA_SECRETS_DENIED; > } >@@ -167,9 +173,9 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct > 0); > if ((rodc_uac & UF_PARTIAL_SECRETS_ACCOUNT) > != UF_PARTIAL_SECRETS_ACCOUNT) { >- TALLOC_FREE(frame); > DBG_ERR("Attempt to use an RODC account that is not an RODC: %s\n", > ldb_dn_get_linearized(rodc_msg->dn)); >+ TALLOC_FREE(frame); > return WERR_DS_DRA_SECRETS_DENIED; > } > >@@ -178,6 +184,9 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct > &num_never_reveal_sids, > &never_reveal_sids); > if (!W_ERROR_IS_OK(werr)) { >+ DBG_ERR("Failed to parse msDS-NeverRevealGroup on %s: %s\n", >+ ldb_dn_get_linearized(rodc_msg->dn), >+ win_errstr(werr)); > TALLOC_FREE(frame); > return WERR_DS_DRA_SECRETS_DENIED; > } >@@ -187,6 +196,9 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct > &num_reveal_sids, > &reveal_sids); > if (!W_ERROR_IS_OK(werr)) { >+ DBG_ERR("Failed to parse msDS-RevealOnDemandGroup on %s: %s\n", >+ ldb_dn_get_linearized(rodc_msg->dn), >+ win_errstr(werr)); > TALLOC_FREE(frame); > return WERR_DS_DRA_SECRETS_DENIED; > } >@@ -247,6 +259,10 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to(struct ldb_context *sam_ctx, > &token_sids, > object_sid, 1); > if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { >+ DBG_ERR("Failed to get tokenGroups on %s to confirm access via RODC %s: %s\n", >+ ldb_dn_get_linearized(obj_msg->dn), >+ ldb_dn_get_linearized(rodc_msg->dn), >+ win_errstr(werr)); > return WERR_DS_DRA_SECRETS_DENIED; > } > >-- >2.25.1 > > >From d3430cc21e43fa861a4c7e70044996f7551e8c36 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 1 Oct 2021 15:59:28 +1300 >Subject: [PATCH 618/686] CVE-2020-25718 dsdb: Bring sid_helper.c into common > code as rodc_helper.c > >These common routines will assist the KDC to do the same access >checking as the RPC servers need to do regarding which accounts >a RODC can act with regard to. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> > >[jsutton@samba.org Adapted to fix conflicts] >--- > .../common/sid_helper.c => dsdb/common/rodc_helper.c} | 1 - > source4/dsdb/wscript_build | 2 +- > source4/rpc_server/drsuapi/getncchanges.c | 1 - > source4/rpc_server/netlogon/dcerpc_netlogon.c | 1 - > source4/rpc_server/wscript_build | 9 +-------- > 5 files changed, 2 insertions(+), 12 deletions(-) > rename source4/{rpc_server/common/sid_helper.c => dsdb/common/rodc_helper.c} (99%) > >diff --git a/source4/rpc_server/common/sid_helper.c b/source4/dsdb/common/rodc_helper.c >similarity index 99% >rename from source4/rpc_server/common/sid_helper.c >rename to source4/dsdb/common/rodc_helper.c >index c6e7fbeb7ab..09aa3f5e710 100644 >--- a/source4/rpc_server/common/sid_helper.c >+++ b/source4/dsdb/common/rodc_helper.c >@@ -23,7 +23,6 @@ > #include "rpc_server/dcerpc_server.h" > #include "librpc/gen_ndr/ndr_security.h" > #include "source4/dsdb/samdb/samdb.h" >-#include "rpc_server/common/sid_helper.h" > #include "libcli/security/security.h" > > /* >diff --git a/source4/dsdb/wscript_build b/source4/dsdb/wscript_build >index 34ba8edb44a..471fbf98267 100644 >--- a/source4/dsdb/wscript_build >+++ b/source4/dsdb/wscript_build >@@ -13,7 +13,7 @@ bld.SAMBA_LIBRARY('samdb', > ) > > bld.SAMBA_LIBRARY('samdb-common', >- source='common/util.c common/util_trusts.c common/util_groups.c common/util_samr.c common/dsdb_dn.c common/dsdb_access.c common/util_links.c', >+ source='common/util.c common/util_trusts.c common/util_groups.c common/util_samr.c common/dsdb_dn.c common/dsdb_access.c common/util_links.c common/rodc_helper.c', > autoproto='common/proto.h', > private_library=True, > deps='ldb NDR_DRSBLOBS util_ldb LIBCLI_AUTH samba-hostconfig samba_socket cli-ldap-common flag_mapping UTIL_RUNCMD' >diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c >index 1465c139656..703e523eddf 100644 >--- a/source4/rpc_server/drsuapi/getncchanges.c >+++ b/source4/rpc_server/drsuapi/getncchanges.c >@@ -32,7 +32,6 @@ > #include "libcli/security/session.h" > #include "rpc_server/drsuapi/dcesrv_drsuapi.h" > #include "rpc_server/dcerpc_server_proto.h" >-#include "rpc_server/common/sid_helper.h" > #include "../libcli/drsuapi/drsuapi.h" > #include "lib/util/binsearch.h" > #include "lib/util/tsort.h" >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index f8f24d782ff..83ec3b92ee4 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -42,7 +42,6 @@ > #include "librpc/gen_ndr/ndr_winbind.h" > #include "librpc/gen_ndr/ndr_winbind_c.h" > #include "lib/socket/netif.h" >-#include "rpc_server/common/sid_helper.h" > #include "lib/util/util_str_escape.h" > > #define DCESRV_INTERFACE_NETLOGON_BIND(context, iface) \ >diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build >index 510335a6498..0c14079e137 100644 >--- a/source4/rpc_server/wscript_build >+++ b/source4/rpc_server/wscript_build >@@ -7,17 +7,10 @@ bld.SAMBA_SUBSYSTEM('DCERPC_SHARE', > enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER'), > ) > >-bld.SAMBA_SUBSYSTEM('DCERPC_SID_HELPER', >- source='common/sid_helper.c', >- autoproto='common/sid_helper.h', >- deps='ldb', >- enabled=bld.AD_DC_BUILD_IS_ENABLED(), >- ) >- > bld.SAMBA_SUBSYSTEM('DCERPC_COMMON', > source='common/server_info.c common/forward.c common/loadparm.c', > autoproto='common/proto.h', >- deps='ldb DCERPC_SHARE DCERPC_SID_HELPER', >+ deps='ldb DCERPC_SHARE', > enabled=bld.AD_DC_BUILD_IS_ENABLED() > ) > >-- >2.25.1 > > >From 6d473c10a9185ac278af58bffbd3ca2037aa9c31 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 1 Oct 2021 16:14:37 +1300 >Subject: [PATCH 619/686] CVE-2020-25718 kdc: Confirm the RODC was allowed to > issue a particular ticket > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > selftest/knownfail_heimdal_kdc | 12 -- > source4/auth/sam.c | 5 +- > source4/dsdb/common/rodc_helper.c | 47 ++++---- > source4/kdc/mit_samba.c | 6 +- > source4/kdc/pac-glue.c | 106 +++++++++++++++++- > source4/kdc/pac-glue.h | 13 ++- > source4/kdc/wdc-samba4.c | 40 ++++++- > source4/rpc_server/drsuapi/getncchanges.c | 11 +- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 1 + > 9 files changed, 187 insertions(+), 54 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index c315446386d..7d0597fa279 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -265,25 +265,16 @@ > # KDC TGT tests > # > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_allowed_denied >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_no_krbtgt_link > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_no_partial_secrets >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_allowed_denied >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_no_krbtgt_link > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_no_partial_secrets >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_krbtgt_link > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_partial_secrets >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_mac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_mac >@@ -316,11 +307,8 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_srealm > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_allowed_denied >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_no_krbtgt_link > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_no_partial_secrets >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed > # > # PAC request tests >diff --git a/source4/auth/sam.c b/source4/auth/sam.c >index 709e901b45b..aca2c1ec03c 100644 >--- a/source4/auth/sam.c >+++ b/source4/auth/sam.c >@@ -57,7 +57,10 @@ > \ > "pwdLastSet", \ > "msDS-UserPasswordExpiryTimeComputed", \ >- "accountExpires" >+ "accountExpires", \ >+ \ >+ /* Needed for RODC rule processing */ \ >+ "msDS-KrbTgtLinkBL" > > const char *krbtgt_attrs[] = { > KRBTGT_ATTRS, NULL >diff --git a/source4/dsdb/common/rodc_helper.c b/source4/dsdb/common/rodc_helper.c >index 09aa3f5e710..1cd644c6def 100644 >--- a/source4/dsdb/common/rodc_helper.c >+++ b/source4/dsdb/common/rodc_helper.c >@@ -47,19 +47,18 @@ bool sid_list_match(uint32_t num_sids1, > > /* > * Return an array of SIDs from a ldb_message given an attribute name assumes >- * the SIDs are in NDR form (with additional sids applied on the end). >+ * the SIDs are in NDR form (with primary_sid applied on the start). > */ >-WERROR samdb_result_sid_array_ndr(struct ldb_context *sam_ctx, >- struct ldb_message *msg, >- TALLOC_CTX *mem_ctx, >- const char *attr, >- uint32_t *num_sids, >- struct dom_sid **sids, >- const struct dom_sid *additional_sids, >- unsigned int num_additional) >+static WERROR samdb_result_sid_array_ndr(struct ldb_context *sam_ctx, >+ struct ldb_message *msg, >+ TALLOC_CTX *mem_ctx, >+ const char *attr, >+ uint32_t *num_sids, >+ struct dom_sid **sids, >+ const struct dom_sid *primary_sid) > { > struct ldb_message_element *el; >- unsigned int i, j; >+ unsigned int i; > > el = ldb_msg_find_element(msg, attr); > if (!el) { >@@ -69,24 +68,25 @@ WERROR samdb_result_sid_array_ndr(struct ldb_context *sam_ctx, > > /* Make array long enough for NULL and additional SID */ > (*sids) = talloc_array(mem_ctx, struct dom_sid, >- el->num_values + num_additional); >+ el->num_values + 1); > W_ERROR_HAVE_NO_MEMORY(*sids); > >- for (i=0; i<el->num_values; i++) { >+ (*sids)[0] = *primary_sid; >+ >+ for (i = 0; i<el->num_values; i++) { > enum ndr_err_code ndr_err; >+ struct dom_sid sid = { 0, }; > >- ndr_err = ndr_pull_struct_blob_all_noalloc(&el->values[i], &(*sids)[i], >+ ndr_err = ndr_pull_struct_blob_all_noalloc(&el->values[i], &sid, > (ndr_pull_flags_fn_t)ndr_pull_dom_sid); > if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { > return WERR_INTERNAL_DB_CORRUPTION; > } >+ /* Primary SID is already in position zero. */ >+ (*sids)[i+1] = sid; > } > >- for (j = 0; j < num_additional; j++) { >- (*sids)[i++] = additional_sids[j]; >- } >- >- *num_sids = i; >+ *num_sids = i+1; > > return WERR_OK; > } >@@ -131,6 +131,7 @@ WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx, > } > > WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ctx, >+ const struct dom_sid *rodc_machine_account_sid, > struct ldb_message *rodc_msg, > struct ldb_message *obj_msg, > uint32_t num_token_sids, >@@ -202,6 +203,12 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct > return WERR_DS_DRA_SECRETS_DENIED; > } > >+ /* The RODC can replicate and print tickets for itself. */ >+ if (dom_sid_equal(&token_sids[0], rodc_machine_account_sid)) { >+ TALLOC_FREE(frame); >+ return WERR_OK; >+ } >+ > if (never_reveal_sids && > sid_list_match(num_token_sids, > token_sids, >@@ -230,6 +237,7 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct > * rather than relying on the caller providing those > */ > WERROR samdb_confirm_rodc_allowed_to_repl_to(struct ldb_context *sam_ctx, >+ struct dom_sid *rodc_machine_account_sid, > struct ldb_message *rodc_msg, > struct ldb_message *obj_msg) > { >@@ -256,7 +264,7 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to(struct ldb_context *sam_ctx, > frame, "tokenGroups", > &num_token_sids, > &token_sids, >- object_sid, 1); >+ object_sid); > if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { > DBG_ERR("Failed to get tokenGroups on %s to confirm access via RODC %s: %s\n", > ldb_dn_get_linearized(obj_msg->dn), >@@ -266,6 +274,7 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to(struct ldb_context *sam_ctx, > } > > werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(sam_ctx, >+ rodc_machine_account_sid, > rodc_msg, > obj_msg, > num_token_sids, >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index 69cdbfba929..99a5214a896 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -435,7 +435,8 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, > &logon_info_blob, > cred_ndr_ptr, > &upn_dns_info_blob, >- NULL, NULL); >+ NULL, NULL, >+ NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > talloc_free(tmp_ctx); > if (NT_STATUS_EQUAL(nt_status, >@@ -567,7 +568,8 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > &pac_blob, > NULL, > &upn_blob, >- NULL, NULL); >+ NULL, NULL, >+ NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > code = EINVAL; > goto done; >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index b2e8a6762cb..870949888d5 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -35,6 +35,7 @@ > #include "libcli/security/security.h" > #include "dsdb/samdb/samdb.h" > #include "auth/kerberos/pac_utils.h" >+#include "source4/dsdb/common/util.h" > > static > NTSTATUS samba_get_logon_info_pac_blob(TALLOC_CTX *mem_ctx, >@@ -744,13 +745,19 @@ int samba_krbtgt_is_in_db(struct samba_kdc_entry *p, > return 0; > } > >+/* >+ * We return not just the blobs, but also the user_info_dc because we >+ * will need, in the RODC case, to confirm that the returned user is >+ * permitted to be replicated to the KDC >+ */ > NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > struct samba_kdc_entry *p, > DATA_BLOB **_logon_info_blob, > DATA_BLOB **_cred_ndr_blob, > DATA_BLOB **_upn_info_blob, > DATA_BLOB **_pac_attrs_blob, >- const krb5_boolean *pac_request) >+ const krb5_boolean *pac_request, >+ struct auth_user_info_dc **_user_info_dc) > { > struct auth_user_info_dc *user_info_dc; > DATA_BLOB *logon_blob = NULL; >@@ -848,7 +855,15 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > } > } > >- TALLOC_FREE(user_info_dc); >+ /* >+ * Return to the caller to allow a check on the allowed/denied >+ * RODC replication groups >+ */ >+ if (_user_info_dc == NULL) { >+ TALLOC_FREE(user_info_dc); >+ } else { >+ *_user_info_dc = user_info_dc; >+ } > *_logon_info_blob = logon_blob; > if (_cred_ndr_blob != NULL) { > *_cred_ndr_blob = cred_blob; >@@ -1094,3 +1109,90 @@ out: > TALLOC_FREE(frame); > return code; > } >+ >+ >+/* >+ * In the RODC case, to confirm that the returned user is permitted to >+ * be replicated to the KDC (krbgtgt_xxx user) represented by *rodc >+ */ >+WERROR samba_rodc_confirm_user_is_allowed(uint32_t num_object_sids, >+ struct dom_sid *object_sids, >+ struct samba_kdc_entry *rodc, >+ struct samba_kdc_entry *object) >+{ >+ int ret; >+ WERROR werr; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ const char *rodc_attrs[] = { "msDS-KrbTgtLink", >+ "msDS-NeverRevealGroup", >+ "msDS-RevealOnDemandGroup", >+ "userAccountControl", >+ "objectSid", >+ NULL }; >+ struct ldb_result *rodc_machine_account = NULL; >+ struct ldb_dn *rodc_machine_account_dn = samdb_result_dn(rodc->kdc_db_ctx->samdb, >+ frame, >+ rodc->msg, >+ "msDS-KrbTgtLinkBL", >+ NULL); >+ const struct dom_sid *rodc_machine_account_sid = NULL; >+ >+ if (rodc_machine_account_dn == NULL) { >+ DBG_ERR("krbtgt account %s has no msDS-KrbTgtLinkBL to find RODC machine account for allow/deny list\n", >+ ldb_dn_get_linearized(rodc->msg->dn)); >+ TALLOC_FREE(frame); >+ return WERR_DS_DRA_BAD_DN; >+ } >+ >+ /* >+ * Follow the link and get the RODC account (the krbtgt >+ * account is the krbtgt_XXX account, but the >+ * msDS-NeverRevealGroup and msDS-RevealOnDemandGroup is on >+ * the RODC$ account) >+ * >+ * We need DSDB_SEARCH_SHOW_EXTENDED_DN as we get a SID lists >+ * out of the extended DNs >+ */ >+ >+ ret = dsdb_search_dn(rodc->kdc_db_ctx->samdb, >+ frame, >+ &rodc_machine_account, >+ rodc_machine_account_dn, >+ rodc_attrs, >+ DSDB_SEARCH_SHOW_EXTENDED_DN); >+ if (ret != LDB_SUCCESS) { >+ DBG_ERR("Failed to fetch RODC machine account %s pointed to by %s to check allow/deny list: %s\n", >+ ldb_dn_get_linearized(rodc_machine_account_dn), >+ ldb_dn_get_linearized(rodc->msg->dn), >+ ldb_errstring(rodc->kdc_db_ctx->samdb)); >+ TALLOC_FREE(frame); >+ return WERR_DS_DRA_BAD_DN; >+ } >+ >+ if (rodc_machine_account->count != 1) { >+ DBG_ERR("Failed to fetch RODC machine account %s pointed to by %s to check allow/deny list: (%d)\n", >+ ldb_dn_get_linearized(rodc_machine_account_dn), >+ ldb_dn_get_linearized(rodc->msg->dn), >+ rodc_machine_account->count); >+ TALLOC_FREE(frame); >+ return WERR_DS_DRA_BAD_DN; >+ } >+ >+ /* if the object SID is equal to the user_sid, allow */ >+ rodc_machine_account_sid = samdb_result_dom_sid(frame, >+ rodc_machine_account->msgs[0], >+ "objectSid"); >+ if (rodc_machine_account_sid == NULL) { >+ return WERR_DS_DRA_BAD_DN; >+ } >+ >+ werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(rodc->kdc_db_ctx->samdb, >+ rodc_machine_account_sid, >+ rodc_machine_account->msgs[0], >+ object->msg, >+ num_object_sids, >+ object_sids); >+ >+ TALLOC_FREE(frame); >+ return werr; >+} >diff --git a/source4/kdc/pac-glue.h b/source4/kdc/pac-glue.h >index 2a7cb68f274..89aa8da63c3 100644 >--- a/source4/kdc/pac-glue.h >+++ b/source4/kdc/pac-glue.h >@@ -52,8 +52,8 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > DATA_BLOB **_cred_ndr_blob, > DATA_BLOB **_upn_info_blob, > DATA_BLOB **_pac_attrs_blob, >- const krb5_boolean *pac_request); >- >+ const krb5_boolean *pac_request, >+ struct auth_user_info_dc **_user_info_dc); > NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > krb5_context context, > struct ldb_context *samdb, >@@ -79,3 +79,12 @@ krb5_error_code samba_kdc_validate_pac_blob( > krb5_context context, > struct samba_kdc_entry *client_skdc_entry, > const krb5_pac pac); >+ >+/* >+ * In the RODC case, to confirm that the returned user is permitted to >+ * be replicated to the KDC (krbgtgt_xxx user) represented by *rodc >+ */ >+WERROR samba_rodc_confirm_user_is_allowed(uint32_t num_sids, >+ struct dom_sid *sids, >+ struct samba_kdc_entry *rodc, >+ struct samba_kdc_entry *object); >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index 11d9ff84f04..71507018120 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -27,6 +27,7 @@ > #include "kdc/pac-glue.h" > #include "sdb.h" > #include "sdb_hdb.h" >+#include "librpc/gen_ndr/auth.h" > > /* > * Given the right private pointer from hdb_samba4, >@@ -68,7 +69,8 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, > cred_ndr_ptr, > &upn_blob, > &pac_attrs_blob, >- pac_request); >+ pac_request, >+ NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > talloc_free(mem_ctx); > return EINVAL; >@@ -161,9 +163,15 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > } > } > >- /* If the krbtgt was generated by an RODC, and we are not that >+ /* >+ * If the krbtgt was generated by an RODC, and we are not that > * RODC, then we need to regenerate the PAC - we can't trust >- * it */ >+ * it, and confirm that the RODC was permitted to print this ticket >+ * >+ * Becasue of the samba_kdc_validate_pac_blob() step we can be >+ * sure that the record in 'client' matches the SID in the >+ * original PAC. >+ */ > ret = samba_krbtgt_is_in_db(krbtgt_skdc_entry, &is_in_db, &is_untrusted); > if (ret != 0) { > talloc_free(mem_ctx); >@@ -237,6 +245,8 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > > if (is_untrusted) { > struct samba_kdc_entry *client_skdc_entry = NULL; >+ struct auth_user_info_dc *user_info_dc = NULL; >+ WERROR werr; > > if (client == NULL) { > return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; >@@ -247,12 +257,30 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > > nt_status = samba_kdc_get_pac_blobs(mem_ctx, client_skdc_entry, > &pac_blob, NULL, &upn_blob, >- NULL, NULL); >+ NULL, NULL, >+ &user_info_dc); > if (!NT_STATUS_IS_OK(nt_status)) { > talloc_free(mem_ctx); >- return EINVAL; >+ return KRB5KDC_ERR_TGT_REVOKED; >+ } >+ >+ /* >+ * Now check if the SID list in the user_info_dc >+ * intersects correctly with the RODC allow/deny >+ * lists >+ */ >+ >+ werr = samba_rodc_confirm_user_is_allowed(user_info_dc->num_sids, >+ user_info_dc->sids, >+ krbtgt_skdc_entry, >+ client_skdc_entry); >+ if (!W_ERROR_IS_OK(werr)) { >+ talloc_free(mem_ctx); >+ return KRB5KDC_ERR_TGT_REVOKED; > } >- } else { >+ } >+ >+ if (!is_untrusted) { > pac_blob = talloc_zero(mem_ctx, DATA_BLOB); > if (!pac_blob) { > talloc_free(mem_ctx); >diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c >index 703e523eddf..39e6c5b7308 100644 >--- a/source4/rpc_server/drsuapi/getncchanges.c >+++ b/source4/rpc_server/drsuapi/getncchanges.c >@@ -1199,7 +1199,6 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > NULL }; > const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL }; > struct ldb_result *rodc_res = NULL, *obj_res = NULL; >- const struct dom_sid *object_sid = NULL; > WERROR werr; > > DEBUG(3,(__location__ ": DRSUAPI_EXOP_REPL_SECRET extended op on %s\n", >@@ -1287,15 +1286,6 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > ret = dsdb_search_dn(b_state->sam_ctx_system, mem_ctx, &obj_res, obj_dn, obj_attrs, 0); > if (ret != LDB_SUCCESS || obj_res->count != 1) goto failed; > >- /* if the object SID is equal to the user_sid, allow */ >- object_sid = samdb_result_dom_sid(mem_ctx, obj_res->msgs[0], "objectSid"); >- if (object_sid == NULL) { >- goto failed; >- } >- if (dom_sid_equal(user_sid, object_sid)) { >- goto allowed; >- } >- > /* > * Must be an RODC account at this point, verify machine DN matches the > * SID account >@@ -1313,6 +1303,7 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, > } > > werr = samdb_confirm_rodc_allowed_to_repl_to(b_state->sam_ctx_system, >+ user_sid, > rodc_res->msgs[0], > obj_res->msgs[0]); > >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index 83ec3b92ee4..e640ad1e6f3 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -2839,6 +2839,7 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx, > if (ret != LDB_SUCCESS || obj_res->count != 1) goto denied; > > werr = samdb_confirm_rodc_allowed_to_repl_to(sam_ctx, >+ user_sid, > rodc_res->msgs[0], > obj_res->msgs[0]); > >-- >2.25.1 > > >From 1581f6ff63def737e201b609a9b1a7e60d16fd33 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 4 Oct 2021 12:43:13 +1300 >Subject: [PATCH 620/686] CVE-2020-25718 kdc: Return ERR_POLICY if RODC krbtgt > account is invalid > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail_heimdal_kdc | 8 -------- > source4/dsdb/common/rodc_helper.c | 2 +- > source4/kdc/pac-glue.c | 4 ++-- > source4/kdc/wdc-samba4.c | 6 +++++- > 4 files changed, 8 insertions(+), 12 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 7d0597fa279..5b6fb0ddf69 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -265,16 +265,10 @@ > # KDC TGT tests > # > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_no_krbtgt_link >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_no_partial_secrets > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_no_krbtgt_link >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_no_partial_secrets > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_krbtgt_link >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_partial_secrets > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_mac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_mac >@@ -307,8 +301,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_srealm > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_no_krbtgt_link >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_no_partial_secrets > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed > # > # PAC request tests >diff --git a/source4/dsdb/common/rodc_helper.c b/source4/dsdb/common/rodc_helper.c >index 1cd644c6def..e81ecef79c0 100644 >--- a/source4/dsdb/common/rodc_helper.c >+++ b/source4/dsdb/common/rodc_helper.c >@@ -176,7 +176,7 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct > DBG_ERR("Attempt to use an RODC account that is not an RODC: %s\n", > ldb_dn_get_linearized(rodc_msg->dn)); > TALLOC_FREE(frame); >- return WERR_DS_DRA_SECRETS_DENIED; >+ return WERR_DOMAIN_CONTROLLER_NOT_FOUND; > } > > werr = samdb_result_sid_array_dn(sam_ctx, rodc_msg, >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index 870949888d5..33f2eebaa70 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -1141,7 +1141,7 @@ WERROR samba_rodc_confirm_user_is_allowed(uint32_t num_object_sids, > DBG_ERR("krbtgt account %s has no msDS-KrbTgtLinkBL to find RODC machine account for allow/deny list\n", > ldb_dn_get_linearized(rodc->msg->dn)); > TALLOC_FREE(frame); >- return WERR_DS_DRA_BAD_DN; >+ return WERR_DOMAIN_CONTROLLER_NOT_FOUND; > } > > /* >@@ -1166,7 +1166,7 @@ WERROR samba_rodc_confirm_user_is_allowed(uint32_t num_object_sids, > ldb_dn_get_linearized(rodc->msg->dn), > ldb_errstring(rodc->kdc_db_ctx->samdb)); > TALLOC_FREE(frame); >- return WERR_DS_DRA_BAD_DN; >+ return WERR_DOMAIN_CONTROLLER_NOT_FOUND; > } > > if (rodc_machine_account->count != 1) { >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index 71507018120..c9bf5dd9cf5 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -276,7 +276,11 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > client_skdc_entry); > if (!W_ERROR_IS_OK(werr)) { > talloc_free(mem_ctx); >- return KRB5KDC_ERR_TGT_REVOKED; >+ if (W_ERROR_EQUAL(werr, WERR_DOMAIN_CONTROLLER_NOT_FOUND)) { >+ return KRB5KDC_ERR_POLICY; >+ } else { >+ return KRB5KDC_ERR_TGT_REVOKED; >+ } > } > } > >-- >2.25.1 > > >From 5fc9a3c14a8da18397ca8f6415a36c259b084fe6 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 8 Oct 2021 08:29:51 +1300 >Subject: [PATCH 621/686] CVE-2020-25719 kdc: Avoid races and multiple DB > lookups in s4u2self check > >Looking up the DB twice is subject to a race and is a poor >use of resources, so instead just pass in the record we >already got when trying to confirm that the server in >S4U2Self is the same as the requesting client. > >The client record has already been bound to the the >original client by the SID check in the PAC. > >Likewise by looking up server only once we ensure >that the keys looked up originally are in the record >we confirm the SID for here. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14686 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/heimdal/kdc/krb5tgs.c | 26 +++++++++++------ > source4/heimdal/lib/hdb/hdb.h | 2 +- > source4/kdc/db-glue.c | 54 ++++++++++++----------------------- > source4/kdc/db-glue.h | 5 ++-- > source4/kdc/hdb-samba4.c | 43 ++++++++-------------------- > 5 files changed, 52 insertions(+), 78 deletions(-) > >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index cff35fc2a65..ae16dac7448 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -313,7 +313,7 @@ check_constrained_delegation(krb5_context context, > * Determine if s4u2self is allowed from this client to this server > * > * For example, regardless of the principal being impersonated, if the >- * 'client' and 'server' are the same, then it's safe. >+ * 'client' and 'server' (target) are the same, then it's safe. > */ > > static krb5_error_code >@@ -321,18 +321,28 @@ check_s4u2self(krb5_context context, > krb5_kdc_configuration *config, > HDB *clientdb, > hdb_entry_ex *client, >- krb5_const_principal server) >+ hdb_entry_ex *target_server, >+ krb5_const_principal target_server_principal) > { > krb5_error_code ret; > >- /* if client does a s4u2self to itself, that ok */ >- if (krb5_principal_compare(context, client->entry.principal, server) == TRUE) >- return 0; >- >+ /* >+ * Always allow the plugin to check, this might be faster, allow a >+ * policy or audit check and can look into the DB records >+ * directly >+ */ > if (clientdb->hdb_check_s4u2self) { >- ret = clientdb->hdb_check_s4u2self(context, clientdb, client, server); >+ ret = clientdb->hdb_check_s4u2self(context, >+ clientdb, >+ client, >+ target_server); > if (ret == 0) > return 0; >+ } else if (krb5_principal_compare(context, >+ client->entry.principal, >+ target_server_principal) == TRUE) { >+ /* if client does a s4u2self to itself, and there is no plugin, that is ok */ >+ return 0; > } else { > ret = KRB5KDC_ERR_BADOPTION; > } >@@ -1751,7 +1761,7 @@ server_lookup: > * Check that service doing the impersonating is > * requesting a ticket to it-self. > */ >- ret = check_s4u2self(context, config, clientdb, client, sp); >+ ret = check_s4u2self(context, config, clientdb, client, server, sp); > if (ret) { > kdc_log(context, config, 0, "S4U2Self: %s is not allowed " > "to impersonate to service " >diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h >index 6a09ecb6fe1..5ef9d9565f3 100644 >--- a/source4/heimdal/lib/hdb/hdb.h >+++ b/source4/heimdal/lib/hdb/hdb.h >@@ -266,7 +266,7 @@ typedef struct HDB{ > /** > * Check if s4u2self is allowed from this client to this server > */ >- krb5_error_code (*hdb_check_s4u2self)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal); >+ krb5_error_code (*hdb_check_s4u2self)(krb5_context, struct HDB *, hdb_entry_ex *, hdb_entry_ex *); > }HDB; > > #define HDB_INTERFACE_VERSION 7 >diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c >index 63d910eccb4..bb63e2f31ad 100644 >--- a/source4/kdc/db-glue.c >+++ b/source4/kdc/db-glue.c >@@ -2502,53 +2502,37 @@ krb5_error_code samba_kdc_nextkey(krb5_context context, > > /* Check if a given entry may delegate or do s4u2self to this target principal > * >- * This is currently a very nasty hack - allowing only delegation to itself. >+ * The safest way to determine 'self' is to check the DB record made at >+ * the time the principal was presented to the KDC. > */ > krb5_error_code > samba_kdc_check_s4u2self(krb5_context context, >- struct samba_kdc_db_context *kdc_db_ctx, >- struct samba_kdc_entry *skdc_entry, >- krb5_const_principal target_principal) >+ struct samba_kdc_entry *skdc_entry_client, >+ struct samba_kdc_entry *skdc_entry_server_target) > { >- krb5_error_code ret; >- struct ldb_dn *realm_dn; >- struct ldb_message *msg; > struct dom_sid *orig_sid; > struct dom_sid *target_sid; >- const char *delegation_check_attrs[] = { >- "objectSid", NULL >- }; >- >- TALLOC_CTX *mem_ctx = talloc_named(kdc_db_ctx, 0, "samba_kdc_check_s4u2self"); >- >- if (!mem_ctx) { >- ret = ENOMEM; >- krb5_set_error_message(context, ret, "samba_kdc_check_s4u2self: talloc_named() failed!"); >- return ret; >- } >- >- ret = samba_kdc_lookup_server(context, kdc_db_ctx, mem_ctx, target_principal, >- SDB_F_GET_CLIENT|SDB_F_GET_SERVER, >- delegation_check_attrs, &realm_dn, &msg); >- >- if (ret != 0) { >- talloc_free(mem_ctx); >- return ret; >- } >+ TALLOC_CTX *frame = talloc_stackframe(); > >- orig_sid = samdb_result_dom_sid(mem_ctx, skdc_entry->msg, "objectSid"); >- target_sid = samdb_result_dom_sid(mem_ctx, msg, "objectSid"); >+ orig_sid = samdb_result_dom_sid(frame, >+ skdc_entry_client->msg, >+ "objectSid"); >+ target_sid = samdb_result_dom_sid(frame, >+ skdc_entry_server_target->msg, >+ "objectSid"); > >- /* Allow delegation to the same principal, even if by a different >- * name. The easy and safe way to prove this is by SID >- * comparison */ >+ /* >+ * Allow delegation to the same record (representing a >+ * principal), even if by a different name. The easy and safe >+ * way to prove this is by SID comparison >+ */ > if (!(orig_sid && target_sid && dom_sid_equal(orig_sid, target_sid))) { >- talloc_free(mem_ctx); >+ talloc_free(frame); > return KRB5KDC_ERR_BADOPTION; > } > >- talloc_free(mem_ctx); >- return ret; >+ talloc_free(frame); >+ return 0; > } > > /* Certificates printed by a the Certificate Authority might have a >diff --git a/source4/kdc/db-glue.h b/source4/kdc/db-glue.h >index aa630f5d349..cadfac1deb8 100644 >--- a/source4/kdc/db-glue.h >+++ b/source4/kdc/db-glue.h >@@ -40,9 +40,8 @@ krb5_error_code samba_kdc_nextkey(krb5_context context, > > krb5_error_code > samba_kdc_check_s4u2self(krb5_context context, >- struct samba_kdc_db_context *kdc_db_ctx, >- struct samba_kdc_entry *skdc_entry, >- krb5_const_principal target_principal); >+ struct samba_kdc_entry *skdc_entry_client, >+ struct samba_kdc_entry *skdc_entry_server_target); > > krb5_error_code > samba_kdc_check_pkinit_ms_upn_match(krb5_context context, >diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c >index cff472574d4..0e25cd72321 100644 >--- a/source4/kdc/hdb-samba4.c >+++ b/source4/kdc/hdb-samba4.c >@@ -274,38 +274,19 @@ hdb_samba4_check_pkinit_ms_upn_match(krb5_context context, HDB *db, > > static krb5_error_code > hdb_samba4_check_s4u2self(krb5_context context, HDB *db, >- hdb_entry_ex *entry, >- krb5_const_principal target_principal) >+ hdb_entry_ex *client_entry, >+ hdb_entry_ex *server_target_entry) > { >- struct samba_kdc_db_context *kdc_db_ctx; >- struct samba_kdc_entry *skdc_entry; >- krb5_error_code ret; >- >- kdc_db_ctx = talloc_get_type_abort(db->hdb_db, >- struct samba_kdc_db_context); >- skdc_entry = talloc_get_type_abort(entry->ctx, >- struct samba_kdc_entry); >- >- ret = samba_kdc_check_s4u2self(context, kdc_db_ctx, >- skdc_entry, >- target_principal); >- switch (ret) { >- case 0: >- break; >- case SDB_ERR_WRONG_REALM: >- ret = HDB_ERR_WRONG_REALM; >- break; >- case SDB_ERR_NOENTRY: >- ret = HDB_ERR_NOENTRY; >- break; >- case SDB_ERR_NOT_FOUND_HERE: >- ret = HDB_ERR_NOT_FOUND_HERE; >- break; >- default: >- break; >- } >- >- return ret; >+ struct samba_kdc_entry *skdc_client_entry >+ = talloc_get_type_abort(client_entry->ctx, >+ struct samba_kdc_entry); >+ struct samba_kdc_entry *skdc_server_target_entry >+ = talloc_get_type_abort(server_target_entry->ctx, >+ struct samba_kdc_entry); >+ >+ return samba_kdc_check_s4u2self(context, >+ skdc_client_entry, >+ skdc_server_target_entry); > } > > static void reset_bad_password_netlogon(TALLOC_CTX *mem_ctx, >-- >2.25.1 > > >From a24ae63d70b0f935ced9dce8ee8b927c5795ca57 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 27 Sep 2021 12:10:02 +1300 >Subject: [PATCH 622/686] CVE-2020-25721 auth: Fill in the new > HAS_SAM_NAME_AND_SID values > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14835 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > python/samba/tests/krb5/s4u_tests.py | 2 -- > selftest/knownfail_heimdal_kdc | 10 ---------- > selftest/knownfail_mit_kdc | 4 ---- > source4/kdc/pac-glue.c | 8 ++++++++ > 4 files changed, 8 insertions(+), 16 deletions(-) > >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index 5005affd6b3..a80a7b3427e 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -309,7 +309,6 @@ class S4UKerberosTests(KDCBaseTest): > tgt=service_tgt, > authenticator_subkey=authenticator_subkey, > kdc_options=str(kdc_options), >- expect_upn_dns_info_ex=False, > expect_claims=False) > > self._generic_kdc_exchange(kdc_exchange_dict, >@@ -611,7 +610,6 @@ class S4UKerberosTests(KDCBaseTest): > kdc_options=kdc_options, > pac_options=pac_options, > expect_edata=expect_edata, >- expect_upn_dns_info_ex=False, > expected_proxy_target=expected_proxy_target, > expected_transited_services=expected_transited_services, > expect_pac=expect_pac) >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 5b6fb0ddf69..80044551c9c 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -245,12 +245,6 @@ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_forwardable > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_empty_allowed > # >-# The lack of KRB5SignedPath means we no longer return >-# KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case >-# >-^samba4.krb5.kdc with machine account.as-req-pac-request.fl2000dc:local >-# >-# > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_auth_data_required > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_auth_data_required > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_a >@@ -270,10 +264,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_revealed >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_mac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_mac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_user >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_user > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_host > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index d01b792eb94..7b0cd39723a 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -432,10 +432,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_mac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_mac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_upn_user >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_upn_dns_info_ex_user > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_sname >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index 33f2eebaa70..587f647b72e 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -101,6 +101,14 @@ NTSTATUS samba_get_upn_info_pac_blob(TALLOC_CTX *mem_ctx, > pac_upn.upn_dns_info.flags |= PAC_UPN_DNS_FLAG_CONSTRUCTED; > } > >+ pac_upn.upn_dns_info.flags |= PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID; >+ >+ pac_upn.upn_dns_info.ex.sam_name_and_sid.samaccountname >+ = info->info->account_name; >+ >+ pac_upn.upn_dns_info.ex.sam_name_and_sid.objectsid >+ = &info->sids[0]; >+ > ndr_err = ndr_push_union_blob(upn_data, mem_ctx, &pac_upn, > PAC_TYPE_UPN_DNS_INFO, > (ndr_push_flags_fn_t)ndr_push_PAC_INFO); >-- >2.25.1 > > >From 9e97f6c6733c9b066745aab0d3e4178d776b424d Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Wed, 20 Oct 2021 11:36:58 +1300 >Subject: [PATCH 623/686] CVE-2020-25722 Ensure the structural objectclass > cannot be changed > >If the structural objectclass is allowed to change, then the restrictions >locking an object to remaining a user or computer will not be enforcable. > >Likewise other LDAP inheritance rules, which allow only certain >child objects can be bypassed, which can in turn allow creation of >(unprivileged) users where only DNS objects were expected. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14889 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs and fixed knownfail > conflicts] >--- > selftest/knownfail.d/ldap | 1 - > selftest/knownfail.d/uac_mod_lock | 28 --------------- > selftest/knownfail.d/uac_objectclass_restrict | 4 --- > source4/dsdb/samdb/ldb_modules/objectclass.c | 36 +++++++++++++++++++ > 4 files changed, 36 insertions(+), 33 deletions(-) > delete mode 100644 selftest/knownfail.d/ldap > delete mode 100644 selftest/knownfail.d/uac_mod_lock > >diff --git a/selftest/knownfail.d/ldap b/selftest/knownfail.d/ldap >deleted file mode 100644 >index 2773a7f1a23..00000000000 >--- a/selftest/knownfail.d/ldap >+++ /dev/null >@@ -1 +0,0 @@ >-^samba4.ldap.python.+test_objectclasses >diff --git a/selftest/knownfail.d/uac_mod_lock b/selftest/knownfail.d/uac_mod_lock >deleted file mode 100644 >index 79db7dc7a8f..00000000000 >--- a/selftest/knownfail.d/uac_mod_lock >+++ /dev/null >@@ -1,28 +0,0 @@ >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_NORMAL_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_user_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_user_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_user_UF_NORMAL_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_priv_user_UF_NORMAL_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_WORKSTATION_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_user_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_keep_dollar >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_lock_wp_user_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar >diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict >index 51387ae0786..c7dd2157d3c 100644 >--- a/selftest/knownfail.d/uac_objectclass_restrict >+++ b/selftest/knownfail.d/uac_objectclass_restrict >@@ -15,7 +15,3 @@ > ^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-user_mod-replace_CC_default_computer\(ad_dc_default\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_add_computer_sd_cc\(ad_dc_ntvfs\) > ^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_mod_computer_cc\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_computer_replace\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_user_replace\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_SERVER_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) >-^samba4.user_account_control.python\(ad_dc_ntvfs\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_replace\(ad_dc_ntvfs\) >diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c >index 36ab76e19fc..d8feff0262c 100644 >--- a/source4/dsdb/samdb/ldb_modules/objectclass.c >+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c >@@ -811,6 +811,7 @@ static int objectclass_do_mod(struct oc_context *ac) > struct ldb_message_element *oc_el_entry, *oc_el_change; > struct ldb_val *vals; > struct ldb_message *msg; >+ const struct dsdb_class *current_structural_objectclass; > const struct dsdb_class *objectclass; > unsigned int i, j, k; > bool found; >@@ -830,6 +831,22 @@ static int objectclass_do_mod(struct oc_context *ac) > return ldb_operr(ldb); > } > >+ /* >+ * Get the current new top-most structural object class >+ * >+ * We must not allow this to change >+ */ >+ >+ current_structural_objectclass >+ = dsdb_get_last_structural_class(ac->schema, >+ oc_el_entry); >+ if (current_structural_objectclass == NULL) { >+ ldb_asprintf_errstring(ldb, >+ "objectclass: cannot find current structural objectclass on %s!", >+ ldb_dn_get_linearized(ac->search_res->message->dn)); >+ return LDB_ERR_OBJECT_CLASS_VIOLATION; >+ } >+ > /* use a new message structure */ > msg = ldb_msg_new(ac); > if (msg == NULL) { >@@ -939,6 +956,25 @@ static int objectclass_do_mod(struct oc_context *ac) > return LDB_ERR_OBJECT_CLASS_VIOLATION; > } > >+ /* >+ * Has (so far, we re-check for each and every >+ * "objectclass" in the message) the structural >+ * objectclass changed? >+ */ >+ >+ if (objectclass != current_structural_objectclass) { >+ const char *dn >+ = ldb_dn_get_linearized(ac->search_res->message->dn); >+ ldb_asprintf_errstring(ldb, >+ "objectclass: not permitted " >+ "to change the structural " >+ "objectClass on %s [%s] => [%s]!", >+ dn, >+ current_structural_objectclass->lDAPDisplayName, >+ objectclass->lDAPDisplayName); >+ return LDB_ERR_OBJECT_CLASS_VIOLATION; >+ } >+ > /* Check for unrelated objectclasses */ > ret = check_unrelated_objectclasses(ac->module, ac->schema, > objectclass, >-- >2.25.1 > > >From df1147f175779e5b302b31e52df92e91d8f3287c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:42:41 +1300 >Subject: [PATCH 624/686] CVE-2020-25719 s4:kdc: Add KDC support for > PAC_REQUESTER_SID PAC buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail_heimdal_kdc | 57 ------------ > source4/kdc/mit_samba.c | 4 +- > source4/kdc/pac-glue.c | 163 ++++++++++++++++++++++++++++++--- > source4/kdc/pac-glue.h | 2 + > source4/kdc/wdc-samba4.c | 34 ++++++- > 5 files changed, 185 insertions(+), 75 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 80044551c9c..9cad1ca4d05 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -301,60 +301,3 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_false > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_none > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true >-# >-# PAC requester SID tests >-# >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_as_requester_sid >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_renew >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting >-# >-# PAC tests >-# >-^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc:local >-^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc_ntvfs:local >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index 99a5214a896..e015c5a52db 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -435,7 +435,7 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, > &logon_info_blob, > cred_ndr_ptr, > &upn_dns_info_blob, >- NULL, NULL, >+ NULL, NULL, NULL, > NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > talloc_free(tmp_ctx); >@@ -465,6 +465,7 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, > upn_dns_info_blob, > NULL, > NULL, >+ NULL, > pac); > > talloc_free(tmp_ctx); >@@ -569,6 +570,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > NULL, > &upn_blob, > NULL, NULL, >+ NULL, > NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > code = EINVAL; >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index 587f647b72e..f2543ab5306 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -40,7 +40,8 @@ > static > NTSTATUS samba_get_logon_info_pac_blob(TALLOC_CTX *mem_ctx, > const struct auth_user_info_dc *info, >- DATA_BLOB *pac_data) >+ DATA_BLOB *pac_data, >+ DATA_BLOB *requester_sid_blob) > { > struct netr_SamInfo3 *info3; > union PAC_INFO pac_info; >@@ -50,6 +51,9 @@ NTSTATUS samba_get_logon_info_pac_blob(TALLOC_CTX *mem_ctx, > ZERO_STRUCT(pac_info); > > *pac_data = data_blob_null; >+ if (requester_sid_blob != NULL) { >+ *requester_sid_blob = data_blob_null; >+ } > > nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx, info, &info3); > if (!NT_STATUS_IS_OK(nt_status)) { >@@ -75,6 +79,25 @@ NTSTATUS samba_get_logon_info_pac_blob(TALLOC_CTX *mem_ctx, > return nt_status; > } > >+ if (requester_sid_blob != NULL && info->num_sids > 0) { >+ union PAC_INFO pac_requester_sid; >+ >+ ZERO_STRUCT(pac_requester_sid); >+ >+ pac_requester_sid.requester_sid.sid = info->sids[0]; >+ >+ ndr_err = ndr_push_union_blob(requester_sid_blob, mem_ctx, >+ &pac_requester_sid, >+ PAC_TYPE_REQUESTER_SID, >+ (ndr_push_flags_fn_t)ndr_push_PAC_INFO); >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >+ nt_status = ndr_map_error2ntstatus(ndr_err); >+ DEBUG(1, ("PAC_REQUESTER_SID (presig) push failed: %s\n", >+ nt_errstr(nt_status))); >+ return nt_status; >+ } >+ } >+ > return NT_STATUS_OK; > } > >@@ -460,6 +483,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > const DATA_BLOB *cred_blob, > const DATA_BLOB *upn_blob, > const DATA_BLOB *pac_attrs_blob, >+ const DATA_BLOB *requester_sid_blob, > const DATA_BLOB *deleg_blob, > krb5_pac *pac) > { >@@ -467,6 +491,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > krb5_data cred_data; > krb5_data upn_data; > krb5_data pac_attrs_data; >+ krb5_data requester_sid_data; > krb5_data deleg_data; > krb5_error_code ret; > #ifdef SAMBA4_USES_HEIMDAL >@@ -524,6 +549,20 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > } > } > >+ ZERO_STRUCT(requester_sid_data); >+ if (requester_sid_blob != NULL) { >+ ret = smb_krb5_copy_data_contents(&requester_sid_data, >+ requester_sid_blob->data, >+ requester_sid_blob->length); >+ if (ret != 0) { >+ smb_krb5_free_data_contents(context, &logon_data); >+ smb_krb5_free_data_contents(context, &cred_data); >+ smb_krb5_free_data_contents(context, &upn_data); >+ smb_krb5_free_data_contents(context, &pac_attrs_data); >+ return ret; >+ } >+ } >+ > ZERO_STRUCT(deleg_data); > if (deleg_blob != NULL) { > ret = smb_krb5_copy_data_contents(&deleg_data, >@@ -534,6 +573,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > smb_krb5_free_data_contents(context, &cred_data); > smb_krb5_free_data_contents(context, &upn_data); > smb_krb5_free_data_contents(context, &pac_attrs_data); >+ smb_krb5_free_data_contents(context, &requester_sid_data); > return ret; > } > } >@@ -544,6 +584,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > smb_krb5_free_data_contents(context, &cred_data); > smb_krb5_free_data_contents(context, &upn_data); > smb_krb5_free_data_contents(context, &pac_attrs_data); >+ smb_krb5_free_data_contents(context, &requester_sid_data); > smb_krb5_free_data_contents(context, &deleg_data); > return ret; > } >@@ -554,6 +595,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > smb_krb5_free_data_contents(context, &cred_data); > smb_krb5_free_data_contents(context, &upn_data); > smb_krb5_free_data_contents(context, &pac_attrs_data); >+ smb_krb5_free_data_contents(context, &requester_sid_data); > smb_krb5_free_data_contents(context, &deleg_data); > return ret; > } >@@ -566,6 +608,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > if (ret != 0) { > smb_krb5_free_data_contents(context, &upn_data); > smb_krb5_free_data_contents(context, &pac_attrs_data); >+ smb_krb5_free_data_contents(context, &requester_sid_data); > smb_krb5_free_data_contents(context, &deleg_data); > return ret; > } >@@ -585,6 +628,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > if (ret != 0) { > smb_krb5_free_data_contents(context, &upn_data); > smb_krb5_free_data_contents(context, &pac_attrs_data); >+ smb_krb5_free_data_contents(context, &requester_sid_data); > smb_krb5_free_data_contents(context, &deleg_data); > return ret; > } >@@ -597,6 +641,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > smb_krb5_free_data_contents(context, &upn_data); > if (ret != 0) { > smb_krb5_free_data_contents(context, &pac_attrs_data); >+ smb_krb5_free_data_contents(context, &requester_sid_data); > smb_krb5_free_data_contents(context, &deleg_data); > return ret; > } >@@ -607,6 +652,18 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > PAC_TYPE_ATTRIBUTES_INFO, > &pac_attrs_data); > smb_krb5_free_data_contents(context, &pac_attrs_data); >+ if (ret != 0) { >+ smb_krb5_free_data_contents(context, &requester_sid_data); >+ smb_krb5_free_data_contents(context, &deleg_data); >+ return ret; >+ } >+ } >+ >+ if (requester_sid_blob != NULL) { >+ ret = krb5_pac_add_buffer(context, *pac, >+ PAC_TYPE_REQUESTER_SID, >+ &requester_sid_data); >+ smb_krb5_free_data_contents(context, &requester_sid_data); > if (ret != 0) { > smb_krb5_free_data_contents(context, &deleg_data); > return ret; >@@ -765,6 +822,7 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > DATA_BLOB **_upn_info_blob, > DATA_BLOB **_pac_attrs_blob, > const krb5_boolean *pac_request, >+ DATA_BLOB **_requester_sid_blob, > struct auth_user_info_dc **_user_info_dc) > { > struct auth_user_info_dc *user_info_dc; >@@ -772,6 +830,7 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > DATA_BLOB *cred_blob = NULL; > DATA_BLOB *upn_blob = NULL; > DATA_BLOB *pac_attrs_blob = NULL; >+ DATA_BLOB *requester_sid_blob = NULL; > NTSTATUS nt_status; > > *_logon_info_blob = NULL; >@@ -782,6 +841,9 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > if (_pac_attrs_blob != NULL) { > *_pac_attrs_blob = NULL; > } >+ if (_requester_sid_blob != NULL) { >+ *_requester_sid_blob = NULL; >+ } > > logon_blob = talloc_zero(mem_ctx, DATA_BLOB); > if (logon_blob == NULL) { >@@ -807,6 +869,13 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > } > } > >+ if (_requester_sid_blob != NULL) { >+ requester_sid_blob = talloc_zero(mem_ctx, DATA_BLOB); >+ if (requester_sid_blob == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ } >+ > nt_status = authsam_make_user_info_dc(mem_ctx, p->kdc_db_ctx->samdb, > lpcfg_netbios_name(p->kdc_db_ctx->lp_ctx), > lpcfg_sam_name(p->kdc_db_ctx->lp_ctx), >@@ -824,7 +893,8 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > > nt_status = samba_get_logon_info_pac_blob(logon_blob, > user_info_dc, >- logon_blob); >+ logon_blob, >+ requester_sid_blob); > if (!NT_STATUS_IS_OK(nt_status)) { > DEBUG(0, ("Building PAC LOGON INFO failed: %s\n", > nt_errstr(nt_status))); >@@ -880,6 +950,9 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > if (_pac_attrs_blob != NULL) { > *_pac_attrs_blob = pac_attrs_blob; > } >+ if (_requester_sid_blob != NULL) { >+ *_requester_sid_blob = requester_sid_blob; >+ } > return NT_STATUS_OK; > } > >@@ -912,7 +985,7 @@ NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > } > > nt_status = samba_get_logon_info_pac_blob(mem_ctx, >- user_info_dc, pac_blob); >+ user_info_dc, pac_blob, NULL); > > return nt_status; > } >@@ -1062,6 +1135,52 @@ NTSTATUS samba_kdc_check_client_access(struct samba_kdc_entry *kdc_entry, > return nt_status; > } > >+static krb5_error_code samba_get_requester_sid(TALLOC_CTX *mem_ctx, >+ krb5_pac pac, >+ krb5_context context, >+ struct dom_sid *sid) >+{ >+ NTSTATUS nt_status; >+ enum ndr_err_code ndr_err; >+ krb5_error_code ret; >+ >+ DATA_BLOB pac_requester_sid_in; >+ krb5_data k5pac_requester_sid_in; >+ >+ union PAC_INFO info; >+ >+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); >+ if (tmp_ctx == NULL) { >+ return ENOMEM; >+ } >+ >+ ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_REQUESTER_SID, >+ &k5pac_requester_sid_in); >+ if (ret != 0) { >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ >+ pac_requester_sid_in = data_blob_const(k5pac_requester_sid_in.data, >+ k5pac_requester_sid_in.length); >+ >+ ndr_err = ndr_pull_union_blob(&pac_requester_sid_in, tmp_ctx, &info, >+ PAC_TYPE_REQUESTER_SID, >+ (ndr_pull_flags_fn_t)ndr_pull_PAC_INFO); >+ smb_krb5_free_data_contents(context, &k5pac_requester_sid_in); >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >+ nt_status = ndr_map_error2ntstatus(ndr_err); >+ DEBUG(0,("can't parse the PAC REQUESTER_SID: %s\n", nt_errstr(nt_status))); >+ talloc_free(tmp_ctx); >+ return EINVAL; >+ } >+ >+ *sid = info.requester_sid.sid; >+ >+ talloc_free(tmp_ctx); >+ return 0; >+} >+ > /* Does a parse and SID check, but no crypto. */ > krb5_error_code samba_kdc_validate_pac_blob( > krb5_context context, >@@ -1075,22 +1194,36 @@ krb5_error_code samba_kdc_validate_pac_blob( > krb5_error_code code; > bool ok; > >- code = kerberos_pac_to_user_info_dc(frame, >- pac, >- context, >- &pac_user_info, >- NULL, >- NULL); >- if (code != 0) { >- goto out; >- } >+ /* >+ * First, try to get the SID from the requester SID buffer in the PAC. >+ */ >+ code = samba_get_requester_sid(frame, pac, context, &pac_sid); >+ >+ if (code == ENOENT) { >+ /* >+ * If the requester SID buffer isn't present, fall back to the >+ * SID in the LOGON_INFO PAC buffer. >+ */ >+ code = kerberos_pac_to_user_info_dc(frame, >+ pac, >+ context, >+ &pac_user_info, >+ NULL, >+ NULL); >+ if (code != 0) { >+ goto out; >+ } >+ >+ if (pac_user_info->num_sids == 0) { >+ code = EINVAL; >+ goto out; >+ } > >- if (pac_user_info->num_sids == 0) { >- code = EINVAL; >+ pac_sid = pac_user_info->sids[0]; >+ } else if (code != 0) { > goto out; > } > >- pac_sid = pac_user_info->sids[0]; > client_sid = samdb_result_dom_sid(frame, > client_skdc_entry->msg, > "objectSid"); >diff --git a/source4/kdc/pac-glue.h b/source4/kdc/pac-glue.h >index 89aa8da63c3..266e000f9cd 100644 >--- a/source4/kdc/pac-glue.h >+++ b/source4/kdc/pac-glue.h >@@ -32,6 +32,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context, > const DATA_BLOB *cred_blob, > const DATA_BLOB *upn_blob, > const DATA_BLOB *pac_attrs_blob, >+ const DATA_BLOB *requester_sid_blob, > const DATA_BLOB *deleg_blob, > krb5_pac *pac); > >@@ -53,6 +54,7 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > DATA_BLOB **_upn_info_blob, > DATA_BLOB **_pac_attrs_blob, > const krb5_boolean *pac_request, >+ DATA_BLOB **_requester_sid_blob, > struct auth_user_info_dc **_user_info_dc); > NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > krb5_context context, >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index c9bf5dd9cf5..ecd182702c3 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -49,6 +49,7 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, > DATA_BLOB *cred_blob = NULL; > DATA_BLOB *upn_blob = NULL; > DATA_BLOB *pac_attrs_blob = NULL; >+ DATA_BLOB *requester_sid_blob = NULL; > krb5_error_code ret; > NTSTATUS nt_status; > struct samba_kdc_entry *skdc_entry = >@@ -70,6 +71,7 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, > &upn_blob, > &pac_attrs_blob, > pac_request, >+ &requester_sid_blob, > NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > talloc_free(mem_ctx); >@@ -91,7 +93,7 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, > > ret = samba_make_krb5_pac(context, logon_blob, cred_blob, > upn_blob, pac_attrs_blob, >- NULL, pac); >+ requester_sid_blob, NULL, pac); > > talloc_free(mem_ctx); > return ret; >@@ -125,6 +127,7 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > krb5_pac new_pac = NULL; > DATA_BLOB *pac_blob = NULL; > DATA_BLOB *upn_blob = NULL; >+ DATA_BLOB *requester_sid_blob = NULL; > DATA_BLOB *deleg_blob = NULL; > krb5_error_code ret; > NTSTATUS nt_status; >@@ -141,6 +144,7 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > ssize_t kdc_checksum_idx = -1; > ssize_t tkt_checksum_idx = -1; > ssize_t attrs_info_idx = -1; >+ ssize_t requester_sid_idx = -1; > > if (!mem_ctx) { > return ENOMEM; >@@ -257,7 +261,7 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > > nt_status = samba_kdc_get_pac_blobs(mem_ctx, client_skdc_entry, > &pac_blob, NULL, &upn_blob, >- NULL, NULL, >+ NULL, NULL, &requester_sid_blob, > &user_info_dc); > if (!NT_STATUS_IS_OK(nt_status)) { > talloc_free(mem_ctx); >@@ -408,6 +412,18 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > } > attrs_info_idx = i; > break; >+ case PAC_TYPE_REQUESTER_SID: >+ if (requester_sid_idx != -1) { >+ DEBUG(1, ("requester sid type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ requester_sid_idx, >+ i)); >+ SAFE_FREE(types); >+ talloc_free(mem_ctx); >+ return EINVAL; >+ } >+ requester_sid_idx = i; >+ break; > default: > continue; > } >@@ -546,6 +562,11 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > * we just add a place holder here. > */ > type_blob = data_blob_const(&zero_byte, 1); >+ >+ if (requester_sid_idx == -1 && requester_sid_blob != NULL) { >+ /* inject REQUESTER_SID behind */ >+ forced_next_type = PAC_TYPE_REQUESTER_SID; >+ } > break; > case PAC_TYPE_KDC_CHECKSUM: > /* >@@ -557,6 +578,15 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > case PAC_TYPE_ATTRIBUTES_INFO: > /* just copy... */ > break; >+ case PAC_TYPE_REQUESTER_SID: >+ /* >+ * Replace in the RODC case, otherwise >+ * requester_sid_blob is NULL and we just copy. >+ */ >+ if (requester_sid_blob != NULL) { >+ type_blob = *requester_sid_blob; >+ } >+ break; > default: > /* just copy... */ > break; >-- >2.25.1 > > >From 5556f8882d0ab1a104df39e06688303d35d2d9c3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 27 Oct 2021 13:53:25 +1300 >Subject: [PATCH 625/686] CVE-2020-25719 heimdal:kdc: Check return code > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14873 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/heimdal/kdc/krb5tgs.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index ae16dac7448..32ee16d019c 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -1355,7 +1355,10 @@ tgs_build_reply(krb5_context context, > ret = KRB5KDC_ERR_POLICY; > goto out; > } >- _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm); >+ ret = _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm); >+ if (ret) { >+ goto out; >+ } > if(t->enc_part.kvno){ > second_kvno = *t->enc_part.kvno; > kvno_ptr = &second_kvno; >-- >2.25.1 > > >From df32b20f3d8515922b18e2aabc5f9deda14e3108 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 26 Oct 2021 20:34:44 +1300 >Subject: [PATCH 626/686] CVE-2020-25719 heimdal:kdc: Move fetching krbtgt > entry to before enctype selection > >This allows us to use it when validating user-to-user. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14873 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > source4/heimdal/kdc/krb5tgs.c | 70 +++++++++++++++++------------------ > 1 file changed, 35 insertions(+), 35 deletions(-) > >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index 32ee16d019c..007ce3b2779 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -1512,6 +1512,41 @@ server_lookup: > goto out; > } > >+ /* Now refetch the primary krbtgt, and get the current kvno (the >+ * sign check may have been on an old kvno, and the server may >+ * have been an incoming trust) */ >+ ret = krb5_make_principal(context, &krbtgt_principal, >+ krb5_principal_get_comp_string(context, >+ krbtgt->entry.principal, >+ 1), >+ KRB5_TGS_NAME, >+ krb5_principal_get_comp_string(context, >+ krbtgt->entry.principal, >+ 1), NULL); >+ if(ret) { >+ kdc_log(context, config, 0, >+ "Failed to generate krbtgt principal"); >+ goto out; >+ } >+ >+ ret = _kdc_db_fetch(context, config, krbtgt_principal, HDB_F_GET_KRBTGT, NULL, NULL, &krbtgt_out); >+ krb5_free_principal(context, krbtgt_principal); >+ if (ret) { >+ krb5_error_code ret2; >+ char *ktpn, *ktpn2; >+ ret = krb5_unparse_name(context, krbtgt->entry.principal, &ktpn); >+ ret2 = krb5_unparse_name(context, krbtgt_principal, &ktpn2); >+ kdc_log(context, config, 0, >+ "Request with wrong krbtgt: %s, %s not found in our database", >+ (ret == 0) ? ktpn : "<unknown>", (ret2 == 0) ? ktpn2 : "<unknown>"); >+ if(ret == 0) >+ free(ktpn); >+ if(ret2 == 0) >+ free(ktpn2); >+ ret = KRB5KRB_AP_ERR_NOT_US; >+ goto out; >+ } >+ > /* > * Select enctype, return key and kvno. > */ >@@ -1562,41 +1597,6 @@ server_lookup: > * backward. > */ > >- /* Now refetch the primary krbtgt, and get the current kvno (the >- * sign check may have been on an old kvno, and the server may >- * have been an incoming trust) */ >- ret = krb5_make_principal(context, &krbtgt_principal, >- krb5_principal_get_comp_string(context, >- krbtgt->entry.principal, >- 1), >- KRB5_TGS_NAME, >- krb5_principal_get_comp_string(context, >- krbtgt->entry.principal, >- 1), NULL); >- if(ret) { >- kdc_log(context, config, 0, >- "Failed to generate krbtgt principal"); >- goto out; >- } >- >- ret = _kdc_db_fetch(context, config, krbtgt_principal, HDB_F_GET_KRBTGT, NULL, NULL, &krbtgt_out); >- krb5_free_principal(context, krbtgt_principal); >- if (ret) { >- krb5_error_code ret2; >- char *ktpn, *ktpn2; >- ret = krb5_unparse_name(context, krbtgt->entry.principal, &ktpn); >- ret2 = krb5_unparse_name(context, krbtgt_principal, &ktpn2); >- kdc_log(context, config, 0, >- "Request with wrong krbtgt: %s, %s not found in our database", >- (ret == 0) ? ktpn : "<unknown>", (ret2 == 0) ? ktpn2 : "<unknown>"); >- if(ret == 0) >- free(ktpn); >- if(ret2 == 0) >- free(ktpn2); >- ret = KRB5KRB_AP_ERR_NOT_US; >- goto out; >- } >- > /* The first realm is the realm of the service, the second is > * krbtgt/<this>/@REALM component of the krbtgt DN the request was > * encrypted to. The redirection via the krbtgt_out entry allows >-- >2.25.1 > > >From 1aee622f446c0af45c59e8a5d34089c9e3bb5e4e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 27 Oct 2021 13:50:03 +1300 >Subject: [PATCH 627/686] CVE-2020-25719 heimdal:kdc: Use sname from request > rather than user-to-user TGT client name > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14873 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail_heimdal_kdc | 20 ------ > source4/heimdal/kdc/krb5tgs.c | 113 ++++++++++++++++----------------- > 2 files changed, 55 insertions(+), 78 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 9cad1ca4d05..852a02d6d18 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -265,39 +265,19 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_matching_sname_host > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_sname >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_non_existent_sname >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_other_sname >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_no_krbtgt_link > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_no_partial_secrets > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_not_revealed >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_cname_host >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_correct_cname >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_correct_realm >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_other_cname >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_wrong_realm > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_srealm > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed >-# >-# PAC request tests >-# >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_false >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_none >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_true >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_false >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_none >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index 007ce3b2779..5ad5c3752cd 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -1333,64 +1333,7 @@ tgs_build_reply(krb5_context context, > if (b->kdc_options.canonicalize) > flags |= HDB_F_CANON; > >- if(b->kdc_options.enc_tkt_in_skey){ >- Ticket *t; >- hdb_entry_ex *uu; >- krb5_principal p; >- Key *uukey; >- krb5uint32 second_kvno = 0; >- krb5uint32 *kvno_ptr = NULL; >- >- if(b->additional_tickets == NULL || >- b->additional_tickets->len == 0){ >- ret = KRB5KDC_ERR_BADOPTION; /* ? */ >- kdc_log(context, config, 0, >- "No second ticket present in request"); >- goto out; >- } >- t = &b->additional_tickets->val[0]; >- if(!get_krbtgt_realm(&t->sname)){ >- kdc_log(context, config, 0, >- "Additional ticket is not a ticket-granting ticket"); >- ret = KRB5KDC_ERR_POLICY; >- goto out; >- } >- ret = _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm); >- if (ret) { >- goto out; >- } >- if(t->enc_part.kvno){ >- second_kvno = *t->enc_part.kvno; >- kvno_ptr = &second_kvno; >- } >- ret = _kdc_db_fetch(context, config, p, >- HDB_F_GET_KRBTGT, kvno_ptr, >- NULL, &uu); >- krb5_free_principal(context, p); >- if(ret){ >- if (ret == HDB_ERR_NOENTRY) >- ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; >- goto out; >- } >- ret = hdb_enctype2key(context, &uu->entry, >- t->enc_part.etype, &uukey); >- if(ret){ >- _kdc_free_ent(context, uu); >- ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */ >- goto out; >- } >- ret = krb5_decrypt_ticket(context, t, &uukey->key, &adtkt, 0); >- _kdc_free_ent(context, uu); >- if(ret) >- goto out; >- >- ret = verify_flags(context, config, &adtkt, spn); >- if (ret) >- goto out; >- >- s = &adtkt.cname; >- r = adtkt.crealm; >- } else if (s == NULL) { >+ if (s == NULL) { > ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; > krb5_set_error_message(context, ret, "No server in request"); > goto out; >@@ -1555,7 +1498,61 @@ server_lookup: > krb5_enctype etype; > > if(b->kdc_options.enc_tkt_in_skey) { >+ Ticket *t; >+ hdb_entry_ex *uu; >+ krb5_principal p; >+ Key *uukey; >+ krb5uint32 second_kvno = 0; >+ krb5uint32 *kvno_ptr = NULL; > size_t i; >+ >+ if(b->additional_tickets == NULL || >+ b->additional_tickets->len == 0){ >+ ret = KRB5KDC_ERR_BADOPTION; /* ? */ >+ kdc_log(context, config, 0, >+ "No second ticket present in request"); >+ goto out; >+ } >+ t = &b->additional_tickets->val[0]; >+ if(!get_krbtgt_realm(&t->sname)){ >+ kdc_log(context, config, 0, >+ "Additional ticket is not a ticket-granting ticket"); >+ ret = KRB5KDC_ERR_POLICY; >+ goto out; >+ } >+ ret = _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm); >+ if (ret) { >+ goto out; >+ } >+ if(t->enc_part.kvno){ >+ second_kvno = *t->enc_part.kvno; >+ kvno_ptr = &second_kvno; >+ } >+ ret = _kdc_db_fetch(context, config, p, >+ HDB_F_GET_KRBTGT, kvno_ptr, >+ NULL, &uu); >+ krb5_free_principal(context, p); >+ if(ret){ >+ if (ret == HDB_ERR_NOENTRY) >+ ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; >+ goto out; >+ } >+ ret = hdb_enctype2key(context, &uu->entry, >+ t->enc_part.etype, &uukey); >+ if(ret){ >+ _kdc_free_ent(context, uu); >+ ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */ >+ goto out; >+ } >+ ret = krb5_decrypt_ticket(context, t, &uukey->key, &adtkt, 0); >+ _kdc_free_ent(context, uu); >+ if(ret) >+ goto out; >+ >+ ret = verify_flags(context, config, &adtkt, spn); >+ if (ret) >+ goto out; >+ > ekey = &adtkt.key; > for(i = 0; i < b->etype.len; i++) > if (b->etype.val[i] == adtkt.key.keytype) >-- >2.25.1 > > >From 99d8166c901bc206581ccf34626ef5d8a059bb5a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 27 Oct 2021 15:51:58 +1300 >Subject: [PATCH 628/686] CVE-2020-25719 heimdal:kdc: Check name in request > against name in user-to-user TGT > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14873 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail_heimdal_kdc | 3 -- > source4/heimdal/kdc/krb5tgs.c | 56 +++++++++++++++++++++++++++++++++- > 2 files changed, 55 insertions(+), 4 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 852a02d6d18..f1b3cfa6b56 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -276,8 +276,5 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_cname_host >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index 5ad5c3752cd..bc228b50d28 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -1297,9 +1297,12 @@ tgs_build_reply(krb5_context context, > krb5_error_code ret; > krb5_principal cp = NULL, sp = NULL, tp = NULL, dp = NULL; > krb5_principal krbtgt_principal = NULL; >+ krb5_principal user2user_princ = NULL; > char *spn = NULL, *cpn = NULL, *tpn = NULL, *dpn = NULL; >+ char *user2user_name = NULL; > hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL; > HDB *clientdb, *s4u2self_impersonated_clientdb; >+ HDB *serverdb = NULL; > krb5_realm ref_realm = NULL; > EncTicketPart *tgt = &ticket->ticket; > const EncryptionKey *ekey; >@@ -1364,7 +1367,7 @@ tgs_build_reply(krb5_context context, > > server_lookup: > ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER | flags, >- NULL, NULL, &server); >+ NULL, &serverdb, &server); > > if(ret == HDB_ERR_NOT_FOUND_HERE) { > kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", sp); >@@ -1505,6 +1508,7 @@ server_lookup: > krb5uint32 second_kvno = 0; > krb5uint32 *kvno_ptr = NULL; > size_t i; >+ hdb_entry_ex *user2user_client = NULL; > > if(b->additional_tickets == NULL || > b->additional_tickets->len == 0){ >@@ -1553,6 +1557,53 @@ server_lookup: > if (ret) > goto out; > >+ /* Fetch the name from the TGT. */ >+ ret = _krb5_principalname2krb5_principal(context, &user2user_princ, >+ adtkt.cname, adtkt.crealm); >+ if (ret) { >+ goto out; >+ } >+ >+ ret = krb5_unparse_name(context, user2user_princ, &user2user_name); >+ if (ret) { >+ goto out; >+ } >+ >+ /* Look up the name given in the TGT in the database. */ >+ ret = db_fetch_client(context, config, flags, user2user_princ, user2user_name, >+ krb5_principal_get_realm(context, krbtgt_out->entry.principal), >+ NULL, &user2user_client); >+ if (ret) { >+ goto out; >+ } >+ >+ if (user2user_client != NULL) { >+ /* >+ * If the account is present in the database, check the account >+ * flags. >+ */ >+ ret = kdc_check_flags(context, config, >+ user2user_client, user2user_name, >+ NULL, NULL, >+ FALSE); >+ if (ret) { >+ _kdc_free_ent(context, user2user_client); >+ goto out; >+ } >+ >+ /* >+ * Also check that the account is the same one specified in the >+ * request. >+ */ >+ ret = check_s4u2self(context, config, serverdb, server, user2user_client, user2user_princ); >+ if (ret) { >+ _kdc_free_ent(context, user2user_client); >+ goto out; >+ } >+ } >+ >+ _kdc_free_ent(context, user2user_client); >+ > ekey = &adtkt.key; > for(i = 0; i < b->etype.len; i++) > if (b->etype.val[i] == adtkt.key.keytype) >@@ -2038,6 +2089,7 @@ server_lookup: > reply); > > out: >+ free(user2user_name); > if (tpn != cpn) > free(tpn); > free(spn); >@@ -2055,6 +2107,8 @@ out: > if(s4u2self_impersonated_client) > _kdc_free_ent(context, s4u2self_impersonated_client); > >+ if (user2user_princ) >+ krb5_free_principal(context, user2user_princ); > if (tp && tp != cp) > krb5_free_principal(context, tp); > if (cp) >-- >2.25.1 > > >From 3f759a1f8d9eba6f29260e320e9053a7bb42f549 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 27 Oct 2021 15:52:06 +1300 >Subject: [PATCH 629/686] CVE-2020-25719 heimdal:kdc: Verify PAC in TGT > provided for user-to-user authentication > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14873 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail_heimdal_kdc | 11 ----------- > source4/heimdal/kdc/krb5tgs.c | 33 ++++++++++++++++++++++++++++----- > 2 files changed, 28 insertions(+), 16 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index f1b3cfa6b56..4bde0f33977 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -264,17 +264,6 @@ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_revealed >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_allowed_denied >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_denied >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_no_krbtgt_link >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_no_partial_secrets >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_not_allowed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_not_revealed >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_nonexisting >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index bc228b50d28..4f15a549afe 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -1301,6 +1301,7 @@ tgs_build_reply(krb5_context context, > char *spn = NULL, *cpn = NULL, *tpn = NULL, *dpn = NULL; > char *user2user_name = NULL; > hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL; >+ hdb_entry_ex *user2user_krbtgt = NULL; > HDB *clientdb, *s4u2self_impersonated_clientdb; > HDB *serverdb = NULL; > krb5_realm ref_realm = NULL; >@@ -1309,6 +1310,7 @@ tgs_build_reply(krb5_context context, > krb5_keyblock sessionkey; > krb5_kvno kvno; > krb5_pac mspac = NULL; >+ krb5_pac user2user_pac = NULL; > uint16_t rodc_id; > krb5_boolean add_ticket_sig = FALSE; > >@@ -1502,13 +1504,13 @@ server_lookup: > > if(b->kdc_options.enc_tkt_in_skey) { > Ticket *t; >- hdb_entry_ex *uu; > krb5_principal p; > Key *uukey; > krb5uint32 second_kvno = 0; > krb5uint32 *kvno_ptr = NULL; > size_t i; > hdb_entry_ex *user2user_client = NULL; >+ krb5_boolean user2user_kdc_issued = FALSE; > > if(b->additional_tickets == NULL || > b->additional_tickets->len == 0){ >@@ -1534,22 +1536,20 @@ server_lookup: > } > ret = _kdc_db_fetch(context, config, p, > HDB_F_GET_KRBTGT, kvno_ptr, >- NULL, &uu); >+ NULL, &user2user_krbtgt); > krb5_free_principal(context, p); > if(ret){ > if (ret == HDB_ERR_NOENTRY) > ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; > goto out; > } >- ret = hdb_enctype2key(context, &uu->entry, >+ ret = hdb_enctype2key(context, &user2user_krbtgt->entry, > t->enc_part.etype, &uukey); > if(ret){ >- _kdc_free_ent(context, uu); > ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */ > goto out; > } > ret = krb5_decrypt_ticket(context, t, &uukey->key, &adtkt, 0); >- _kdc_free_ent(context, uu); > if(ret) > goto out; > >@@ -1602,7 +1602,27 @@ server_lookup: > } > } > >+ /* Verify the PAC of the TGT. */ >+ ret = check_PAC(context, config, user2user_princ, NULL, >+ user2user_client, user2user_krbtgt, user2user_krbtgt, user2user_krbtgt, >+ &uukey->key, &tkey_check->key, &adtkt, &user2user_kdc_issued, &user2user_pac); > _kdc_free_ent(context, user2user_client); >+ if (ret) { >+ const char *msg = krb5_get_error_message(context, ret); >+ kdc_log(context, config, 0, >+ "Verify PAC failed for %s (%s) from %s with %s", >+ spn, user2user_name, from, msg); >+ krb5_free_error_message(context, msg); >+ goto out; >+ } >+ >+ if (user2user_pac == NULL || !user2user_kdc_issued) { >+ ret = KRB5KDC_ERR_BADOPTION; >+ kdc_log(context, config, 0, >+ "Ticket not signed with PAC; user-to-user failed (%s).", >+ mspac ? "Ticket unsigned" : "No PAC"); >+ goto out; >+ } > > ekey = &adtkt.key; > for(i = 0; i < b->etype.len; i++) >@@ -2106,6 +2126,8 @@ out: > _kdc_free_ent(context, client); > if(s4u2self_impersonated_client) > _kdc_free_ent(context, s4u2self_impersonated_client); >+ if (user2user_krbtgt) >+ _kdc_free_ent(context, user2user_krbtgt); > > if (user2user_princ) > krb5_free_principal(context, user2user_princ); >@@ -2124,6 +2146,7 @@ out: > free_EncTicketPart(&adtkt); > > krb5_pac_free(context, mspac); >+ krb5_pac_free(context, user2user_pac); > > return ret; > } >-- >2.25.1 > > >From 9a72ef400ac94442111ade94c7127fecbf2e9252 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 4 Oct 2021 15:18:34 +1300 >Subject: [PATCH 630/686] CVE-2020-25722 kdc: Do not honour a request for a > 3-part SPN (ending in our domain/realm) unless a DC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14776 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > selftest/knownfail_heimdal_kdc | 6 ------ > selftest/knownfail_mit_kdc | 6 ------ > source4/kdc/db-glue.c | 23 +++++++++++++++++++++++ > 3 files changed, 23 insertions(+), 12 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 4bde0f33977..8bf36faf8ed 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -250,12 +250,6 @@ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_a > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_b > # >-# SPN tests >-# >-^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_instance_spn_computer >-^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_domain_spn_computer >-^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_realm_spn_computer >-# > # KDC TGT tests > # > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 7b0cd39723a..d20bbc175f2 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -381,12 +381,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc > ^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc > # >-# SPN tests >-# >-^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_instance_spn_computer >-^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_domain_spn_computer >-^samba.tests.krb5.spn_tests.samba.tests.krb5.spn_tests.SpnTests.test_spn_3_part_our_realm_spn_computer >-# > # Alias tests > # > ^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_delete >diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c >index bb63e2f31ad..222961a6957 100644 >--- a/source4/kdc/db-glue.c >+++ b/source4/kdc/db-glue.c >@@ -962,6 +962,29 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context, > entry_ex->entry.flags.server = 0; > } > } >+ >+ /* >+ * We restrict a 3-part SPN ending in my domain/realm to full >+ * domain controllers. >+ * >+ * This avoids any cases where (eg) a demoted DC still has >+ * these more restricted SPNs. >+ */ >+ if (krb5_princ_size(context, principal) > 2) { >+ char *third_part >+ = smb_krb5_principal_get_comp_string(mem_ctx, >+ context, >+ principal, >+ 2); >+ bool is_our_realm = >+ lpcfg_is_my_domain_or_realm(lp_ctx, >+ third_part); >+ bool is_dc = userAccountControl & >+ (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT); >+ if (is_our_realm && !is_dc) { >+ entry_ex->entry.flags.server = 0; >+ } >+ } > /* > * To give the correct type of error to the client, we must > * not just return the entry without .server set, we must >-- >2.25.1 > > >From 6938b2d0ed1c695f542ca2dc6adcbad2ad3813c4 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 29 Oct 2021 14:35:52 +1300 >Subject: [PATCH 631/686] CVE-2020-25719 heimdal:kdc: Require PAC to be present > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14686 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail_heimdal_kdc | 4 ---- > source4/heimdal/kdc/krb5tgs.c | 5 ++++- > 2 files changed, 4 insertions(+), 5 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 8bf36faf8ed..933b6c2af04 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -252,12 +252,8 @@ > # > # KDC TGT tests > # >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_revealed >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_revealed >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_not_revealed >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index 4f15a549afe..bc618db5955 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -74,9 +74,12 @@ check_PAC(krb5_context context, > *ppac = NULL; > > ret = _krb5_kdc_pac_ticket_parse(context, tkt, &signedticket, &pac); >- if (ret || pac == NULL) >+ if (ret) > return ret; > >+ if (pac == NULL) >+ return KRB5KDC_ERR_BADOPTION; >+ > /* Verify the server signature. */ > ret = krb5_pac_verify(context, pac, tkt->authtime, client_principal, > server_check_key, NULL); >-- >2.25.1 > > >From a6482742e3f8e57d653b6efe0302015e69e25107 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 29 Oct 2021 15:43:28 +1300 >Subject: [PATCH 632/686] CVE-2020-25718 tests/krb5: Only fetch RODC account > credentials when necessary > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_base_test.py | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 4b4f1486f60..f64bd0b206e 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -710,9 +710,6 @@ class KDCBaseTest(RawKerberosTest): > self.assertFalse(not_delegated) > > samdb = self.get_samdb() >- rodc_samdb = self.get_rodc_samdb() >- >- rodc_dn = self.get_server_dn(rodc_samdb) > > user_name = self.get_new_username() > if name_prefix is not None: >@@ -764,6 +761,9 @@ class KDCBaseTest(RawKerberosTest): > # Handle secret replication to the RODC. > > if allowed_replication or revealed_to_rodc: >+ rodc_samdb = self.get_rodc_samdb() >+ rodc_dn = self.get_server_dn(rodc_samdb) >+ > # Allow replicating this account's secrets if requested, or allow > # it only temporarily if we're about to replicate them. > allowed_cleanup = self.add_to_group( >@@ -784,6 +784,9 @@ class KDCBaseTest(RawKerberosTest): > revealed=revealed_to_rodc) > > if denied_replication: >+ rodc_samdb = self.get_rodc_samdb() >+ rodc_dn = self.get_server_dn(rodc_samdb) >+ > # Deny replicating this account's secrets to the RODC. > self.add_to_group(dn, rodc_dn, 'msDS-NeverRevealGroup') > >-- >2.25.1 > > >From 56e4753ef072720dbd799733170638d34431a11f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 29 Oct 2021 15:07:07 +1300 >Subject: [PATCH 633/686] CVE-2020-25719 tests/krb5: Add tests for using a > ticket with a renamed account > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 17 ++++++++++ > python/samba/tests/krb5/test_ccache.py | 41 ++++++++++++++++------ > python/samba/tests/krb5/test_ldap.py | 33 ++++++++++++++---- > python/samba/tests/krb5/test_rpc.py | 27 ++++++++++++--- > python/samba/tests/krb5/test_smb.py | 43 ++++++++++++++++++------ > selftest/knownfail_mit_kdc | 1 + > 6 files changed, 129 insertions(+), 33 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index cfe1ad42d61..abac5a47a56 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -1769,6 +1769,23 @@ class KdcTgsTests(KDCBaseTest): > pac = self.get_ticket_pac(ticket) > self.assertIsNotNone(pac) > >+ def test_tgs_rename(self): >+ creds = self.get_cached_creds(account_type=self.AccountType.USER, >+ use_cache=False) >+ tgt = self.get_tgt(creds) >+ >+ # Rename the account. >+ new_name = self.get_new_username() >+ >+ samdb = self.get_samdb() >+ msg = ldb.Message(creds.get_dn()) >+ msg['sAMAccountName'] = ldb.MessageElement(new_name, >+ ldb.FLAG_MOD_REPLACE, >+ 'sAMAccountName') >+ samdb.modify(msg) >+ >+ self._run_tgs(tgt, expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN) >+ > def _get_tgt(self, > client_creds, > renewable=False, >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >index d21ec84796e..75038ea5cc1 100755 >--- a/python/samba/tests/krb5/test_ccache.py >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -20,6 +20,8 @@ > import sys > import os > >+import ldb >+ > from ldb import SCOPE_SUBTREE > from samba import NTSTATUSError, gensec > from samba.auth import AuthContext >@@ -42,13 +44,16 @@ class CcacheTests(KDCBaseTest): > """ > > def test_ccache(self): >- self._run_ccache_test("ccacheusr") >+ self._run_ccache_test() >+ >+ def test_ccache_rename(self): >+ self._run_ccache_test(rename=True) > > def test_ccache_no_pac(self): >- self._run_ccache_test("ccacheusr_nopac", include_pac=False, >+ self._run_ccache_test(include_pac=False, > expect_anon=True, allow_error=True) > >- def _run_ccache_test(self, user_name, include_pac=True, >+ def _run_ccache_test(self, rename=False, include_pac=True, > expect_anon=False, allow_error=False): > # Create a user account and a machine account, along with a Kerberos > # credentials cache file where the service ticket authenticating the >@@ -60,7 +65,10 @@ class CcacheTests(KDCBaseTest): > samdb = self.get_samdb() > > # Create the user account. >- (user_credentials, _) = self.create_account(samdb, user_name) >+ user_credentials = self.get_cached_creds( >+ account_type=self.AccountType.USER, >+ use_cache=False) >+ user_name = user_credentials.get_username() > > # Create the machine account. > (mach_credentials, _) = self.create_account( >@@ -80,6 +88,24 @@ class CcacheTests(KDCBaseTest): > # Remove the cached credentials file. > self.addCleanup(os.remove, cachefile.name) > >+ # Retrieve the user account's SID. >+ ldb_res = samdb.search(scope=SCOPE_SUBTREE, >+ expression="(sAMAccountName=%s)" % user_name, >+ attrs=["objectSid"]) >+ self.assertEqual(1, len(ldb_res)) >+ sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) >+ >+ if rename: >+ # Rename the account. >+ >+ new_name = self.get_new_username() >+ >+ msg = ldb.Message(user_credentials.get_dn()) >+ msg['sAMAccountName'] = ldb.MessageElement(new_name, >+ ldb.FLAG_MOD_REPLACE, >+ 'sAMAccountName') >+ samdb.modify(msg) >+ > # Authenticate in-process to the machine account using the user's > # cached credentials. > >@@ -121,13 +147,6 @@ class CcacheTests(KDCBaseTest): > # Ensure that the first SID contained within the obtained security > # token is the SID of the user we created. > >- # Retrieve the user account's SID. >- ldb_res = samdb.search(scope=SCOPE_SUBTREE, >- expression="(sAMAccountName=%s)" % user_name, >- attrs=["objectSid"]) >- self.assertEqual(1, len(ldb_res)) >- sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) >- > # Retrieve the SIDs from the security token. > try: > session = gensec_server.session_info() >diff --git a/python/samba/tests/krb5/test_ldap.py b/python/samba/tests/krb5/test_ldap.py >index 0205bdf6fb7..c1375730e6f 100755 >--- a/python/samba/tests/krb5/test_ldap.py >+++ b/python/samba/tests/krb5/test_ldap.py >@@ -20,6 +20,8 @@ > import sys > import os > >+import ldb >+ > from ldb import LdbError, ERR_OPERATIONS_ERROR, SCOPE_BASE, SCOPE_SUBTREE > from samba.dcerpc import security > from samba.ndr import ndr_unpack >@@ -41,13 +43,16 @@ class LdapTests(KDCBaseTest): > """ > > def test_ldap(self): >- self._run_ldap_test("ldapusr") >+ self._run_ldap_test() >+ >+ def test_ldap_rename(self): >+ self._run_ldap_test(rename=True) > > def test_ldap_no_pac(self): >- self._run_ldap_test("ldapusr_nopac", include_pac=False, >+ self._run_ldap_test(include_pac=False, > expect_anon=True, allow_error=True) > >- def _run_ldap_test(self, user_name, include_pac=True, >+ def _run_ldap_test(self, rename=False, include_pac=True, > expect_anon=False, allow_error=False): > # Create a user account and a machine account, along with a Kerberos > # credentials cache file where the service ticket authenticating the >@@ -59,7 +64,10 @@ class LdapTests(KDCBaseTest): > service = "ldap" > > # Create the user account. >- (user_credentials, _) = self.create_account(samdb, user_name) >+ user_credentials = self.get_cached_creds( >+ account_type=self.AccountType.USER, >+ use_cache=False) >+ user_name = user_credentials.get_username() > > mach_credentials = self.get_dc_creds() > >@@ -75,9 +83,6 @@ class LdapTests(KDCBaseTest): > # Remove the cached credentials file. > self.addCleanup(os.remove, cachefile.name) > >- # Authenticate in-process to the machine account using the user's >- # cached credentials. >- > # Retrieve the user account's SID. > ldb_res = samdb.search(scope=SCOPE_SUBTREE, > expression="(sAMAccountName=%s)" % user_name, >@@ -85,6 +90,20 @@ class LdapTests(KDCBaseTest): > self.assertEqual(1, len(ldb_res)) > sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) > >+ if rename: >+ # Rename the account. >+ >+ new_name = self.get_new_username() >+ >+ msg = ldb.Message(user_credentials.get_dn()) >+ msg['sAMAccountName'] = ldb.MessageElement(new_name, >+ ldb.FLAG_MOD_REPLACE, >+ 'sAMAccountName') >+ samdb.modify(msg) >+ >+ # Authenticate in-process to the machine account using the user's >+ # cached credentials. >+ > # Connect to the machine account and retrieve the user SID. > try: > ldb_as_user = SamDB(url="ldap://%s" % mach_name, >diff --git a/python/samba/tests/krb5/test_rpc.py b/python/samba/tests/krb5/test_rpc.py >index 0f2170a8ded..03c125f518a 100755 >--- a/python/samba/tests/krb5/test_rpc.py >+++ b/python/samba/tests/krb5/test_rpc.py >@@ -20,6 +20,8 @@ > import sys > import os > >+import ldb >+ > from samba import NTSTATUSError, credentials > from samba.dcerpc import lsa > from samba.ntstatus import NT_STATUS_NO_IMPERSONATION_TOKEN >@@ -39,13 +41,16 @@ class RpcTests(KDCBaseTest): > """ > > def test_rpc(self): >- self._run_rpc_test("rpcusr") >+ self._run_rpc_test() >+ >+ def test_rpc_rename(self): >+ self._run_rpc_test(rename=True) > > def test_rpc_no_pac(self): >- self._run_rpc_test("rpcusr_nopac", include_pac=False, >+ self._run_rpc_test(include_pac=False, > expect_anon=True, allow_error=True) > >- def _run_rpc_test(self, user_name, include_pac=True, >+ def _run_rpc_test(self, rename=False, include_pac=True, > expect_anon=False, allow_error=False): > # Create a user account and a machine account, along with a Kerberos > # credentials cache file where the service ticket authenticating the >@@ -57,7 +62,10 @@ class RpcTests(KDCBaseTest): > service = "cifs" > > # Create the user account. >- (user_credentials, _) = self.create_account(samdb, user_name) >+ user_credentials = self.get_cached_creds( >+ account_type=self.AccountType.USER, >+ use_cache=False) >+ user_name = user_credentials.get_username() > > mach_credentials = self.get_dc_creds() > >@@ -73,6 +81,17 @@ class RpcTests(KDCBaseTest): > # Remove the cached credentials file. > self.addCleanup(os.remove, cachefile.name) > >+ if rename: >+ # Rename the account. >+ >+ new_name = self.get_new_username() >+ >+ msg = ldb.Message(user_credentials.get_dn()) >+ msg['sAMAccountName'] = ldb.MessageElement(new_name, >+ ldb.FLAG_MOD_REPLACE, >+ 'sAMAccountName') >+ samdb.modify(msg) >+ > # Authenticate in-process to the machine account using the user's > # cached credentials. > >diff --git a/python/samba/tests/krb5/test_smb.py b/python/samba/tests/krb5/test_smb.py >index 7408e5dbece..47e9e48c971 100755 >--- a/python/samba/tests/krb5/test_smb.py >+++ b/python/samba/tests/krb5/test_smb.py >@@ -20,6 +20,8 @@ > import sys > import os > >+import ldb >+ > from ldb import SCOPE_SUBTREE > from samba import NTSTATUSError > from samba.dcerpc import security >@@ -43,13 +45,16 @@ class SmbTests(KDCBaseTest): > """ > > def test_smb(self): >- self._run_smb_test("smbusr") >+ self._run_smb_test() >+ >+ def test_smb_rename(self): >+ self._run_smb_test(rename=True) > > def test_smb_no_pac(self): >- self._run_smb_test("smbusr_nopac", include_pac=False, >+ self._run_smb_test(include_pac=False, > expect_error=True) > >- def _run_smb_test(self, user_name, include_pac=True, >+ def _run_smb_test(self, rename=False, include_pac=True, > expect_error=False): > # Create a user account and a machine account, along with a Kerberos > # credentials cache file where the service ticket authenticating the >@@ -62,7 +67,12 @@ class SmbTests(KDCBaseTest): > share = "tmp" > > # Create the user account. >- (user_credentials, _) = self.create_account(samdb, user_name) >+ user_credentials = self.get_cached_creds( >+ account_type=self.AccountType.USER, >+ use_cache=False) >+ user_name = user_credentials.get_username() >+ >+ mach_credentials = self.get_dc_creds() > > mach_credentials = self.get_dc_creds() > >@@ -78,6 +88,24 @@ class SmbTests(KDCBaseTest): > # Remove the cached credentials file. > self.addCleanup(os.remove, cachefile.name) > >+ # Retrieve the user account's SID. >+ ldb_res = samdb.search(scope=SCOPE_SUBTREE, >+ expression="(sAMAccountName=%s)" % user_name, >+ attrs=["objectSid"]) >+ self.assertEqual(1, len(ldb_res)) >+ sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) >+ >+ if rename: >+ # Rename the account. >+ >+ new_name = self.get_new_username() >+ >+ msg = ldb.Message(user_credentials.get_dn()) >+ msg['sAMAccountName'] = ldb.MessageElement(new_name, >+ ldb.FLAG_MOD_REPLACE, >+ 'sAMAccountName') >+ samdb.modify(msg) >+ > # Set the Kerberos 5 credentials cache environment variable. This is > # required because the codepath that gets run (gse_krb5) looks for it > # in here and not in the credentials object. >@@ -88,13 +116,6 @@ class SmbTests(KDCBaseTest): > # Authenticate in-process to the machine account using the user's > # cached credentials. > >- # Retrieve the user account's SID. >- ldb_res = samdb.search(scope=SCOPE_SUBTREE, >- expression="(sAMAccountName=%s)" % user_name, >- attrs=["objectSid"]) >- self.assertEqual(1, len(ldb_res)) >- sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) >- > # Connect to a share and retrieve the user SID. > s3_lp = s3param.get_context() > s3_lp.load(self.get_lp().configfile) >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index d20bbc175f2..167cada5c2e 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -417,6 +417,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_nonexisting > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rename > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_denied > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_krbtgt_link >-- >2.25.1 > > >From 9006c4d940c8e61c5971116cafda690f5eed27e1 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 29 Oct 2021 15:53:33 +1300 >Subject: [PATCH 634/686] CVE-2020-25718 heimdal:kdc: Add comment about tests > for tickets of users not revealed to an RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14886 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >--- > selftest/knownfail_heimdal_kdc | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 933b6c2af04..7eba899966e 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -250,7 +250,9 @@ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_a > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_b > # >-# KDC TGT tests >+# https://bugzilla.samba.org/show_bug.cgi?id=14886: Tests for accounts not revealed to the RODC >+# >+# The KDC should not accept tickets from an RODC for accounts not in the msDS-RevealedUsers list. > # > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_not_revealed > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_not_revealed >-- >2.25.1 > > >From 66ead3880dfb3e9a0de4026e5b64da99c0e822a8 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 2 Nov 2021 14:52:22 +1300 >Subject: [PATCH 635/686] Revert "CVE-2020-25719 heimdal:kdc: Require authdata > to be present" > >This reverts an earlier commit that was incorrect. > >It is not Samba practice to include a revert, but at this point in >the patch preperation the ripple though the knownfail files is >more trouble than can be justified. > >It is not correct to refuse to parse all tickets with no authorization >data, only for the KDC to require that a PAC is found, which is done >in "heimdal:kdc: Require PAC to be present" > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/heimdal/lib/krb5/pac.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 749d0fdb4eb..05bcc523080 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -1369,7 +1369,7 @@ _krb5_kdc_pac_ticket_parse(krb5_context context, > *ppac = NULL; > > if (ad == NULL || ad->len == 0) >- return KRB5KDC_ERR_BADOPTION; >+ return 0; > > for (i = 0; i < ad->len; i++) { > AuthorizationData child; >-- >2.25.1 > > >From 2842b2005ac0b6a6d9df942aad0109a5f3858e43 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 2 Nov 2021 14:02:14 +1300 >Subject: [PATCH 636/686] CVE-2020-25719 selftest: Always expect a PAC in TGS > replies with Heimdal > >This is tested in other places already, but this ensures a global >check that a TGS-REP has a PAC, regardless. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/selftest/tests.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 8f8d4c1611f..19e0f1f720c 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -715,7 +715,7 @@ planoldpythontestsuite("ad_dc:local", "samba.tests.dckeytab", extra_args=['-U"$U > > have_fast_support = int('SAMBA_USES_MITKDC' in config_hash) > tkt_sig_support = int('SAMBA4_USES_HEIMDAL' in config_hash) >-expect_pac = 0 >+expect_pac = int('SAMBA4_USES_HEIMDAL' in config_hash) > planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", > environ={'SERVICE_USERNAME':'$SERVER', >-- >2.25.1 > > >From 6d537bb5e6e13f328797f2292a18a7466f8cccc8 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 2 Nov 2021 14:11:27 +0100 >Subject: [PATCH 637/686] CVE-2020-25722 pytests: Give computer accounts unique > (and valid) sAMAccountNames and SPNs > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > python/samba/tests/samba_tool/computer.py | 18 ++++++++++++------ > 1 file changed, 12 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/samba_tool/computer.py b/python/samba/tests/samba_tool/computer.py >index 0f51cf31c80..ed1c22034c2 100644 >--- a/python/samba/tests/samba_tool/computer.py >+++ b/python/samba/tests/samba_tool/computer.py >@@ -39,23 +39,29 @@ class ComputerCmdTestCase(SambaToolCmdTest): > # ips used to test --ip-address option > self.ipv4 = '10.10.10.10' > self.ipv6 = '2001:0db8:0a0b:12f0:0000:0000:0000:0001' >+ computer_basename = self.randomName().lower() > data = [ > { >- 'name': 'testcomputer1', >+ 'name': computer_basename + 'cmp1', > 'ip_address_list': [self.ipv4] > }, > { >- 'name': 'testcomputer2', >+ 'name': computer_basename + 'cmp2', > 'ip_address_list': [self.ipv6], >- 'service_principal_name_list': ['SPN0'] >+ 'service_principal_name_list': [ >+ 'host/' + computer_basename + 'SPN20', >+ ], > }, > { >- 'name': 'testcomputer3$', >+ 'name': computer_basename + 'cmp3$', > 'ip_address_list': [self.ipv4, self.ipv6], >- 'service_principal_name_list': ['SPN0', 'SPN1'] >+ 'service_principal_name_list': [ >+ 'host/' + computer_basename + 'SPN30', >+ 'host/' + computer_basename + 'SPN31', >+ ], > }, > { >- 'name': 'testcomputer4$', >+ 'name': computer_basename + 'cmp4$', > }, > ] > self.computers = [self._randomComputer(base=item) for item in data] >-- >2.25.1 > > >From c3831f6fa84d15bc0bc440d8902748adae4c6e6a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 2 Nov 2021 21:21:17 +1300 >Subject: [PATCH 638/686] CVE-2020-25722 selftest: Add test for duplicate > servicePrincipalNames on an add operation > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/spn_uniqueness | 2 ++ > source4/dsdb/tests/python/sam.py | 21 +++++++++++++++++++++ > 2 files changed, 23 insertions(+) > create mode 100644 selftest/knownfail.d/spn_uniqueness > >diff --git a/selftest/knownfail.d/spn_uniqueness b/selftest/knownfail.d/spn_uniqueness >new file mode 100644 >index 00000000000..aff49780991 >--- /dev/null >+++ b/selftest/knownfail.d/spn_uniqueness >@@ -0,0 +1,2 @@ >+^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_service_principal_name_uniqueness\(ad_dc_ntvfs\) >+^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_service_principal_name_uniqueness\(fl2008r2dc\) >diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py >index 8e5d3e15576..5aac7a543e3 100755 >--- a/source4/dsdb/tests/python/sam.py >+++ b/source4/dsdb/tests/python/sam.py >@@ -90,6 +90,7 @@ class SamTests(samba.tests.TestCase): > delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn) > delete_force(self.ldb, "cn=ldaptest\,specialuser,cn=users," + self.base_dn) > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) >+ delete_force(self.ldb, "cn=ldaptestcomputer2,cn=computers," + self.base_dn) > delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) > delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn) > >@@ -3501,6 +3502,26 @@ class SamTests(samba.tests.TestCase): > > delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) > >+ def test_service_principal_name_uniqueness(self): >+ """Test the servicePrincipalName uniqueness behaviour""" >+ print("Testing servicePrincipalName uniqueness behaviour") >+ >+ ldb.add({ >+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, >+ "objectclass": "computer", >+ "servicePrincipalName": "HOST/testname.testdom"}) >+ >+ try: >+ ldb.add({ >+ "dn": "cn=ldaptestcomputer2,cn=computers," + self.base_dn, >+ "objectclass": "computer", >+ "servicePrincipalName": "HOST/testname.testdom"}) >+ except LdbError as e: >+ num, _ = e.args >+ self.assertEqual(num, ERR_CONSTRAINT_VIOLATION) >+ else: >+ self.fail() >+ > def test_sam_description_attribute(self): > """Test SAM description attribute""" > print("Test SAM description attribute") >-- >2.25.1 > > >From 0c4c97ea031c91c0dbcfa064b5c1847a409f36eb Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 2 Nov 2021 21:00:00 +1300 >Subject: [PATCH 639/686] CVE-2020-25722 selftest: Ensure check for duplicate > servicePrincipalNames is not bypassed for an add operation > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564 > >If one of the objectClass checks passed, samldb_add() could return >through one of the samldb_fill_*() functions and skip the >servicePrincipalName uniqueness checking. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> > >[jsutton@samba.org Adapted knownfails to ad_dc_ntvfs] >--- > selftest/knownfail.d/spn_uniqueness | 2 -- > source4/dsdb/samdb/ldb_modules/samldb.c | 25 ++++++++++++------------- > 2 files changed, 12 insertions(+), 15 deletions(-) > delete mode 100644 selftest/knownfail.d/spn_uniqueness > >diff --git a/selftest/knownfail.d/spn_uniqueness b/selftest/knownfail.d/spn_uniqueness >deleted file mode 100644 >index aff49780991..00000000000 >--- a/selftest/knownfail.d/spn_uniqueness >+++ /dev/null >@@ -1,2 +0,0 @@ >-^samba4.sam.python\(ad_dc_ntvfs\).__main__.SamTests.test_service_principal_name_uniqueness\(ad_dc_ntvfs\) >-^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_service_principal_name_uniqueness\(fl2008r2dc\) >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 75b0933d479..ba71bea98e4 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -4837,6 +4837,18 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req) > } > } > >+ el = ldb_msg_find_element(ac->msg, "servicePrincipalName"); >+ if ((el != NULL)) { >+ /* >+ * We need to check whether the SPN collides with an existing >+ * one (anywhere) including via aliases. >+ */ >+ ret = samldb_spn_uniqueness_check(ac, el); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ } >+ > if (samdb_find_attribute(ldb, ac->msg, > "objectclass", "user") != NULL) { > ac->type = SAMLDB_TYPE_USER; >@@ -4935,19 +4947,6 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req) > return samldb_fill_object(ac); > } > >- >- el = ldb_msg_find_element(ac->msg, "servicePrincipalName"); >- if ((el != NULL)) { >- /* >- * We need to check whether the SPN collides with an existing >- * one (anywhere) including via aliases. >- */ >- ret = samldb_spn_uniqueness_check(ac, el); >- if (ret != LDB_SUCCESS) { >- return ret; >- } >- } >- > if (samdb_find_attribute(ldb, ac->msg, > "objectclass", "subnet") != NULL) { > ret = samldb_verify_subnet(ac, ac->msg->dn); >-- >2.25.1 > > >From 2b3c56b0a21b97284cef72f7085c5cb21adc4a33 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 11 Nov 2019 16:39:13 +1300 >Subject: [PATCH 640/686] selftest: Add expected-output tests for the ndrdump > struct mode > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14191 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 88373c472c52ddc1191c1c20e74bff7776d0e805) > >[jsutton@samba.org Adapted to fix conflicts] >--- > python/samba/tests/blackbox/ndrdump.py | 28 +++++++++++++- > selftest/knownfail.d/ndrdump | 2 + > .../tests/dns-decode_dns_name_packet-hex.txt | 35 ++++++++++++++++++ > source4/librpc/tests/krb5pac-PAC_DATA.dat | Bin 0 -> 768 bytes > 4 files changed, 64 insertions(+), 1 deletion(-) > create mode 100644 selftest/knownfail.d/ndrdump > create mode 100644 source4/librpc/tests/dns-decode_dns_name_packet-hex.txt > create mode 100644 source4/librpc/tests/krb5pac-PAC_DATA.dat > >diff --git a/python/samba/tests/blackbox/ndrdump.py b/python/samba/tests/blackbox/ndrdump.py >index d00e04b485b..4146f378c6a 100644 >--- a/python/samba/tests/blackbox/ndrdump.py >+++ b/python/samba/tests/blackbox/ndrdump.py >@@ -49,13 +49,18 @@ class NdrDumpTests(BlackboxTestCase): > self.data_path("dns-decode_dns_name_packet-hex.dat")) > > def test_ndrdump_with_hex_struct_name(self): >+ expected = open(self.data_path("dns-decode_dns_name_packet-hex.txt")).read() > try: >- self.check_run( >+ actual = self.check_output( > "ndrdump dns dns_name_packet struct --hex-input %s" % > self.data_path("dns-decode_dns_name_packet-hex.dat")) > except BlackboxProcessError as e: > self.fail(e) > >+ # check_output will return bytes >+ # convert expected to bytes for python 3 >+ self.assertEqual(actual, expected.encode('utf-8')) >+ > def test_ndrdump_upn_dns_info_ex(self): > with open(self.data_path( > 'krb5pac_upn_dns_info_ex.txt')) as f: >@@ -127,3 +132,24 @@ class NdrDumpTests(BlackboxTestCase): > # check_output will return bytes > # convert expected to bytes for python 3 > self.assertEqual(actual, expected.encode('utf-8')) >+ >+ def test_ndrdump_with_binary_struct_name(self): >+ # Prefix of the expected unparsed PAC data (without times, as >+ # these vary by host) >+ expected = '''pull returned NT_STATUS_OK >+ PAC_DATA: struct PAC_DATA >+ num_buffers : 0x00000005 (5) >+ version : 0x00000000 (0) >+ buffers: ARRAY(5)''' >+ try: >+ actual = self.check_output( >+ "ndrdump krb5pac PAC_DATA struct %s" % >+ self.data_path("krb5pac-PAC_DATA.dat")) >+ except BlackboxProcessError as e: >+ self.fail(e) >+ >+ # check_output will return bytes >+ # convert expected to bytes for python 3 >+ self.assertEqual(actual[:len(expected)], >+ expected.encode('utf-8')) >+ self.assertTrue(actual.endswith(b"dump OK\n")) >diff --git a/selftest/knownfail.d/ndrdump b/selftest/knownfail.d/ndrdump >new file mode 100644 >index 00000000000..6ad82d78eb1 >--- /dev/null >+++ b/selftest/knownfail.d/ndrdump >@@ -0,0 +1,2 @@ >+^samba.tests.blackbox.ndrdump.samba.tests.blackbox.ndrdump.NdrDumpTests.test_ndrdump_with_binary_struct_name >+^samba.tests.blackbox.ndrdump.samba.tests.blackbox.ndrdump.NdrDumpTests.test_ndrdump_with_hex_struct_name >diff --git a/source4/librpc/tests/dns-decode_dns_name_packet-hex.txt b/source4/librpc/tests/dns-decode_dns_name_packet-hex.txt >new file mode 100644 >index 00000000000..a973c28d5b9 >--- /dev/null >+++ b/source4/librpc/tests/dns-decode_dns_name_packet-hex.txt >@@ -0,0 +1,35 @@ >+pull returned NT_STATUS_OK >+ dns_name_packet: struct dns_name_packet >+ id : 0xecef (60655) >+ operation : 0x2800 (10240) >+ 0x00: DNS_RCODE (0) >+ 0: DNS_FLAG_RECURSION_AVAIL >+ 0: DNS_FLAG_RECURSION_DESIRED >+ 0: DNS_FLAG_TRUNCATION >+ 0: DNS_FLAG_AUTHORITATIVE >+ 0x05: DNS_OPCODE (5) >+ 0: DNS_FLAG_REPLY >+ qdcount : 0x0001 (1) >+ ancount : 0x0000 (0) >+ nscount : 0x0001 (1) >+ arcount : 0x0000 (0) >+ questions: ARRAY(1) >+ questions: struct dns_name_question >+ name : 'samba2003.example.com' >+ question_type : DNS_QTYPE_SOA (0x6) >+ question_class : DNS_QCLASS_IN (0x1) >+ answers: ARRAY(0) >+ nsrecs: ARRAY(1) >+ nsrecs: struct dns_res_rec >+ name : 'cnamedotprefix0.samba2003.example.com' >+ rr_type : DNS_QTYPE_CNAME (0x5) >+ rr_class : DNS_QCLASS_IN (0x1) >+ ttl : 0x00000384 (900) >+ length : 0x0013 (19) >+ rdata : union dns_rdata(case 0x5) >+ cname_record : '' >+ unexpected : DATA_BLOB length=18 >+[0000] 0F 62 6E 61 6D 65 64 6F 74 70 72 65 66 69 78 32 .bnamedo tprefix2 >+[0010] C0 0C .. >+ additional: ARRAY(0) >+dump OK >diff --git a/source4/librpc/tests/krb5pac-PAC_DATA.dat b/source4/librpc/tests/krb5pac-PAC_DATA.dat >new file mode 100644 >index 0000000000000000000000000000000000000000..71b48d9d7190d4f630064254e48cb71fbddb11ae >GIT binary patch >literal 768 >zcmbu7O)G>^6vzM1G&3G!)Z?u*QAC-|+?CBpGR(waUTQX$#*Csc!U7xLz)mTPS(uMt >zqb!u2W+Bt;h%7B6Ni4+wJkK3$BssTpe)rsa?#ns%df<pboYPEe-$(XRgDz*lPwY_B >z+V`?=QE#+gr~L=*8<vSO<wQ2N#f968(74*G8t;y5*H}8ZE`~T>%Eix~g+1Y2byPJ1 >z2*3?zLsQeQX=%1<wv!D!=ZWVTTq5`D&~wiDU)F>VU7WMf%p6?^ev6Zw{wj@nfiQwR >zmau?j>KfLuiY#q`{GUiZl9$w3t}7hW^lH{=nwlPorMRgPMA=4BZ;t@x=U55}&c>0n >z;|vJ~JZ&_mo86O_S1+;3fc1)&`!RXDz%Ln2u&N3(s6G47^%!Pl@@xgxOR-j2a+X$M >z4jZ<&f<^Wfa(0Y;FP(?nSs_C&fe~7T7=NyKX-u)Nn5o1#fAlT7UpXuv4?Pz9GV;FO >PaOeEiT{6{_%JqK$_tIkz > >literal 0 >HcmV?d00001 > >-- >2.25.1 > > >From f7d54e352576007c29748624490f50be00c73e1e Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 4 Nov 2019 12:15:26 +1300 >Subject: [PATCH 641/686] pidl: Generate compatability wrappers for ndr_print > functions > >This creates wrappers that are compatible with the functions called by >ndrdump which have an extra "int flags" parameter for NDR_IN and >NDR_OUT. This will make ndrdump of public structures work again. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14191 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Pair-progammed-with: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 78521577eb11d2d601768f3c521549793341a450) >--- > pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) > >diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm >index 2fc4327faf4..3a43f605355 100644 >--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm >+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm >@@ -2768,7 +2768,7 @@ sub StructEntry($$) > $self->pidl("\t\t.struct_size = sizeof($type_decl),"); > $self->pidl("\t\t.ndr_push = (ndr_push_flags_fn_t) ndr_push_$d->{NAME},"); > $self->pidl("\t\t.ndr_pull = (ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},"); >- $self->pidl("\t\t.ndr_print = (ndr_print_function_t) ndr_print_$d->{NAME},"); >+ $self->pidl("\t\t.ndr_print = (ndr_print_function_t) ndr_print_flags_$d->{NAME},"); > $self->pidl("\t},"); > return 1; > } >@@ -3014,6 +3014,18 @@ sub ParseTypePrintFunction($$$) > > $self->pidl_hdr("void ".TypeFunctionName("ndr_print", $e)."(struct ndr_print *ndr, const char *name, $args);"); > >+ if (has_property($e, "public")) { >+ $self->pidl("static void ".TypeFunctionName("ndr_print_flags", $e). >+ "(struct ndr_print *$ndr, const char *name, int unused, $args)" >+ ); >+ $self->pidl("{"); >+ $self->indent; >+ $self->pidl(TypeFunctionName("ndr_print", $e)."($ndr, name, $varname);"); >+ $self->deindent; >+ $self->pidl("}"); >+ $self->pidl(""); >+ } >+ > return if (has_property($e, "noprint")); > > $self->pidl("_PUBLIC_ void ".TypeFunctionName("ndr_print", $e)."(struct ndr_print *$ndr, const char *name, $args)"); >-- >2.25.1 > > >From ece00b23bb7960a5e17d8440cdd8b4ac388cde5c Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 5 Nov 2019 16:15:38 +1300 >Subject: [PATCH 642/686] ndrdump: Fix new "struct" feature > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14191 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Pair-progammed-with: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 3b9e983b648bd3738d8a5e1d53f29cd21ba63387) >--- > librpc/tools/ndrdump.c | 2 +- > selftest/knownfail.d/ndrdump | 2 -- > 2 files changed, 1 insertion(+), 3 deletions(-) > delete mode 100644 selftest/knownfail.d/ndrdump > >diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c >index 089b160b65f..01c5e549d66 100644 >--- a/librpc/tools/ndrdump.c >+++ b/librpc/tools/ndrdump.c >@@ -360,7 +360,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > } > > if (strcmp(type, "struct") == 0) { >- flags = 0; /* neither NDR_IN nor NDR_OUT */ >+ flags = NDR_SCALARS|NDR_BUFFERS; /* neither NDR_IN nor NDR_OUT */ > f = find_struct(p, format, &f_buffer); > } else { > f = find_function(p, format); >diff --git a/selftest/knownfail.d/ndrdump b/selftest/knownfail.d/ndrdump >deleted file mode 100644 >index 6ad82d78eb1..00000000000 >--- a/selftest/knownfail.d/ndrdump >+++ /dev/null >@@ -1,2 +0,0 @@ >-^samba.tests.blackbox.ndrdump.samba.tests.blackbox.ndrdump.NdrDumpTests.test_ndrdump_with_binary_struct_name >-^samba.tests.blackbox.ndrdump.samba.tests.blackbox.ndrdump.NdrDumpTests.test_ndrdump_with_hex_struct_name >-- >2.25.1 > > >From 1cb3b10f347c3aa5ff477564c5cc31346b29ca5e Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 15 Nov 2019 19:25:54 +1300 >Subject: [PATCH 643/686] ndrdump: Use human-readable strings for NDR decode > errors > >These make much more sense than the NTSTATUS values they can be forced >to map to. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 816869ecea06b0b936e3ead4074bb754ee8650ca) > >[jsutton@samba.org Adapted to fix conflicts and remove > --stop-on-parse-failure change] >--- > librpc/tools/ndrdump.c | 32 +++++++------------ > python/samba/tests/blackbox/ndrdump.py | 2 +- > .../tests/dns-decode_dns_name_packet-hex.txt | 2 +- > 3 files changed, 14 insertions(+), 22 deletions(-) > >diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c >index 01c5e549d66..76592fc08cd 100644 >--- a/librpc/tools/ndrdump.c >+++ b/librpc/tools/ndrdump.c >@@ -170,7 +170,6 @@ static NTSTATUS ndrdump_pull_and_print_pipes(const char *function, > struct ndr_print *ndr_print, > const struct ndr_interface_call_pipes *pipes) > { >- NTSTATUS status; > enum ndr_err_code ndr_err; > uint32_t i; > >@@ -198,12 +197,12 @@ static NTSTATUS ndrdump_pull_and_print_pipes(const char *function, > ndr_pull->current_mem_ctx = c; > ndr_err = pipes->pipes[i].ndr_pull(ndr_pull, NDR_SCALARS, c); > ndr_pull->current_mem_ctx = saved_mem_ctx; >- status = ndr_map_error2ntstatus(ndr_err); > >- printf("pull returned %s\n", nt_errstr(status)); >- if (!NT_STATUS_IS_OK(status)) { >+ printf("pull returned %s\n", >+ ndr_map_error2string(ndr_err)); >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { > talloc_free(c); >- return status; >+ return ndr_map_error2ntstatus(ndr_err); > } > pipes->pipes[i].ndr_print(ndr_print, n, c); > talloc_free(c); >@@ -429,8 +428,8 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > } > > if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- status = ndr_map_error2ntstatus(ndr_err); >- printf("pull for context file returned %s\n", nt_errstr(status)); >+ printf("pull for context file returned %s\n", >+ ndr_map_error2string(ndr_err)); > exit(1); > } > memcpy(v_st, st, f->struct_size); >@@ -475,10 +474,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > ndr_print->depth = 1; > > ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr_pull, mem_ctx, &sec_vt); >- status = ndr_map_error2ntstatus(ndr_err); >- if (!NT_STATUS_IS_OK(status)) { >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { > printf("ndr_pop_dcerpc_sec_verification_trailer returned %s\n", >- nt_errstr(status)); >+ ndr_map_error2string(ndr_err)); > } > > if (sec_vt != NULL && sec_vt->count.count > 0) { >@@ -505,9 +503,8 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > } > > ndr_err = f->ndr_pull(ndr_pull, flags, st); >- status = ndr_map_error2ntstatus(ndr_err); >- >- printf("pull returned %s\n", nt_errstr(status)); >+ printf("pull returned %s\n", >+ ndr_map_error2string(ndr_err)); > > if (ndr_pull->offset > ndr_pull->relative_highest_offset) { > highest_ofs = ndr_pull->offset; >@@ -529,11 +526,6 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > > f->ndr_print(ndr_print, format, flags, st); > >- if (!NT_STATUS_IS_OK(status)) { >- printf("dump FAILED\n"); >- exit(1); >- } >- > if (flags & NDR_IN) { > status = ndrdump_pull_and_print_pipes(format, > ndr_pull, >@@ -588,8 +580,8 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > ndr_v_pull->flags |= LIBNDR_FLAG_REF_ALLOC; > > ndr_err = f->ndr_pull(ndr_v_pull, flags, v_st); >- status = ndr_map_error2ntstatus(ndr_err); >- printf("pull returned %s\n", nt_errstr(status)); >+ printf("pull returned %s\n", >+ ndr_map_error2string(ndr_err)); > if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { > printf("validate pull FAILED\n"); > exit(1); >diff --git a/python/samba/tests/blackbox/ndrdump.py b/python/samba/tests/blackbox/ndrdump.py >index 4146f378c6a..5b5d5ed019c 100644 >--- a/python/samba/tests/blackbox/ndrdump.py >+++ b/python/samba/tests/blackbox/ndrdump.py >@@ -136,7 +136,7 @@ class NdrDumpTests(BlackboxTestCase): > def test_ndrdump_with_binary_struct_name(self): > # Prefix of the expected unparsed PAC data (without times, as > # these vary by host) >- expected = '''pull returned NT_STATUS_OK >+ expected = '''pull returned Success > PAC_DATA: struct PAC_DATA > num_buffers : 0x00000005 (5) > version : 0x00000000 (0) >diff --git a/source4/librpc/tests/dns-decode_dns_name_packet-hex.txt b/source4/librpc/tests/dns-decode_dns_name_packet-hex.txt >index a973c28d5b9..02e95c0bd20 100644 >--- a/source4/librpc/tests/dns-decode_dns_name_packet-hex.txt >+++ b/source4/librpc/tests/dns-decode_dns_name_packet-hex.txt >@@ -1,4 +1,4 @@ >-pull returned NT_STATUS_OK >+pull returned Success > dns_name_packet: struct dns_name_packet > id : 0xecef (60655) > operation : 0x2800 (10240) >-- >2.25.1 > > >From 44699f1e25e07c0bcead318eb015b454f98e2309 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Sat, 16 Nov 2019 21:25:11 +1300 >Subject: [PATCH 644/686] ndrdump: avoid use after free > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Douglas Bagnall <dbagnall@samba.org> >Autobuild-Date(master): Sun Nov 17 23:54:11 UTC 2019 on sn-devel-184 > >(cherry picked from commit e856877ef88bf273cbf814ff17abad900ba7ea27) >--- > librpc/tools/ndrdump.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c >index 76592fc08cd..cf0ce7148bc 100644 >--- a/librpc/tools/ndrdump.c >+++ b/librpc/tools/ndrdump.c >@@ -205,10 +205,11 @@ static NTSTATUS ndrdump_pull_and_print_pipes(const char *function, > return ndr_map_error2ntstatus(ndr_err); > } > pipes->pipes[i].ndr_print(ndr_print, n, c); >- talloc_free(c); > if (*count == 0) { >+ talloc_free(c); > break; > } >+ talloc_free(c); > idx++; > } > } >-- >2.25.1 > > >From 07c8bf838609989c7a4948fc9337519f4f72cbf0 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Wed, 20 Nov 2019 12:17:37 +1300 >Subject: [PATCH 645/686] ndrdump: Fix one more NTSTATUS rather than friendly > ndr message > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit db6c12f1584215c21cd5e56bef13c6d1c8b608ce) >--- > librpc/tools/ndrdump.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c >index cf0ce7148bc..9237e6289c6 100644 >--- a/librpc/tools/ndrdump.c >+++ b/librpc/tools/ndrdump.c >@@ -559,8 +559,8 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > } > > ndr_err = f->ndr_push(ndr_v_push, flags, st); >- status = ndr_map_error2ntstatus(ndr_err); >- printf("push returned %s\n", nt_errstr(status)); >+ printf("push returned %s\n", >+ ndr_map_error2string(ndr_err)); > if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { > printf("validate push FAILED\n"); > exit(1); >-- >2.25.1 > > >From 30140a7d076b9e6850237231d28bbd96d5fb3116 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Wed, 20 Nov 2019 09:58:15 +1300 >Subject: [PATCH 646/686] ndrdump: Add const > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 3194baaf88d78f86cbf821600cd69712e1cc02a2) >--- > librpc/tools/ndrdump.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > >diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c >index 9237e6289c6..17356cb21ca 100644 >--- a/librpc/tools/ndrdump.c >+++ b/librpc/tools/ndrdump.c >@@ -242,7 +242,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > * name of a public structure > */ > const char *format = NULL; >- uint8_t *data; >+ const uint8_t *data; > size_t size; > DATA_BLOB blob; > struct ndr_pull *ndr_pull; >@@ -403,8 +403,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > exit(1); > } > >- blob.data = data; >- blob.length = size; >+ blob = data_blob_const(data, size); > > ndr_pull = ndr_pull_init_blob(&blob, mem_ctx); > if (ndr_pull == NULL) { >@@ -450,10 +449,11 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > } > > if (hex_input) { >- blob = hexdump_to_data_blob(mem_ctx, (char *)data, size); >+ blob = hexdump_to_data_blob(mem_ctx, >+ (const char *)data, >+ size); > } else { >- blob.data = data; >- blob.length = size; >+ blob = data_blob_const(data, size); > } > > ndr_pull = ndr_pull_init_blob(&blob, mem_ctx); >-- >2.25.1 > > >From cbcbe5be76de751afbd2fc18603341e931fcda87 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Wed, 20 Nov 2019 10:00:52 +1300 >Subject: [PATCH 647/686] ndrdump: Allow for base64-encoded input in a file and > on the command line > >It has become customary to provide reproduction steps for fuzzing failures >in terms of an ndrdump command line. This allows the input to be provided >as a argument or in a file rather than via base64 -d. This makes reproducing >the issue easier as everything can be put in a plaintext bug report. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 6f0d30fd5cc921dedbc0f0741e3959b4ebc4027d) > >[jsutton@samba.org Adapted to fix conflicts] >--- > librpc/tools/ndrdump.c | 52 ++++++++++++++++++++++++++++++++++++------ > 1 file changed, 45 insertions(+), 7 deletions(-) > >diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c >index 17356cb21ca..614221fca25 100644 >--- a/librpc/tools/ndrdump.c >+++ b/librpc/tools/ndrdump.c >@@ -26,6 +26,7 @@ > #include "librpc/gen_ndr/ndr_dcerpc.h" > #include "lib/cmdline/popt_common.h" > #include "param/param.h" >+#include "lib/util/base64.h" > > static const struct ndr_interface_call *find_function( > const struct ndr_interface_table *p, >@@ -242,6 +243,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > * name of a public structure > */ > const char *format = NULL; >+ const char *cmdline_input = NULL; > const uint8_t *data; > size_t size; > DATA_BLOB blob; >@@ -261,8 +263,19 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > bool assume_ndr64 = false; > bool quiet = false; > bool hex_input = false; >+ bool base64_input = false; > int opt; >- enum {OPT_CONTEXT_FILE=1000, OPT_VALIDATE, OPT_DUMP_DATA, OPT_LOAD_DSO, OPT_NDR64, OPT_QUIET, OPT_HEX_INPUT}; >+ enum { >+ OPT_CONTEXT_FILE=1000, >+ OPT_VALIDATE, >+ OPT_DUMP_DATA, >+ OPT_LOAD_DSO, >+ OPT_NDR64, >+ OPT_QUIET, >+ OPT_BASE64_INPUT, >+ OPT_HEX_INPUT, >+ OPT_CMDLINE_INPUT, >+ }; > struct poptOption long_options[] = { > POPT_AUTOHELP > {"context-file", 'c', POPT_ARG_STRING, NULL, OPT_CONTEXT_FILE, "In-filename to parse first", "CTX-FILE" }, >@@ -271,7 +284,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > {"load-dso", 'l', POPT_ARG_STRING, NULL, OPT_LOAD_DSO, "load from shared object file", NULL }, > {"ndr64", 0, POPT_ARG_NONE, NULL, OPT_NDR64, "Assume NDR64 data", NULL }, > {"quiet", 0, POPT_ARG_NONE, NULL, OPT_QUIET, "Don't actually dump anything", NULL }, >+ {"base64-input", 0, POPT_ARG_NONE, NULL, OPT_BASE64_INPUT, "Read the input file in as a base64 string", NULL }, > {"hex-input", 0, POPT_ARG_NONE, NULL, OPT_HEX_INPUT, "Read the input file in as a hex dump", NULL }, >+ {"input", 0, POPT_ARG_STRING, NULL, OPT_CMDLINE_INPUT, "Provide the input on the command line (use with --base64-input)", "INPUT" }, > POPT_COMMON_SAMBA > POPT_COMMON_VERSION > {0} >@@ -313,9 +328,15 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > case OPT_QUIET: > quiet = true; > break; >+ case OPT_BASE64_INPUT: >+ base64_input = true; >+ break; > case OPT_HEX_INPUT: > hex_input = true; > break; >+ case OPT_CMDLINE_INPUT: >+ cmdline_input = poptGetOptArg(pc); >+ break; > } > } > >@@ -435,10 +456,18 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > memcpy(v_st, st, f->struct_size); > } > >- if (filename) >+ if (filename && cmdline_input) { >+ printf("cannot combine --input with a filename\n"); >+ TALLOC_FREE(mem_ctx); >+ exit(1); >+ } else if (cmdline_input) { >+ data = (const uint8_t *)cmdline_input; >+ size = strlen(cmdline_input); >+ } else if (filename) { > data = (uint8_t *)file_load(filename, &size, 0, mem_ctx); >- else >+ } else { > data = (uint8_t *)stdin_load(mem_ctx, &size); >+ } > > if (!data) { > if (filename) >@@ -448,10 +477,19 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > exit(1); > } > >- if (hex_input) { >- blob = hexdump_to_data_blob(mem_ctx, >- (const char *)data, >- size); >+ if (hex_input && base64_input) { >+ printf("cannot combine --hex-input with --base64-input\n"); >+ TALLOC_FREE(mem_ctx); >+ exit(1); >+ >+ } else if (hex_input) { >+ blob = hexdump_to_data_blob(mem_ctx, (const char *)data, size); >+ } else if (base64_input) { >+ /* Use talloc_strndup() to ensure null termination */ >+ blob = base64_decode_data_blob(talloc_strndup(mem_ctx, >+ (const char *)data, size)); >+ /* base64_decode_data_blob() allocates on NULL */ >+ talloc_steal(mem_ctx, blob.data); > } else { > blob = data_blob_const(data, size); > } >-- >2.25.1 > > >From 9bb6629ceadb985dac2288f84c34153831b0b553 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Wed, 20 Nov 2019 10:55:18 +1300 >Subject: [PATCH 648/686] python: Return the stdout when also checking error > codes > >This will aid in checking that ndrdump behaves as expected when >failing to parse > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 24fa3374e041f9ad26b6f124aed0c5a61a7d551e) >--- > python/samba/tests/__init__.py | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py >index d5be84ea297..9527f0cafac 100644 >--- a/python/samba/tests/__init__.py >+++ b/python/samba/tests/__init__.py >@@ -520,6 +520,7 @@ class BlackboxTestCase(TestCaseInTempDir): > stdoutdata, > stderrdata, > msg) >+ return stdoutdata > > def check_output(self, line): > use_shell = not isinstance(line, list) >-- >2.25.1 > > >From 49a9c6b098976f3442f5dea686e6eecfcf6faa49 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Wed, 20 Nov 2019 18:53:09 +1300 >Subject: [PATCH 649/686] ndrdump: Show the actual struct/function name in the > print, not just what it was called > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit bbae56411c716d8678687cf7c559488b618e8935) > >[jsutton@samba.org Adapted to fix conflicts] >--- > librpc/tools/ndrdump.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c >index 614221fca25..cd6ae9c7eda 100644 >--- a/librpc/tools/ndrdump.c >+++ b/librpc/tools/ndrdump.c >@@ -563,7 +563,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) > ndrdump_data(blob.data, blob.length, dumpdata); > } > >- f->ndr_print(ndr_print, format, flags, st); >+ f->ndr_print(ndr_print, f->name, flags, st); > > if (flags & NDR_IN) { > status = ndrdump_pull_and_print_pipes(format, >-- >2.25.1 > > >From 52fe97ca760840a9e8eaf748fccac16d262e66f7 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 6 Dec 2019 11:00:57 +1300 >Subject: [PATCH 650/686] selftest: Confirm that ndrdump struct mode is not > available for enums > >These are not passed by pointer so the structure dump system does not work >for these. It is best to dump the containing structure instead. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 238d08b07d0178940c28839518c9f1afbc605378) > >[jsutton@samba.org Adapted to fix conflicts] >--- > python/samba/tests/blackbox/ndrdump.py | 14 ++++++++++++++ > selftest/knownfail.d/ndrdump-structs-only | 1 + > 2 files changed, 15 insertions(+) > create mode 100644 selftest/knownfail.d/ndrdump-structs-only > >diff --git a/python/samba/tests/blackbox/ndrdump.py b/python/samba/tests/blackbox/ndrdump.py >index 5b5d5ed019c..cd5ee6bd1a1 100644 >--- a/python/samba/tests/blackbox/ndrdump.py >+++ b/python/samba/tests/blackbox/ndrdump.py >@@ -61,6 +61,20 @@ class NdrDumpTests(BlackboxTestCase): > # convert expected to bytes for python 3 > self.assertEqual(actual, expected.encode('utf-8')) > >+ def test_ndrdump_with_enum_not_struct(self): >+ expected = '''Public structure 'netr_SchannelType' not found >+''' >+ try: >+ actual = self.check_exit_code( >+ "ndrdump misc netr_SchannelType --input=x struct", >+ 1) >+ except BlackboxProcessError as e: >+ self.fail(e) >+ >+ # check_output will return bytes >+ # convert expected to bytes for python 3 >+ self.assertEqual(actual, expected.encode('utf-8')) >+ > def test_ndrdump_upn_dns_info_ex(self): > with open(self.data_path( > 'krb5pac_upn_dns_info_ex.txt')) as f: >diff --git a/selftest/knownfail.d/ndrdump-structs-only b/selftest/knownfail.d/ndrdump-structs-only >new file mode 100644 >index 00000000000..733ea495490 >--- /dev/null >+++ b/selftest/knownfail.d/ndrdump-structs-only >@@ -0,0 +1 @@ >+^samba.tests.blackbox.ndrdump.samba.tests.blackbox.ndrdump.NdrDumpTests.test_ndrdump_with_enum_not_struct >-- >2.25.1 > > >From 8ef649e3f54af8ffd12ee333de445a8c9c2d8345 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 5 Dec 2019 11:37:05 +1300 >Subject: [PATCH 651/686] pidl:NDR/Parser: only include structs in > ndr_interface_public_struct > >We only have ndrdump and the fuzzers set up for structures, not BITMAPS, >ENUMS etc. > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Tue Dec 10 17:45:46 UTC 2019 on sn-devel-184 > >(cherry picked from commit bc0c876a9ebbec1a31856a9e7147a481c69ba434) > >[jsutton@samba.org Adapted to keep knownfail as the test still fails] >--- > pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 20 ++++++++++++++++---- > 1 file changed, 16 insertions(+), 4 deletions(-) > >diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm >index 3a43f605355..126440e114a 100644 >--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm >+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm >@@ -80,6 +80,18 @@ sub has_fast_array($$) > return ($t->{NAME} eq "uint8") or ($t->{NAME} eq "string"); > } > >+sub is_public_struct >+{ >+ my ($d) = @_; >+ if (!has_property($d, "public")) { >+ return 0; >+ } >+ my $t = $d; >+ if ($d->{TYPE} eq "TYPEDEF") { >+ $t = $d->{DATA}; >+ } >+ return $t->{TYPE} eq "STRUCT"; >+} > > #################################### > # pidl() is our basic output routine >@@ -2783,7 +2795,7 @@ sub FunctionTable($$) > my $uname = uc $interface->{NAME}; > > foreach my $d (@{$interface->{TYPES}}) { >- next unless (has_property($d, "public")); >+ next unless (is_public_struct($d)); > $count_public_structs += 1; > } > return if ($#{$interface->{FUNCTIONS}}+1 == 0 and >@@ -2797,8 +2809,8 @@ sub FunctionTable($$) > $self->pidl("static const struct ndr_interface_public_struct $interface->{NAME}\_public_structs[] = {"); > > foreach my $d (@{$interface->{TYPES}}) { >- next unless (has_property($d, "public")); >- $self->StructEntry($d) >+ next unless (is_public_struct($d)); >+ $self->StructEntry($d); > } > $self->pidl("\t{ .name = NULL }"); > $self->pidl("};"); >@@ -3014,7 +3026,7 @@ sub ParseTypePrintFunction($$$) > > $self->pidl_hdr("void ".TypeFunctionName("ndr_print", $e)."(struct ndr_print *ndr, const char *name, $args);"); > >- if (has_property($e, "public")) { >+ if (is_public_struct($e)) { > $self->pidl("static void ".TypeFunctionName("ndr_print_flags", $e). > "(struct ndr_print *$ndr, const char *name, int unused, $args)" > ); >-- >2.25.1 > > >From c734e350e75c05ea191d01c1263f2d8e0746a790 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Wed, 13 May 2020 16:54:39 +0200 >Subject: [PATCH 652/686] selftest: Split out a provision_ad_member() function > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit c94f6ddccae9093364b003287a95a43379067dd6) > >[jsutton@samba.org Adapted to fix conflicts and remove trustvar > parameters] >--- > selftest/target/Samba3.pm | 29 ++++++++++++++++++++--------- > 1 file changed, 20 insertions(+), 9 deletions(-) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 75960dbc790..883c8369c3c 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -365,20 +365,15 @@ sub setup_nt4_member > return $ret; > } > >-sub setup_ad_member >+sub provision_ad_member > { >- my ($self, $prefix, $dcvars) = @_; >+ my ($self, >+ $prefix, >+ $dcvars) = @_; > > my $prefix_abs = abs_path($prefix); > my @dirs = (); > >- # If we didn't build with ADS, pretend this env was never available >- if (not $self->have_ads()) { >- return "UNKNOWN"; >- } >- >- print "PROVISIONING S3 AD MEMBER..."; >- > mkdir($prefix_abs, 0777); > > my $share_dir="$prefix_abs/share"; >@@ -493,6 +488,22 @@ sub setup_ad_member > return $ret; > } > >+sub setup_ad_member >+{ >+ my ($self, >+ $prefix, >+ $dcvars) = @_; >+ >+ # If we didn't build with ADS, pretend this env was never available >+ if (not $self->have_ads()) { >+ return "UNKNOWN"; >+ } >+ >+ print "PROVISIONING AD MEMBER..."; >+ >+ return $self->provision_ad_member($prefix, $dcvars); >+} >+ > sub setup_ad_member_rfc2307 > { > my ($self, $prefix, $dcvars) = @_; >-- >2.25.1 > > >From c4c4dfd80a6827310bfb7956c5a9220fb91be2aa Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Tue, 11 May 2021 17:59:51 +0200 >Subject: [PATCH 653/686] selftest: Pass down the machine account name to > provision_ad_member > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit fbe68dcbb783409589cdefd8ee551c9971c51f08) > >[jsutton@samba.org Fixed conflicts and removed inapplicable changes] >--- > selftest/target/Samba3.pm | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 883c8369c3c..c3dbb41eb60 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -369,6 +369,7 @@ sub provision_ad_member > { > my ($self, > $prefix, >+ $machine_account, > $dcvars) = @_; > > my $prefix_abs = abs_path($prefix); >@@ -421,7 +422,7 @@ sub provision_ad_member > "; > > my $ret = $self->provision($prefix, $dcvars->{DOMAIN}, >- "LOCALADMEMBER", >+ $machine_account, > "loCalMemberPass", > $member_options, > $dcvars->{SERVER_IP}, >@@ -501,7 +502,9 @@ sub setup_ad_member > > print "PROVISIONING AD MEMBER..."; > >- return $self->provision_ad_member($prefix, $dcvars); >+ return $self->provision_ad_member($prefix, >+ "LOCALADMEMBER", >+ $dcvars); > } > > sub setup_ad_member_rfc2307 >-- >2.25.1 > > >From dfd99e7689699abde0a46f13e11599ccfe466259 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 10 May 2021 10:37:11 +0200 >Subject: [PATCH 654/686] selftest: Add ad_member_offline_logon env > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 6219eb52a24d04cd03a0f1b66a26677c81a44fb9) > >[jsutton@samba.org Adapted to fix conflicts] >--- > selftest/target/Samba.pm | 2 ++ > selftest/target/Samba3.pm | 19 +++++++++++++++++++ > 2 files changed, 21 insertions(+) > >diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm >index 3fe53f94a2c..7fd57a45582 100644 >--- a/selftest/target/Samba.pm >+++ b/selftest/target/Samba.pm >@@ -427,6 +427,8 @@ sub get_interface($) > $interfaces{"prockilldc"} = 46; > $interfaces{"proclimitdc"} = 47; > >+ $interfaces{"offlineadmem"} = 58; >+ > $interfaces{"rootdnsforwarder"} = 64; > > # update lib/socket_wrapper/socket_wrapper.c >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index c3dbb41eb60..4f48e15ed47 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -185,6 +185,7 @@ sub check_env($$) > ad_member_rfc2307 => ["ad_dc_ntvfs"], > ad_member_idmap_rid => ["ad_dc"], > ad_member_idmap_ad => ["fl2008r2dc"], >+ ad_member_offline_logon => ["ad_dc"], > ); > > sub setup_nt4_dc >@@ -793,6 +794,24 @@ sub setup_ad_member_idmap_ad > return $ret; > } > >+sub setup_ad_member_offline_logon >+{ >+ my ($self, >+ $prefix, >+ $dcvars) = @_; >+ >+ # If we didn't build with ADS, pretend this env was never available >+ if (not $self->have_ads()) { >+ return "UNKNOWN"; >+ } >+ >+ print "PROVISIONING AD MEMBER OFFLINE LOGON..."; >+ >+ return $self->provision_ad_member($prefix, >+ "OFFLINEADMEM", >+ $dcvars); >+} >+ > sub setup_simpleserver > { > my ($self, $path) = @_; >-- >2.25.1 > > >From 6e8cd95aff4cee974f604113d479804bf18dfaf6 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 10 May 2021 10:40:27 +0200 >Subject: [PATCH 655/686] selftest: Turn on offline logon for > ad_member_offline_logon > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit a04a5885745533127c8eb36265f1eb664ab276a1) > >[jsutton@samba.org Adapted to fix conflicts] >--- > selftest/target/Samba3.pm | 12 ++++++++++-- > 1 file changed, 10 insertions(+), 2 deletions(-) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 4f48e15ed47..4d8b8d4798f 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -371,7 +371,8 @@ sub provision_ad_member > my ($self, > $prefix, > $machine_account, >- $dcvars) = @_; >+ $dcvars, >+ $offline_logon) = @_; > > my $prefix_abs = abs_path($prefix); > my @dirs = (); >@@ -403,6 +404,11 @@ sub provision_ad_member > $substitution_path = "$share_dir/D_$dcvars->{DOMAIN}/u_$dcvars->{DOMAIN}/alice/g_$dcvars->{DOMAIN}/domain users"; > push(@dirs, $substitution_path); > >+ my $option_offline_logon = "no"; >+ if (defined($offline_logon)) { >+ $option_offline_logon = "yes"; >+ } >+ > my $member_options = " > security = ads > workgroup = $dcvars->{DOMAIN} >@@ -411,6 +417,7 @@ sub provision_ad_member > template homedir = /home/%D/%G/%U > winbind scan trusted domains = no > winbind use krb5 enterprise principals = yes >+ winbind offline logon = $option_offline_logon > > [sub_dug] > path = $share_dir/D_%D/U_%U/G_%G >@@ -809,7 +816,8 @@ sub setup_ad_member_offline_logon > > return $self->provision_ad_member($prefix, > "OFFLINEADMEM", >- $dcvars); >+ $dcvars, >+ 1); > } > > sub setup_simpleserver >-- >2.25.1 > > >From ae2363ff675c22ceb441470e8ec2899a60c59ddd Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 10 May 2021 16:37:16 +0200 >Subject: [PATCH 656/686] selftest: Add skip_wait to check_or_start > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit eef192b10e4f07ed912286d94ceb1b119659dc68) > >[jsutton@samba.org Adapted to fix conflicts and to older check_or_start > function] >--- > selftest/target/Samba3.pm | 30 +++++++++++++++++------------- > 1 file changed, 17 insertions(+), 13 deletions(-) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 4d8b8d4798f..4ae5390f1e7 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -225,7 +225,7 @@ sub setup_nt4_dc > > $vars or return undef; > >- if (not $self->check_or_start($vars, "yes", "yes", "yes")) { >+ if (not $self->check_or_start($vars, "yes", "yes", "yes", 0)) { > return undef; > } > >@@ -274,7 +274,7 @@ sub setup_nt4_dc_schannel > > $vars or return undef; > >- if (not $self->check_or_start($vars, "yes", "yes", "yes")) { >+ if (not $self->check_or_start($vars, "yes", "yes", "yes", 0)) { > return undef; > } > >@@ -351,7 +351,7 @@ sub setup_nt4_member > return undef; > } > >- if (not $self->check_or_start($ret, "yes", "yes", "yes")) { >+ if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { > return undef; > } > >@@ -483,7 +483,7 @@ sub provision_ad_member > # access the share for tests. > chmod 0777, "$prefix/share"; > >- if (not $self->check_or_start($ret, "yes", "yes", "yes")) { >+ if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { > return undef; > } > >@@ -597,7 +597,7 @@ sub setup_ad_member_rfc2307 > # access the share for tests. > chmod 0777, "$prefix/share"; > >- if (not $self->check_or_start($ret, "yes", "yes", "yes")) { >+ if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { > return undef; > } > >@@ -689,7 +689,7 @@ sub setup_ad_member_idmap_rid > # access the share for tests. > chmod 0777, "$prefix/share"; > >- if (not $self->check_or_start($ret, "yes", "yes", "yes")) { >+ if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { > return undef; > } > >@@ -780,7 +780,7 @@ sub setup_ad_member_idmap_ad > # access the share for tests. > chmod 0777, "$prefix/share"; > >- if (not $self->check_or_start($ret, "yes", "yes", "yes")) { >+ if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { > return undef; > } > >@@ -914,7 +914,7 @@ sub setup_simpleserver > > $vars or return undef; > >- if (not $self->check_or_start($vars, "yes", "no", "yes")) { >+ if (not $self->check_or_start($vars, "yes", "no", "yes", 0)) { > return undef; > } > >@@ -1058,7 +1058,7 @@ sub setup_fileserver > > $vars or return undef; > >- if (not $self->check_or_start($vars, "yes", "no", "yes")) { >+ if (not $self->check_or_start($vars, "yes", "no", "yes", 0)) { > return undef; > } > >@@ -1213,7 +1213,7 @@ $ret->{USERNAME} = KTEST\\Administrator > # access the share for tests. > chmod 0777, "$prefix/share"; > >- if (not $self->check_or_start($ret, "yes", "no", "yes")) { >+ if (not $self->check_or_start($ret, "yes", "no", "yes", 0)) { > return undef; > } > return $ret; >@@ -1237,7 +1237,7 @@ ntlm auth = yes > > $vars or return undef; > >- if (not $self->check_or_start($vars, "yes", "no", "yes")) { >+ if (not $self->check_or_start($vars, "yes", "no", "yes", 0)) { > return undef; > } > >@@ -1273,8 +1273,8 @@ sub read_pid($$) > return $pid; > } > >-sub check_or_start($$$$$) { >- my ($self, $env_vars, $nmbd, $winbindd, $smbd) = @_; >+sub check_or_start($$$$$$) { >+ my ($self, $env_vars, $nmbd, $winbindd, $smbd, $skip_wait) = @_; > > # use a pipe for stdin in the child processes. This allows > # those processes to monitor the pipe for EOF to ensure they >@@ -1473,6 +1473,10 @@ sub check_or_start($$$$$) { > > close(STDIN_READER); > >+ if ($skip_wait) { >+ return 1; >+ } >+ > return $self->wait_for_start($env_vars, $nmbd, $winbindd, $smbd); > } > >-- >2.25.1 > > >From 8f293fbbf1f06b62addd165884ab380ad6b747a2 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 10 May 2021 10:40:31 +0200 >Subject: [PATCH 657/686] selftest: Set winbind offline in > ad_member_offline_logon target > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 763e03235462adbe29edd92339e7a11b5a008556) > >[jsutton@samba.org Adapted to old check_or_start function] >--- > selftest/target/Samba3.pm | 109 +++++++++++++++++++++++++++++++++++++- > 1 file changed, 107 insertions(+), 2 deletions(-) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 4ae5390f1e7..b8bae945d47 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -483,8 +483,113 @@ sub provision_ad_member > # access the share for tests. > chmod 0777, "$prefix/share"; > >- if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { >- return undef; >+ if (defined($offline_logon)) { >+ my $wbinfo = Samba::bindir_path($self, "wbinfo"); >+ >+ if (not $self->check_or_start($ret, "no", "yes", "no", 0)) { >+ return undef; >+ } >+ >+ # Fill samlogoncache for alice >+ $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' "; >+ $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' "; >+ $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" "; >+ $cmd .= "$wbinfo --pam-logon=ADDOMAIN/alice%Secret007"; >+ if (system($cmd) != 0) { >+ warn("Filling the cache failed\n$cmd"); >+ return undef; >+ } >+ >+ $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' "; >+ $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' "; >+ $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" "; >+ $cmd .= "$wbinfo --ccache-save=ADDOMAIN/alice%Secret007"; >+ if (system($cmd) != 0) { >+ warn("Filling the cache failed\n$cmd"); >+ return undef; >+ } >+ >+ # Fill samlogoncache for bob >+ $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' "; >+ $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' "; >+ $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" "; >+ $cmd .= "$wbinfo --pam-logon=ADDOMAIN/bob%Secret007"; >+ if (system($cmd) != 0) { >+ warn("Filling the cache failed\n$cmd"); >+ return undef; >+ } >+ >+ $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' "; >+ $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' "; >+ $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" "; >+ $cmd .= "$wbinfo --ccache-save=ADDOMAIN/bob%Secret007"; >+ if (system($cmd) != 0) { >+ warn("Filling the cache failed\n$cmd"); >+ return undef; >+ } >+ >+ # Set windindd offline >+ my $smbcontrol = Samba::bindir_path($self, "smbcontrol"); >+ $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' "; >+ $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' "; >+ $cmd .= "UID_WRAPPER_ROOT='1' "; >+ $cmd .= "$smbcontrol $ret->{CONFIGURATION} winbindd offline"; >+ if (system($cmd) != 0) { >+ warn("Setting winbindd offline failed\n$cmd"); >+ return undef; >+ } >+ >+ # Validate the offline cache >+ my $smbcontrol = Samba::bindir_path($self, "smbcontrol"); >+ $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' "; >+ $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' "; >+ $cmd .= "UID_WRAPPER_ROOT='1' "; >+ $cmd .= "$smbcontrol $ret->{CONFIGURATION} winbindd validate-cache"; >+ if (system($cmd) != 0) { >+ warn("Validation of winbind credential cache failed\n$cmd"); >+ teardown_env($self, $ret); >+ return undef; >+ } >+ >+ # Shut down winbindd >+ teardown_env($self, $ret); >+ >+ ### Change SOCKET_WRAPPER_DIR so it can't connect to AD >+ my $swrap_env = $ENV{SOCKET_WRAPPER_DIR}; >+ $ENV{SOCKET_WRAPPER_DIR} = "$prefix_abs"; >+ >+ # Start winbindd in offline mode >+ if (not $self->check_or_start($ret, "no", "yes", "no", 1)) { >+ return undef; >+ } >+ >+ # Set socket dir again >+ $ENV{SOCKET_WRAPPER_DIR} = $swrap_env; >+ >+ print "checking for winbindd\n"; >+ my $count = 0; >+ my $rc = 0; >+ $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' "; >+ $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' "; >+ $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" "; >+ $cmd .= "$wbinfo --ping"; >+ >+ do { >+ $rc = system($cmd); >+ if ($rc != 0) { >+ sleep(1); >+ } >+ $count++; >+ } while ($rc != 0 && $count < 20); >+ if ($count == 20) { >+ print "WINBINDD not reachable after 20 seconds\n"; >+ teardown_env($self, $ret); >+ return undef; >+ } >+ } else { >+ if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { >+ return undef; >+ } > } > > $ret->{DC_SERVER} = $dcvars->{SERVER}; >-- >2.25.1 > > >From 24bd36495f924a6ecaf22b46f391c48bafc395bc Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 10 May 2021 12:52:18 +0200 >Subject: [PATCH 658/686] testprogs: Add test for offline logon support > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 08434e413faaa142b9f9fb1f1b75822249fb81a9) > >[jsutton@samba.org Removed knownfails that do not apply to 4.10] >--- > source4/selftest/tests.py | 10 ++++++ > testprogs/blackbox/test_offline_logon.sh | 43 ++++++++++++++++++++++++ > 2 files changed, 53 insertions(+) > create mode 100755 testprogs/blackbox/test_offline_logon.sh > >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 19e0f1f720c..d6e945f1827 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1267,6 +1267,16 @@ planoldpythontestsuite("chgdcpass:local", "samba.tests.blackbox.samba_dnsupdate" > for env in ["ad_dc_ntvfs", "s4member", "rodc", "promoted_dc", "ad_dc", "ad_member"]: > plantestsuite("samba.blackbox.wbinfo(%s:local)" % env, "%s:local" % env, [os.path.join(samba4srcdir, "../nsswitch/tests/test_wbinfo.sh"), '$DOMAIN', '$DC_USERNAME', '$DC_PASSWORD', env]) > >+# Offline logon (ad_member) >+plantestsuite("samba.blackbox.offline_logon", >+ "ad_member_offline_logon", >+ [os.path.join(bbdir, "test_offline_logon.sh"), >+ '$DOMAIN', >+ 'alice', 'Secret007', >+ 'bob', 'Secret007', >+ 'jane', 'Secret007', >+ 'joe', 'Secret007']) >+ > # > # KDC Tests > # >diff --git a/testprogs/blackbox/test_offline_logon.sh b/testprogs/blackbox/test_offline_logon.sh >new file mode 100755 >index 00000000000..6b54a387371 >--- /dev/null >+++ b/testprogs/blackbox/test_offline_logon.sh >@@ -0,0 +1,43 @@ >+#!/bin/sh >+# Blackbox tests for winbind offline logon support >+# Copyright (c) 2021 Andreas Schneider <asn@samba.org> >+ >+if [ $# -lt 9 ]; then >+cat <<EOF >+Usage: test_offline_logon.sh DOMAIN CACHED_USER_NAME_1 CACHED_USER_PASS_1 CACHED_USER_NAME_2 CACHED_USER_PASS_2 ONLINE_USER_NAME_1 ONLINE_USER_PASS_1 ONLINE_USER_NAME_2 ONLINE_USER_PASS_2 >+EOF >+ exit 1; >+fi >+ >+DOMAIN=$1 >+CACHED_USER_NAME_1=$2 >+CACHED_USER_PASS_1=$3 >+CACHED_USER_NAME_2=$4 >+CACHED_USER_PASS_2=$5 >+ONLINE_USER_NAME_1=$6 >+ONLINE_USER_PASS_1=$7 >+ONLINE_USER_NAME_2=$8 >+ONLINE_USER_PASS_2=$9 >+shift 9 >+ >+. `dirname $0`/subunit.sh >+ >+samba_bindir="$BINDIR" >+wbinfo="$samba_bindir/wbinfo" >+ >+# Check that the DC is offline >+testit_expect_failure "wbinfo.ping-dc" $VALGRIND $wbinfo --ping-dc || failed=`expr $failed + 1` >+ >+# We should have cached credentials for alice and bob >+# --pam-logon sets always the WBFLAG_PAM_CACHED_LOGIN flag >+testit "wbinfo.pam_logon_$CACHED_USER_NAME_1" $VALGRIND $wbinfo --pam-logon=$DOMAIN/$CACHED_USER_NAME_1%$CACHED_USER_PASS_1 || failed=`expr $failed + 1` >+testit "wbinfo.kerberos_logon_$CACHED_USER_NAME_1" $VALGRIND $wbinfo --krb5auth=$DOMAIN/$CACHED_USER_NAME_2%$CACHED_USER_PASS_2 || failed=`expr $failed + 1` >+ >+testit "wbinfo.pam_logon_$CACHED_USER_NAME_2" $VALGRIND $wbinfo --pam-logon=$DOMAIN/$CACHED_USER_NAME_2%$CACHED_USER_PASS_2 || failed=`expr $failed + 1` >+testit "wbinfo.kerberos_logon_$CACHED_USER_NAME_2" $VALGRIND $wbinfo --krb5auth=$DOMAIN/$CACHED_USER_NAME_2%$CACHED_USER_PASS_2 || failed=`expr $failed + 1` >+ >+# We should not be able to auth with jane or joe >+testit_expect_failure "wbinfo.pam_logon_$ONLINE_USER_NAME_1" $VALGRIND $wbinfo --pam-logon=$DOMAIN/$ONLINE_USER_NAME_1%$ONLINE_USER_PASS_1 || failed=`expr $failed + 1` >+testit_expect_failure "wbinfo.pam_logon_$ONLINE_USER_NAME_2" $VALGRIND $wbinfo --pam-logon=$DOMAIN/$ONLINE_USER_NAME_2%$ONLINE_USER_PASS_2 || failed=`expr $failed + 1` >+ >+exit $failed >-- >2.25.1 > > >From 6798d6471b21396d337c0d0e2c70c916a5c11cba Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Wed, 19 May 2021 08:18:22 +0200 >Subject: [PATCH 659/686] selftest: Rename offline logon env to > ad_member_offlogon > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Wed May 19 20:01:00 UTC 2021 on sn-devel-184 > >(cherry picked from commit c216e056b229a9e018c23b7c4500a31711bb30aa) > >[jsutton@samba.org Adapted to fix conflicts] >--- > selftest/target/Samba3.pm | 4 ++-- > source4/selftest/tests.py | 2 +- > 2 files changed, 3 insertions(+), 3 deletions(-) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index b8bae945d47..2ee3b7afedc 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -185,7 +185,7 @@ sub check_env($$) > ad_member_rfc2307 => ["ad_dc_ntvfs"], > ad_member_idmap_rid => ["ad_dc"], > ad_member_idmap_ad => ["fl2008r2dc"], >- ad_member_offline_logon => ["ad_dc"], >+ ad_member_offlogon => ["ad_dc"], > ); > > sub setup_nt4_dc >@@ -906,7 +906,7 @@ sub setup_ad_member_idmap_ad > return $ret; > } > >-sub setup_ad_member_offline_logon >+sub setup_ad_member_offlogon > { > my ($self, > $prefix, >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index d6e945f1827..b54b5dedf23 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1269,7 +1269,7 @@ for env in ["ad_dc_ntvfs", "s4member", "rodc", "promoted_dc", "ad_dc", "ad_membe > > # Offline logon (ad_member) > plantestsuite("samba.blackbox.offline_logon", >- "ad_member_offline_logon", >+ "ad_member_offlogon", > [os.path.join(bbdir, "test_offline_logon.sh"), > '$DOMAIN', > 'alice', 'Secret007', >-- >2.25.1 > > >From a8ff585b9f743725c58a93be4258575ade1ad302 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 5 Oct 2021 16:42:00 +0200 >Subject: [PATCH 660/686] selftest/Samba3: replace (winbindd => "yes", > skip_wait => 1) with (winbindd => "offline") > >This is much more flexible and concentrates the logic in a single place. > >We'll use winbindd => "offline" in other places soon. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14870 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 4dc3c68c9a28f71888e3d6dd3b1f0bcdb8fa45de) > >[jsutton@samba.org Adapted to old check_or_start function and fixed > conflicts] >--- > selftest/target/Samba3.pm | 64 ++++++++++++++------------------------- > 1 file changed, 22 insertions(+), 42 deletions(-) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 2ee3b7afedc..4c9e9410178 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -225,7 +225,7 @@ sub setup_nt4_dc > > $vars or return undef; > >- if (not $self->check_or_start($vars, "yes", "yes", "yes", 0)) { >+ if (not $self->check_or_start($vars, "yes", "yes", "yes")) { > return undef; > } > >@@ -274,7 +274,7 @@ sub setup_nt4_dc_schannel > > $vars or return undef; > >- if (not $self->check_or_start($vars, "yes", "yes", "yes", 0)) { >+ if (not $self->check_or_start($vars, "yes", "yes", "yes")) { > return undef; > } > >@@ -351,7 +351,7 @@ sub setup_nt4_member > return undef; > } > >- if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { >+ if (not $self->check_or_start($ret, "yes", "yes", "yes")) { > return undef; > } > >@@ -486,7 +486,7 @@ sub provision_ad_member > if (defined($offline_logon)) { > my $wbinfo = Samba::bindir_path($self, "wbinfo"); > >- if (not $self->check_or_start($ret, "no", "yes", "no", 0)) { >+ if (not $self->check_or_start($ret, "no", "yes", "no")) { > return undef; > } > >@@ -559,35 +559,15 @@ sub provision_ad_member > $ENV{SOCKET_WRAPPER_DIR} = "$prefix_abs"; > > # Start winbindd in offline mode >- if (not $self->check_or_start($ret, "no", "yes", "no", 1)) { >+ if (not $self->check_or_start($ret, "no", "offline", "no")) { > return undef; > } > > # Set socket dir again > $ENV{SOCKET_WRAPPER_DIR} = $swrap_env; > >- print "checking for winbindd\n"; >- my $count = 0; >- my $rc = 0; >- $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' "; >- $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' "; >- $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" "; >- $cmd .= "$wbinfo --ping"; >- >- do { >- $rc = system($cmd); >- if ($rc != 0) { >- sleep(1); >- } >- $count++; >- } while ($rc != 0 && $count < 20); >- if ($count == 20) { >- print "WINBINDD not reachable after 20 seconds\n"; >- teardown_env($self, $ret); >- return undef; >- } > } else { >- if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { >+ if (not $self->check_or_start($ret, "yes", "yes", "yes")) { > return undef; > } > } >@@ -702,7 +682,7 @@ sub setup_ad_member_rfc2307 > # access the share for tests. > chmod 0777, "$prefix/share"; > >- if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { >+ if (not $self->check_or_start($ret, "yes", "yes", "yes")) { > return undef; > } > >@@ -794,7 +774,7 @@ sub setup_ad_member_idmap_rid > # access the share for tests. > chmod 0777, "$prefix/share"; > >- if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { >+ if (not $self->check_or_start($ret, "yes", "yes", "yes")) { > return undef; > } > >@@ -885,7 +865,7 @@ sub setup_ad_member_idmap_ad > # access the share for tests. > chmod 0777, "$prefix/share"; > >- if (not $self->check_or_start($ret, "yes", "yes", "yes", 0)) { >+ if (not $self->check_or_start($ret, "yes", "yes", "yes")) { > return undef; > } > >@@ -1019,7 +999,7 @@ sub setup_simpleserver > > $vars or return undef; > >- if (not $self->check_or_start($vars, "yes", "no", "yes", 0)) { >+ if (not $self->check_or_start($vars, "yes", "no", "yes")) { > return undef; > } > >@@ -1163,7 +1143,7 @@ sub setup_fileserver > > $vars or return undef; > >- if (not $self->check_or_start($vars, "yes", "no", "yes", 0)) { >+ if (not $self->check_or_start($vars, "yes", "no", "yes")) { > return undef; > } > >@@ -1318,7 +1298,7 @@ $ret->{USERNAME} = KTEST\\Administrator > # access the share for tests. > chmod 0777, "$prefix/share"; > >- if (not $self->check_or_start($ret, "yes", "no", "yes", 0)) { >+ if (not $self->check_or_start($ret, "yes", "no", "yes")) { > return undef; > } > return $ret; >@@ -1342,7 +1322,7 @@ ntlm auth = yes > > $vars or return undef; > >- if (not $self->check_or_start($vars, "yes", "no", "yes", 0)) { >+ if (not $self->check_or_start($vars, "yes", "no", "yes")) { > return undef; > } > >@@ -1378,8 +1358,8 @@ sub read_pid($$) > return $pid; > } > >-sub check_or_start($$$$$$) { >- my ($self, $env_vars, $nmbd, $winbindd, $smbd, $skip_wait) = @_; >+sub check_or_start($$$$$) { >+ my ($self, $env_vars, $nmbd, $winbindd, $smbd) = @_; > > # use a pipe for stdin in the child processes. This allows > # those processes to monitor the pipe for EOF to ensure they >@@ -1475,7 +1455,7 @@ sub check_or_start($$$$$$) { > > $ENV{ENVNAME} = "$ENV{ENVNAME}.winbindd"; > >- if ($winbindd ne "yes") { >+ if ($winbindd ne "yes" and $winbindd ne "offline") { > $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { > my $signame = shift; > print("Skip winbindd received signal $signame"); >@@ -1578,10 +1558,6 @@ sub check_or_start($$$$$$) { > > close(STDIN_READER); > >- if ($skip_wait) { >- return 1; >- } >- > return $self->wait_for_start($env_vars, $nmbd, $winbindd, $smbd); > } > >@@ -2710,13 +2686,17 @@ sub wait_for_start($$$$$) > } > } > >- if ($winbindd eq "yes") { >+ if ($winbindd eq "yes" or $winbindd eq "offline") { > print "checking for winbindd\n"; > my $count = 0; > $cmd = "SELFTEST_WINBINDD_SOCKET_DIR='$envvars->{SELFTEST_WINBINDD_SOCKET_DIR}' "; > $cmd .= "NSS_WRAPPER_PASSWD='$envvars->{NSS_WRAPPER_PASSWD}' "; > $cmd .= "NSS_WRAPPER_GROUP='$envvars->{NSS_WRAPPER_GROUP}' "; >- $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping-dc"; >+ if ($winbindd eq "yes") { >+ $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping-dc"; >+ } elsif ($winbindd eq "offline") { >+ $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping"; >+ } > > do { > if ($ret != 0) { >-- >2.25.1 > > >From ba26b6868308afafad5d3894b9c83df4daa2d573 Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <scabrero@samba.org> >Date: Tue, 5 Oct 2021 12:31:29 +0200 >Subject: [PATCH 661/686] CVE-2020-25717: selftest: Add ad_member_no_nss_wb > environment > >This environment creates an AD member that doesn't have >'nss_winbind' configured, while winbindd is still started. > >For testing we map a DOMAIN\root user to the local root >account and unix token of the local root user. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Samuel Cabrero <scabrero@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7d4f1e3c68f24fef8472b5a73a92d3e43898e831) > >[jsutton@samba.org Adapted to fix conflicts] >--- > selftest/target/Samba.pm | 2 ++ > selftest/target/Samba3.pm | 57 ++++++++++++++++++++++++++++++++++++++- > 2 files changed, 58 insertions(+), 1 deletion(-) > >diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm >index 7fd57a45582..021b16e1c04 100644 >--- a/selftest/target/Samba.pm >+++ b/selftest/target/Samba.pm >@@ -429,6 +429,8 @@ sub get_interface($) > > $interfaces{"offlineadmem"} = 58; > >+ $interfaces{"admemnonsswb"} = 60; >+ > $interfaces{"rootdnsforwarder"} = 64; > > # update lib/socket_wrapper/socket_wrapper.c >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 4c9e9410178..4f34d9d18bd 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -186,6 +186,7 @@ sub check_env($$) > ad_member_idmap_rid => ["ad_dc"], > ad_member_idmap_ad => ["fl2008r2dc"], > ad_member_offlogon => ["ad_dc"], >+ ad_member_no_nss_wb => ["ad_dc"], > ); > > sub setup_nt4_dc >@@ -372,7 +373,14 @@ sub provision_ad_member > $prefix, > $machine_account, > $dcvars, >- $offline_logon) = @_; >+ $extra_member_options, >+ $offline_logon, >+ $no_nss_winbind) = @_; >+ >+ if (defined($offline_logon) && defined($no_nss_winbind)) { >+ warn ("Offline logon incompatible with no nss winbind\n"); >+ return undef; >+ } > > my $prefix_abs = abs_path($prefix); > my @dirs = (); >@@ -409,6 +417,10 @@ sub provision_ad_member > $option_offline_logon = "yes"; > } > >+ unless (defined($extra_member_options)) { >+ $extra_member_options = ""; >+ } >+ > my $member_options = " > security = ads > workgroup = $dcvars->{DOMAIN} >@@ -419,6 +431,10 @@ sub provision_ad_member > winbind use krb5 enterprise principals = yes > winbind offline logon = $option_offline_logon > >+ # Begin extra member options >+ $extra_member_options >+ # End extra member options >+ > [sub_dug] > path = $share_dir/D_%D/U_%U/G_%G > writeable = yes >@@ -567,6 +583,11 @@ sub provision_ad_member > $ENV{SOCKET_WRAPPER_DIR} = $swrap_env; > > } else { >+ if (defined($no_nss_winbind)) { >+ $ret->{NSS_WRAPPER_MODULE_SO_PATH} = ""; >+ $ret->{NSS_WRAPPER_MODULE_FN_PREFIX} = ""; >+ } >+ > if (not $self->check_or_start($ret, "yes", "yes", "yes")) { > return undef; > } >@@ -902,9 +923,43 @@ sub setup_ad_member_offlogon > return $self->provision_ad_member($prefix, > "OFFLINEADMEM", > $dcvars, >+ undef, > 1); > } > >+sub setup_ad_member_no_nss_wb >+{ >+ my ($self, >+ $prefix, >+ $dcvars) = @_; >+ >+ # If we didn't build with ADS, pretend this env was never available >+ if (not $self->have_ads()) { >+ return "UNKNOWN"; >+ } >+ >+ print "PROVISIONING AD MEMBER WITHOUT NSS WINBIND..."; >+ >+ my $extra_member_options = " >+ username map = $prefix/lib/username.map >+"; >+ >+ my $ret = $self->provision_ad_member($prefix, >+ "ADMEMNONSSWB", >+ $dcvars, >+ $extra_member_options, >+ undef, >+ 1); >+ >+ open(USERMAP, ">$prefix/lib/username.map") or die("Unable to open $prefix/lib/username.map"); >+ print USERMAP " >+root = $dcvars->{DOMAIN}/root >+"; >+ close(USERMAP); >+ >+ return $ret; >+} >+ > sub setup_simpleserver > { > my ($self, $path) = @_; >-- >2.25.1 > > >From a151a6bfeeaaf3954cf34f90cced0316684f9b21 Mon Sep 17 00:00:00 2001 >From: Noel Power <noel.power@suse.com> >Date: Wed, 4 Dec 2019 15:27:04 +0000 >Subject: [PATCH 662/686] selftest: Create new test env ad_dc_smb1 > >ad_dc_smb1 is a copy of the ad_dc test environment but >with the difference that it still supports SMB1, this will allow >use to still run SMB1 tests for that env. > >Signed-off-by: Noel Power <npower@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit b0ea347c507cac6a9d5462d3e8af3572e55d883a) > >[jsutton@samba.org Adapted to fix conflicts] >--- > selftest/target/Samba.pm | 2 ++ > selftest/target/Samba4.pm | 29 ++++++++++++++++++++++++++--- > 2 files changed, 28 insertions(+), 3 deletions(-) > >diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm >index 021b16e1c04..034d2ccf58c 100644 >--- a/selftest/target/Samba.pm >+++ b/selftest/target/Samba.pm >@@ -427,6 +427,8 @@ sub get_interface($) > $interfaces{"prockilldc"} = 46; > $interfaces{"proclimitdc"} = 47; > >+ $interfaces{"addcsmb1"} = 54; >+ > $interfaces{"offlineadmem"} = 58; > > $interfaces{"admemnonsswb"} = 60; >diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm >index 1d4de22dee0..e5387132214 100755 >--- a/selftest/target/Samba4.pm >+++ b/selftest/target/Samba4.pm >@@ -2364,6 +2364,7 @@ sub check_env($$) > dns_hub => [], > ad_dc_ntvfs => ["dns_hub"], > ad_dc => ["dns_hub"], >+ ad_dc_smb1 => ["dns_hub"], > ad_dc_no_nss => ["dns_hub"], > ad_dc_no_ntlm => ["dns_hub"], > backupfromdc => ["dns_hub"], >@@ -2758,15 +2759,26 @@ sub setup_rodc > > sub setup_ad_dc > { >- my ($self, $path) = @_; >+ my ($self, $path, $conf_opts, $server, $dom) = @_; > > # If we didn't build with ADS, pretend this env was never available > if (not $self->{target3}->have_ads()) { > return "UNKNOWN"; > } > >- my $env = $self->provision_ad_dc($path, "addc", "ADDOMAIN", >- "addom.samba.example.com", "", undef); >+ if (!defined($conf_opts)) { >+ $conf_opts = ""; >+ } >+ if (!defined($server)) { >+ $server = "addc"; >+ } >+ if (!defined($dom)) { >+ $dom = "addom.samba.example.com"; >+ } >+ my $env = $self->provision_ad_dc($path, $server, "ADDOMAIN", >+ $dom, >+ $conf_opts, >+ undef); > unless ($env) { > return undef; > } >@@ -2783,6 +2795,17 @@ sub setup_ad_dc > return $env; > } > >+sub setup_ad_dc_smb1 >+{ >+ my ($self, $path) = @_; >+ my $conf_opts = " >+[global] >+ client min protocol = CORE >+ server min protocol = LANMAN1 >+"; >+ return setup_ad_dc($self, $path, $conf_opts, "addcsmb1", "addom2.samba.example.com"); >+} >+ > sub setup_ad_dc_no_nss > { > my ($self, $path) = @_; >-- >2.25.1 > > >From 2eca3618cf7078312a57435caf36870e735a77c4 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 5 Oct 2021 17:14:01 +0200 >Subject: [PATCH 663/686] CVE-2020-25717: selftest: configure 'ktest' env with > winbindd and idmap_autorid > >The 'ktest' environment was/is designed to test kerberos in an active >directory member setup. It was created at a time we wanted to test >smbd/winbindd with kerberos without having the source4 ad dc available. > >This still applies to testing the build with system krb5 libraries >but without relying on a running ad dc. > >As a domain member setup requires a running winbindd, we should test it >that way, in order to reflect a valid setup. > >As a side effect it provides a way to demonstrate that we can accept >smb connections authenticated via kerberos, but no connection to >a domain controller! In order get this working offline, we need an >idmap backend with ID_TYPE_BOTH support, so we use 'autorid', which >should be the default choice. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14646 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit dac27126170070cdb413c24ac99a02fb20748517) > >[jsutton@samba.org Adapted to fix conflicts with knownfails and old > check_or_start function] >--- > selftest/knownfail.d/ktest | 26 -------------------------- > selftest/target/Samba3.pm | 13 +++++-------- > 2 files changed, 5 insertions(+), 34 deletions(-) > delete mode 100644 selftest/knownfail.d/ktest > >diff --git a/selftest/knownfail.d/ktest b/selftest/knownfail.d/ktest >deleted file mode 100644 >index 13a45fa743e..00000000000 >--- a/selftest/knownfail.d/ktest >+++ /dev/null >@@ -1,26 +0,0 @@ >-^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest >-^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest >-^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5...rpcclient.ktest:local >-^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5...rpcclient.ktest:local >-^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest >-^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest >-^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest >-^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest >-^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,packet...rpcclient.ktest:local >-^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,packet...rpcclient.ktest:local >-^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest >-^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest >-^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,sign...rpcclient.ktest:local >-^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,sign...rpcclient.ktest:local >-^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest >-^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest >-^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,seal...rpcclient.ktest:local >-^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,seal...rpcclient.ktest:local >-^samba3.blackbox.smbclient_krb5.old.ccache..smbclient.ktest:local >-^samba3.blackbox.smbclient_krb5.new.ccache..smbclient.ktest:local >-^samba3.blackbox.smbclient_large_file..krb5.smbclient.large.posix.write.read.ktest:local >-^samba3.blackbox.smbclient_large_file..krb5.cmp.of.read.and.written.files.ktest:local >-^samba3.blackbox.smbclient_krb5.old.ccache.-e.smbclient.ktest:local >-^samba3.blackbox.smbclient_krb5.new.ccache.-e.smbclient.ktest:local >-^samba3.blackbox.smbclient_large_file.-e.krb5.smbclient.large.posix.write.read.ktest:local >-^samba3.blackbox.smbclient_large_file.-e.krb5.cmp.of.read.and.written.files.ktest:local >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 4f34d9d18bd..39788a7f702 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -1268,7 +1268,6 @@ sub setup_ktest > workgroup = KTEST > realm = ktest.samba.example.com > security = ads >- username map = $prefix/lib/username.map > server signing = required > server min protocol = SMB3_00 > client max protocol = SMB3 >@@ -1276,6 +1275,10 @@ sub setup_ktest > # This disables NTLM auth against the local SAM, which > # we use can then test this setting by. > ntlm auth = disabled >+ >+ idmap config * : backend = autorid >+ idmap config * : range = 1000000-1999999 >+ idmap config * : rangesize = 100000 > "; > > my $ret = $self->provision($prefix, "KTEST", >@@ -1299,12 +1302,6 @@ sub setup_ktest > > $ret->{KRB5_CONFIG} = $ctx->{krb5_conf}; > >- open(USERMAP, ">$prefix/lib/username.map") or die("Unable to open $prefix/lib/username.map"); >- print USERMAP " >-$ret->{USERNAME} = KTEST\\Administrator >-"; >- close(USERMAP); >- > #This is the secrets.tdb created by 'net ads join' from Samba3 to a > #Samba4 DC with the same parameters as are being used here. The > #domain SID is S-1-5-21-1071277805-689288055-3486227160 >@@ -1353,7 +1350,7 @@ $ret->{USERNAME} = KTEST\\Administrator > # access the share for tests. > chmod 0777, "$prefix/share"; > >- if (not $self->check_or_start($ret, "yes", "no", "yes")) { >+ if (not $self->check_or_start($ret, "yes", "offline", "yes")) { > return undef; > } > return $ret; >-- >2.25.1 > > >From 41d0a5b623d371d12ca036359a67970c90f8647b Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Fri, 18 Jan 2019 15:28:54 +0100 >Subject: [PATCH 664/686] lib:mscat: Use size_t for len value to fix build > issue > >asn1_read_value_type() only uses it as an unsigned it, a negative value >isn't assinged. > >Signed-off-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit 56bbfd90c4188e5f1fe560eafaf30334f9afccbf) >--- > lib/mscat/mscat_ctl.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > >diff --git a/lib/mscat/mscat_ctl.c b/lib/mscat/mscat_ctl.c >index 972922c4f75..20147a32c35 100644 >--- a/lib/mscat/mscat_ctl.c >+++ b/lib/mscat/mscat_ctl.c >@@ -94,13 +94,15 @@ static int mscat_asn1_read_value(TALLOC_CTX *mem_ctx, > { > DATA_BLOB tmp = data_blob_null; > unsigned int etype = ASN1_ETYPE_INVALID; >- int len = 0; >+ int tmp_len = 0; >+ size_t len; > int rc; > >- rc = asn1_read_value_type(root, name, NULL, &len, &etype); >+ rc = asn1_read_value_type(root, name, NULL, &tmp_len, &etype); > if (rc != ASN1_SUCCESS) { > return rc; > } >+ len = tmp_len; > > if (etype == ASN1_ETYPE_BIT_STRING) { > if (len + 7 < len) { >@@ -125,11 +127,12 @@ static int mscat_asn1_read_value(TALLOC_CTX *mem_ctx, > rc = asn1_read_value(root, > name, > tmp.data, >- &len); >+ &tmp_len); > if (rc != ASN1_SUCCESS) { > data_blob_free(&tmp); > return rc; > } >+ len = tmp_len; > > if (etype == ASN1_ETYPE_BIT_STRING) { > if (len + 7 < len) { >-- >2.25.1 > > >From 14dadd9072688ad1512a34138797242ba8e7f13c Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Tue, 26 Mar 2019 21:14:13 +0100 >Subject: [PATCH 665/686] s4:heimdal: Disable format truncation warnings > >We build that code and do not treat warnings as errors anyway, >so just disable format truncation. > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit fefb84b5b137e20d1cfb5436702ef6a8aa8ac79b) >--- > source4/heimdal_build/wscript_build | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/source4/heimdal_build/wscript_build b/source4/heimdal_build/wscript_build >index 5f50f3c2ae6..81f8041fd14 100644 >--- a/source4/heimdal_build/wscript_build >+++ b/source4/heimdal_build/wscript_build >@@ -699,9 +699,14 @@ if not bld.CONFIG_SET("USING_SYSTEM_ASN1"): > > HEIMDAL_ERRTABLE('HEIMDAL_ASN1_ERR_ET', 'lib/asn1/asn1_err.et') > >+ heimdal_heim_asn1_cflags = '' >+ if bld.CONFIG_SET('HAVE_WNO_FORMAT_TRUNCATION'): >+ heimdal_heim_asn1_cflags = '-Wno-format-truncation' >+ > HEIMDAL_SUBSYSTEM('HEIMDAL_HEIM_ASN1', > HEIMDAL_HEIM_ASN1_DER_SOURCE + 'lib/asn1/extra.c lib/asn1/timegm.c lib/asn1/asn1_err.c', > includes='../heimdal/lib/asn1', >+ cflags=heimdal_heim_asn1_cflags, > deps='roken com_err' > ) > >-- >2.25.1 > > >From a6b74db824f6999577dddd686ebac3bcb98d3543 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Fri, 18 Jan 2019 13:11:38 +0100 >Subject: [PATCH 666/686] lib:mscat: Fix may be used uninitialized warnings > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit f3c30b2f8cd39b9eaf5ff7ba0d3c96669e8ade37) >--- > lib/mscat/mscat_pkcs7.c | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > >diff --git a/lib/mscat/mscat_pkcs7.c b/lib/mscat/mscat_pkcs7.c >index 55944232205..d606a86f095 100644 >--- a/lib/mscat/mscat_pkcs7.c >+++ b/lib/mscat/mscat_pkcs7.c >@@ -121,7 +121,9 @@ int mscat_pkcs7_import_catfile(struct mscat_pkcs7 *mp7, > gnutls_datum_t mscat_data = { > .size = 0, > }; >- DATA_BLOB blob; >+ DATA_BLOB blob = { >+ .length = 0, >+ }; > int rc; > > tmp_ctx = talloc_new(mp7); >@@ -164,7 +166,9 @@ int mscat_pkcs7_verify(struct mscat_pkcs7 *mp7, > TALLOC_CTX *tmp_ctx = NULL; > gnutls_x509_trust_list_t tl = NULL; > gnutls_datum_t ca_data; >- DATA_BLOB blob; >+ DATA_BLOB blob = { >+ .length = 0, >+ }; > uint32_t flags = 0; > const char *oid; > int count; >-- >2.25.1 > > >From 298baae908d33c744631e6396aaaf238dd3a0380 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Fri, 18 Jan 2019 16:16:05 +0100 >Subject: [PATCH 667/686] s4:dsdb: Fix size types in audit_log > >audit_log.c:878:7: error: assuming signed overflow does not occur when >simplifying conditional to constant [-Werror=strict-overflow] > >Signed-off-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit 9ac30e77f3d0570ca0adca79be8608e0dc2fa7c2) >--- > source4/dsdb/samdb/ldb_modules/audit_log.c | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/audit_log.c b/source4/dsdb/samdb/ldb_modules/audit_log.c >index 8a576023342..e2093b4470b 100644 >--- a/source4/dsdb/samdb/ldb_modules/audit_log.c >+++ b/source4/dsdb/samdb/ldb_modules/audit_log.c >@@ -829,7 +829,7 @@ static char *log_attributes( > enum ldb_request_type operation, > const struct ldb_message *message) > { >- int i, j; >+ size_t i, j; > for (i=0;i<message->num_elements;i++) { > if (i > 0) { > buffer = talloc_asprintf_append_buffer(buffer, " "); >@@ -840,7 +840,7 @@ static char *log_attributes( > ldb, > LDB_DEBUG_ERROR, > "Error: Invalid element name (NULL) at " >- "position %d", i); >+ "position %zu", i); > return NULL; > } > >@@ -874,7 +874,7 @@ static char *log_attributes( > for (j=0;j<message->elements[i].num_values;j++) { > struct ldb_val v; > bool use_b64_encode = false; >- int length; >+ size_t length; > if (j > 0) { > buffer = talloc_asprintf_append_buffer( > buffer, >@@ -898,8 +898,8 @@ static char *log_attributes( > buffer = talloc_asprintf_append_buffer( > buffer, > "[%*.*s%s]", >- length, >- length, >+ (int)length, >+ (int)length, > (char *)v.data, > (v.length > MAX_LENGTH ? "..." : "")); > } >-- >2.25.1 > > >From e4371a60cc317157d347898db03a72bf0ac4d667 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Fri, 18 Jan 2019 17:50:56 +0100 >Subject: [PATCH 668/686] s4:dsdb: Fix size type for num_of_attrs in acl_read > >This fixes a compile error on sn-devel184. > >Signed-off-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit c195134e3550530d3abb3012d3b63860bb872c85) >--- > source4/dsdb/samdb/ldb_modules/acl_read.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c >index 9d93f671420..1e016b970ee 100644 >--- a/source4/dsdb/samdb/ldb_modules/acl_read.c >+++ b/source4/dsdb/samdb/ldb_modules/acl_read.c >@@ -458,7 +458,8 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares) > struct aclread_context *ac; > struct ldb_message *ret_msg; > struct ldb_message *msg; >- int ret, num_of_attrs = 0; >+ int ret; >+ size_t num_of_attrs = 0; > unsigned int i, k = 0; > struct security_descriptor *sd = NULL; > struct dom_sid *sid = NULL; >-- >2.25.1 > > >From e0d2aa8252e53a52eebdebb21a73bdd2db3e2690 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Fri, 18 Jan 2019 19:09:12 +0100 >Subject: [PATCH 669/686] s4:kdc: Fix size type for num_bind in kdc-heimdal > >This fixes a compile error on sn-devel184. > >Signed-off-by: Andreas Schneider <asn@samba.org> > >Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org> >Autobuild-Date(master): Sat Jan 19 15:36:51 CET 2019 on sn-devel-144 > >(cherry picked from commit 448d67bae7201523f971f02d2f8578752cd83706) >--- > source4/kdc/kdc-heimdal.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source4/kdc/kdc-heimdal.c b/source4/kdc/kdc-heimdal.c >index 49aa560470c..28dadcb1fd5 100644 >--- a/source4/kdc/kdc-heimdal.c >+++ b/source4/kdc/kdc-heimdal.c >@@ -128,7 +128,7 @@ static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc, > /* if we are allowing incoming packets from any address, then > we need to bind to the wildcard address */ > if (!lpcfg_bind_interfaces_only(lp_ctx)) { >- int num_binds = 0; >+ size_t num_binds = 0; > char **wcard = iface_list_wildcard(kdc); > NT_STATUS_HAVE_NO_MEMORY(wcard); > for (i=0; wcard[i]; i++) { >-- >2.25.1 > > >From 8f058ae7e64be50a311c66a954096682187446b8 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Tue, 23 Apr 2019 12:57:02 +0200 >Subject: [PATCH 670/686] s3:modules: Fix size types > >error: assuming signed overflow does not occur when simplifying >conditional to constant [-Werror=strict-overflow] > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit bd5b4a16c7e45b4deafb9071d915b90740d45543) >--- > source3/modules/vfs_glusterfs.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index cf51f5dd06b..145c9a45194 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -159,8 +159,8 @@ static int vfs_gluster_set_volfile_servers(glfs_t *fs, > const char *volfile_servers) > { > char *server = NULL; >- int server_count = 0; >- int server_success = 0; >+ size_t server_count = 0; >+ size_t server_success = 0; > int ret = -1; > TALLOC_CTX *frame = talloc_stackframe(); > >@@ -172,7 +172,7 @@ static int vfs_gluster_set_volfile_servers(glfs_t *fs, > int port = 0; > > server_count++; >- DBG_INFO("server %d %s\n", server_count, server); >+ DBG_INFO("server %zu %s\n", server_count, server); > > /* Determine the transport type */ > if (strncmp(server, "unix+", 5) == 0) { >@@ -249,7 +249,7 @@ out: > if (server_count == 0) { > ret = -1; > } else if (server_success < server_count) { >- DBG_WARNING("Failed to set %d out of %d servers parsed\n", >+ DBG_WARNING("Failed to set %zu out of %zu servers parsed\n", > server_count - server_success, server_count); > ret = 0; > } >-- >2.25.1 > > >From a230d0ee50e4b06db2a3936d37a04d4801f098c4 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 18 Nov 2019 22:02:13 +0100 >Subject: [PATCH 671/686] selftest: force LC_ALL=en_US.utf8 LANG=en_US.utf8 > >That makes sure we have the same as on gitlab runners >(see bootstrap/config.py). > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit c48ae9cf4dbbcd4154f6642f18a73c871024cccb) >--- > selftest/selftest.pl | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/selftest/selftest.pl b/selftest/selftest.pl >index 8c273951ab3..d6cb3decb23 100755 >--- a/selftest/selftest.pl >+++ b/selftest/selftest.pl >@@ -302,7 +302,9 @@ unless (defined($ENV{VALGRIND})) { > $ENV{PYTHONUNBUFFERED} = 1; > > # do not depend on the users setup >+# see also bootstrap/config.py > $ENV{TZ} = "UTC"; >+$ENV{LC_ALL} = $ENV{LANG} = "en_US.utf8"; > > my $bindir_abs = abs_path($bindir); > >-- >2.25.1 > > >From 9c5f41bfb49b4568e34bd4b68d28169d7ef52189 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de> >Date: Thu, 4 Jul 2019 20:38:50 +0200 >Subject: [PATCH 672/686] python: use os.urandom, which is available in python > by definition > >os.urandom also uses CSPRNG methods like getrandom() when the underlying OS >provides those. > >Signed-off-by: Bjoern Jacke <bjacke@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 436423162592a684d52634e6db05f20bce6a5362) >--- > python/samba/netcmd/user.py | 41 ++----------------------------------- > 1 file changed, 2 insertions(+), 39 deletions(-) > >diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py >index 7bf2bbc011c..1583bf97337 100644 >--- a/python/samba/netcmd/user.py >+++ b/python/samba/netcmd/user.py >@@ -124,33 +124,6 @@ virtual_attributes = { > }, > } > >-get_random_bytes_fn = None >-if get_random_bytes_fn is None: >- try: >- import Crypto.Random >- get_random_bytes_fn = Crypto.Random.get_random_bytes >- except ImportError as e: >- pass >-if get_random_bytes_fn is None: >- try: >- import M2Crypto.Rand >- get_random_bytes_fn = M2Crypto.Rand.rand_bytes >- except ImportError as e: >- pass >- >- >-def check_random(): >- if get_random_bytes_fn is not None: >- return None >- return "Crypto.Random or M2Crypto.Rand required" >- >- >-def get_random_bytes(num): >- random_reason = check_random() >- if random_reason is not None: >- raise ImportError(random_reason) >- return get_random_bytes_fn(num) >- > > def get_crypt_value(alg, utf8pw, rounds=0): > algs = { >@@ -158,7 +131,7 @@ def get_crypt_value(alg, utf8pw, rounds=0): > "6": {"length": 86}, > } > assert alg in algs >- salt = get_random_bytes(16) >+ salt = os.urandom(16) > # The salt needs to be in [A-Za-z0-9./] > # base64 is close enough and as we had 16 > # random bytes but only need 16 characters >@@ -203,9 +176,6 @@ def get_rounds(options): > > > try: >- random_reason = check_random() >- if random_reason is not None: >- raise ImportError(random_reason) > import hashlib > h = hashlib.sha1() > h = None >@@ -213,8 +183,6 @@ try: > } > except ImportError as e: > reason = "hashlib.sha1()" >- if random_reason: >- reason += " and " + random_reason > reason += " required" > disabled_virtual_attributes["virtualSSHA"] = { > "reason": reason, >@@ -222,9 +190,6 @@ except ImportError as e: > > for (alg, attr) in [("5", "virtualCryptSHA256"), ("6", "virtualCryptSHA512")]: > try: >- random_reason = check_random() >- if random_reason is not None: >- raise ImportError(random_reason) > import crypt > v = get_crypt_value(alg, "") > v = None >@@ -232,8 +197,6 @@ for (alg, attr) in [("5", "virtualCryptSHA256"), ("6", "virtualCryptSHA512")]: > } > except ImportError as e: > reason = "crypt" >- if random_reason: >- reason += " and " + random_reason > reason += " required" > disabled_virtual_attributes[attr] = { > "reason": reason, >@@ -1307,7 +1270,7 @@ class GetPasswordCommand(Command): > u8 = get_utf8(a, b, username or account_name) > if u8 is None: > continue >- salt = get_random_bytes(4) >+ salt = os.urandom(4) > h = hashlib.sha1() > h.update(u8) > h.update(salt) >-- >2.25.1 > > >From 708d16502b869f02d2e109105a9924d020f46b32 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Sat, 6 Nov 2021 13:29:10 +1300 >Subject: [PATCH 673/686] tests/krb5: Adapt constrained delegation tests to > 4.10 Heimdal > >Either expect or don't expect the realm to be appended. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > python/samba/tests/krb5/s4u_tests.py | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index a80a7b3427e..f8de337a041 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -580,12 +580,13 @@ class S4UKerberosTests(KDCBaseTest): > etypes = kdc_dict.pop('etypes', (AES256_CTS_HMAC_SHA1_96, > ARCFOUR_HMAC_MD5)) > >- expected_proxy_target = service2_creds.get_spn() >+ expected_proxy_target = (service2_creds.get_spn() + '@' + >+ service2_creds.get_realm()) > > expected_transited_services = kdc_dict.pop( > 'expected_transited_services', []) > >- transited_service = f'host/{service1_name}@{service1_realm}' >+ transited_service = f'host/{service1_name}' > expected_transited_services.append(transited_service) > > expect_pac = kdc_dict.pop('expect_pac', True) >-- >2.25.1 > > >From 57f7bacdf17b2ca9c5b6b29596d21ddbbc32dc69 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 5 Nov 2021 21:57:35 +1300 >Subject: [PATCH 674/686] tests/krb5: Remove RBCD tests > >These are not needed, and now produce errors due to >msDS-AllowedToActOnBehalfOfOtherIdentity not existing in the schema. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > python/samba/tests/krb5/s4u_tests.py | 338 +-------------------------- > selftest/knownfail_heimdal_kdc | 11 - > 2 files changed, 9 insertions(+), 340 deletions(-) > >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index f8de337a041..cf733673aee 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -485,32 +485,18 @@ class S4UKerberosTests(KDCBaseTest): > service2_opts = kdc_dict.pop('service2_opts', {}) > > allow_delegation = kdc_dict.pop('allow_delegation', False) >- allow_rbcd = kdc_dict.pop('allow_rbcd', False) >- self.assertFalse(allow_delegation and allow_rbcd) > >- if allow_rbcd: >- service1_creds = self.get_cached_creds( >- account_type=self.AccountType.COMPUTER, >- opts=service1_opts) >- >- self.assertNotIn('delegation_from_dn', service2_opts) >- service2_opts['delegation_from_dn'] = str(service1_creds.get_dn()) >- >- service2_creds = self.get_cached_creds( >- account_type=self.AccountType.COMPUTER, >- opts=service2_opts) >- else: >- service2_creds = self.get_cached_creds( >- account_type=self.AccountType.COMPUTER, >- opts=service2_opts) >+ service2_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service2_opts) > >- if allow_delegation: >- self.assertNotIn('delegation_to_spn', service1_opts) >- service1_opts['delegation_to_spn'] = service2_creds.get_spn() >+ if allow_delegation: >+ self.assertNotIn('delegation_to_spn', service1_opts) >+ service1_opts['delegation_to_spn'] = service2_creds.get_spn() > >- service1_creds = self.get_cached_creds( >- account_type=self.AccountType.COMPUTER, >- opts=service1_opts) >+ service1_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service1_opts) > > client_tkt_options = kdc_dict.pop('client_tkt_options', 'forwardable') > expected_flags = krb5_asn1.TicketFlags(client_tkt_options) >@@ -742,173 +728,6 @@ class S4UKerberosTests(KDCBaseTest): > 'allow_delegation': True > }) > >- def test_rbcd_no_auth_data_required(self): >- self._run_delegation_test( >- { >- 'expected_error_mode': 0, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'service2_opts': { >- 'no_auth_data_required': True >- }, >- 'expect_pac': False >- }) >- >- def test_rbcd_existing_delegation_info(self): >- # Test constrained delegation with an existing S4U_DELEGATION_INFO >- # structure in the PAC. >- >- services = ['service1', 'service2', 'service3'] >- >- self._run_delegation_test( >- { >- 'expected_error_mode': 0, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_client_tkt_fn': functools.partial( >- self.add_delegation_info, services=services), >- 'expected_transited_services': services >- }) >- >- def test_rbcd_not_allowed(self): >- # Test resource-based constrained delegation when the target service >- # does not allow it. >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_BADOPTION, >- 'expected_status': ntstatus.NT_STATUS_NOT_FOUND, >- 'allow_rbcd': False, >- 'pac_options': '0001' # supports RBCD >- }) >- >- def test_rbcd_no_client_pac_a(self): >- # Test constrained delegation when the client service ticket does not >- # contain a PAC, and an empty msDS-AllowedToDelegateTo attribute. >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_MODIFIED, >- 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_client_tkt_fn': self.remove_ticket_pac >- }) >- >- def test_rbcd_no_client_pac_b(self): >- # Test constrained delegation when the client service ticket does not >- # contain a PAC, and a non-empty msDS-AllowedToDelegateTo attribute. >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_MODIFIED, >- 'expected_status': ntstatus.NT_STATUS_NO_MATCH, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_client_tkt_fn': self.remove_ticket_pac, >- 'service1_opts': { >- 'delegation_to_spn': ('host/test') >- } >- }) >- >- def test_rbcd_no_service_pac(self): >- # Test constrained delegation when the service TGT does not contain a >- # PAC. >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_BADOPTION, >- 'expected_status': >- ntstatus.NT_STATUS_NOT_FOUND, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_service_tgt_fn': self.remove_ticket_pac >- }) >- >- def test_rbcd_no_client_pac_no_auth_data_required_a(self): >- # Test constrained delegation when the client service ticket does not >- # contain a PAC, and an empty msDS-AllowedToDelegateTo attribute. >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_MODIFIED, >- 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_client_tkt_fn': self.remove_ticket_pac, >- 'service2_opts': { >- 'no_auth_data_required': True >- } >- }) >- >- def test_rbcd_no_client_pac_no_auth_data_required_b(self): >- # Test constrained delegation when the client service ticket does not >- # contain a PAC, and a non-empty msDS-AllowedToDelegateTo attribute. >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_MODIFIED, >- 'expected_status': ntstatus.NT_STATUS_NO_MATCH, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_client_tkt_fn': self.remove_ticket_pac, >- 'service1_opts': { >- 'delegation_to_spn': ('host/test') >- }, >- 'service2_opts': { >- 'no_auth_data_required': True >- } >- }) >- >- def test_rbcd_no_service_pac_no_auth_data_required(self): >- # Test constrained delegation when the service TGT does not contain a >- # PAC. >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_BADOPTION, >- 'expected_status': >- ntstatus.NT_STATUS_NOT_FOUND, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_service_tgt_fn': self.remove_ticket_pac, >- 'service2_opts': { >- 'no_auth_data_required': True >- } >- }) >- >- def test_rbcd_non_forwardable(self): >- # Test resource-based constrained delegation with a non-forwardable >- # ticket. >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_BADOPTION, >- 'expected_status': ntstatus.NT_STATUS_ACCOUNT_RESTRICTION, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_client_tkt_fn': functools.partial( >- self.set_ticket_forwardable, flag=False) >- }) >- >- def test_rbcd_no_pac_options_a(self): >- # Test resource-based constrained delegation without the RBCD bit set >- # in the PAC options, and an empty msDS-AllowedToDelegateTo attribute. >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_BADOPTION, >- 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >- 'allow_rbcd': True, >- 'pac_options': '1' # does not support RBCD >- }) >- >- def test_rbcd_no_pac_options_b(self): >- # Test resource-based constrained delegation without the RBCD bit set >- # in the PAC options, and a non-empty msDS-AllowedToDelegateTo >- # attribute. >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_BADOPTION, >- 'expected_status': ntstatus.NT_STATUS_NO_MATCH, >- 'allow_rbcd': True, >- 'pac_options': '1', # does not support RBCD >- 'service1_opts': { >- 'delegation_to_spn': ('host/test') >- } >- }) >- > def test_bronze_bit_constrained_delegation_old_checksum(self): > # Attempt to modify the ticket without updating the PAC checksums. > self._run_delegation_test( >@@ -923,20 +742,6 @@ class S4UKerberosTests(KDCBaseTest): > 'expect_edata': False > }) > >- def test_bronze_bit_rbcd_old_checksum(self): >- # Attempt to modify the ticket without updating the PAC checksums. >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_MODIFIED, >- 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'client_tkt_options': '0', # non-forwardable ticket >- 'modify_client_tkt_fn': functools.partial( >- self.set_ticket_forwardable, >- flag=True, update_pac_checksums=False) >- }) >- > def test_constrained_delegation_missing_client_checksum(self): > # Present a user ticket without the required checksums. > for checksum in self.pac_checksum_types: >@@ -971,42 +776,6 @@ class S4UKerberosTests(KDCBaseTest): > self.remove_pac_checksum, checksum=checksum) > }) > >- def test_rbcd_missing_client_checksum(self): >- # Present a user ticket without the required checksums. >- for checksum in self.pac_checksum_types: >- with self.subTest(checksum=checksum): >- if checksum == krb5pac.PAC_TYPE_TICKET_CHECKSUM: >- expected_error_mode = KDC_ERR_MODIFIED >- else: >- expected_error_mode = KDC_ERR_GENERIC >- >- self._run_delegation_test( >- { >- 'expected_error_mode': expected_error_mode, >- 'expected_status': >- ntstatus.NT_STATUS_NOT_SUPPORTED, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_client_tkt_fn': functools.partial( >- self.remove_pac_checksum, checksum=checksum) >- }) >- >- def test_rbcd_missing_service_checksum(self): >- # Present the service's ticket without the required checksums. >- for checksum in filter(lambda x: x != krb5pac.PAC_TYPE_TICKET_CHECKSUM, >- self.pac_checksum_types): >- with self.subTest(checksum=checksum): >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_GENERIC, >- 'expected_status': >- ntstatus.NT_STATUS_INSUFFICIENT_RESOURCES, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_service_tgt_fn': functools.partial( >- self.remove_pac_checksum, checksum=checksum) >- }) >- > def test_constrained_delegation_zeroed_client_checksum(self): > # Present a user ticket with invalid checksums. > for checksum in self.pac_checksum_types: >@@ -1042,43 +811,6 @@ class S4UKerberosTests(KDCBaseTest): > self.zeroed_pac_checksum, checksum=checksum) > }) > >- def test_rbcd_zeroed_client_checksum(self): >- # Present a user ticket with invalid checksums. >- for checksum in self.pac_checksum_types: >- with self.subTest(checksum=checksum): >- self._run_delegation_test( >- { >- 'expected_error_mode': KDC_ERR_MODIFIED, >- 'expected_status': >- ntstatus.NT_STATUS_NOT_SUPPORTED, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_client_tkt_fn': functools.partial( >- self.zeroed_pac_checksum, checksum=checksum) >- }) >- >- def test_rbcd_zeroed_service_checksum(self): >- # Present the service's ticket with invalid checksums. >- for checksum in self.pac_checksum_types: >- with self.subTest(checksum=checksum): >- if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >- expected_error_mode = (KDC_ERR_MODIFIED, >- KDC_ERR_BAD_INTEGRITY) >- expected_status = ntstatus.NT_STATUS_WRONG_PASSWORD >- else: >- expected_error_mode = 0 >- expected_status = None >- >- self._run_delegation_test( >- { >- 'expected_error_mode': expected_error_mode, >- 'expected_status': expected_status, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_service_tgt_fn': functools.partial( >- self.zeroed_pac_checksum, checksum=checksum) >- }) >- > unkeyed_ctypes = {Cksumtype.MD5, Cksumtype.SHA1, Cksumtype.CRC32} > > def test_constrained_delegation_unkeyed_client_checksum(self): >@@ -1133,58 +865,6 @@ class S4UKerberosTests(KDCBaseTest): > checksum=checksum, ctype=ctype) > }) > >- def test_rbcd_unkeyed_client_checksum(self): >- # Present a user ticket with invalid checksums. >- for checksum in self.pac_checksum_types: >- for ctype in self.unkeyed_ctypes: >- with self.subTest(checksum=checksum, ctype=ctype): >- if (checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM >- and ctype == Cksumtype.SHA1): >- expected_error_mode = KDC_ERR_SUMTYPE_NOSUPP >- else: >- expected_error_mode = KDC_ERR_GENERIC >- >- self._run_delegation_test( >- { >- 'expected_error_mode': expected_error_mode, >- 'expected_status': >- ntstatus.NT_STATUS_NOT_SUPPORTED, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_client_tkt_fn': functools.partial( >- self.unkeyed_pac_checksum, >- checksum=checksum, ctype=ctype) >- }) >- >- def test_rbcd_unkeyed_service_checksum(self): >- # Present the service's ticket with invalid checksums. >- for checksum in self.pac_checksum_types: >- for ctype in self.unkeyed_ctypes: >- with self.subTest(checksum=checksum, ctype=ctype): >- if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >- if ctype == Cksumtype.SHA1: >- expected_error_mode = (KDC_ERR_SUMTYPE_NOSUPP, >- KDC_ERR_BAD_INTEGRITY) >- expected_status = ntstatus.NT_STATUS_LOGON_FAILURE >- else: >- expected_error_mode = KDC_ERR_GENERIC >- expected_status = ( >- ntstatus.NT_STATUS_INSUFFICIENT_RESOURCES) >- else: >- expected_error_mode = 0 >- expected_status = None >- >- self._run_delegation_test( >- { >- 'expected_error_mode': expected_error_mode, >- 'expected_status': expected_status, >- 'allow_rbcd': True, >- 'pac_options': '0001', # supports RBCD >- 'modify_service_tgt_fn': functools.partial( >- self.unkeyed_pac_checksum, >- checksum=checksum, ctype=ctype) >- }) >- > def remove_pac_checksum(self, ticket, checksum): > checksum_keys = self.get_krbtgt_checksum_key() > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 7eba899966e..27baa42bc24 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -234,21 +234,10 @@ > # > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac\(.*\)$ >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_existing_delegation_info >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_missing_client_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_a >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_b >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_unkeyed_client_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_unkeyed_service_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_client_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_service_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_forwardable > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_empty_allowed > # > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_auth_data_required >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_auth_data_required >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_a >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_b > # > # https://bugzilla.samba.org/show_bug.cgi?id=14886: Tests for accounts not revealed to the RODC > # >-- >2.25.1 > > >From fbdffffc1dac23173790410e9d786c2043559a98 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Sun, 7 Nov 2021 16:42:50 +1300 >Subject: [PATCH 675/686] selftest: Update expected output for ndrdump tests > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > source4/librpc/tests/dns-decode_dns_name_packet-hex.txt | 1 + > source4/librpc/tests/krb5pac_upn_dns_info_ex.txt | 4 ---- > .../librpc/tests/krb5pac_upn_dns_info_ex_not_supported.txt | 4 ---- > 3 files changed, 1 insertion(+), 8 deletions(-) > >diff --git a/source4/librpc/tests/dns-decode_dns_name_packet-hex.txt b/source4/librpc/tests/dns-decode_dns_name_packet-hex.txt >index 02e95c0bd20..2833c676c2c 100644 >--- a/source4/librpc/tests/dns-decode_dns_name_packet-hex.txt >+++ b/source4/librpc/tests/dns-decode_dns_name_packet-hex.txt >@@ -3,6 +3,7 @@ pull returned Success > id : 0xecef (60655) > operation : 0x2800 (10240) > 0x00: DNS_RCODE (0) >+ 0: DNS_FLAG_BROADCAST > 0: DNS_FLAG_RECURSION_AVAIL > 0: DNS_FLAG_RECURSION_DESIRED > 0: DNS_FLAG_TRUNCATION >diff --git a/source4/librpc/tests/krb5pac_upn_dns_info_ex.txt b/source4/librpc/tests/krb5pac_upn_dns_info_ex.txt >index 9747d1b6d3a..29478739de7 100644 >--- a/source4/librpc/tests/krb5pac_upn_dns_info_ex.txt >+++ b/source4/librpc/tests/krb5pac_upn_dns_info_ex.txt >@@ -65,8 +65,6 @@ pull returned Success > 1: SE_GROUP_ENABLED > 0: SE_GROUP_OWNER > 0: SE_GROUP_USE_FOR_DENY_ONLY >- 0: SE_GROUP_INTEGRITY >- 0: SE_GROUP_INTEGRITY_ENABLED > 0: SE_GROUP_RESOURCE > 0x00: SE_GROUP_LOGON_ID (0) > user_flags : 0x00000020 (32) >@@ -137,8 +135,6 @@ pull returned Success > 1: SE_GROUP_ENABLED > 0: SE_GROUP_OWNER > 0: SE_GROUP_USE_FOR_DENY_ONLY >- 0: SE_GROUP_INTEGRITY >- 0: SE_GROUP_INTEGRITY_ENABLED > 0: SE_GROUP_RESOURCE > 0x00: SE_GROUP_LOGON_ID (0) > resource_groups: struct PAC_DOMAIN_GROUP_MEMBERSHIP >diff --git a/source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.txt b/source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.txt >index d29832ede49..f419b5b7c0e 100644 >--- a/source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.txt >+++ b/source4/librpc/tests/krb5pac_upn_dns_info_ex_not_supported.txt >@@ -65,8 +65,6 @@ pull returned Success > 1: SE_GROUP_ENABLED > 0: SE_GROUP_OWNER > 0: SE_GROUP_USE_FOR_DENY_ONLY >- 0: SE_GROUP_INTEGRITY >- 0: SE_GROUP_INTEGRITY_ENABLED > 0: SE_GROUP_RESOURCE > 0x00: SE_GROUP_LOGON_ID (0) > user_flags : 0x00000020 (32) >@@ -137,8 +135,6 @@ pull returned Success > 1: SE_GROUP_ENABLED > 0: SE_GROUP_OWNER > 0: SE_GROUP_USE_FOR_DENY_ONLY >- 0: SE_GROUP_INTEGRITY >- 0: SE_GROUP_INTEGRITY_ENABLED > 0: SE_GROUP_RESOURCE > 0x00: SE_GROUP_LOGON_ID (0) > resource_groups: struct PAC_DOMAIN_GROUP_MEMBERSHIP >-- >2.25.1 > > >From 968ac0840406be3050b650f37848d3ec3dcd722c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 5 Nov 2021 11:08:37 +1300 >Subject: [PATCH 676/686] bootstrap: Bring in CI system from 4.12 > >Update bootstrap to match the changes backported from commit >1c59f49aaede8ec1662d4e49aef84fcd902a8a76. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > bootstrap/.gitlab-ci.yml | 123 ++++ > bootstrap/READMD.md | 104 +++ > bootstrap/config.py | 649 ++++++++++++++++++ > bootstrap/generated-dists/Vagrantfile | 84 +++ > bootstrap/generated-dists/centos7/Dockerfile | 27 + > .../generated-dists/centos7/bootstrap.sh | 111 +++ > bootstrap/generated-dists/centos7/locale.sh | 55 ++ > .../generated-dists/centos7/packages.yml | 91 +++ > bootstrap/generated-dists/centos8/Dockerfile | 27 + > .../generated-dists/centos8/bootstrap.sh | 112 +++ > bootstrap/generated-dists/centos8/locale.sh | 55 ++ > .../generated-dists/centos8/packages.yml | 94 +++ > bootstrap/generated-dists/debian10/Dockerfile | 27 + > .../generated-dists/debian10/bootstrap.sh | 107 +++ > bootstrap/generated-dists/debian10/locale.sh | 55 ++ > .../generated-dists/debian10/packages.yml | 92 +++ > bootstrap/generated-dists/fedora31/Dockerfile | 27 + > .../generated-dists/fedora31/bootstrap.sh | 111 +++ > bootstrap/generated-dists/fedora31/locale.sh | 55 ++ > .../generated-dists/fedora31/packages.yml | 98 +++ > bootstrap/generated-dists/fedora32/Dockerfile | 27 + > .../generated-dists/fedora32/bootstrap.sh | 111 +++ > bootstrap/generated-dists/fedora32/locale.sh | 55 ++ > .../generated-dists/fedora32/packages.yml | 98 +++ > .../generated-dists/opensuse150/Dockerfile | 27 + > .../generated-dists/opensuse150/bootstrap.sh | 107 +++ > .../generated-dists/opensuse150/locale.sh | 55 ++ > .../generated-dists/opensuse150/packages.yml | 89 +++ > .../generated-dists/opensuse151/Dockerfile | 27 + > .../generated-dists/opensuse151/bootstrap.sh | 107 +++ > .../generated-dists/opensuse151/locale.sh | 55 ++ > .../generated-dists/opensuse151/packages.yml | 89 +++ > .../generated-dists/ubuntu1604/Dockerfile | 27 + > .../generated-dists/ubuntu1604/bootstrap.sh | 106 +++ > .../generated-dists/ubuntu1604/locale.sh | 55 ++ > .../generated-dists/ubuntu1604/packages.yml | 91 +++ > .../generated-dists/ubuntu1804/Dockerfile | 27 + > .../generated-dists/ubuntu1804/bootstrap.sh | 108 +++ > .../generated-dists/ubuntu1804/locale.sh | 55 ++ > .../generated-dists/ubuntu1804/packages.yml | 93 +++ > .../generated-dists/ubuntu2004/Dockerfile | 27 + > .../generated-dists/ubuntu2004/bootstrap.sh | 108 +++ > .../generated-dists/ubuntu2004/locale.sh | 55 ++ > .../generated-dists/ubuntu2004/packages.yml | 93 +++ > bootstrap/sha1sum.txt | 1 + > bootstrap/template.py | 142 ++++ > 46 files changed, 3939 insertions(+) > create mode 100644 bootstrap/.gitlab-ci.yml > create mode 100644 bootstrap/READMD.md > create mode 100644 bootstrap/config.py > create mode 100644 bootstrap/generated-dists/Vagrantfile > create mode 100644 bootstrap/generated-dists/centos7/Dockerfile > create mode 100755 bootstrap/generated-dists/centos7/bootstrap.sh > create mode 100755 bootstrap/generated-dists/centos7/locale.sh > create mode 100644 bootstrap/generated-dists/centos7/packages.yml > create mode 100644 bootstrap/generated-dists/centos8/Dockerfile > create mode 100755 bootstrap/generated-dists/centos8/bootstrap.sh > create mode 100755 bootstrap/generated-dists/centos8/locale.sh > create mode 100644 bootstrap/generated-dists/centos8/packages.yml > create mode 100644 bootstrap/generated-dists/debian10/Dockerfile > create mode 100755 bootstrap/generated-dists/debian10/bootstrap.sh > create mode 100755 bootstrap/generated-dists/debian10/locale.sh > create mode 100644 bootstrap/generated-dists/debian10/packages.yml > create mode 100644 bootstrap/generated-dists/fedora31/Dockerfile > create mode 100755 bootstrap/generated-dists/fedora31/bootstrap.sh > create mode 100755 bootstrap/generated-dists/fedora31/locale.sh > create mode 100644 bootstrap/generated-dists/fedora31/packages.yml > create mode 100644 bootstrap/generated-dists/fedora32/Dockerfile > create mode 100755 bootstrap/generated-dists/fedora32/bootstrap.sh > create mode 100755 bootstrap/generated-dists/fedora32/locale.sh > create mode 100644 bootstrap/generated-dists/fedora32/packages.yml > create mode 100644 bootstrap/generated-dists/opensuse150/Dockerfile > create mode 100755 bootstrap/generated-dists/opensuse150/bootstrap.sh > create mode 100755 bootstrap/generated-dists/opensuse150/locale.sh > create mode 100644 bootstrap/generated-dists/opensuse150/packages.yml > create mode 100644 bootstrap/generated-dists/opensuse151/Dockerfile > create mode 100755 bootstrap/generated-dists/opensuse151/bootstrap.sh > create mode 100755 bootstrap/generated-dists/opensuse151/locale.sh > create mode 100644 bootstrap/generated-dists/opensuse151/packages.yml > create mode 100644 bootstrap/generated-dists/ubuntu1604/Dockerfile > create mode 100755 bootstrap/generated-dists/ubuntu1604/bootstrap.sh > create mode 100755 bootstrap/generated-dists/ubuntu1604/locale.sh > create mode 100644 bootstrap/generated-dists/ubuntu1604/packages.yml > create mode 100644 bootstrap/generated-dists/ubuntu1804/Dockerfile > create mode 100755 bootstrap/generated-dists/ubuntu1804/bootstrap.sh > create mode 100755 bootstrap/generated-dists/ubuntu1804/locale.sh > create mode 100644 bootstrap/generated-dists/ubuntu1804/packages.yml > create mode 100644 bootstrap/generated-dists/ubuntu2004/Dockerfile > create mode 100755 bootstrap/generated-dists/ubuntu2004/bootstrap.sh > create mode 100755 bootstrap/generated-dists/ubuntu2004/locale.sh > create mode 100644 bootstrap/generated-dists/ubuntu2004/packages.yml > create mode 100644 bootstrap/sha1sum.txt > create mode 100755 bootstrap/template.py > >diff --git a/bootstrap/.gitlab-ci.yml b/bootstrap/.gitlab-ci.yml >new file mode 100644 >index 00000000000..d6cf02109fd >--- /dev/null >+++ b/bootstrap/.gitlab-ci.yml >@@ -0,0 +1,123 @@ >+services: >+ - docker:dind >+ >+.build_image_template: >+ image: docker:latest >+ stage: images >+ tags: >+ - docker >+ - gce >+ variables: >+ SAMBA_CI_IS_BROKEN_IMAGE: "no" >+ SAMBA_CI_TEST_JOB: "samba-o3" >+ before_script: >+ # Ensure we are generating correct the container >+ - uname -a >+ - cat /etc/os-release >+ - echo "SAMBA_CI_CONTAINER_REGISTRY[${SAMBA_CI_CONTAINER_REGISTRY}]" >+ - echo "SAMBA_CI_CONTAINER_TAG[${SAMBA_CI_CONTAINER_TAG}]" >+ - echo "SAMBA_CI_IS_BROKEN_IMAGE[${SAMBA_CI_IS_BROKEN_IMAGE}]" >+ - echo "SAMBA_CI_REBUILD_IMAGES[${SAMBA_CI_REBUILD_IMAGES}]" >+ - echo "SAMBA_CI_REBUILD_BROKEN_IMAGES[${SAMBA_CI_REBUILD_BROKEN_IMAGES}]" >+ - echo "GITLAB_USER_LOGIN[${GITLAB_USER_LOGIN}]" >+ - echo "${SAMBA_CI_CONTAINER_TAG}" > /tmp/sha1sum-tag.txt >+ - diff -u bootstrap/sha1sum.txt /tmp/sha1sum-tag.txt >+ script: | >+ set -xueo pipefail >+ ci_image_name=samba-ci-${CI_JOB_NAME} >+ docker build -t ${ci_image_name} --build-arg SHA1SUM=${SAMBA_CI_CONTAINER_TAG} bootstrap/generated-dists/${CI_JOB_NAME} >+ ci_image_path="${SAMBA_CI_CONTAINER_REGISTRY}/${ci_image_name}" >+ timestamp=$(date +%Y%m%d%H%M%S) >+ docker_hash=$(docker image inspect --format='{{index .Id}}' ${ci_image_name} | cut -d : -f 2 | cut -c 1-9) >+ timestamp_tag=${SAMBA_CI_CONTAINER_TAG}-${timestamp}-${GITLAB_USER_LOGIN}-${docker_hash} >+ samba_repo_root=/home/samba/samba >+ # Ensure we are generating the correct container that we expect to be in >+ echo "${SAMBA_CI_CONTAINER_TAG}" > /tmp/sha1sum-tag.txt >+ diff -u bootstrap/sha1sum.txt /tmp/sha1sum-tag.txt >+ docker run --volume $(pwd):${samba_repo_root} --workdir ${samba_repo_root} ${ci_image_name} \ >+ /bin/bash -c "echo \"${SAMBA_CI_CONTAINER_TAG}\" > /tmp/sha1sum-tag.txt; diff -u bootstrap/sha1sum.txt /tmp/sha1sum-tag.txt" >+ docker run --volume $(pwd):${samba_repo_root} --workdir ${samba_repo_root} ${ci_image_name} \ >+ diff -u bootstrap/sha1sum.txt /sha1sum.txt >+ docker run --volume $(pwd):${samba_repo_root} --workdir ${samba_repo_root} ${ci_image_name} \ >+ bootstrap/template.py --sha1sum > /tmp/sha1sum-template.txt >+ diff -u bootstrap/sha1sum.txt /tmp/sha1sum-template.txt >+ # run smoke test with samba-o3 or samba-fuzz >+ docker run --volume $(pwd):${samba_repo_root} --workdir ${samba_repo_root} ${ci_image_name} \ >+ /bin/bash -c "sudo chown -R samba:samba ./** && export PKG_CONFIG_PATH=/usr/lib64/compat-gnutls34/pkgconfig:/usr/lib64/compat-nettle32/pkgconfig && script/autobuild.py ${SAMBA_CI_TEST_JOB} --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase" >+ docker tag ${ci_image_name} ${ci_image_path}:${SAMBA_CI_CONTAINER_TAG} >+ docker tag ${ci_image_name} ${ci_image_path}:${timestamp_tag} >+ # We build all images, but only upload is it's not marked as broken >+ test x"${SAMBA_CI_IS_BROKEN_IMAGE}" = x"yes" || { \ >+ docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY; \ >+ docker push ${ci_image_path}:${SAMBA_CI_CONTAINER_TAG}; \ >+ docker push ${ci_image_path}:${timestamp_tag}; \ >+ } >+ echo "Success for ${ci_image_path}:${timestamp_tag}" >+ test x"${SAMBA_CI_IS_BROKEN_IMAGE}" = x"no" || { \ >+ echo "The image ${CI_JOB_NAME} is marked as broken and should have failed!"; \ >+ echo "Replace .build_image_template_force_broken with .build_image_template!"; \ >+ echo "Add a .samba-o3-template section at the end of the main .gitlab-ci.yml!"; \ >+ /bin/false; \ >+ } >+ only: >+ variables: >+ # >+ # You need a custom pipeline which passes >+ # SAMBA_CI_REBUILD_IMAGES="yes". >+ # >+ # https://gitlab.com/samba-team/devel/samba/pipelines/new >+ # >+ - $SAMBA_CI_REBUILD_IMAGES == "yes" >+ >+.build_image_template_force_broken: >+ extends: .build_image_template >+ variables: >+ SAMBA_CI_IS_BROKEN_IMAGE: "yes" >+ only: >+ variables: >+ # >+ # You need a custom pipeline which passes >+ # SAMBA_CI_REBUILD_BROKEN_IMAGES="yes" >+ # in order to build broken images for debugging >+ # >+ # https://gitlab.com/samba-team/devel/samba/pipelines/new >+ # >+ - $SAMBA_CI_REBUILD_BROKEN_IMAGES == "yes" >+ >+# This is ONLY for oss-fuzz, so we test a fuzz build not a real one >+ubuntu1604: >+ extends: .build_image_template >+ variables: >+ SAMBA_CI_TEST_JOB: "samba-fuzz" >+ >+ubuntu1804: >+ extends: .build_image_template >+ >+ubuntu2004: >+ extends: .build_image_template >+ >+debian10: >+ extends: .build_image_template >+ >+fedora31: >+ extends: .build_image_template >+ >+fedora32: >+ extends: .build_image_template >+ >+centos8: >+ extends: .build_image_template >+ >+centos7: >+ extends: .build_image_template >+ variables: >+ # Shallow copies are not supported by git on CentOS7 >+ GIT_DEPTH: "" >+ # We install a compat-gnutls34 package for GnuTLS >= 3.4.7 >+ PKG_CONFIG_PATH: /usr/lib64/compat-gnutls34/pkgconfig:/usr/lib64/compat-nettle32/pkgconfig >+ >+opensuse150: >+ extends: .build_image_template >+ >+opensuse151: >+ extends: .build_image_template >diff --git a/bootstrap/READMD.md b/bootstrap/READMD.md >new file mode 100644 >index 00000000000..023686e20c4 >--- /dev/null >+++ b/bootstrap/READMD.md >@@ -0,0 +1,104 @@ >+# Samba Bootstrap >+ >+A pure python3 module with CLI to bootstrap Samba envs for multiple distributions. >+ >+## Features >+ >+- manage Samba dependencies list for multiple distributions >+- render dependencies package list to boostrap shell scripts(apt, yum and dnf) >+- render Vagrantfile to provision vitual machines with bootstrap scripts >+- render Dockerfile to build docker images with bootstrap scripts >+- build/tag/push docker images >+ >+## Supported Distributions >+ >+deb: Debian 7|8|9|10, Ubuntu 1404|1604|1804 >+rpm: CentOS 6|7, Fedora 28|29, openSUSE Leap 15.0|15.1 >+ >+Easy to add more. >+ >+## Usage >+ >+Render files: >+ >+ bootstrap/template.py --render >+ >+Files are rendered into `bootstrap/generated-dists` directory in current dir. >+It also generates bootstrap/sha1sum.txt and prints out the sha1sum of the >+current code/configuration. >+ >+Just calculate the sha1sum for consistency checks: >+ >+ bootstrap/template.py --sha1sum >+ >+The checksum needs to be added as `SAMBA_CI_CONTAINER_TAG` in >+the toplevel .gitlab-ci.yml file. >+ >+## User Stories >+ >+As a gitlab-ci user, I can use this tool to build new CI docker images: >+ >+ After committing the result of calling `bootstrap/template.py --render` >+ and updating `SAMBA_CI_CONTAINER_TAG` in .gitlab-ci.yml, you can push >+ The branch to git@gitlab.com:samba-team/devel/samba.git using: >+ >+ git push -o ci.skip git@gitlab.com:samba-team/devel/samba.git ... >+ >+ The `-o ci.skip` option means gitlab won't start a pipeline >+ for the just pushed branch. >+ >+ Instead you would start a custom pipeline at: >+ >+ https://gitlab.com/samba-team/devel/samba/pipelines/new >+ >+ But you need to pass `SAMBA_CI_REBUILD_IMAGES=yes` as environment >+ variable. It means the pipeline runs the 'images' stage and builds >+ the new container images for all supported distributions and >+ uploads the images into the registry.gitlab.com/samba-team/devel/samba >+ container registry. >+ >+ If you want to try to build images for the (currently) broken >+ distributions, you would pass `SAMBA_CI_REBUILD_BROKEN_IMAGES=yes` >+ in addition to the custom pipeline. Note the images for >+ the broken distributions are just build, but not uploaded >+ to the container registry. And any failures in the image >+ creation is ignored. Once you managed to get success, you should >+ move from `.build_image_template_force_broken` to `.build_image_template`. >+ And also add a `.samba-o3-template` job for the new image >+ in the main .gitlab-ci.yml file. >+ >+ Over time we'll get a lot of images pushed to the container registry. >+ The approach we're using allows gitlab project maintainers to >+ remove old images! But it is possible to regenerate the images >+ if you have the need to run a gitlab ci pipeline based on an >+ older branch. >+ >+As a Samba developer/tester, I can setup a Samba env very quickly. >+ >+With Docker: >+ >+ cd ~/samba >+ git clean -xdf >+ docker login >+ docker pull registry.gitlab.com/samba-team/devel/samba/samba-ci-ubuntu1804:${sha1sum} >+ docker run -it -v $(pwd):/home/samba/samba samba-ci-ubuntu1804:${sha1sum} bash >+ >+With podman: >+ >+ podman run -ti --cap-add=SYS_PTRACE --security-opt seccomp=unconfined registry.gitlab.com/samba-team/devel/samba/samba-ci-ubuntu1804:${sha1sum} bash >+ >+With Vagrant: >+ >+ cd bootstrap/generated-dists/ >+ vagrant up # start all >+ vagrant up debian9 # start one >+ vagrant ssh debian9 >+ vagrant destroy debian9 # destroy one >+ vagrant destroy # destroy all >+ >+Or a remote/cloud machine: >+ >+ scp bootstrap/generated-dists/fedora30/bootstrap.sh USER@IP: >+ ssh USER@IP >+ sudo bash ./bootstrap.sh >+ >diff --git a/bootstrap/config.py b/bootstrap/config.py >new file mode 100644 >index 00000000000..93e321a7e81 >--- /dev/null >+++ b/bootstrap/config.py >@@ -0,0 +1,649 @@ >+#!/usr/bin/env python3 >+ >+# Copyright (C) Catalyst.Net 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 <http://www.gnu.org/licenses/>. >+ >+""" >+Manage dependencies and bootstrap environments for Samba. >+ >+Config file for packages and templates. >+ >+Author: Joe Guo <joeg@catalyst.net.nz> >+""" >+import os >+from os.path import abspath, dirname, join >+HERE = abspath(dirname(__file__)) >+# output dir for rendered files >+OUT = join(HERE, 'generated-dists') >+ >+ >+# pkgs with same name in all packaging systems >+COMMON = [ >+ 'acl', >+ 'attr', >+ 'autoconf', >+ 'binutils', >+ 'bison', >+ 'curl', >+ 'chrpath', >+ 'flex', >+ 'gcc', >+ 'gdb', >+ 'git', >+ 'gzip', >+ 'hostname', >+ 'htop', >+ 'lcov', >+ 'make', >+ 'patch', >+ 'perl', >+ 'psmisc', # for pstree in test >+ 'rng-tools', >+ 'rsync', >+ 'sed', >+ 'sudo', # docker images has no sudo by default >+ 'tar', >+ 'tree', >+] >+ >+ >+# define pkgs for all packaging systems in parallel >+# make it easier to find missing ones >+# use latest ubuntu and fedora as defaults >+# deb, rpm, ... >+PKGS = [ >+ # NAME1-dev, NAME2-devel >+ ('lmdb-utils', 'lmdb'), >+ ('mingw-w64', 'mingw64-gcc'), >+ ('zlib1g-dev', 'zlib-devel'), >+ ('libbsd-dev', 'libbsd-devel'), >+ ('liburing-dev', 'liburing-devel'), >+ ('libarchive-dev', 'libarchive-devel'), >+ ('libblkid-dev', 'libblkid-devel'), >+ ('libcap-dev', 'libcap-devel'), >+ ('libacl1-dev', 'libacl-devel'), >+ ('libattr1-dev', 'libattr-devel'), >+ >+ # libNAME1-dev, NAME2-devel >+ ('libpopt-dev', 'popt-devel'), >+ ('libreadline-dev', 'readline-devel'), >+ ('libjansson-dev', 'jansson-devel'), >+ ('liblmdb-dev', 'lmdb-devel'), >+ ('libncurses5-dev', 'ncurses-devel'), >+ # NOTE: Debian 7+ or Ubuntu 16.04+ >+ ('libsystemd-dev', 'systemd-devel'), >+ ('libkrb5-dev', 'krb5-devel'), >+ ('libldap2-dev', 'openldap-devel'), >+ ('libcups2-dev', 'cups-devel'), >+ ('libpam0g-dev', 'pam-devel'), >+ ('libgpgme11-dev', 'gpgme-devel'), >+ # NOTE: Debian 8+ and Ubuntu 14.04+ >+ ('libgnutls28-dev', 'gnutls-devel'), >+ ('libtasn1-bin', 'libtasn1-tools'), >+ ('libtasn1-dev', 'libtasn1-devel'), >+ ('', 'quota-devel'), >+ ('uuid-dev', 'libuuid-devel'), >+ ('libjs-jquery', ''), >+ ('libavahi-common-dev', 'avahi-devel'), >+ ('libdbus-1-dev', 'dbus-devel'), >+ ('libpcap-dev', 'libpcap-devel'), >+ ('libunwind-dev', 'libunwind-devel'), # for back trace >+ ('libglib2.0-dev', 'glib2-devel'), >+ ('libicu-dev', 'libicu-devel'), >+ ('heimdal-multidev', ''), >+ >+ # NAME1, NAME2 >+ # for debian, locales provide locale support with language packs >+ # ubuntu split language packs to language-pack-xx >+ # for centos, glibc-common provide locale support with language packs >+ # fedora split language packs to glibc-langpack-xx >+ ('locales', 'glibc-common'), # required for locale >+ ('language-pack-en', 'glibc-langpack-en'), # we need en_US.UTF-8 >+ ('bind9utils', 'bind-utils'), >+ ('dnsutils', ''), >+ ('xsltproc', 'libxslt'), >+ ('krb5-user', ''), >+ ('krb5-config', ''), >+ ('krb5-kdc', 'krb5-server'), >+ ('apt-utils', 'yum-utils'), >+ ('pkg-config', 'pkgconfig'), >+ ('procps', 'procps-ng'), # required for the free cmd in tests >+ ('lsb-release', 'lsb-release'), # we need lsb_relase to show info >+ ('', 'rpcgen'), # required for test >+ # refer: https://fedoraproject.org/wiki/Changes/SunRPCRemoval >+ ('', 'libtirpc-devel'), # for <rpc/rpc.h> header on fedora >+ ('', 'libnsl2-devel'), # for <rpcsvc/yp_prot.h> header on fedora >+ ('', 'rpcsvc-proto-devel'), # for <rpcsvc/rquota.h> header >+ ('mawk', 'gawk'), >+ >+ ('python3', 'python3'), >+ ('python3-cryptography', 'python3-cryptography'), # for krb5 tests >+ ('python3-dev', 'python3-devel'), >+ ('python3-dbg', ''), >+ ('python3-iso8601', ''), >+ ('python3-gpg', 'python3-gpg'), # defaults to ubuntu/fedora latest >+ ('python3-markdown', 'python3-markdown'), >+ ('python3-matplotlib', ''), >+ ('python3-dnspython', 'python3-dns'), >+ ('python3-pexpect', ''), # for wintest only >+ ('python3-pyasn1', 'python3-pyasn1'), # for krb5 tests >+ >+ ('', 'libsemanage-python'), >+ ('', 'policycoreutils-python'), >+ >+ # perl >+ ('libparse-yapp-perl', 'perl-Parse-Yapp'), >+ ('libjson-perl', 'perl-JSON-Parse'), >+ ('perl-modules', ''), >+ ('', 'perl-Archive-Tar'), >+ ('', 'perl-ExtUtils-MakeMaker'), >+ ('', 'perl-Test-Base'), >+ ('', 'perl-generators'), >+ ('', 'perl-interpreter'), >+ >+ # fs >+ ('xfslibs-dev', 'xfsprogs-devel'), # for xfs quota support >+ ('', 'glusterfs-api-devel'), >+ ('glusterfs-common', 'glusterfs-devel'), >+ ('libcephfs-dev', 'libcephfs-devel'), >+ >+ # misc >+ # @ means group for rpm, use fedora as rpm default >+ ('build-essential', '@development-tools'), >+ ('debhelper', ''), >+ # rpm has no pkg for docbook-xml >+ ('docbook-xml', 'docbook-dtds'), >+ ('docbook-xsl', 'docbook-style-xsl'), >+ ('', 'keyutils-libs-devel'), >+ ('', 'which'), >+] >+ >+ >+DEB_PKGS = COMMON + [pkg for pkg, _ in PKGS if pkg] >+RPM_PKGS = COMMON + [pkg for _, pkg in PKGS if pkg] >+ >+GENERATED_MARKER = r""" >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+""" >+ >+ >+APT_BOOTSTRAP = r""" >+#!/bin/bash >+{GENERATED_MARKER} >+set -xueo pipefail >+ >+export DEBIAN_FRONTEND=noninteractive >+apt-get -y update >+ >+apt-get -y install \ >+ {pkgs} >+ >+apt-get -y autoremove >+apt-get -y autoclean >+apt-get -y clean >+""" >+ >+ >+YUM_BOOTSTRAP = r""" >+#!/bin/bash >+{GENERATED_MARKER} >+set -xueo pipefail >+ >+yum update -y >+yum install -y epel-release >+yum install -y yum-plugin-copr >+yum copr enable -y sergiomb/SambaAD >+yum update -y >+ >+yum install -y \ >+ {pkgs} >+ >+yum clean all >+ >+if [ ! -f /usr/bin/python3 ]; then >+ ln -sf /usr/bin/python3.6 /usr/bin/python3 >+fi >+""" >+ >+CENTOS8_YUM_BOOTSTRAP = r""" >+#!/bin/bash >+{GENERATED_MARKER} >+set -xueo pipefail >+ >+yum update -y >+yum install -y dnf-plugins-core >+yum install -y epel-release >+yum config-manager --set-enabled PowerTools -y || \ >+ yum config-manager --set-enabled powertools -y >+yum update -y >+ >+yum install -y \ >+ --setopt=install_weak_deps=False \ >+ {pkgs} >+ >+yum clean all >+""" >+ >+DNF_BOOTSTRAP = r""" >+#!/bin/bash >+{GENERATED_MARKER} >+set -xueo pipefail >+ >+dnf update -y >+ >+dnf install -y \ >+ --setopt=install_weak_deps=False \ >+ {pkgs} >+ >+dnf clean all >+""" >+ >+ZYPPER_BOOTSTRAP = r""" >+#!/bin/bash >+{GENERATED_MARKER} >+set -xueo pipefail >+ >+zypper --non-interactive refresh >+zypper --non-interactive update >+zypper --non-interactive install \ >+ --no-recommends \ >+ system-user-nobody \ >+ {pkgs} >+ >+zypper --non-interactive clean >+ >+if [ -f /usr/lib/mit/bin/krb5-config ]; then >+ ln -sf /usr/lib/mit/bin/krb5-config /usr/bin/krb5-config >+fi >+""" >+ >+# A generic shell script to setup locale >+LOCALE_SETUP = r""" >+#!/bin/bash >+{GENERATED_MARKER} >+set -xueo pipefail >+ >+# refer to /usr/share/i18n/locales >+INPUTFILE=en_US >+# refer to /usr/share/i18n/charmaps >+CHARMAP=UTF-8 >+# locale to generate in /usr/lib/locale >+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style >+LOCALE=$INPUTFILE.utf8 >+ >+# if locale is already correct, exit >+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0 >+ >+# if locale not available, generate locale into /usr/lib/locale >+if ! ( locale --all-locales | grep -i $LOCALE ) >+then >+ # no-archive means create its own dir >+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE >+fi >+ >+# update locale conf and global env file >+# set both LC_ALL and LANG for safe >+ >+# update conf for Debian family >+FILE=/etc/default/locale >+if [ -f $FILE ] >+then >+ echo LC_ALL="$LOCALE" > $FILE >+ echo LANG="$LOCALE" >> $FILE >+fi >+ >+# update conf for RedHat family >+FILE=/etc/locale.conf >+if [ -f $FILE ] >+then >+ # LC_ALL is not valid in this file, set LANG only >+ echo LANG="$LOCALE" > $FILE >+fi >+ >+# update global env file >+FILE=/etc/environment >+if [ -f $FILE ] >+then >+ # append LC_ALL if not exist >+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE >+ # append LANG if not exist >+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE >+fi >+""" >+ >+ >+DOCKERFILE = r""" >+{GENERATED_MARKER} >+FROM {docker_image} >+ >+# pass in with --build-arg while build >+ARG SHA1SUM >+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt >+ >+ADD *.sh /tmp/ >+# need root permission, do it before USER samba >+RUN /tmp/bootstrap.sh && /tmp/locale.sh >+ >+# if ld.gold exists, force link it to ld >+RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD" >+ >+# make test can not work with root, so we have to create a new user >+RUN useradd -m -U -s /bin/bash samba && \ >+ mkdir -p /etc/sudoers.d && \ >+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba >+ >+USER samba >+WORKDIR /home/samba >+# samba tests rely on this >+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 >+""" >+ >+# Vagrantfile snippet for each dist >+VAGRANTFILE_SNIPPET = r""" >+ config.vm.define "{name}" do |v| >+ v.vm.box = "{vagrant_box}" >+ v.vm.hostname = "{name}" >+ v.vm.provision :shell, path: "{name}/bootstrap.sh" >+ v.vm.provision :shell, path: "{name}/locale.sh" >+ end >+""" >+ >+# global Vagrantfile with snippets for all dists >+VAGRANTFILE_GLOBAL = r""" >+{GENERATED_MARKER} >+ >+Vagrant.configure("2") do |config| >+ config.ssh.insert_key = false >+ >+{vagrantfile_snippets} >+ >+end >+""" >+ >+ >+DEB_DISTS = { >+ 'debian10': { >+ 'docker_image': 'debian:10', >+ 'vagrant_box': 'debian/buster64', >+ 'replace': { >+ 'language-pack-en': '', # included in locales >+ 'liburing-dev': '', # not available >+ } >+ }, >+ 'ubuntu1604': { >+ 'docker_image': 'ubuntu:16.04', >+ 'vagrant_box': 'ubuntu/xenial64', >+ 'replace': { >+ 'python-gpg': 'python-gpgme', >+ 'python3-gpg': 'python3-gpgme', >+ 'glusterfs-common': '', >+ 'libcephfs-dev': '', >+ 'liburing-dev': '', # not available >+ } >+ }, >+ 'ubuntu1804': { >+ 'docker_image': 'ubuntu:18.04', >+ 'vagrant_box': 'ubuntu/bionic64', >+ 'replace': { >+ 'liburing-dev': '', # not available >+ } >+ }, >+ 'ubuntu2004': { >+ 'docker_image': 'ubuntu:20.04', >+ 'vagrant_box': 'ubuntu/focal64', >+ 'replace': { >+ 'liburing-dev': '', # not available >+ } >+ }, >+} >+ >+ >+RPM_DISTS = { >+ 'centos7': { >+ 'docker_image': 'centos:7', >+ 'vagrant_box': 'centos/7', >+ 'bootstrap': YUM_BOOTSTRAP, >+ 'replace': { >+ 'lsb-release': 'redhat-lsb', >+ 'python3': 'python36', >+ 'python3-cryptography': 'python36-cryptography', >+ 'python3-devel': 'python36-devel', >+ 'python3-dns': 'python36-dns', >+ 'python3-pyasn1': 'python36-pyasn1', >+ 'python3-gpg': 'python36-gpg', >+ 'python3-iso8601' : 'python36-iso8601', >+ 'python3-markdown': 'python36-markdown', >+ # although python36-devel is available >+ # after epel-release installed >+ # however, all other python3 pkgs are still python36-ish >+ 'python2-gpg': 'pygpgme', >+ 'python3-gpg': '', # no python3-gpg yet >+ '@development-tools': '"@Development Tools"', # add quotes >+ 'glibc-langpack-en': '', # included in glibc-common >+ 'glibc-locale-source': '', # included in glibc-common >+ # update perl core modules on centos >+ # fix: Can't locate Archive/Tar.pm in @INC >+ 'perl': 'perl-core', >+ 'rpcsvc-proto-devel': '', >+ 'glusterfs-api-devel': '', >+ 'glusterfs-devel': '', >+ 'libcephfs-devel': '', >+ 'gnutls-devel': 'compat-gnutls34-devel', >+ 'liburing-devel': '', # not available >+ } >+ }, >+ 'centos8': { >+ 'docker_image': 'centos:8', >+ 'vagrant_box': 'centos/8', >+ 'bootstrap': CENTOS8_YUM_BOOTSTRAP, >+ 'replace': { >+ 'lsb-release': 'redhat-lsb', >+ '@development-tools': '"@Development Tools"', # add quotes >+ 'libsemanage-python': 'python3-libsemanage', >+ 'lcov': '', # does not exist >+ 'perl-JSON-Parse': '', # does not exist? >+ 'perl-Test-Base': 'perl-Test-Simple', >+ 'policycoreutils-python': 'python3-policycoreutils', >+ 'quota-devel': '', # FIXME: Add me back, once available! >+ 'liburing-devel': '', # not available yet, Add me back, once available! >+ } >+ }, >+ 'fedora31': { >+ 'docker_image': 'fedora:31', >+ 'vagrant_box': 'fedora/31-cloud-base', >+ 'bootstrap': DNF_BOOTSTRAP, >+ 'replace': { >+ 'lsb-release': 'redhat-lsb', >+ 'libsemanage-python': 'python3-libsemanage', >+ 'policycoreutils-python': 'python3-policycoreutils', >+ } >+ }, >+ 'fedora32': { >+ 'docker_image': 'fedora:32', >+ 'vagrant_box': 'fedora/32-cloud-base', >+ 'bootstrap': DNF_BOOTSTRAP, >+ 'replace': { >+ 'lsb-release': 'redhat-lsb', >+ 'libsemanage-python': 'python3-libsemanage', >+ 'policycoreutils-python': 'python3-policycoreutils', >+ } >+ }, >+ 'opensuse150': { >+ 'docker_image': 'opensuse/leap:15.0', >+ 'vagrant_box': 'opensuse/openSUSE-15.0-x86_64', >+ 'bootstrap': ZYPPER_BOOTSTRAP, >+ 'replace': { >+ '@development-tools': '', >+ 'dbus-devel': 'dbus-1-devel', >+ 'docbook-style-xsl': 'docbook-xsl-stylesheets', >+ 'glibc-common': 'glibc-locale', >+ 'glibc-locale-source': 'glibc-i18ndata', >+ 'glibc-langpack-en': '', >+ 'jansson-devel': 'libjansson-devel', >+ 'keyutils-libs-devel': 'keyutils-devel', >+ 'krb5-workstation': 'krb5-client', >+ 'libnsl2-devel': 'libnsl-devel', >+ 'libsemanage-python': 'python2-semanage', >+ 'openldap-devel': 'openldap2-devel', >+ 'perl-Archive-Tar': 'perl-Archive-Tar-Wrapper', >+ 'perl-JSON-Parse': 'perl-JSON-XS', >+ 'perl-generators': '', >+ 'perl-interpreter': '', >+ 'procps-ng': 'procps', >+ 'python-dns': 'python2-dnspython', >+ 'python3-dns': 'python3-dnspython', >+ 'python3-markdown': 'python3-Markdown', >+ 'quota-devel': '', >+ 'glusterfs-api-devel': '', >+ 'libtasn1-tools': '', # asn1Parser is part of libtasn1 >+ 'mingw64-gcc': '', # doesn't exist >+ 'liburing-devel': '', # not available >+ } >+ }, >+ 'opensuse151': { >+ 'docker_image': 'opensuse/leap:15.1', >+ 'vagrant_box': 'opensuse/openSUSE-15.1-x86_64', >+ 'bootstrap': ZYPPER_BOOTSTRAP, >+ 'replace': { >+ '@development-tools': '', >+ 'dbus-devel': 'dbus-1-devel', >+ 'docbook-style-xsl': 'docbook-xsl-stylesheets', >+ 'glibc-common': 'glibc-locale', >+ 'glibc-locale-source': 'glibc-i18ndata', >+ 'glibc-langpack-en': '', >+ 'jansson-devel': 'libjansson-devel', >+ 'keyutils-libs-devel': 'keyutils-devel', >+ 'krb5-workstation': 'krb5-client', >+ 'libnsl2-devel': 'libnsl-devel', >+ 'libsemanage-python': 'python2-semanage', >+ 'openldap-devel': 'openldap2-devel', >+ 'perl-Archive-Tar': 'perl-Archive-Tar-Wrapper', >+ 'perl-JSON-Parse': 'perl-JSON-XS', >+ 'perl-generators': '', >+ 'perl-interpreter': '', >+ 'procps-ng': 'procps', >+ 'python-dns': 'python2-dnspython', >+ 'python3-dns': 'python3-dnspython', >+ 'python3-markdown': 'python3-Markdown', >+ 'quota-devel': '', >+ 'glusterfs-api-devel': '', >+ 'libtasn1-tools': '', # asn1Parser is part of libtasn1 >+ 'mingw64-gcc': '', # doesn't exist >+ 'liburing-devel': '', # not available, will be added in 15.2 >+ } >+ } >+} >+ >+ >+DEB_FAMILY = { >+ 'name': 'deb', >+ 'pkgs': DEB_PKGS, >+ 'bootstrap': APT_BOOTSTRAP, # family default >+ 'dists': DEB_DISTS, >+} >+ >+ >+RPM_FAMILY = { >+ 'name': 'rpm', >+ 'pkgs': RPM_PKGS, >+ 'bootstrap': YUM_BOOTSTRAP, # family default >+ 'dists': RPM_DISTS, >+} >+ >+ >+YML_HEADER = r""" >+--- >+packages: >+""" >+ >+ >+def expand_family_dists(family): >+ dists = {} >+ for name, config in family['dists'].items(): >+ config = config.copy() >+ config['name'] = name >+ config['home'] = join(OUT, name) >+ config['family'] = family['name'] >+ config['GENERATED_MARKER'] = GENERATED_MARKER >+ >+ # replace dist specific pkgs >+ replace = config.get('replace', {}) >+ pkgs = [] >+ for pkg in family['pkgs']: >+ pkg = replace.get(pkg, pkg) # replace if exists or get self >+ if pkg: >+ pkgs.append(pkg) >+ pkgs.sort() >+ >+ lines = [' - {}'.format(pkg) for pkg in pkgs] >+ config['packages.yml'] = YML_HEADER.lstrip() + os.linesep.join(lines) >+ >+ sep = ' \\' + os.linesep + ' ' >+ config['pkgs'] = sep.join(pkgs) >+ >+ # get dist bootstrap template or fall back to family default >+ bootstrap_template = config.get('bootstrap', family['bootstrap']) >+ config['bootstrap.sh'] = bootstrap_template.format(**config).strip() >+ config['locale.sh'] = LOCALE_SETUP.format(**config).strip() >+ >+ config['Dockerfile'] = DOCKERFILE.format(**config).strip() >+ # keep the indent, no strip >+ config['vagrantfile_snippet'] = VAGRANTFILE_SNIPPET.format(**config) >+ >+ dists[name] = config >+ return dists >+ >+ >+# expanded config for dists >+DEB_DISTS_EXP = expand_family_dists(DEB_FAMILY) >+RPM_DISTS_EXP = expand_family_dists(RPM_FAMILY) >+ >+# assemble all together >+DISTS = {} >+DISTS.update(DEB_DISTS_EXP) >+DISTS.update(RPM_DISTS_EXP) >+ >+ >+def render_vagrantfile(dists): >+ """ >+ Render all snippets for each dist into global Vagrantfile. >+ >+ Vagrant supports multiple vms in one Vagrantfile. >+ This make it easier to manage the fleet, e.g: >+ >+ start all: vagrant up >+ start one: vagrant up ubuntu1804 >+ >+ All other commands apply to above syntax, e.g.: status, destroy, provision >+ """ >+ # sort dists by name and put all vagrantfile snippets together >+ snippets = [ >+ dists[dist]['vagrantfile_snippet'] >+ for dist in sorted(dists.keys())] >+ >+ return VAGRANTFILE_GLOBAL.format( >+ vagrantfile_snippets=''.join(snippets), >+ GENERATED_MARKER=GENERATED_MARKER >+ ) >+ >+ >+VAGRANTFILE = render_vagrantfile(DISTS) >+ >+ >+# data we need to expose >+__all__ = ['DISTS', 'VAGRANTFILE', 'OUT'] >diff --git a/bootstrap/generated-dists/Vagrantfile b/bootstrap/generated-dists/Vagrantfile >new file mode 100644 >index 00000000000..e01c20bc161 >--- /dev/null >+++ b/bootstrap/generated-dists/Vagrantfile >@@ -0,0 +1,84 @@ >+ >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+ >+Vagrant.configure("2") do |config| >+ config.ssh.insert_key = false >+ >+ >+ config.vm.define "centos7" do |v| >+ v.vm.box = "centos/7" >+ v.vm.hostname = "centos7" >+ v.vm.provision :shell, path: "centos7/bootstrap.sh" >+ v.vm.provision :shell, path: "centos7/locale.sh" >+ end >+ >+ config.vm.define "centos8" do |v| >+ v.vm.box = "centos/8" >+ v.vm.hostname = "centos8" >+ v.vm.provision :shell, path: "centos8/bootstrap.sh" >+ v.vm.provision :shell, path: "centos8/locale.sh" >+ end >+ >+ config.vm.define "debian10" do |v| >+ v.vm.box = "debian/buster64" >+ v.vm.hostname = "debian10" >+ v.vm.provision :shell, path: "debian10/bootstrap.sh" >+ v.vm.provision :shell, path: "debian10/locale.sh" >+ end >+ >+ config.vm.define "fedora31" do |v| >+ v.vm.box = "fedora/31-cloud-base" >+ v.vm.hostname = "fedora31" >+ v.vm.provision :shell, path: "fedora31/bootstrap.sh" >+ v.vm.provision :shell, path: "fedora31/locale.sh" >+ end >+ >+ config.vm.define "fedora32" do |v| >+ v.vm.box = "fedora/32-cloud-base" >+ v.vm.hostname = "fedora32" >+ v.vm.provision :shell, path: "fedora32/bootstrap.sh" >+ v.vm.provision :shell, path: "fedora32/locale.sh" >+ end >+ >+ config.vm.define "opensuse150" do |v| >+ v.vm.box = "opensuse/openSUSE-15.0-x86_64" >+ v.vm.hostname = "opensuse150" >+ v.vm.provision :shell, path: "opensuse150/bootstrap.sh" >+ v.vm.provision :shell, path: "opensuse150/locale.sh" >+ end >+ >+ config.vm.define "opensuse151" do |v| >+ v.vm.box = "opensuse/openSUSE-15.1-x86_64" >+ v.vm.hostname = "opensuse151" >+ v.vm.provision :shell, path: "opensuse151/bootstrap.sh" >+ v.vm.provision :shell, path: "opensuse151/locale.sh" >+ end >+ >+ config.vm.define "ubuntu1604" do |v| >+ v.vm.box = "ubuntu/xenial64" >+ v.vm.hostname = "ubuntu1604" >+ v.vm.provision :shell, path: "ubuntu1604/bootstrap.sh" >+ v.vm.provision :shell, path: "ubuntu1604/locale.sh" >+ end >+ >+ config.vm.define "ubuntu1804" do |v| >+ v.vm.box = "ubuntu/bionic64" >+ v.vm.hostname = "ubuntu1804" >+ v.vm.provision :shell, path: "ubuntu1804/bootstrap.sh" >+ v.vm.provision :shell, path: "ubuntu1804/locale.sh" >+ end >+ >+ config.vm.define "ubuntu2004" do |v| >+ v.vm.box = "ubuntu/focal64" >+ v.vm.hostname = "ubuntu2004" >+ v.vm.provision :shell, path: "ubuntu2004/bootstrap.sh" >+ v.vm.provision :shell, path: "ubuntu2004/locale.sh" >+ end >+ >+ >+end >diff --git a/bootstrap/generated-dists/centos7/Dockerfile b/bootstrap/generated-dists/centos7/Dockerfile >new file mode 100644 >index 00000000000..2f171ad1c62 >--- /dev/null >+++ b/bootstrap/generated-dists/centos7/Dockerfile >@@ -0,0 +1,27 @@ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+FROM centos:7 >+ >+# pass in with --build-arg while build >+ARG SHA1SUM >+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt >+ >+ADD *.sh /tmp/ >+# need root permission, do it before USER samba >+RUN /tmp/bootstrap.sh && /tmp/locale.sh >+ >+# if ld.gold exists, force link it to ld >+RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD" >+ >+# make test can not work with root, so we have to create a new user >+RUN useradd -m -U -s /bin/bash samba && \ >+ mkdir -p /etc/sudoers.d && \ >+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba >+ >+USER samba >+WORKDIR /home/samba >+# samba tests rely on this >+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 >\ No newline at end of file >diff --git a/bootstrap/generated-dists/centos7/bootstrap.sh b/bootstrap/generated-dists/centos7/bootstrap.sh >new file mode 100755 >index 00000000000..37f5d684663 >--- /dev/null >+++ b/bootstrap/generated-dists/centos7/bootstrap.sh >@@ -0,0 +1,111 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+yum update -y >+yum install -y epel-release >+yum install -y yum-plugin-copr >+yum copr enable -y sergiomb/SambaAD >+yum update -y >+ >+yum install -y \ >+ "@Development Tools" \ >+ acl \ >+ attr \ >+ autoconf \ >+ avahi-devel \ >+ bind-utils \ >+ binutils \ >+ bison \ >+ chrpath \ >+ compat-gnutls34-devel \ >+ cups-devel \ >+ curl \ >+ dbus-devel \ >+ docbook-dtds \ >+ docbook-style-xsl \ >+ flex \ >+ gawk \ >+ gcc \ >+ gdb \ >+ git \ >+ glib2-devel \ >+ glibc-common \ >+ gpgme-devel \ >+ gzip \ >+ hostname \ >+ htop \ >+ jansson-devel \ >+ keyutils-libs-devel \ >+ krb5-devel \ >+ krb5-server \ >+ lcov \ >+ libacl-devel \ >+ libarchive-devel \ >+ libattr-devel \ >+ libblkid-devel \ >+ libbsd-devel \ >+ libcap-devel \ >+ libicu-devel \ >+ libnsl2-devel \ >+ libpcap-devel \ >+ libsemanage-python \ >+ libtasn1-devel \ >+ libtasn1-tools \ >+ libtirpc-devel \ >+ libunwind-devel \ >+ libuuid-devel \ >+ libxslt \ >+ lmdb \ >+ lmdb-devel \ >+ make \ >+ mingw64-gcc \ >+ ncurses-devel \ >+ openldap-devel \ >+ pam-devel \ >+ patch \ >+ perl-Archive-Tar \ >+ perl-ExtUtils-MakeMaker \ >+ perl-JSON-Parse \ >+ perl-Parse-Yapp \ >+ perl-Test-Base \ >+ perl-core \ >+ perl-generators \ >+ perl-interpreter \ >+ pkgconfig \ >+ policycoreutils-python \ >+ popt-devel \ >+ procps-ng \ >+ psmisc \ >+ python36 \ >+ python36-cryptography \ >+ python36-devel \ >+ python36-dns \ >+ python36-markdown \ >+ python36-pyasn1 \ >+ quota-devel \ >+ readline-devel \ >+ redhat-lsb \ >+ rng-tools \ >+ rpcgen \ >+ rsync \ >+ sed \ >+ sudo \ >+ systemd-devel \ >+ tar \ >+ tree \ >+ which \ >+ xfsprogs-devel \ >+ yum-utils \ >+ zlib-devel >+ >+yum clean all >+ >+if [ ! -f /usr/bin/python3 ]; then >+ ln -sf /usr/bin/python3.6 /usr/bin/python3 >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/centos7/locale.sh b/bootstrap/generated-dists/centos7/locale.sh >new file mode 100755 >index 00000000000..cc64e180483 >--- /dev/null >+++ b/bootstrap/generated-dists/centos7/locale.sh >@@ -0,0 +1,55 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+# refer to /usr/share/i18n/locales >+INPUTFILE=en_US >+# refer to /usr/share/i18n/charmaps >+CHARMAP=UTF-8 >+# locale to generate in /usr/lib/locale >+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style >+LOCALE=$INPUTFILE.utf8 >+ >+# if locale is already correct, exit >+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0 >+ >+# if locale not available, generate locale into /usr/lib/locale >+if ! ( locale --all-locales | grep -i $LOCALE ) >+then >+ # no-archive means create its own dir >+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE >+fi >+ >+# update locale conf and global env file >+# set both LC_ALL and LANG for safe >+ >+# update conf for Debian family >+FILE=/etc/default/locale >+if [ -f $FILE ] >+then >+ echo LC_ALL="$LOCALE" > $FILE >+ echo LANG="$LOCALE" >> $FILE >+fi >+ >+# update conf for RedHat family >+FILE=/etc/locale.conf >+if [ -f $FILE ] >+then >+ # LC_ALL is not valid in this file, set LANG only >+ echo LANG="$LOCALE" > $FILE >+fi >+ >+# update global env file >+FILE=/etc/environment >+if [ -f $FILE ] >+then >+ # append LC_ALL if not exist >+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE >+ # append LANG if not exist >+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/centos7/packages.yml b/bootstrap/generated-dists/centos7/packages.yml >new file mode 100644 >index 00000000000..1b80882bd8c >--- /dev/null >+++ b/bootstrap/generated-dists/centos7/packages.yml >@@ -0,0 +1,91 @@ >+--- >+packages: >+ - "@Development Tools" >+ - acl >+ - attr >+ - autoconf >+ - avahi-devel >+ - bind-utils >+ - binutils >+ - bison >+ - chrpath >+ - compat-gnutls34-devel >+ - cups-devel >+ - curl >+ - dbus-devel >+ - docbook-dtds >+ - docbook-style-xsl >+ - flex >+ - gawk >+ - gcc >+ - gdb >+ - git >+ - glib2-devel >+ - glibc-common >+ - gpgme-devel >+ - gzip >+ - hostname >+ - htop >+ - jansson-devel >+ - keyutils-libs-devel >+ - krb5-devel >+ - krb5-server >+ - lcov >+ - libacl-devel >+ - libarchive-devel >+ - libattr-devel >+ - libblkid-devel >+ - libbsd-devel >+ - libcap-devel >+ - libicu-devel >+ - libnsl2-devel >+ - libpcap-devel >+ - libsemanage-python >+ - libtasn1-devel >+ - libtasn1-tools >+ - libtirpc-devel >+ - libunwind-devel >+ - libuuid-devel >+ - libxslt >+ - lmdb >+ - lmdb-devel >+ - make >+ - mingw64-gcc >+ - ncurses-devel >+ - openldap-devel >+ - pam-devel >+ - patch >+ - perl-Archive-Tar >+ - perl-ExtUtils-MakeMaker >+ - perl-JSON-Parse >+ - perl-Parse-Yapp >+ - perl-Test-Base >+ - perl-core >+ - perl-generators >+ - perl-interpreter >+ - pkgconfig >+ - policycoreutils-python >+ - popt-devel >+ - procps-ng >+ - psmisc >+ - python36 >+ - python36-cryptography >+ - python36-devel >+ - python36-dns >+ - python36-markdown >+ - python36-pyasn1 >+ - quota-devel >+ - readline-devel >+ - redhat-lsb >+ - rng-tools >+ - rpcgen >+ - rsync >+ - sed >+ - sudo >+ - systemd-devel >+ - tar >+ - tree >+ - which >+ - xfsprogs-devel >+ - yum-utils >+ - zlib-devel >\ No newline at end of file >diff --git a/bootstrap/generated-dists/centos8/Dockerfile b/bootstrap/generated-dists/centos8/Dockerfile >new file mode 100644 >index 00000000000..f6343e9d5a2 >--- /dev/null >+++ b/bootstrap/generated-dists/centos8/Dockerfile >@@ -0,0 +1,27 @@ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+FROM centos:8 >+ >+# pass in with --build-arg while build >+ARG SHA1SUM >+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt >+ >+ADD *.sh /tmp/ >+# need root permission, do it before USER samba >+RUN /tmp/bootstrap.sh && /tmp/locale.sh >+ >+# if ld.gold exists, force link it to ld >+RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD" >+ >+# make test can not work with root, so we have to create a new user >+RUN useradd -m -U -s /bin/bash samba && \ >+ mkdir -p /etc/sudoers.d && \ >+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba >+ >+USER samba >+WORKDIR /home/samba >+# samba tests rely on this >+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 >\ No newline at end of file >diff --git a/bootstrap/generated-dists/centos8/bootstrap.sh b/bootstrap/generated-dists/centos8/bootstrap.sh >new file mode 100755 >index 00000000000..2ee15dba86c >--- /dev/null >+++ b/bootstrap/generated-dists/centos8/bootstrap.sh >@@ -0,0 +1,112 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+yum update -y >+yum install -y dnf-plugins-core >+yum install -y epel-release >+yum config-manager --set-enabled PowerTools -y || \ >+ yum config-manager --set-enabled powertools -y >+yum update -y >+ >+yum install -y \ >+ --setopt=install_weak_deps=False \ >+ "@Development Tools" \ >+ acl \ >+ attr \ >+ autoconf \ >+ avahi-devel \ >+ bind-utils \ >+ binutils \ >+ bison \ >+ chrpath \ >+ cups-devel \ >+ curl \ >+ dbus-devel \ >+ docbook-dtds \ >+ docbook-style-xsl \ >+ flex \ >+ gawk \ >+ gcc \ >+ gdb \ >+ git \ >+ glib2-devel \ >+ glibc-common \ >+ glibc-langpack-en \ >+ glusterfs-api-devel \ >+ glusterfs-devel \ >+ gnutls-devel \ >+ gpgme-devel \ >+ gzip \ >+ hostname \ >+ htop \ >+ jansson-devel \ >+ keyutils-libs-devel \ >+ krb5-devel \ >+ krb5-server \ >+ libacl-devel \ >+ libarchive-devel \ >+ libattr-devel \ >+ libblkid-devel \ >+ libbsd-devel \ >+ libcap-devel \ >+ libcephfs-devel \ >+ libicu-devel \ >+ libnsl2-devel \ >+ libpcap-devel \ >+ libtasn1-devel \ >+ libtasn1-tools \ >+ libtirpc-devel \ >+ libunwind-devel \ >+ libuuid-devel \ >+ libxslt \ >+ lmdb \ >+ lmdb-devel \ >+ make \ >+ mingw64-gcc \ >+ ncurses-devel \ >+ openldap-devel \ >+ pam-devel \ >+ patch \ >+ perl \ >+ perl-Archive-Tar \ >+ perl-ExtUtils-MakeMaker \ >+ perl-Parse-Yapp \ >+ perl-Test-Simple \ >+ perl-generators \ >+ perl-interpreter \ >+ pkgconfig \ >+ popt-devel \ >+ procps-ng \ >+ psmisc \ >+ python3 \ >+ python3-cryptography \ >+ python3-devel \ >+ python3-dns \ >+ python3-gpg \ >+ python3-libsemanage \ >+ python3-markdown \ >+ python3-policycoreutils \ >+ python3-pyasn1 \ >+ readline-devel \ >+ redhat-lsb \ >+ rng-tools \ >+ rpcgen \ >+ rpcsvc-proto-devel \ >+ rsync \ >+ sed \ >+ sudo \ >+ systemd-devel \ >+ tar \ >+ tree \ >+ which \ >+ xfsprogs-devel \ >+ yum-utils \ >+ zlib-devel >+ >+yum clean all >\ No newline at end of file >diff --git a/bootstrap/generated-dists/centos8/locale.sh b/bootstrap/generated-dists/centos8/locale.sh >new file mode 100755 >index 00000000000..cc64e180483 >--- /dev/null >+++ b/bootstrap/generated-dists/centos8/locale.sh >@@ -0,0 +1,55 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+# refer to /usr/share/i18n/locales >+INPUTFILE=en_US >+# refer to /usr/share/i18n/charmaps >+CHARMAP=UTF-8 >+# locale to generate in /usr/lib/locale >+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style >+LOCALE=$INPUTFILE.utf8 >+ >+# if locale is already correct, exit >+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0 >+ >+# if locale not available, generate locale into /usr/lib/locale >+if ! ( locale --all-locales | grep -i $LOCALE ) >+then >+ # no-archive means create its own dir >+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE >+fi >+ >+# update locale conf and global env file >+# set both LC_ALL and LANG for safe >+ >+# update conf for Debian family >+FILE=/etc/default/locale >+if [ -f $FILE ] >+then >+ echo LC_ALL="$LOCALE" > $FILE >+ echo LANG="$LOCALE" >> $FILE >+fi >+ >+# update conf for RedHat family >+FILE=/etc/locale.conf >+if [ -f $FILE ] >+then >+ # LC_ALL is not valid in this file, set LANG only >+ echo LANG="$LOCALE" > $FILE >+fi >+ >+# update global env file >+FILE=/etc/environment >+if [ -f $FILE ] >+then >+ # append LC_ALL if not exist >+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE >+ # append LANG if not exist >+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/centos8/packages.yml b/bootstrap/generated-dists/centos8/packages.yml >new file mode 100644 >index 00000000000..2467b35dafb >--- /dev/null >+++ b/bootstrap/generated-dists/centos8/packages.yml >@@ -0,0 +1,94 @@ >+--- >+packages: >+ - "@Development Tools" >+ - acl >+ - attr >+ - autoconf >+ - avahi-devel >+ - bind-utils >+ - binutils >+ - bison >+ - chrpath >+ - cups-devel >+ - curl >+ - dbus-devel >+ - docbook-dtds >+ - docbook-style-xsl >+ - flex >+ - gawk >+ - gcc >+ - gdb >+ - git >+ - glib2-devel >+ - glibc-common >+ - glibc-langpack-en >+ - glusterfs-api-devel >+ - glusterfs-devel >+ - gnutls-devel >+ - gpgme-devel >+ - gzip >+ - hostname >+ - htop >+ - jansson-devel >+ - keyutils-libs-devel >+ - krb5-devel >+ - krb5-server >+ - libacl-devel >+ - libarchive-devel >+ - libattr-devel >+ - libblkid-devel >+ - libbsd-devel >+ - libcap-devel >+ - libcephfs-devel >+ - libicu-devel >+ - libnsl2-devel >+ - libpcap-devel >+ - libtasn1-devel >+ - libtasn1-tools >+ - libtirpc-devel >+ - libunwind-devel >+ - libuuid-devel >+ - libxslt >+ - lmdb >+ - lmdb-devel >+ - make >+ - mingw64-gcc >+ - ncurses-devel >+ - openldap-devel >+ - pam-devel >+ - patch >+ - perl >+ - perl-Archive-Tar >+ - perl-ExtUtils-MakeMaker >+ - perl-Parse-Yapp >+ - perl-Test-Simple >+ - perl-generators >+ - perl-interpreter >+ - pkgconfig >+ - popt-devel >+ - procps-ng >+ - psmisc >+ - python3 >+ - python3-cryptography >+ - python3-devel >+ - python3-dns >+ - python3-gpg >+ - python3-libsemanage >+ - python3-markdown >+ - python3-policycoreutils >+ - python3-pyasn1 >+ - readline-devel >+ - redhat-lsb >+ - rng-tools >+ - rpcgen >+ - rpcsvc-proto-devel >+ - rsync >+ - sed >+ - sudo >+ - systemd-devel >+ - tar >+ - tree >+ - which >+ - xfsprogs-devel >+ - yum-utils >+ - zlib-devel >\ No newline at end of file >diff --git a/bootstrap/generated-dists/debian10/Dockerfile b/bootstrap/generated-dists/debian10/Dockerfile >new file mode 100644 >index 00000000000..a7141db7e17 >--- /dev/null >+++ b/bootstrap/generated-dists/debian10/Dockerfile >@@ -0,0 +1,27 @@ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+FROM debian:10 >+ >+# pass in with --build-arg while build >+ARG SHA1SUM >+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt >+ >+ADD *.sh /tmp/ >+# need root permission, do it before USER samba >+RUN /tmp/bootstrap.sh && /tmp/locale.sh >+ >+# if ld.gold exists, force link it to ld >+RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD" >+ >+# make test can not work with root, so we have to create a new user >+RUN useradd -m -U -s /bin/bash samba && \ >+ mkdir -p /etc/sudoers.d && \ >+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba >+ >+USER samba >+WORKDIR /home/samba >+# samba tests rely on this >+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 >\ No newline at end of file >diff --git a/bootstrap/generated-dists/debian10/bootstrap.sh b/bootstrap/generated-dists/debian10/bootstrap.sh >new file mode 100755 >index 00000000000..9391c1ca815 >--- /dev/null >+++ b/bootstrap/generated-dists/debian10/bootstrap.sh >@@ -0,0 +1,107 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+export DEBIAN_FRONTEND=noninteractive >+apt-get -y update >+ >+apt-get -y install \ >+ acl \ >+ apt-utils \ >+ attr \ >+ autoconf \ >+ bind9utils \ >+ binutils \ >+ bison \ >+ build-essential \ >+ chrpath \ >+ curl \ >+ debhelper \ >+ dnsutils \ >+ docbook-xml \ >+ docbook-xsl \ >+ flex \ >+ gcc \ >+ gdb \ >+ git \ >+ glusterfs-common \ >+ gzip \ >+ heimdal-multidev \ >+ hostname \ >+ htop \ >+ krb5-config \ >+ krb5-kdc \ >+ krb5-user \ >+ lcov \ >+ libacl1-dev \ >+ libarchive-dev \ >+ libattr1-dev \ >+ libavahi-common-dev \ >+ libblkid-dev \ >+ libbsd-dev \ >+ libcap-dev \ >+ libcephfs-dev \ >+ libcups2-dev \ >+ libdbus-1-dev \ >+ libglib2.0-dev \ >+ libgnutls28-dev \ >+ libgpgme11-dev \ >+ libicu-dev \ >+ libjansson-dev \ >+ libjs-jquery \ >+ libjson-perl \ >+ libkrb5-dev \ >+ libldap2-dev \ >+ liblmdb-dev \ >+ libncurses5-dev \ >+ libpam0g-dev \ >+ libparse-yapp-perl \ >+ libpcap-dev \ >+ libpopt-dev \ >+ libreadline-dev \ >+ libsystemd-dev \ >+ libtasn1-bin \ >+ libtasn1-dev \ >+ libunwind-dev \ >+ lmdb-utils \ >+ locales \ >+ lsb-release \ >+ make \ >+ mawk \ >+ mingw-w64 \ >+ patch \ >+ perl \ >+ perl-modules \ >+ pkg-config \ >+ procps \ >+ psmisc \ >+ python3 \ >+ python3-cryptography \ >+ python3-dbg \ >+ python3-dev \ >+ python3-dnspython \ >+ python3-gpg \ >+ python3-iso8601 \ >+ python3-markdown \ >+ python3-matplotlib \ >+ python3-pexpect \ >+ python3-pyasn1 \ >+ rng-tools \ >+ rsync \ >+ sed \ >+ sudo \ >+ tar \ >+ tree \ >+ uuid-dev \ >+ xfslibs-dev \ >+ xsltproc \ >+ zlib1g-dev >+ >+apt-get -y autoremove >+apt-get -y autoclean >+apt-get -y clean >\ No newline at end of file >diff --git a/bootstrap/generated-dists/debian10/locale.sh b/bootstrap/generated-dists/debian10/locale.sh >new file mode 100755 >index 00000000000..cc64e180483 >--- /dev/null >+++ b/bootstrap/generated-dists/debian10/locale.sh >@@ -0,0 +1,55 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+# refer to /usr/share/i18n/locales >+INPUTFILE=en_US >+# refer to /usr/share/i18n/charmaps >+CHARMAP=UTF-8 >+# locale to generate in /usr/lib/locale >+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style >+LOCALE=$INPUTFILE.utf8 >+ >+# if locale is already correct, exit >+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0 >+ >+# if locale not available, generate locale into /usr/lib/locale >+if ! ( locale --all-locales | grep -i $LOCALE ) >+then >+ # no-archive means create its own dir >+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE >+fi >+ >+# update locale conf and global env file >+# set both LC_ALL and LANG for safe >+ >+# update conf for Debian family >+FILE=/etc/default/locale >+if [ -f $FILE ] >+then >+ echo LC_ALL="$LOCALE" > $FILE >+ echo LANG="$LOCALE" >> $FILE >+fi >+ >+# update conf for RedHat family >+FILE=/etc/locale.conf >+if [ -f $FILE ] >+then >+ # LC_ALL is not valid in this file, set LANG only >+ echo LANG="$LOCALE" > $FILE >+fi >+ >+# update global env file >+FILE=/etc/environment >+if [ -f $FILE ] >+then >+ # append LC_ALL if not exist >+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE >+ # append LANG if not exist >+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/debian10/packages.yml b/bootstrap/generated-dists/debian10/packages.yml >new file mode 100644 >index 00000000000..dee4d5cef20 >--- /dev/null >+++ b/bootstrap/generated-dists/debian10/packages.yml >@@ -0,0 +1,92 @@ >+--- >+packages: >+ - acl >+ - apt-utils >+ - attr >+ - autoconf >+ - bind9utils >+ - binutils >+ - bison >+ - build-essential >+ - chrpath >+ - curl >+ - debhelper >+ - dnsutils >+ - docbook-xml >+ - docbook-xsl >+ - flex >+ - gcc >+ - gdb >+ - git >+ - glusterfs-common >+ - gzip >+ - heimdal-multidev >+ - hostname >+ - htop >+ - krb5-config >+ - krb5-kdc >+ - krb5-user >+ - lcov >+ - libacl1-dev >+ - libarchive-dev >+ - libattr1-dev >+ - libavahi-common-dev >+ - libblkid-dev >+ - libbsd-dev >+ - libcap-dev >+ - libcephfs-dev >+ - libcups2-dev >+ - libdbus-1-dev >+ - libglib2.0-dev >+ - libgnutls28-dev >+ - libgpgme11-dev >+ - libicu-dev >+ - libjansson-dev >+ - libjs-jquery >+ - libjson-perl >+ - libkrb5-dev >+ - libldap2-dev >+ - liblmdb-dev >+ - libncurses5-dev >+ - libpam0g-dev >+ - libparse-yapp-perl >+ - libpcap-dev >+ - libpopt-dev >+ - libreadline-dev >+ - libsystemd-dev >+ - libtasn1-bin >+ - libtasn1-dev >+ - libunwind-dev >+ - lmdb-utils >+ - locales >+ - lsb-release >+ - make >+ - mawk >+ - mingw-w64 >+ - patch >+ - perl >+ - perl-modules >+ - pkg-config >+ - procps >+ - psmisc >+ - python3 >+ - python3-cryptography >+ - python3-dbg >+ - python3-dev >+ - python3-dnspython >+ - python3-gpg >+ - python3-iso8601 >+ - python3-markdown >+ - python3-matplotlib >+ - python3-pexpect >+ - python3-pyasn1 >+ - rng-tools >+ - rsync >+ - sed >+ - sudo >+ - tar >+ - tree >+ - uuid-dev >+ - xfslibs-dev >+ - xsltproc >+ - zlib1g-dev >\ No newline at end of file >diff --git a/bootstrap/generated-dists/fedora31/Dockerfile b/bootstrap/generated-dists/fedora31/Dockerfile >new file mode 100644 >index 00000000000..ff8d0b435c8 >--- /dev/null >+++ b/bootstrap/generated-dists/fedora31/Dockerfile >@@ -0,0 +1,27 @@ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+FROM fedora:31 >+ >+# pass in with --build-arg while build >+ARG SHA1SUM >+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt >+ >+ADD *.sh /tmp/ >+# need root permission, do it before USER samba >+RUN /tmp/bootstrap.sh && /tmp/locale.sh >+ >+# if ld.gold exists, force link it to ld >+RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD" >+ >+# make test can not work with root, so we have to create a new user >+RUN useradd -m -U -s /bin/bash samba && \ >+ mkdir -p /etc/sudoers.d && \ >+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba >+ >+USER samba >+WORKDIR /home/samba >+# samba tests rely on this >+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 >\ No newline at end of file >diff --git a/bootstrap/generated-dists/fedora31/bootstrap.sh b/bootstrap/generated-dists/fedora31/bootstrap.sh >new file mode 100755 >index 00000000000..09d36e88058 >--- /dev/null >+++ b/bootstrap/generated-dists/fedora31/bootstrap.sh >@@ -0,0 +1,111 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+dnf update -y >+ >+dnf install -y \ >+ --setopt=install_weak_deps=False \ >+ @development-tools \ >+ acl \ >+ attr \ >+ autoconf \ >+ avahi-devel \ >+ bind-utils \ >+ binutils \ >+ bison \ >+ chrpath \ >+ cups-devel \ >+ curl \ >+ dbus-devel \ >+ docbook-dtds \ >+ docbook-style-xsl \ >+ flex \ >+ gawk \ >+ gcc \ >+ gdb \ >+ git \ >+ glib2-devel \ >+ glibc-common \ >+ glibc-langpack-en \ >+ glusterfs-api-devel \ >+ glusterfs-devel \ >+ gnutls-devel \ >+ gpgme-devel \ >+ gzip \ >+ hostname \ >+ htop \ >+ jansson-devel \ >+ keyutils-libs-devel \ >+ krb5-devel \ >+ krb5-server \ >+ lcov \ >+ libacl-devel \ >+ libarchive-devel \ >+ libattr-devel \ >+ libblkid-devel \ >+ libbsd-devel \ >+ libcap-devel \ >+ libcephfs-devel \ >+ libicu-devel \ >+ libnsl2-devel \ >+ libpcap-devel \ >+ libtasn1-devel \ >+ libtasn1-tools \ >+ libtirpc-devel \ >+ libunwind-devel \ >+ liburing-devel \ >+ libuuid-devel \ >+ libxslt \ >+ lmdb \ >+ lmdb-devel \ >+ make \ >+ mingw64-gcc \ >+ ncurses-devel \ >+ openldap-devel \ >+ pam-devel \ >+ patch \ >+ perl \ >+ perl-Archive-Tar \ >+ perl-ExtUtils-MakeMaker \ >+ perl-JSON-Parse \ >+ perl-Parse-Yapp \ >+ perl-Test-Base \ >+ perl-generators \ >+ perl-interpreter \ >+ pkgconfig \ >+ popt-devel \ >+ procps-ng \ >+ psmisc \ >+ python3 \ >+ python3-cryptography \ >+ python3-devel \ >+ python3-dns \ >+ python3-gpg \ >+ python3-libsemanage \ >+ python3-markdown \ >+ python3-policycoreutils \ >+ python3-pyasn1 \ >+ quota-devel \ >+ readline-devel \ >+ redhat-lsb \ >+ rng-tools \ >+ rpcgen \ >+ rpcsvc-proto-devel \ >+ rsync \ >+ sed \ >+ sudo \ >+ systemd-devel \ >+ tar \ >+ tree \ >+ which \ >+ xfsprogs-devel \ >+ yum-utils \ >+ zlib-devel >+ >+dnf clean all >\ No newline at end of file >diff --git a/bootstrap/generated-dists/fedora31/locale.sh b/bootstrap/generated-dists/fedora31/locale.sh >new file mode 100755 >index 00000000000..cc64e180483 >--- /dev/null >+++ b/bootstrap/generated-dists/fedora31/locale.sh >@@ -0,0 +1,55 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+# refer to /usr/share/i18n/locales >+INPUTFILE=en_US >+# refer to /usr/share/i18n/charmaps >+CHARMAP=UTF-8 >+# locale to generate in /usr/lib/locale >+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style >+LOCALE=$INPUTFILE.utf8 >+ >+# if locale is already correct, exit >+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0 >+ >+# if locale not available, generate locale into /usr/lib/locale >+if ! ( locale --all-locales | grep -i $LOCALE ) >+then >+ # no-archive means create its own dir >+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE >+fi >+ >+# update locale conf and global env file >+# set both LC_ALL and LANG for safe >+ >+# update conf for Debian family >+FILE=/etc/default/locale >+if [ -f $FILE ] >+then >+ echo LC_ALL="$LOCALE" > $FILE >+ echo LANG="$LOCALE" >> $FILE >+fi >+ >+# update conf for RedHat family >+FILE=/etc/locale.conf >+if [ -f $FILE ] >+then >+ # LC_ALL is not valid in this file, set LANG only >+ echo LANG="$LOCALE" > $FILE >+fi >+ >+# update global env file >+FILE=/etc/environment >+if [ -f $FILE ] >+then >+ # append LC_ALL if not exist >+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE >+ # append LANG if not exist >+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/fedora31/packages.yml b/bootstrap/generated-dists/fedora31/packages.yml >new file mode 100644 >index 00000000000..a2fbd0eb83b >--- /dev/null >+++ b/bootstrap/generated-dists/fedora31/packages.yml >@@ -0,0 +1,98 @@ >+--- >+packages: >+ - @development-tools >+ - acl >+ - attr >+ - autoconf >+ - avahi-devel >+ - bind-utils >+ - binutils >+ - bison >+ - chrpath >+ - cups-devel >+ - curl >+ - dbus-devel >+ - docbook-dtds >+ - docbook-style-xsl >+ - flex >+ - gawk >+ - gcc >+ - gdb >+ - git >+ - glib2-devel >+ - glibc-common >+ - glibc-langpack-en >+ - glusterfs-api-devel >+ - glusterfs-devel >+ - gnutls-devel >+ - gpgme-devel >+ - gzip >+ - hostname >+ - htop >+ - jansson-devel >+ - keyutils-libs-devel >+ - krb5-devel >+ - krb5-server >+ - lcov >+ - libacl-devel >+ - libarchive-devel >+ - libattr-devel >+ - libblkid-devel >+ - libbsd-devel >+ - libcap-devel >+ - libcephfs-devel >+ - libicu-devel >+ - libnsl2-devel >+ - libpcap-devel >+ - libtasn1-devel >+ - libtasn1-tools >+ - libtirpc-devel >+ - libunwind-devel >+ - liburing-devel >+ - libuuid-devel >+ - libxslt >+ - lmdb >+ - lmdb-devel >+ - make >+ - mingw64-gcc >+ - ncurses-devel >+ - openldap-devel >+ - pam-devel >+ - patch >+ - perl >+ - perl-Archive-Tar >+ - perl-ExtUtils-MakeMaker >+ - perl-JSON-Parse >+ - perl-Parse-Yapp >+ - perl-Test-Base >+ - perl-generators >+ - perl-interpreter >+ - pkgconfig >+ - popt-devel >+ - procps-ng >+ - psmisc >+ - python3 >+ - python3-cryptography >+ - python3-devel >+ - python3-dns >+ - python3-gpg >+ - python3-libsemanage >+ - python3-markdown >+ - python3-policycoreutils >+ - python3-pyasn1 >+ - quota-devel >+ - readline-devel >+ - redhat-lsb >+ - rng-tools >+ - rpcgen >+ - rpcsvc-proto-devel >+ - rsync >+ - sed >+ - sudo >+ - systemd-devel >+ - tar >+ - tree >+ - which >+ - xfsprogs-devel >+ - yum-utils >+ - zlib-devel >\ No newline at end of file >diff --git a/bootstrap/generated-dists/fedora32/Dockerfile b/bootstrap/generated-dists/fedora32/Dockerfile >new file mode 100644 >index 00000000000..d8a75cf8445 >--- /dev/null >+++ b/bootstrap/generated-dists/fedora32/Dockerfile >@@ -0,0 +1,27 @@ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+FROM fedora:32 >+ >+# pass in with --build-arg while build >+ARG SHA1SUM >+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt >+ >+ADD *.sh /tmp/ >+# need root permission, do it before USER samba >+RUN /tmp/bootstrap.sh && /tmp/locale.sh >+ >+# if ld.gold exists, force link it to ld >+RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD" >+ >+# make test can not work with root, so we have to create a new user >+RUN useradd -m -U -s /bin/bash samba && \ >+ mkdir -p /etc/sudoers.d && \ >+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba >+ >+USER samba >+WORKDIR /home/samba >+# samba tests rely on this >+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 >\ No newline at end of file >diff --git a/bootstrap/generated-dists/fedora32/bootstrap.sh b/bootstrap/generated-dists/fedora32/bootstrap.sh >new file mode 100755 >index 00000000000..09d36e88058 >--- /dev/null >+++ b/bootstrap/generated-dists/fedora32/bootstrap.sh >@@ -0,0 +1,111 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+dnf update -y >+ >+dnf install -y \ >+ --setopt=install_weak_deps=False \ >+ @development-tools \ >+ acl \ >+ attr \ >+ autoconf \ >+ avahi-devel \ >+ bind-utils \ >+ binutils \ >+ bison \ >+ chrpath \ >+ cups-devel \ >+ curl \ >+ dbus-devel \ >+ docbook-dtds \ >+ docbook-style-xsl \ >+ flex \ >+ gawk \ >+ gcc \ >+ gdb \ >+ git \ >+ glib2-devel \ >+ glibc-common \ >+ glibc-langpack-en \ >+ glusterfs-api-devel \ >+ glusterfs-devel \ >+ gnutls-devel \ >+ gpgme-devel \ >+ gzip \ >+ hostname \ >+ htop \ >+ jansson-devel \ >+ keyutils-libs-devel \ >+ krb5-devel \ >+ krb5-server \ >+ lcov \ >+ libacl-devel \ >+ libarchive-devel \ >+ libattr-devel \ >+ libblkid-devel \ >+ libbsd-devel \ >+ libcap-devel \ >+ libcephfs-devel \ >+ libicu-devel \ >+ libnsl2-devel \ >+ libpcap-devel \ >+ libtasn1-devel \ >+ libtasn1-tools \ >+ libtirpc-devel \ >+ libunwind-devel \ >+ liburing-devel \ >+ libuuid-devel \ >+ libxslt \ >+ lmdb \ >+ lmdb-devel \ >+ make \ >+ mingw64-gcc \ >+ ncurses-devel \ >+ openldap-devel \ >+ pam-devel \ >+ patch \ >+ perl \ >+ perl-Archive-Tar \ >+ perl-ExtUtils-MakeMaker \ >+ perl-JSON-Parse \ >+ perl-Parse-Yapp \ >+ perl-Test-Base \ >+ perl-generators \ >+ perl-interpreter \ >+ pkgconfig \ >+ popt-devel \ >+ procps-ng \ >+ psmisc \ >+ python3 \ >+ python3-cryptography \ >+ python3-devel \ >+ python3-dns \ >+ python3-gpg \ >+ python3-libsemanage \ >+ python3-markdown \ >+ python3-policycoreutils \ >+ python3-pyasn1 \ >+ quota-devel \ >+ readline-devel \ >+ redhat-lsb \ >+ rng-tools \ >+ rpcgen \ >+ rpcsvc-proto-devel \ >+ rsync \ >+ sed \ >+ sudo \ >+ systemd-devel \ >+ tar \ >+ tree \ >+ which \ >+ xfsprogs-devel \ >+ yum-utils \ >+ zlib-devel >+ >+dnf clean all >\ No newline at end of file >diff --git a/bootstrap/generated-dists/fedora32/locale.sh b/bootstrap/generated-dists/fedora32/locale.sh >new file mode 100755 >index 00000000000..cc64e180483 >--- /dev/null >+++ b/bootstrap/generated-dists/fedora32/locale.sh >@@ -0,0 +1,55 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+# refer to /usr/share/i18n/locales >+INPUTFILE=en_US >+# refer to /usr/share/i18n/charmaps >+CHARMAP=UTF-8 >+# locale to generate in /usr/lib/locale >+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style >+LOCALE=$INPUTFILE.utf8 >+ >+# if locale is already correct, exit >+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0 >+ >+# if locale not available, generate locale into /usr/lib/locale >+if ! ( locale --all-locales | grep -i $LOCALE ) >+then >+ # no-archive means create its own dir >+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE >+fi >+ >+# update locale conf and global env file >+# set both LC_ALL and LANG for safe >+ >+# update conf for Debian family >+FILE=/etc/default/locale >+if [ -f $FILE ] >+then >+ echo LC_ALL="$LOCALE" > $FILE >+ echo LANG="$LOCALE" >> $FILE >+fi >+ >+# update conf for RedHat family >+FILE=/etc/locale.conf >+if [ -f $FILE ] >+then >+ # LC_ALL is not valid in this file, set LANG only >+ echo LANG="$LOCALE" > $FILE >+fi >+ >+# update global env file >+FILE=/etc/environment >+if [ -f $FILE ] >+then >+ # append LC_ALL if not exist >+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE >+ # append LANG if not exist >+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/fedora32/packages.yml b/bootstrap/generated-dists/fedora32/packages.yml >new file mode 100644 >index 00000000000..a2fbd0eb83b >--- /dev/null >+++ b/bootstrap/generated-dists/fedora32/packages.yml >@@ -0,0 +1,98 @@ >+--- >+packages: >+ - @development-tools >+ - acl >+ - attr >+ - autoconf >+ - avahi-devel >+ - bind-utils >+ - binutils >+ - bison >+ - chrpath >+ - cups-devel >+ - curl >+ - dbus-devel >+ - docbook-dtds >+ - docbook-style-xsl >+ - flex >+ - gawk >+ - gcc >+ - gdb >+ - git >+ - glib2-devel >+ - glibc-common >+ - glibc-langpack-en >+ - glusterfs-api-devel >+ - glusterfs-devel >+ - gnutls-devel >+ - gpgme-devel >+ - gzip >+ - hostname >+ - htop >+ - jansson-devel >+ - keyutils-libs-devel >+ - krb5-devel >+ - krb5-server >+ - lcov >+ - libacl-devel >+ - libarchive-devel >+ - libattr-devel >+ - libblkid-devel >+ - libbsd-devel >+ - libcap-devel >+ - libcephfs-devel >+ - libicu-devel >+ - libnsl2-devel >+ - libpcap-devel >+ - libtasn1-devel >+ - libtasn1-tools >+ - libtirpc-devel >+ - libunwind-devel >+ - liburing-devel >+ - libuuid-devel >+ - libxslt >+ - lmdb >+ - lmdb-devel >+ - make >+ - mingw64-gcc >+ - ncurses-devel >+ - openldap-devel >+ - pam-devel >+ - patch >+ - perl >+ - perl-Archive-Tar >+ - perl-ExtUtils-MakeMaker >+ - perl-JSON-Parse >+ - perl-Parse-Yapp >+ - perl-Test-Base >+ - perl-generators >+ - perl-interpreter >+ - pkgconfig >+ - popt-devel >+ - procps-ng >+ - psmisc >+ - python3 >+ - python3-cryptography >+ - python3-devel >+ - python3-dns >+ - python3-gpg >+ - python3-libsemanage >+ - python3-markdown >+ - python3-policycoreutils >+ - python3-pyasn1 >+ - quota-devel >+ - readline-devel >+ - redhat-lsb >+ - rng-tools >+ - rpcgen >+ - rpcsvc-proto-devel >+ - rsync >+ - sed >+ - sudo >+ - systemd-devel >+ - tar >+ - tree >+ - which >+ - xfsprogs-devel >+ - yum-utils >+ - zlib-devel >\ No newline at end of file >diff --git a/bootstrap/generated-dists/opensuse150/Dockerfile b/bootstrap/generated-dists/opensuse150/Dockerfile >new file mode 100644 >index 00000000000..fc8740b534d >--- /dev/null >+++ b/bootstrap/generated-dists/opensuse150/Dockerfile >@@ -0,0 +1,27 @@ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+FROM opensuse/leap:15.0 >+ >+# pass in with --build-arg while build >+ARG SHA1SUM >+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt >+ >+ADD *.sh /tmp/ >+# need root permission, do it before USER samba >+RUN /tmp/bootstrap.sh && /tmp/locale.sh >+ >+# if ld.gold exists, force link it to ld >+RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD" >+ >+# make test can not work with root, so we have to create a new user >+RUN useradd -m -U -s /bin/bash samba && \ >+ mkdir -p /etc/sudoers.d && \ >+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba >+ >+USER samba >+WORKDIR /home/samba >+# samba tests rely on this >+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 >\ No newline at end of file >diff --git a/bootstrap/generated-dists/opensuse150/bootstrap.sh b/bootstrap/generated-dists/opensuse150/bootstrap.sh >new file mode 100755 >index 00000000000..341b0ef9d35 >--- /dev/null >+++ b/bootstrap/generated-dists/opensuse150/bootstrap.sh >@@ -0,0 +1,107 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+zypper --non-interactive refresh >+zypper --non-interactive update >+zypper --non-interactive install \ >+ --no-recommends \ >+ system-user-nobody \ >+ acl \ >+ attr \ >+ autoconf \ >+ avahi-devel \ >+ bind-utils \ >+ binutils \ >+ bison \ >+ chrpath \ >+ cups-devel \ >+ curl \ >+ dbus-1-devel \ >+ docbook-dtds \ >+ docbook-xsl-stylesheets \ >+ flex \ >+ gawk \ >+ gcc \ >+ gdb \ >+ git \ >+ glib2-devel \ >+ glibc-locale \ >+ glusterfs-devel \ >+ gnutls-devel \ >+ gpgme-devel \ >+ gzip \ >+ hostname \ >+ htop \ >+ keyutils-devel \ >+ krb5-devel \ >+ krb5-server \ >+ lcov \ >+ libacl-devel \ >+ libarchive-devel \ >+ libattr-devel \ >+ libblkid-devel \ >+ libbsd-devel \ >+ libcap-devel \ >+ libcephfs-devel \ >+ libicu-devel \ >+ libjansson-devel \ >+ libnsl-devel \ >+ libpcap-devel \ >+ libtasn1-devel \ >+ libtirpc-devel \ >+ libunwind-devel \ >+ libuuid-devel \ >+ libxslt \ >+ lmdb \ >+ lmdb-devel \ >+ lsb-release \ >+ make \ >+ ncurses-devel \ >+ openldap2-devel \ >+ pam-devel \ >+ patch \ >+ perl \ >+ perl-Archive-Tar-Wrapper \ >+ perl-ExtUtils-MakeMaker \ >+ perl-JSON-XS \ >+ perl-Parse-Yapp \ >+ perl-Test-Base \ >+ pkgconfig \ >+ policycoreutils-python \ >+ popt-devel \ >+ procps \ >+ psmisc \ >+ python2-semanage \ >+ python3 \ >+ python3-Markdown \ >+ python3-cryptography \ >+ python3-devel \ >+ python3-dnspython \ >+ python3-gpg \ >+ python3-pyasn1 \ >+ readline-devel \ >+ rng-tools \ >+ rpcgen \ >+ rpcsvc-proto-devel \ >+ rsync \ >+ sed \ >+ sudo \ >+ systemd-devel \ >+ tar \ >+ tree \ >+ which \ >+ xfsprogs-devel \ >+ yum-utils \ >+ zlib-devel >+ >+zypper --non-interactive clean >+ >+if [ -f /usr/lib/mit/bin/krb5-config ]; then >+ ln -sf /usr/lib/mit/bin/krb5-config /usr/bin/krb5-config >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/opensuse150/locale.sh b/bootstrap/generated-dists/opensuse150/locale.sh >new file mode 100755 >index 00000000000..cc64e180483 >--- /dev/null >+++ b/bootstrap/generated-dists/opensuse150/locale.sh >@@ -0,0 +1,55 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+# refer to /usr/share/i18n/locales >+INPUTFILE=en_US >+# refer to /usr/share/i18n/charmaps >+CHARMAP=UTF-8 >+# locale to generate in /usr/lib/locale >+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style >+LOCALE=$INPUTFILE.utf8 >+ >+# if locale is already correct, exit >+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0 >+ >+# if locale not available, generate locale into /usr/lib/locale >+if ! ( locale --all-locales | grep -i $LOCALE ) >+then >+ # no-archive means create its own dir >+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE >+fi >+ >+# update locale conf and global env file >+# set both LC_ALL and LANG for safe >+ >+# update conf for Debian family >+FILE=/etc/default/locale >+if [ -f $FILE ] >+then >+ echo LC_ALL="$LOCALE" > $FILE >+ echo LANG="$LOCALE" >> $FILE >+fi >+ >+# update conf for RedHat family >+FILE=/etc/locale.conf >+if [ -f $FILE ] >+then >+ # LC_ALL is not valid in this file, set LANG only >+ echo LANG="$LOCALE" > $FILE >+fi >+ >+# update global env file >+FILE=/etc/environment >+if [ -f $FILE ] >+then >+ # append LC_ALL if not exist >+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE >+ # append LANG if not exist >+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/opensuse150/packages.yml b/bootstrap/generated-dists/opensuse150/packages.yml >new file mode 100644 >index 00000000000..b8c469cadca >--- /dev/null >+++ b/bootstrap/generated-dists/opensuse150/packages.yml >@@ -0,0 +1,89 @@ >+--- >+packages: >+ - acl >+ - attr >+ - autoconf >+ - avahi-devel >+ - bind-utils >+ - binutils >+ - bison >+ - chrpath >+ - cups-devel >+ - curl >+ - dbus-1-devel >+ - docbook-dtds >+ - docbook-xsl-stylesheets >+ - flex >+ - gawk >+ - gcc >+ - gdb >+ - git >+ - glib2-devel >+ - glibc-locale >+ - glusterfs-devel >+ - gnutls-devel >+ - gpgme-devel >+ - gzip >+ - hostname >+ - htop >+ - keyutils-devel >+ - krb5-devel >+ - krb5-server >+ - lcov >+ - libacl-devel >+ - libarchive-devel >+ - libattr-devel >+ - libblkid-devel >+ - libbsd-devel >+ - libcap-devel >+ - libcephfs-devel >+ - libicu-devel >+ - libjansson-devel >+ - libnsl-devel >+ - libpcap-devel >+ - libtasn1-devel >+ - libtirpc-devel >+ - libunwind-devel >+ - libuuid-devel >+ - libxslt >+ - lmdb >+ - lmdb-devel >+ - lsb-release >+ - make >+ - ncurses-devel >+ - openldap2-devel >+ - pam-devel >+ - patch >+ - perl >+ - perl-Archive-Tar-Wrapper >+ - perl-ExtUtils-MakeMaker >+ - perl-JSON-XS >+ - perl-Parse-Yapp >+ - perl-Test-Base >+ - pkgconfig >+ - policycoreutils-python >+ - popt-devel >+ - procps >+ - psmisc >+ - python2-semanage >+ - python3 >+ - python3-Markdown >+ - python3-cryptography >+ - python3-devel >+ - python3-dnspython >+ - python3-gpg >+ - python3-pyasn1 >+ - readline-devel >+ - rng-tools >+ - rpcgen >+ - rpcsvc-proto-devel >+ - rsync >+ - sed >+ - sudo >+ - systemd-devel >+ - tar >+ - tree >+ - which >+ - xfsprogs-devel >+ - yum-utils >+ - zlib-devel >\ No newline at end of file >diff --git a/bootstrap/generated-dists/opensuse151/Dockerfile b/bootstrap/generated-dists/opensuse151/Dockerfile >new file mode 100644 >index 00000000000..5a5fd645700 >--- /dev/null >+++ b/bootstrap/generated-dists/opensuse151/Dockerfile >@@ -0,0 +1,27 @@ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+FROM opensuse/leap:15.1 >+ >+# pass in with --build-arg while build >+ARG SHA1SUM >+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt >+ >+ADD *.sh /tmp/ >+# need root permission, do it before USER samba >+RUN /tmp/bootstrap.sh && /tmp/locale.sh >+ >+# if ld.gold exists, force link it to ld >+RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD" >+ >+# make test can not work with root, so we have to create a new user >+RUN useradd -m -U -s /bin/bash samba && \ >+ mkdir -p /etc/sudoers.d && \ >+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba >+ >+USER samba >+WORKDIR /home/samba >+# samba tests rely on this >+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 >\ No newline at end of file >diff --git a/bootstrap/generated-dists/opensuse151/bootstrap.sh b/bootstrap/generated-dists/opensuse151/bootstrap.sh >new file mode 100755 >index 00000000000..341b0ef9d35 >--- /dev/null >+++ b/bootstrap/generated-dists/opensuse151/bootstrap.sh >@@ -0,0 +1,107 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+zypper --non-interactive refresh >+zypper --non-interactive update >+zypper --non-interactive install \ >+ --no-recommends \ >+ system-user-nobody \ >+ acl \ >+ attr \ >+ autoconf \ >+ avahi-devel \ >+ bind-utils \ >+ binutils \ >+ bison \ >+ chrpath \ >+ cups-devel \ >+ curl \ >+ dbus-1-devel \ >+ docbook-dtds \ >+ docbook-xsl-stylesheets \ >+ flex \ >+ gawk \ >+ gcc \ >+ gdb \ >+ git \ >+ glib2-devel \ >+ glibc-locale \ >+ glusterfs-devel \ >+ gnutls-devel \ >+ gpgme-devel \ >+ gzip \ >+ hostname \ >+ htop \ >+ keyutils-devel \ >+ krb5-devel \ >+ krb5-server \ >+ lcov \ >+ libacl-devel \ >+ libarchive-devel \ >+ libattr-devel \ >+ libblkid-devel \ >+ libbsd-devel \ >+ libcap-devel \ >+ libcephfs-devel \ >+ libicu-devel \ >+ libjansson-devel \ >+ libnsl-devel \ >+ libpcap-devel \ >+ libtasn1-devel \ >+ libtirpc-devel \ >+ libunwind-devel \ >+ libuuid-devel \ >+ libxslt \ >+ lmdb \ >+ lmdb-devel \ >+ lsb-release \ >+ make \ >+ ncurses-devel \ >+ openldap2-devel \ >+ pam-devel \ >+ patch \ >+ perl \ >+ perl-Archive-Tar-Wrapper \ >+ perl-ExtUtils-MakeMaker \ >+ perl-JSON-XS \ >+ perl-Parse-Yapp \ >+ perl-Test-Base \ >+ pkgconfig \ >+ policycoreutils-python \ >+ popt-devel \ >+ procps \ >+ psmisc \ >+ python2-semanage \ >+ python3 \ >+ python3-Markdown \ >+ python3-cryptography \ >+ python3-devel \ >+ python3-dnspython \ >+ python3-gpg \ >+ python3-pyasn1 \ >+ readline-devel \ >+ rng-tools \ >+ rpcgen \ >+ rpcsvc-proto-devel \ >+ rsync \ >+ sed \ >+ sudo \ >+ systemd-devel \ >+ tar \ >+ tree \ >+ which \ >+ xfsprogs-devel \ >+ yum-utils \ >+ zlib-devel >+ >+zypper --non-interactive clean >+ >+if [ -f /usr/lib/mit/bin/krb5-config ]; then >+ ln -sf /usr/lib/mit/bin/krb5-config /usr/bin/krb5-config >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/opensuse151/locale.sh b/bootstrap/generated-dists/opensuse151/locale.sh >new file mode 100755 >index 00000000000..cc64e180483 >--- /dev/null >+++ b/bootstrap/generated-dists/opensuse151/locale.sh >@@ -0,0 +1,55 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+# refer to /usr/share/i18n/locales >+INPUTFILE=en_US >+# refer to /usr/share/i18n/charmaps >+CHARMAP=UTF-8 >+# locale to generate in /usr/lib/locale >+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style >+LOCALE=$INPUTFILE.utf8 >+ >+# if locale is already correct, exit >+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0 >+ >+# if locale not available, generate locale into /usr/lib/locale >+if ! ( locale --all-locales | grep -i $LOCALE ) >+then >+ # no-archive means create its own dir >+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE >+fi >+ >+# update locale conf and global env file >+# set both LC_ALL and LANG for safe >+ >+# update conf for Debian family >+FILE=/etc/default/locale >+if [ -f $FILE ] >+then >+ echo LC_ALL="$LOCALE" > $FILE >+ echo LANG="$LOCALE" >> $FILE >+fi >+ >+# update conf for RedHat family >+FILE=/etc/locale.conf >+if [ -f $FILE ] >+then >+ # LC_ALL is not valid in this file, set LANG only >+ echo LANG="$LOCALE" > $FILE >+fi >+ >+# update global env file >+FILE=/etc/environment >+if [ -f $FILE ] >+then >+ # append LC_ALL if not exist >+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE >+ # append LANG if not exist >+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/opensuse151/packages.yml b/bootstrap/generated-dists/opensuse151/packages.yml >new file mode 100644 >index 00000000000..b8c469cadca >--- /dev/null >+++ b/bootstrap/generated-dists/opensuse151/packages.yml >@@ -0,0 +1,89 @@ >+--- >+packages: >+ - acl >+ - attr >+ - autoconf >+ - avahi-devel >+ - bind-utils >+ - binutils >+ - bison >+ - chrpath >+ - cups-devel >+ - curl >+ - dbus-1-devel >+ - docbook-dtds >+ - docbook-xsl-stylesheets >+ - flex >+ - gawk >+ - gcc >+ - gdb >+ - git >+ - glib2-devel >+ - glibc-locale >+ - glusterfs-devel >+ - gnutls-devel >+ - gpgme-devel >+ - gzip >+ - hostname >+ - htop >+ - keyutils-devel >+ - krb5-devel >+ - krb5-server >+ - lcov >+ - libacl-devel >+ - libarchive-devel >+ - libattr-devel >+ - libblkid-devel >+ - libbsd-devel >+ - libcap-devel >+ - libcephfs-devel >+ - libicu-devel >+ - libjansson-devel >+ - libnsl-devel >+ - libpcap-devel >+ - libtasn1-devel >+ - libtirpc-devel >+ - libunwind-devel >+ - libuuid-devel >+ - libxslt >+ - lmdb >+ - lmdb-devel >+ - lsb-release >+ - make >+ - ncurses-devel >+ - openldap2-devel >+ - pam-devel >+ - patch >+ - perl >+ - perl-Archive-Tar-Wrapper >+ - perl-ExtUtils-MakeMaker >+ - perl-JSON-XS >+ - perl-Parse-Yapp >+ - perl-Test-Base >+ - pkgconfig >+ - policycoreutils-python >+ - popt-devel >+ - procps >+ - psmisc >+ - python2-semanage >+ - python3 >+ - python3-Markdown >+ - python3-cryptography >+ - python3-devel >+ - python3-dnspython >+ - python3-gpg >+ - python3-pyasn1 >+ - readline-devel >+ - rng-tools >+ - rpcgen >+ - rpcsvc-proto-devel >+ - rsync >+ - sed >+ - sudo >+ - systemd-devel >+ - tar >+ - tree >+ - which >+ - xfsprogs-devel >+ - yum-utils >+ - zlib-devel >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu1604/Dockerfile b/bootstrap/generated-dists/ubuntu1604/Dockerfile >new file mode 100644 >index 00000000000..93001fcdcca >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu1604/Dockerfile >@@ -0,0 +1,27 @@ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+FROM ubuntu:16.04 >+ >+# pass in with --build-arg while build >+ARG SHA1SUM >+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt >+ >+ADD *.sh /tmp/ >+# need root permission, do it before USER samba >+RUN /tmp/bootstrap.sh && /tmp/locale.sh >+ >+# if ld.gold exists, force link it to ld >+RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD" >+ >+# make test can not work with root, so we have to create a new user >+RUN useradd -m -U -s /bin/bash samba && \ >+ mkdir -p /etc/sudoers.d && \ >+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba >+ >+USER samba >+WORKDIR /home/samba >+# samba tests rely on this >+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu1604/bootstrap.sh b/bootstrap/generated-dists/ubuntu1604/bootstrap.sh >new file mode 100755 >index 00000000000..f5791357d45 >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu1604/bootstrap.sh >@@ -0,0 +1,106 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+export DEBIAN_FRONTEND=noninteractive >+apt-get -y update >+ >+apt-get -y install \ >+ acl \ >+ apt-utils \ >+ attr \ >+ autoconf \ >+ bind9utils \ >+ binutils \ >+ bison \ >+ build-essential \ >+ chrpath \ >+ curl \ >+ debhelper \ >+ dnsutils \ >+ docbook-xml \ >+ docbook-xsl \ >+ flex \ >+ gcc \ >+ gdb \ >+ git \ >+ gzip \ >+ heimdal-multidev \ >+ hostname \ >+ htop \ >+ krb5-config \ >+ krb5-kdc \ >+ krb5-user \ >+ language-pack-en \ >+ lcov \ >+ libacl1-dev \ >+ libarchive-dev \ >+ libattr1-dev \ >+ libavahi-common-dev \ >+ libblkid-dev \ >+ libbsd-dev \ >+ libcap-dev \ >+ libcups2-dev \ >+ libdbus-1-dev \ >+ libglib2.0-dev \ >+ libgnutls28-dev \ >+ libgpgme11-dev \ >+ libicu-dev \ >+ libjansson-dev \ >+ libjs-jquery \ >+ libjson-perl \ >+ libkrb5-dev \ >+ libldap2-dev \ >+ liblmdb-dev \ >+ libncurses5-dev \ >+ libpam0g-dev \ >+ libparse-yapp-perl \ >+ libpcap-dev \ >+ libpopt-dev \ >+ libreadline-dev \ >+ libsystemd-dev \ >+ libtasn1-bin \ >+ libtasn1-dev \ >+ libunwind-dev \ >+ lmdb-utils \ >+ locales \ >+ lsb-release \ >+ make \ >+ mawk \ >+ mingw-w64 \ >+ patch \ >+ perl \ >+ perl-modules \ >+ pkg-config \ >+ procps \ >+ psmisc \ >+ python3 \ >+ python3-cryptography \ >+ python3-dbg \ >+ python3-dev \ >+ python3-dnspython \ >+ python3-gpgme \ >+ python3-iso8601 \ >+ python3-markdown \ >+ python3-matplotlib \ >+ python3-pexpect \ >+ python3-pyasn1 \ >+ rng-tools \ >+ rsync \ >+ sed \ >+ sudo \ >+ tar \ >+ tree \ >+ uuid-dev \ >+ xfslibs-dev \ >+ xsltproc \ >+ zlib1g-dev >+ >+apt-get -y autoremove >+apt-get -y autoclean >+apt-get -y clean >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu1604/locale.sh b/bootstrap/generated-dists/ubuntu1604/locale.sh >new file mode 100755 >index 00000000000..cc64e180483 >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu1604/locale.sh >@@ -0,0 +1,55 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+# refer to /usr/share/i18n/locales >+INPUTFILE=en_US >+# refer to /usr/share/i18n/charmaps >+CHARMAP=UTF-8 >+# locale to generate in /usr/lib/locale >+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style >+LOCALE=$INPUTFILE.utf8 >+ >+# if locale is already correct, exit >+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0 >+ >+# if locale not available, generate locale into /usr/lib/locale >+if ! ( locale --all-locales | grep -i $LOCALE ) >+then >+ # no-archive means create its own dir >+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE >+fi >+ >+# update locale conf and global env file >+# set both LC_ALL and LANG for safe >+ >+# update conf for Debian family >+FILE=/etc/default/locale >+if [ -f $FILE ] >+then >+ echo LC_ALL="$LOCALE" > $FILE >+ echo LANG="$LOCALE" >> $FILE >+fi >+ >+# update conf for RedHat family >+FILE=/etc/locale.conf >+if [ -f $FILE ] >+then >+ # LC_ALL is not valid in this file, set LANG only >+ echo LANG="$LOCALE" > $FILE >+fi >+ >+# update global env file >+FILE=/etc/environment >+if [ -f $FILE ] >+then >+ # append LC_ALL if not exist >+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE >+ # append LANG if not exist >+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu1604/packages.yml b/bootstrap/generated-dists/ubuntu1604/packages.yml >new file mode 100644 >index 00000000000..932cc162041 >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu1604/packages.yml >@@ -0,0 +1,91 @@ >+--- >+packages: >+ - acl >+ - apt-utils >+ - attr >+ - autoconf >+ - bind9utils >+ - binutils >+ - bison >+ - build-essential >+ - chrpath >+ - curl >+ - debhelper >+ - dnsutils >+ - docbook-xml >+ - docbook-xsl >+ - flex >+ - gcc >+ - gdb >+ - git >+ - gzip >+ - heimdal-multidev >+ - hostname >+ - htop >+ - krb5-config >+ - krb5-kdc >+ - krb5-user >+ - language-pack-en >+ - lcov >+ - libacl1-dev >+ - libarchive-dev >+ - libattr1-dev >+ - libavahi-common-dev >+ - libblkid-dev >+ - libbsd-dev >+ - libcap-dev >+ - libcups2-dev >+ - libdbus-1-dev >+ - libglib2.0-dev >+ - libgnutls28-dev >+ - libgpgme11-dev >+ - libicu-dev >+ - libjansson-dev >+ - libjs-jquery >+ - libjson-perl >+ - libkrb5-dev >+ - libldap2-dev >+ - liblmdb-dev >+ - libncurses5-dev >+ - libpam0g-dev >+ - libparse-yapp-perl >+ - libpcap-dev >+ - libpopt-dev >+ - libreadline-dev >+ - libsystemd-dev >+ - libtasn1-bin >+ - libtasn1-dev >+ - libunwind-dev >+ - lmdb-utils >+ - locales >+ - lsb-release >+ - make >+ - mawk >+ - mingw-w64 >+ - patch >+ - perl >+ - perl-modules >+ - pkg-config >+ - procps >+ - psmisc >+ - python3 >+ - python3-cryptography >+ - python3-dbg >+ - python3-dev >+ - python3-dnspython >+ - python3-gpgme >+ - python3-iso8601 >+ - python3-markdown >+ - python3-matplotlib >+ - python3-pexpect >+ - python3-pyasn1 >+ - rng-tools >+ - rsync >+ - sed >+ - sudo >+ - tar >+ - tree >+ - uuid-dev >+ - xfslibs-dev >+ - xsltproc >+ - zlib1g-dev >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu1804/Dockerfile b/bootstrap/generated-dists/ubuntu1804/Dockerfile >new file mode 100644 >index 00000000000..21686560ad9 >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu1804/Dockerfile >@@ -0,0 +1,27 @@ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+FROM ubuntu:18.04 >+ >+# pass in with --build-arg while build >+ARG SHA1SUM >+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt >+ >+ADD *.sh /tmp/ >+# need root permission, do it before USER samba >+RUN /tmp/bootstrap.sh && /tmp/locale.sh >+ >+# if ld.gold exists, force link it to ld >+RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD" >+ >+# make test can not work with root, so we have to create a new user >+RUN useradd -m -U -s /bin/bash samba && \ >+ mkdir -p /etc/sudoers.d && \ >+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba >+ >+USER samba >+WORKDIR /home/samba >+# samba tests rely on this >+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu1804/bootstrap.sh b/bootstrap/generated-dists/ubuntu1804/bootstrap.sh >new file mode 100755 >index 00000000000..e668057ea82 >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu1804/bootstrap.sh >@@ -0,0 +1,108 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+export DEBIAN_FRONTEND=noninteractive >+apt-get -y update >+ >+apt-get -y install \ >+ acl \ >+ apt-utils \ >+ attr \ >+ autoconf \ >+ bind9utils \ >+ binutils \ >+ bison \ >+ build-essential \ >+ chrpath \ >+ curl \ >+ debhelper \ >+ dnsutils \ >+ docbook-xml \ >+ docbook-xsl \ >+ flex \ >+ gcc \ >+ gdb \ >+ git \ >+ glusterfs-common \ >+ gzip \ >+ heimdal-multidev \ >+ hostname \ >+ htop \ >+ krb5-config \ >+ krb5-kdc \ >+ krb5-user \ >+ language-pack-en \ >+ lcov \ >+ libacl1-dev \ >+ libarchive-dev \ >+ libattr1-dev \ >+ libavahi-common-dev \ >+ libblkid-dev \ >+ libbsd-dev \ >+ libcap-dev \ >+ libcephfs-dev \ >+ libcups2-dev \ >+ libdbus-1-dev \ >+ libglib2.0-dev \ >+ libgnutls28-dev \ >+ libgpgme11-dev \ >+ libicu-dev \ >+ libjansson-dev \ >+ libjs-jquery \ >+ libjson-perl \ >+ libkrb5-dev \ >+ libldap2-dev \ >+ liblmdb-dev \ >+ libncurses5-dev \ >+ libpam0g-dev \ >+ libparse-yapp-perl \ >+ libpcap-dev \ >+ libpopt-dev \ >+ libreadline-dev \ >+ libsystemd-dev \ >+ libtasn1-bin \ >+ libtasn1-dev \ >+ libunwind-dev \ >+ lmdb-utils \ >+ locales \ >+ lsb-release \ >+ make \ >+ mawk \ >+ mingw-w64 \ >+ patch \ >+ perl \ >+ perl-modules \ >+ pkg-config \ >+ procps \ >+ psmisc \ >+ python3 \ >+ python3-cryptography \ >+ python3-dbg \ >+ python3-dev \ >+ python3-dnspython \ >+ python3-gpg \ >+ python3-iso8601 \ >+ python3-markdown \ >+ python3-matplotlib \ >+ python3-pexpect \ >+ python3-pyasn1 \ >+ rng-tools \ >+ rsync \ >+ sed \ >+ sudo \ >+ tar \ >+ tree \ >+ uuid-dev \ >+ xfslibs-dev \ >+ xsltproc \ >+ zlib1g-dev >+ >+apt-get -y autoremove >+apt-get -y autoclean >+apt-get -y clean >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu1804/locale.sh b/bootstrap/generated-dists/ubuntu1804/locale.sh >new file mode 100755 >index 00000000000..cc64e180483 >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu1804/locale.sh >@@ -0,0 +1,55 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+# refer to /usr/share/i18n/locales >+INPUTFILE=en_US >+# refer to /usr/share/i18n/charmaps >+CHARMAP=UTF-8 >+# locale to generate in /usr/lib/locale >+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style >+LOCALE=$INPUTFILE.utf8 >+ >+# if locale is already correct, exit >+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0 >+ >+# if locale not available, generate locale into /usr/lib/locale >+if ! ( locale --all-locales | grep -i $LOCALE ) >+then >+ # no-archive means create its own dir >+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE >+fi >+ >+# update locale conf and global env file >+# set both LC_ALL and LANG for safe >+ >+# update conf for Debian family >+FILE=/etc/default/locale >+if [ -f $FILE ] >+then >+ echo LC_ALL="$LOCALE" > $FILE >+ echo LANG="$LOCALE" >> $FILE >+fi >+ >+# update conf for RedHat family >+FILE=/etc/locale.conf >+if [ -f $FILE ] >+then >+ # LC_ALL is not valid in this file, set LANG only >+ echo LANG="$LOCALE" > $FILE >+fi >+ >+# update global env file >+FILE=/etc/environment >+if [ -f $FILE ] >+then >+ # append LC_ALL if not exist >+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE >+ # append LANG if not exist >+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu1804/packages.yml b/bootstrap/generated-dists/ubuntu1804/packages.yml >new file mode 100644 >index 00000000000..edf5720f84c >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu1804/packages.yml >@@ -0,0 +1,93 @@ >+--- >+packages: >+ - acl >+ - apt-utils >+ - attr >+ - autoconf >+ - bind9utils >+ - binutils >+ - bison >+ - build-essential >+ - chrpath >+ - curl >+ - debhelper >+ - dnsutils >+ - docbook-xml >+ - docbook-xsl >+ - flex >+ - gcc >+ - gdb >+ - git >+ - glusterfs-common >+ - gzip >+ - heimdal-multidev >+ - hostname >+ - htop >+ - krb5-config >+ - krb5-kdc >+ - krb5-user >+ - language-pack-en >+ - lcov >+ - libacl1-dev >+ - libarchive-dev >+ - libattr1-dev >+ - libavahi-common-dev >+ - libblkid-dev >+ - libbsd-dev >+ - libcap-dev >+ - libcephfs-dev >+ - libcups2-dev >+ - libdbus-1-dev >+ - libglib2.0-dev >+ - libgnutls28-dev >+ - libgpgme11-dev >+ - libicu-dev >+ - libjansson-dev >+ - libjs-jquery >+ - libjson-perl >+ - libkrb5-dev >+ - libldap2-dev >+ - liblmdb-dev >+ - libncurses5-dev >+ - libpam0g-dev >+ - libparse-yapp-perl >+ - libpcap-dev >+ - libpopt-dev >+ - libreadline-dev >+ - libsystemd-dev >+ - libtasn1-bin >+ - libtasn1-dev >+ - libunwind-dev >+ - lmdb-utils >+ - locales >+ - lsb-release >+ - make >+ - mawk >+ - mingw-w64 >+ - patch >+ - perl >+ - perl-modules >+ - pkg-config >+ - procps >+ - psmisc >+ - python3 >+ - python3-cryptography >+ - python3-dbg >+ - python3-dev >+ - python3-dnspython >+ - python3-gpg >+ - python3-iso8601 >+ - python3-markdown >+ - python3-matplotlib >+ - python3-pexpect >+ - python3-pyasn1 >+ - rng-tools >+ - rsync >+ - sed >+ - sudo >+ - tar >+ - tree >+ - uuid-dev >+ - xfslibs-dev >+ - xsltproc >+ - zlib1g-dev >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu2004/Dockerfile b/bootstrap/generated-dists/ubuntu2004/Dockerfile >new file mode 100644 >index 00000000000..f94e8801aad >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu2004/Dockerfile >@@ -0,0 +1,27 @@ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+FROM ubuntu:20.04 >+ >+# pass in with --build-arg while build >+ARG SHA1SUM >+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt >+ >+ADD *.sh /tmp/ >+# need root permission, do it before USER samba >+RUN /tmp/bootstrap.sh && /tmp/locale.sh >+ >+# if ld.gold exists, force link it to ld >+RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD" >+ >+# make test can not work with root, so we have to create a new user >+RUN useradd -m -U -s /bin/bash samba && \ >+ mkdir -p /etc/sudoers.d && \ >+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba >+ >+USER samba >+WORKDIR /home/samba >+# samba tests rely on this >+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu2004/bootstrap.sh b/bootstrap/generated-dists/ubuntu2004/bootstrap.sh >new file mode 100755 >index 00000000000..e668057ea82 >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu2004/bootstrap.sh >@@ -0,0 +1,108 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+export DEBIAN_FRONTEND=noninteractive >+apt-get -y update >+ >+apt-get -y install \ >+ acl \ >+ apt-utils \ >+ attr \ >+ autoconf \ >+ bind9utils \ >+ binutils \ >+ bison \ >+ build-essential \ >+ chrpath \ >+ curl \ >+ debhelper \ >+ dnsutils \ >+ docbook-xml \ >+ docbook-xsl \ >+ flex \ >+ gcc \ >+ gdb \ >+ git \ >+ glusterfs-common \ >+ gzip \ >+ heimdal-multidev \ >+ hostname \ >+ htop \ >+ krb5-config \ >+ krb5-kdc \ >+ krb5-user \ >+ language-pack-en \ >+ lcov \ >+ libacl1-dev \ >+ libarchive-dev \ >+ libattr1-dev \ >+ libavahi-common-dev \ >+ libblkid-dev \ >+ libbsd-dev \ >+ libcap-dev \ >+ libcephfs-dev \ >+ libcups2-dev \ >+ libdbus-1-dev \ >+ libglib2.0-dev \ >+ libgnutls28-dev \ >+ libgpgme11-dev \ >+ libicu-dev \ >+ libjansson-dev \ >+ libjs-jquery \ >+ libjson-perl \ >+ libkrb5-dev \ >+ libldap2-dev \ >+ liblmdb-dev \ >+ libncurses5-dev \ >+ libpam0g-dev \ >+ libparse-yapp-perl \ >+ libpcap-dev \ >+ libpopt-dev \ >+ libreadline-dev \ >+ libsystemd-dev \ >+ libtasn1-bin \ >+ libtasn1-dev \ >+ libunwind-dev \ >+ lmdb-utils \ >+ locales \ >+ lsb-release \ >+ make \ >+ mawk \ >+ mingw-w64 \ >+ patch \ >+ perl \ >+ perl-modules \ >+ pkg-config \ >+ procps \ >+ psmisc \ >+ python3 \ >+ python3-cryptography \ >+ python3-dbg \ >+ python3-dev \ >+ python3-dnspython \ >+ python3-gpg \ >+ python3-iso8601 \ >+ python3-markdown \ >+ python3-matplotlib \ >+ python3-pexpect \ >+ python3-pyasn1 \ >+ rng-tools \ >+ rsync \ >+ sed \ >+ sudo \ >+ tar \ >+ tree \ >+ uuid-dev \ >+ xfslibs-dev \ >+ xsltproc \ >+ zlib1g-dev >+ >+apt-get -y autoremove >+apt-get -y autoclean >+apt-get -y clean >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu2004/locale.sh b/bootstrap/generated-dists/ubuntu2004/locale.sh >new file mode 100755 >index 00000000000..cc64e180483 >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu2004/locale.sh >@@ -0,0 +1,55 @@ >+#!/bin/bash >+ >+# >+# This file is generated by 'bootstrap/template.py --render' >+# See also bootstrap/config.py >+# >+ >+set -xueo pipefail >+ >+# refer to /usr/share/i18n/locales >+INPUTFILE=en_US >+# refer to /usr/share/i18n/charmaps >+CHARMAP=UTF-8 >+# locale to generate in /usr/lib/locale >+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style >+LOCALE=$INPUTFILE.utf8 >+ >+# if locale is already correct, exit >+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0 >+ >+# if locale not available, generate locale into /usr/lib/locale >+if ! ( locale --all-locales | grep -i $LOCALE ) >+then >+ # no-archive means create its own dir >+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE >+fi >+ >+# update locale conf and global env file >+# set both LC_ALL and LANG for safe >+ >+# update conf for Debian family >+FILE=/etc/default/locale >+if [ -f $FILE ] >+then >+ echo LC_ALL="$LOCALE" > $FILE >+ echo LANG="$LOCALE" >> $FILE >+fi >+ >+# update conf for RedHat family >+FILE=/etc/locale.conf >+if [ -f $FILE ] >+then >+ # LC_ALL is not valid in this file, set LANG only >+ echo LANG="$LOCALE" > $FILE >+fi >+ >+# update global env file >+FILE=/etc/environment >+if [ -f $FILE ] >+then >+ # append LC_ALL if not exist >+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE >+ # append LANG if not exist >+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE >+fi >\ No newline at end of file >diff --git a/bootstrap/generated-dists/ubuntu2004/packages.yml b/bootstrap/generated-dists/ubuntu2004/packages.yml >new file mode 100644 >index 00000000000..edf5720f84c >--- /dev/null >+++ b/bootstrap/generated-dists/ubuntu2004/packages.yml >@@ -0,0 +1,93 @@ >+--- >+packages: >+ - acl >+ - apt-utils >+ - attr >+ - autoconf >+ - bind9utils >+ - binutils >+ - bison >+ - build-essential >+ - chrpath >+ - curl >+ - debhelper >+ - dnsutils >+ - docbook-xml >+ - docbook-xsl >+ - flex >+ - gcc >+ - gdb >+ - git >+ - glusterfs-common >+ - gzip >+ - heimdal-multidev >+ - hostname >+ - htop >+ - krb5-config >+ - krb5-kdc >+ - krb5-user >+ - language-pack-en >+ - lcov >+ - libacl1-dev >+ - libarchive-dev >+ - libattr1-dev >+ - libavahi-common-dev >+ - libblkid-dev >+ - libbsd-dev >+ - libcap-dev >+ - libcephfs-dev >+ - libcups2-dev >+ - libdbus-1-dev >+ - libglib2.0-dev >+ - libgnutls28-dev >+ - libgpgme11-dev >+ - libicu-dev >+ - libjansson-dev >+ - libjs-jquery >+ - libjson-perl >+ - libkrb5-dev >+ - libldap2-dev >+ - liblmdb-dev >+ - libncurses5-dev >+ - libpam0g-dev >+ - libparse-yapp-perl >+ - libpcap-dev >+ - libpopt-dev >+ - libreadline-dev >+ - libsystemd-dev >+ - libtasn1-bin >+ - libtasn1-dev >+ - libunwind-dev >+ - lmdb-utils >+ - locales >+ - lsb-release >+ - make >+ - mawk >+ - mingw-w64 >+ - patch >+ - perl >+ - perl-modules >+ - pkg-config >+ - procps >+ - psmisc >+ - python3 >+ - python3-cryptography >+ - python3-dbg >+ - python3-dev >+ - python3-dnspython >+ - python3-gpg >+ - python3-iso8601 >+ - python3-markdown >+ - python3-matplotlib >+ - python3-pexpect >+ - python3-pyasn1 >+ - rng-tools >+ - rsync >+ - sed >+ - sudo >+ - tar >+ - tree >+ - uuid-dev >+ - xfslibs-dev >+ - xsltproc >+ - zlib1g-dev >\ No newline at end of file >diff --git a/bootstrap/sha1sum.txt b/bootstrap/sha1sum.txt >new file mode 100644 >index 00000000000..b1e6736def0 >--- /dev/null >+++ b/bootstrap/sha1sum.txt >@@ -0,0 +1 @@ >+5a03ad6f346def64a757bcd2e71dc9a5c10ceae0 >diff --git a/bootstrap/template.py b/bootstrap/template.py >new file mode 100755 >index 00000000000..e12e2e0dc82 >--- /dev/null >+++ b/bootstrap/template.py >@@ -0,0 +1,142 @@ >+#!/usr/bin/env python3 >+ >+# Copyright (C) Catalyst.Net 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 <http://www.gnu.org/licenses/>. >+ >+""" >+Manage dependencies and bootstrap environments for Samba. >+ >+CLI script to render bootstrap.sh/Dockerfile/Vagrantfile. >+ >+Author: Joe Guo <joeg@catalyst.net.nz> >+""" >+ >+import io >+import os >+import hashlib >+import logging >+import argparse >+from config import DISTS, VAGRANTFILE, OUT >+ >+HERE = os.path.abspath(os.path.dirname(__file__)) >+SHA1SUM_FILE_PATH = os.path.join(HERE, 'sha1sum.txt') >+README_FILE_PATH = os.path.join(HERE, 'READMD.md') >+ >+logging.basicConfig(level='INFO') >+log = logging.getLogger(__file__) >+ >+ >+def get_files(path): >+ """Get all files recursively in path as a list""" >+ filepaths = [] >+ for root, dirnames, filenames in os.walk(path): >+ for filename in filenames: >+ filepath = os.path.join(root, filename) >+ filepaths.append(filepath) >+ return filepaths >+ >+ >+def get_sha1sum(debug=False): >+ """Get sha1sum for dists + .gitlab-ci.yml""" >+ filepaths = get_files(HERE) >+ m = hashlib.sha1() >+ i = 0 >+ for filepath in sorted(list(filepaths)): >+ _filepath = os.path.relpath(filepath) >+ i += 1 >+ if filepath == SHA1SUM_FILE_PATH: >+ d = "skip " >+ if debug: >+ print("%s: %s: %s" % (i, d, _filepath)) >+ continue >+ if filepath == README_FILE_PATH: >+ d = "skip " >+ if debug: >+ print("%s: %s: %s" % (i, d, _filepath)) >+ continue >+ if filepath.endswith('.pyc'): >+ d = "skip " >+ if debug: >+ print("%s: %s: %s" % (i, d, _filepath)) >+ continue >+ with io.open(filepath, mode='rb') as _file: >+ _bytes = _file.read() >+ >+ m1 = hashlib.sha1() >+ m1.update(_bytes) >+ d = m1.hexdigest() >+ if debug: >+ print("%s: %s: %s" % (i, d, _filepath)) >+ >+ m.update(_bytes) >+ return m.hexdigest() >+ >+ >+def render(dists): >+ """Render files for all dists""" >+ for dist, config in dists.items(): >+ home = config['home'] >+ os.makedirs(home, exist_ok=True) >+ for key in ['bootstrap.sh', 'locale.sh', 'packages.yml', 'Dockerfile']: >+ path = os.path.join(home, key) >+ log.info('%s: render "%s" to %s', dist, key, path) >+ with io.open(path, mode='wt', encoding='utf8') as fp: >+ fp.write(config[key]) >+ if path.endswith('.sh'): >+ os.chmod(path, 0o755) >+ >+ key = 'Vagrantfile' >+ path = os.path.join(OUT, key) >+ log.info('%s: render "%s" to %s', dist, key, path) >+ with io.open(path, mode='wt', encoding='utf8') as fp: >+ fp.write(VAGRANTFILE) >+ >+ # always calc sha1sum after render >+ sha1sum = get_sha1sum() >+ log.info('write sha1sum to %s: %s', SHA1SUM_FILE_PATH, sha1sum) >+ with io.open(SHA1SUM_FILE_PATH, mode='wt', encoding='utf8') as fp: >+ fp.write(sha1sum + "\n") >+ >+ >+def main(): >+ parser = argparse.ArgumentParser( >+ formatter_class=argparse.ArgumentDefaultsHelpFormatter, >+ description=('Render templates with samba dependencies ' >+ 'to bootstrap multiple distributions.')) >+ >+ parser.add_argument( >+ '-r', '--render', action='store_true', help='Render templates') >+ >+ parser.add_argument( >+ '-s', '--sha1sum', action='store_true', help='Print sha1sum') >+ parser.add_argument( >+ '-d', '--debug', action='store_true', help='Debug sha1sum') >+ >+ args = parser.parse_args() >+ need_help = True >+ >+ if args.render: >+ render(DISTS) >+ need_help = False >+ if args.sha1sum: >+ # we will use the output to check sha1sum in ci >+ print(get_sha1sum(args.debug)) >+ need_help = False >+ if need_help: >+ parser.print_help() >+ >+ >+if __name__ == '__main__': >+ main() >-- >2.25.1 > > >From 0f3f0a8aea779c17a9ff5d823621bb79e6eabb3f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 9 Nov 2021 13:42:28 +1300 >Subject: [PATCH 677/686] CI: Update CI to use up-to-date Docker image > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > .gitlab-ci-private.yml | 26 ++++++++++++++++ > .gitlab-ci.yml | 70 ++++++++++++++++++++++++++++++++++++++++-- > 2 files changed, 94 insertions(+), 2 deletions(-) > >diff --git a/.gitlab-ci-private.yml b/.gitlab-ci-private.yml >index c3860685a80..4ebfa051364 100644 >--- a/.gitlab-ci-private.yml >+++ b/.gitlab-ci-private.yml >@@ -3,10 +3,36 @@ include: > > > .private_template: &private_template >+ # All Samba jobs are interruptible, this avoids burning CPU when a >+ # newer branch is pushed. >+ interruptible: true >+ timeout: 2h >+ >+ variables: >+ AUTOBUILD_JOB_NAME: $CI_JOB_NAME >+ image: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-${SAMBA_CI_CONTAINER_IMAGE}:${SAMBA_CI_CONTAINER_TAG} > stage: build > tags: > - docker > - private >+ before_script: >+ - uname -a >+ - lsb_release -a >+ - cat /etc/os-release >+ - lscpu >+ - cat /proc/cpuinfo >+ - mount >+ - df -h >+ - cat /proc/swaps >+ - free -h >+ # See bootstrap/.gitlab-ci.yml how to generate a new image >+ - echo "SAMBA_CI_CONTAINER_REGISTRY[${SAMBA_CI_CONTAINER_REGISTRY}]" >+ - echo "SAMBA_CI_CONTAINER_TAG[${SAMBA_CI_CONTAINER_TAG}]" >+ - bootstrap/template.py --sha1sum > /tmp/sha1sum-template.txt >+ - diff -u bootstrap/sha1sum.txt /tmp/sha1sum-template.txt >+ - echo "${SAMBA_CI_CONTAINER_TAG}" > /tmp/sha1sum-tag.txt >+ - diff -u bootstrap/sha1sum.txt /tmp/sha1sum-tag.txt >+ - diff -u bootstrap/sha1sum.txt /sha1sum.txt > > build_samba: > <<: *private_template >diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml >index 4249f5296b3..4ca16fba532 100644 >--- a/.gitlab-ci.yml >+++ b/.gitlab-ci.yml >@@ -1,10 +1,50 @@ > # see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options > >-image: registry.gitlab.com/samba-team/samba:latest >- > variables: >+ # We want to be resilient to runner failures >+ ARTIFACT_DOWNLOAD_ATTEMPTS: "3" >+ EXECUTOR_JOB_SECTION_ATTEMPTS: "3" >+ GET_SOURCES_ATTEMPTS: "3" >+ RESTORE_CACHE_ATTEMPTS: "3" >+ # > GIT_STRATEGY: fetch > GIT_DEPTH: "3" >+ # "--enable-coverage" or "" >+ SAMBA_CI_AUTOBUILD_ENABLE_COVERAGE: "" >+ # >+ # we run autobuild.py inside a samba CI docker image located on gitlab's registry >+ # overwrite this variable if you want use your own image registry. >+ # >+ # Or better ask for access to the shared development repository, see >+ # https://wiki.samba.org/index.php/Samba_CI_on_gitlab#Getting_Access >+ # >+ SAMBA_CI_CONTAINER_REGISTRY: registry.gitlab.com/samba-team/devel/samba >+ # >+ # Set this to the contents of bootstrap/sha1sum.txt >+ # which is generated by bootstrap/template.py --render >+ # >+ SAMBA_CI_CONTAINER_TAG: 5a03ad6f346def64a757bcd2e71dc9a5c10ceae0 >+ # >+ # We use the ubuntu1804 image as default as >+ # it matches what we have on sn-devel-184. >+ # >+ SAMBA_CI_CONTAINER_IMAGE: ubuntu1804 >+ # >+ # The following images are available >+ # Please see the samba-o3 sections at the end of this file! >+ # We should run that for each available image >+ # >+ SAMBA_CI_CONTAINER_IMAGE_ubuntu1604: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-ubuntu1604:${SAMBA_CI_CONTAINER_TAG} >+ SAMBA_CI_CONTAINER_IMAGE_ubuntu1804: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-ubuntu1804:${SAMBA_CI_CONTAINER_TAG} >+ SAMBA_CI_CONTAINER_IMAGE_ubuntu2004: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-ubuntu2004:${SAMBA_CI_CONTAINER_TAG} >+ SAMBA_CI_CONTAINER_IMAGE_debian9: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-debian9:${SAMBA_CI_CONTAINER_TAG} >+ SAMBA_CI_CONTAINER_IMAGE_debian10: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-debian10:${SAMBA_CI_CONTAINER_TAG} >+ SAMBA_CI_CONTAINER_IMAGE_opensuse151: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-opensuse151:${SAMBA_CI_CONTAINER_TAG} >+ SAMBA_CI_CONTAINER_IMAGE_opensuse152: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-opensuse152:${SAMBA_CI_CONTAINER_TAG} >+ SAMBA_CI_CONTAINER_IMAGE_fedora32: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-fedora32:${SAMBA_CI_CONTAINER_TAG} >+ SAMBA_CI_CONTAINER_IMAGE_fedora33: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-fedora33:${SAMBA_CI_CONTAINER_TAG} >+ SAMBA_CI_CONTAINER_IMAGE_centos7: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-centos7:${SAMBA_CI_CONTAINER_TAG} >+ SAMBA_CI_CONTAINER_IMAGE_centos8: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-centos8:${SAMBA_CI_CONTAINER_TAG} > > before_script: > - echo "Build starting..." >@@ -13,10 +53,36 @@ after_script: > - tar -xf logs.tar.gz system-info.txt -O > > .shared_template: &shared_template >+ # All Samba jobs are interruptible, this avoids burning CPU when a >+ # newer branch is pushed. >+ interruptible: true >+ timeout: 2h >+ >+ variables: >+ AUTOBUILD_JOB_NAME: $CI_JOB_NAME >+ image: ${SAMBA_CI_CONTAINER_REGISTRY}/samba-ci-${SAMBA_CI_CONTAINER_IMAGE}:${SAMBA_CI_CONTAINER_TAG} > stage: build > tags: > - docker > - shared >+ before_script: >+ - uname -a >+ - lsb_release -a >+ - cat /etc/os-release >+ - lscpu >+ - cat /proc/cpuinfo >+ - mount >+ - df -h >+ - cat /proc/swaps >+ - free -h >+ # See bootstrap/.gitlab-ci.yml how to generate a new image >+ - echo "SAMBA_CI_CONTAINER_REGISTRY[${SAMBA_CI_CONTAINER_REGISTRY}]" >+ - echo "SAMBA_CI_CONTAINER_TAG[${SAMBA_CI_CONTAINER_TAG}]" >+ - bootstrap/template.py --sha1sum > /tmp/sha1sum-template.txt >+ - diff -u bootstrap/sha1sum.txt /tmp/sha1sum-template.txt >+ - echo "${SAMBA_CI_CONTAINER_TAG}" > /tmp/sha1sum-tag.txt >+ - diff -u bootstrap/sha1sum.txt /tmp/sha1sum-tag.txt >+ - diff -u bootstrap/sha1sum.txt /sha1sum.txt > > build_samba_none_env: > <<: *shared_template >-- >2.25.1 > > >From 685ffd06ccd537da13ea1c00d74ddfc7722664a8 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 9 Nov 2021 14:19:02 +1300 >Subject: [PATCH 678/686] CI: Remove Python 2 jobs > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > .gitlab-ci-private.yml | 14 -------------- > .gitlab-ci.yml | 28 ---------------------------- > 2 files changed, 42 deletions(-) > >diff --git a/.gitlab-ci-private.yml b/.gitlab-ci-private.yml >index 4ebfa051364..1467184326d 100644 >--- a/.gitlab-ci-private.yml >+++ b/.gitlab-ci-private.yml >@@ -40,12 +40,6 @@ build_samba: > # this one takes about 4 hours to finish > - script/autobuild.py samba --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase > >-build_samba_py2: >- <<: *private_template >- script: >- # this one takes about 4 hours to finish >- - script/autobuild.py samba-py2 --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase >- > build_samba_fileserver: > <<: *private_template > script: >@@ -57,11 +51,3 @@ build_samba_ad_dc: > script: > # this one takes about 1 hours to finish > - script/autobuild.py samba-ad-dc --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase >- >- >-build_samba_ad_dc_py2: >- <<: *private_template >- script: >- # this one takes about 1 hours to finish >- - script/autobuild.py samba-ad-dc-py2 --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase >- >diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml >index 4ca16fba532..76db378f631 100644 >--- a/.gitlab-ci.yml >+++ b/.gitlab-ci.yml >@@ -90,12 +90,6 @@ build_samba_none_env: > # this one takes about 1 hours to finish > - script/autobuild.py samba-none-env --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase > >-build_samba_none_env_py2: >- <<: *shared_template >- script: >- # this one takes about 1 hours to finish >- - script/autobuild.py samba-none-env-py2 --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase >- > build_samba_nopython: > <<: *shared_template > script: >@@ -127,27 +121,11 @@ build_samba_ad_dc_backup: > script: > - script/autobuild.py samba-ad-dc-backup --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase > >-build_samba_ad_dc_backup_py2: >- <<: *shared_template >- script: >- - script/autobuild.py samba-ad-dc-backup-py2 --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase >- >-build_samba_ad_dc_2_py2: >- <<: *shared_template >- script: >- # this one takes about 1 hours to finish >- - script/autobuild.py samba-ad-dc-2-py2 --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase >- > build_samba_libs: > <<: *shared_template > script: > - script/autobuild.py samba-libs --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase > >-build_samba_libs_py2: >- <<: *shared_template >- script: >- - script/autobuild.py samba-libs-py2 --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase >- > build_samba_static: > <<: *shared_template > script: >@@ -172,9 +150,3 @@ build_others: > - script/autobuild.py talloc --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase > - script/autobuild.py tdb --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase > - script/autobuild.py tevent --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase >- >-build_samba_buildpy2_only: >- <<: *shared_template >- script: >- - python script/autobuild.py samba-buildpy2-only --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase >- >-- >2.25.1 > > >From 31540070277d01cd84fed5a210e6b4da45398a0d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 9 Nov 2021 14:04:46 +1300 >Subject: [PATCH 679/686] CI: Increase build timeout > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > .gitlab-ci-private.yml | 2 +- > .gitlab-ci.yml | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > >diff --git a/.gitlab-ci-private.yml b/.gitlab-ci-private.yml >index 1467184326d..44569461171 100644 >--- a/.gitlab-ci-private.yml >+++ b/.gitlab-ci-private.yml >@@ -6,7 +6,7 @@ include: > # All Samba jobs are interruptible, this avoids burning CPU when a > # newer branch is pushed. > interruptible: true >- timeout: 2h >+ timeout: 4h > > variables: > AUTOBUILD_JOB_NAME: $CI_JOB_NAME >diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml >index 76db378f631..55a4735f7f3 100644 >--- a/.gitlab-ci.yml >+++ b/.gitlab-ci.yml >@@ -56,7 +56,7 @@ after_script: > # All Samba jobs are interruptible, this avoids burning CPU when a > # newer branch is pushed. > interruptible: true >- timeout: 2h >+ timeout: 4h > > variables: > AUTOBUILD_JOB_NAME: $CI_JOB_NAME >-- >2.25.1 > > >From 5b750bf79cc951b10eca6a44d0ce8884294f08a5 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 9 Nov 2021 14:20:44 +1300 >Subject: [PATCH 680/686] autobuild: Add ad_dc_smb1 and ad_member_no_wss_wb > environments > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > script/autobuild.py | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > >diff --git a/script/autobuild.py b/script/autobuild.py >index f7a23d53a79..04ae99c6c2e 100755 >--- a/script/autobuild.py >+++ b/script/autobuild.py >@@ -104,11 +104,13 @@ tasks = { > "--exclude-env=nt4_member " > "--exclude-env=ad_dc " > "--exclude-env=ad_dc_no_nss " >+ "--exclude-env=ad_dc_smb1 " > "--exclude-env=fl2003dc " > "--exclude-env=fl2008r2dc " > "--exclude-env=ad_member " > "--exclude-env=ad_member_idmap_rid " > "--exclude-env=ad_member_idmap_ad " >+ "--exclude-env=ad_member_no_wss_wb " > "--exclude-env=chgdcpass " > "--exclude-env=vampire_2000_dc " > "--exclude-env=fl2000dc " >@@ -151,10 +153,12 @@ tasks = { > ("test", "make test FAIL_IMMEDIATELY=0 " > "TESTS='${PY3_ONLY}" > "--include-env=ad_dc " >+ "--include-env=ad_dc_smb1 " > "--include-env=fl2003dc " > "--include-env=fl2008r2dc " > "--include-env=ad_member " > "--include-env=ad_member_idmap_rid " >+ "--include-env=ad_member_no_wss_wb " > "--include-env=ad_member_idmap_ad'", "text/plain"), > ("check-clean-tree", "script/clean-source-tree.sh", "text/plain")], > >@@ -210,7 +214,7 @@ tasks = { > ("make", "make -j", "text/plain"), > ("test", "make quicktest FAIL_IMMEDIATELY=0 " > "TESTS='${PY3_ONLY}" >- "--include-env=ad_dc'", "text/plain"), >+ "--include-env=ad_dc --include-env=ad_dc_smb1'", "text/plain"), > ("install", "make install", "text/plain"), > ("check-clean-tree", "script/clean-source-tree.sh", "text/plain"), > ("clean", "make clean", "text/plain")], >-- >2.25.1 > > >From 3c1a5c22346293be1f6c35c9d7cd9c51d959f59e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 8 Nov 2021 16:51:16 +1300 >Subject: [PATCH 681/686] wafsamba: Allow unused functions > >This allows the IDL to compile. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > buildtools/wafsamba/samba_autoconf.py | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/buildtools/wafsamba/samba_autoconf.py b/buildtools/wafsamba/samba_autoconf.py >index a39d6ef06d1..03a2f1f057d 100644 >--- a/buildtools/wafsamba/samba_autoconf.py >+++ b/buildtools/wafsamba/samba_autoconf.py >@@ -794,6 +794,7 @@ int main(void) { > conf.ADD_LDFLAGS('-fsanitize=address', testflags=True) > conf.env['ADDRESS_SANITIZER'] = True > >+ conf.ADD_CFLAGS('-Wno-error=unused-function', testflags=True) > > # Let people pass an additional ADDITIONAL_{CFLAGS,LDFLAGS} > # environment variables which are only used the for final build. >-- >2.25.1 > > >From e647fbc6b750bef86aac8cf96962cc06e8ec412a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 8 Nov 2021 16:51:25 +1300 >Subject: [PATCH 682/686] py3compat: Add macros that may not be present in > Python 2 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > python/py3compat.h | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > >diff --git a/python/py3compat.h b/python/py3compat.h >index 89b7552c791..34de92ff834 100644 >--- a/python/py3compat.h >+++ b/python/py3compat.h >@@ -211,6 +211,27 @@ typedef struct PyModuleDef { > void init ## name(void) { PyInit_ ## name(); } \ > static PyObject *PyInit_ ## name(void) > >+/* >+ * Macros that may not be present in Python 2 >+ * >+ * https://docs.python.org/3/c-api/object.html#c.Py_RETURN_NOTIMPLEMENTED >+ * https://bugs.python.org/issue12724 >+ */ >+#ifndef Py_RETURN_NOTIMPLEMENTED >+#define Py_RETURN_NOTIMPLEMENTED return Py_INCREF(Py_NotImplemented), Py_NotImplemented >+#endif >+ >+#ifndef Py_RETURN_NONE >+#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None >+#endif >+ >+#ifndef Py_RETURN_TRUE >+#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True >+#endif >+ >+#ifndef Py_RETURN_FALSE >+#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False >+#endif > > #endif > >-- >2.25.1 > > >From 735d9384c068354f1be59882d2248e64941c0730 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 8 Nov 2021 16:51:50 +1300 >Subject: [PATCH 683/686] selftest: Only add netbios aliases to ad_member > environment > >Otherwise we get SPN collisions between environments. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > selftest/target/Samba3.pm | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 39788a7f702..86cff419b57 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -425,7 +425,6 @@ sub provision_ad_member > security = ads > workgroup = $dcvars->{DOMAIN} > realm = $dcvars->{REALM} >- netbios aliases = foo bar > template homedir = /home/%D/%G/%U > winbind scan trusted domains = no > winbind use krb5 enterprise principals = yes >@@ -616,9 +615,14 @@ sub setup_ad_member > > print "PROVISIONING AD MEMBER..."; > >+ my $extra_member_options = " >+ netbios aliases = foo bar >+"; >+ > return $self->provision_ad_member($prefix, > "LOCALADMEMBER", >- $dcvars); >+ $dcvars, >+ $extra_member_options); > } > > sub setup_ad_member_rfc2307 >-- >2.25.1 > > >From 2d73f61cc97650c1e59237f75749a3d919786379 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Sun, 7 Nov 2021 20:39:29 +1300 >Subject: [PATCH 684/686] selftest: Remove usage tests > >These currently do not all pass, and are not present in 4.10. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > python/samba/tests/usage.py | 228 ------------------------------------ > selftest/knownfail.d/usage | 28 ----- > source4/selftest/tests.py | 2 - > 3 files changed, 258 deletions(-) > delete mode 100644 python/samba/tests/usage.py > delete mode 100644 selftest/knownfail.d/usage > >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >deleted file mode 100644 >index d94186ba406..00000000000 >--- a/python/samba/tests/usage.py >+++ /dev/null >@@ -1,228 +0,0 @@ >-# Unix SMB/CIFS implementation. >-# Copyright © Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >-# >-# 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 <http://www.gnu.org/licenses/>. >- >-import os >-import sys >-import subprocess >-from samba.tests import TestCase >-from unittest import TestSuite >-import re >-import stat >- >-if 'SRCDIR_ABS' in os.environ: >- BASEDIR = os.environ['SRCDIR_ABS'] >-else: >- BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), >- '../../..')) >- >-TEST_DIRS = [ >- "bootstrap", >- "testdata", >- "ctdb", >- "dfs_server", >- "pidl", >- "auth", >- "packaging", >- "python", >- "include", >- "nsswitch", >- "libcli", >- "coverity", >- "release-scripts", >- "testprogs", >- "bin", >- "source3", >- "docs-xml", >- "buildtools", >- "file_server", >- "dynconfig", >- "source4", >- "tests", >- "libds", >- "selftest", >- "lib", >- "script", >- "traffic", >- "testsuite", >- "libgpo", >- "wintest", >- "librpc", >-] >- >- >-EXCLUDE_USAGE = { >- 'script/autobuild.py', # defaults to mount /memdisk/ >- 'script/bisect-test.py', >- 'ctdb/utils/etcd/ctdb_etcd_lock', >- 'selftest/filter-subunit', >- 'selftest/format-subunit', >- 'bin/gen_output.py', # too much output! >- 'source4/scripting/bin/gen_output.py', >- 'lib/ldb/tests/python/index.py', >- 'lib/ldb/tests/python/api.py', >- 'source4/selftest/tests.py', >- 'buildtools/bin/waf', >- 'selftest/tap2subunit', >- 'script/show_test_time', >- 'source4/scripting/bin/subunitrun', >- 'source3/selftest/tests.py', >- 'selftest/tests.py', >- 'python/samba/subunit/run.py', >- 'bin/python/samba/subunit/run.py', >- 'python/samba/tests/dcerpc/raw_protocol.py', >- 'python/samba/tests/krb5/kcrypto.py', >- 'python/samba/tests/krb5/simple_tests.py', >- 'python/samba/tests/krb5/s4u_tests.py', >- 'python/samba/tests/krb5/xrealm_tests.py', >- 'python/samba/tests/krb5/as_canonicalization_tests.py', >- 'python/samba/tests/krb5/compatability_tests.py', >- 'python/samba/tests/krb5/rfc4120_constants.py', >- 'python/samba/tests/krb5/kdc_tests.py', >- 'python/samba/tests/krb5/kdc_base_test.py', >- 'python/samba/tests/krb5/kdc_tgs_tests.py', >- 'python/samba/tests/krb5/test_ccache.py', >- 'python/samba/tests/krb5/test_ldap.py', >- 'python/samba/tests/krb5/test_rpc.py', >- 'python/samba/tests/krb5/test_smb.py', >- 'python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py', >- 'python/samba/tests/krb5/as_req_tests.py', >- 'python/samba/tests/krb5/fast_tests.py', >- 'python/samba/tests/krb5/rodc_tests.py', >- 'python/samba/tests/krb5/salt_tests.py', >- 'python/samba/tests/krb5/spn_tests.py', >- 'python/samba/tests/krb5/alias_tests.py', >- 'python/samba/tests/krb5/test_min_domain_uid.py', >-} >- >- >-EXCLUDE_DIRS = { >- 'source3/script/tests', >- 'python/examples', >- 'source4/dsdb/tests/python', >- 'bin/ab', >- 'bin/python/samba/tests', >- 'bin/python/samba/tests/dcerpc', >- 'bin/python/samba/tests/krb5', >-} >- >- >-def _init_git_file_finder(): >- """Generate a function that quickly answers the question: >- 'is this a git file?' >- """ >- git_file_cache = set() >- p = subprocess.run(['git', >- '-C', BASEDIR, >- 'ls-files', >- '-z'], >- stdout=subprocess.PIPE) >- if p.returncode == 0: >- for fn in p.stdout.split(b'\0'): >- git_file_cache.add(os.path.join(BASEDIR, fn.decode('utf-8'))) >- return git_file_cache.__contains__ >- >- >-is_git_file = _init_git_file_finder() >- >- >-def python_script_iterator(d=BASEDIR, _cache={}): >- """Generate an iterator over executable Python scripts. By default it >- walks the entire source tree. >- """ >- if d not in _cache: >- cache = {} >- _cache[d] = cache >- pyshebang = re.compile(br'#!.+python').match >- safename = re.compile(r'\W+').sub >- for subdir in TEST_DIRS: >- sd = os.path.join(d, subdir) >- for root, dirs, files in os.walk(sd, followlinks=False): >- for fn in files: >- if fn.endswith('~'): >- continue >- if fn.endswith('.inst'): >- continue >- ffn = os.path.join(root, fn) >- if not (subdir == 'bin' or is_git_file(ffn)): >- continue >- >- try: >- s = os.stat(ffn) >- except FileNotFoundError: >- continue >- if not s.st_mode & stat.S_IXUSR: >- continue >- try: >- f = open(ffn, 'rb') >- except OSError as e: >- print("could not open %s: %s" % (ffn, e)) >- continue >- line = f.read(40) >- f.close() >- if not pyshebang(line): >- continue >- name = safename('_', fn) >- while name in cache: >- name += '_' >- cache[name] = ffn >- >- return _cache[d].items() >- >- >-class PythonScriptUsageTests(TestCase): >- """Python scripts run without arguments should print a usage string, >- not fail with a traceback. >- """ >- >- @classmethod >- def initialise(cls): >- for name, filename in python_script_iterator(): >- # We add the actual tests after the class definition so we >- # can give individual names to them, so we can have a >- # knownfail list. >- fn = filename.replace(BASEDIR, '').lstrip('/') >- >- if fn in EXCLUDE_USAGE: >- print("skipping %s (EXCLUDE_USAGE)" % filename) >- continue >- >- if os.path.dirname(fn) in EXCLUDE_DIRS: >- print("skipping %s (EXCLUDE_DIRS)" % filename) >- continue >- >- def _f(self, filename=filename): >- print(filename) >- try: >- p = subprocess.Popen(['python3', filename], >- stderr=subprocess.PIPE, >- stdout=subprocess.PIPE) >- out, err = p.communicate(timeout=5) >- except OSError as e: >- self.fail("Error: %s" % e) >- except subprocess.SubprocessError as e: >- self.fail("Subprocess error: %s" % e) >- >- err = err.decode('utf-8') >- out = out.decode('utf-8') >- self.assertNotIn('Traceback', err) >- >- self.assertIn('usage', out.lower() + err.lower(), >- 'stdout:\n%s\nstderr:\n%s' % (out, err)) >- >- setattr(cls, 'test_%s' % name, _f) >- >- >-PythonScriptUsageTests.initialise() >diff --git a/selftest/knownfail.d/usage b/selftest/knownfail.d/usage >deleted file mode 100644 >index 3c526f32f22..00000000000 >--- a/selftest/knownfail.d/usage >+++ /dev/null >@@ -1,28 +0,0 @@ >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_chgtdcpass.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_compare_cc_results_py.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_demodirsync_py.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_dns_hub_py.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_findprovisionusnranges.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_get_descriptors.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_mymachinepw.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_rebuildextendeddn.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_renamedc.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_repl_cleartext_pwd_py.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_rodcdns.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_dnsupdate.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_dnsupdate_.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_sambadowngradedatabase.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_gpupdate.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_gpupdate_.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_kcc.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_kcc_.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_spnupdate.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_spnupdate_.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_upgradedns.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_upgradedns_.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_upgradeprovision.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_upgradeprovision_.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_smbstatus.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_test_s3_py.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_test_s4_howto_py.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_traffic_learner.none. >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index b54b5dedf23..02c46bb5da6 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1532,5 +1532,3 @@ planoldpythontestsuite("proclimitdc:local", > 'SOCKET_WRAPPER_DEFAULT_IFACE': 11}, > name="samba.tests.process_limits", > py3_compatible=True) >- >-planoldpythontestsuite("none", "samba.tests.usage") >-- >2.25.1 > > >From a4862487aace5e6fea590207d6704d05c9977fb9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 8 Nov 2021 17:00:26 +1300 >Subject: [PATCH 685/686] python: Only import 'cmp' if needed for Python 3 > >Otherwise we get an error. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > python/samba/samdb.py | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/python/samba/samdb.py b/python/samba/samdb.py >index 70d0ca1506b..a6f98144201 100644 >--- a/python/samba/samdb.py >+++ b/python/samba/samdb.py >@@ -35,10 +35,13 @@ from samba.common import normalise_int32 > from samba.compat import text_type > from samba.compat import binary_type > from samba.compat import get_bytes >-from samba.common import cmp >+from samba.compat import PY3 > from samba.dcerpc import security > import binascii > >+if PY3: >+ from samba.common import cmp >+ > __docformat__ = "restructuredText" > > >-- >2.25.1 > > >From 85cfeb175c71bcd6c2054f01276ce143b8e6cb07 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 8 Nov 2021 17:01:20 +1300 >Subject: [PATCH 686/686] python: Remove unneeded import > >This could import non-Python 2 code and result in syntax errors. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > python/samba/tests/dns_forwarder_helpers/dns_hub.py | 1 - > 1 file changed, 1 deletion(-) > >diff --git a/python/samba/tests/dns_forwarder_helpers/dns_hub.py b/python/samba/tests/dns_forwarder_helpers/dns_hub.py >index cf9beb7fa7a..9bd18ae77e1 100755 >--- a/python/samba/tests/dns_forwarder_helpers/dns_hub.py >+++ b/python/samba/tests/dns_forwarder_helpers/dns_hub.py >@@ -24,7 +24,6 @@ import os > import select > import socket > from samba.dcerpc import dns >-from samba.tests.dns_base import DNSTest > import samba.ndr as ndr > > if sys.version_info[0] < 3: >-- >2.25.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
abartlet
:
review+
Actions:
View
Attachments on
bug 14725
:
16930
|
16931
|
16932
|
16933
|
16943
|
16944
|
16945
|
16946
|
16947
|
16949
|
16950
| 16973 |
16982
|
16983
|
17431
|
17432