Package init

This commit is contained in:
dogsheng 2019-12-25 16:07:00 +08:00
parent e1379443d0
commit 717a2d723e
36 changed files with 4262 additions and 95 deletions

133
0001-CVE-2019-10218.patch Normal file
View File

@ -0,0 +1,133 @@
From fc6022b9b19473076c4236fdf4ac474f44ca73e2 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Mon, 5 Aug 2019 13:39:53 -0700
Subject: [PATCH 1/7] CVE-2019-10218 - s3: libsmb: Protect SMB1 client code
from evil server returned names.
Disconnect with NT_STATUS_INVALID_NETWORK_RESPONSE if so.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14071
Signed-off-by: Jeremy Allison <jra@samba.org>
---
source3/libsmb/clilist.c | 75 ++++++++++++++++++++++++++++++++++++++++
source3/libsmb/proto.h | 3 ++
2 files changed, 78 insertions(+)
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index 5cb1fce4338..4f518339e2b 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -24,6 +24,66 @@
#include "trans2.h"
#include "../libcli/smb/smbXcli_base.h"
+/****************************************************************************
+ Check if a returned directory name is safe.
+****************************************************************************/
+
+static NTSTATUS is_bad_name(bool windows_names, const char *name)
+{
+ const char *bad_name_p = NULL;
+
+ bad_name_p = strchr(name, '/');
+ if (bad_name_p != NULL) {
+ /*
+ * Windows and POSIX names can't have '/'.
+ * Server is attacking us.
+ */
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ if (windows_names) {
+ bad_name_p = strchr(name, '\\');
+ if (bad_name_p != NULL) {
+ /*
+ * Windows names can't have '\\'.
+ * Server is attacking us.
+ */
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ }
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Check if a returned directory name is safe. Disconnect if server is
+ sending bad names.
+****************************************************************************/
+
+NTSTATUS is_bad_finfo_name(const struct cli_state *cli,
+ const struct file_info *finfo)
+{
+ NTSTATUS status = NT_STATUS_OK;
+ bool windows_names = true;
+
+ if (cli->requested_posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+ windows_names = false;
+ }
+ if (finfo->name != NULL) {
+ status = is_bad_name(windows_names, finfo->name);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("bad finfo->name\n");
+ return status;
+ }
+ }
+ if (finfo->short_name != NULL) {
+ status = is_bad_name(windows_names, finfo->short_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("bad finfo->short_name\n");
+ return status;
+ }
+ }
+ return NT_STATUS_OK;
+}
+
/****************************************************************************
Calculate a safe next_entry_offset.
****************************************************************************/
@@ -492,6 +552,13 @@ static NTSTATUS cli_list_old_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
TALLOC_FREE(finfo);
return NT_STATUS_NO_MEMORY;
}
+
+ status = is_bad_finfo_name(state->cli, finfo);
+ if (!NT_STATUS_IS_OK(status)) {
+ smbXcli_conn_disconnect(state->cli->conn, status);
+ TALLOC_FREE(finfo);
+ return status;
+ }
}
*pfinfo = finfo;
return NT_STATUS_OK;
@@ -727,6 +794,14 @@ static void cli_list_trans_done(struct tevent_req *subreq)
ff_eos = true;
break;
}
+
+ status = is_bad_finfo_name(state->cli, finfo);
+ if (!NT_STATUS_IS_OK(status)) {
+ smbXcli_conn_disconnect(state->cli->conn, status);
+ tevent_req_nterror(req, status);
+ return;
+ }
+
if (!state->first && (state->mask[0] != '\0') &&
strcsequal(finfo->name, state->mask)) {
DEBUG(1, ("Error: Looping in FIND_NEXT as name %s has "
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index 2bd61b1d2c2..e708e911b97 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -722,6 +722,9 @@ NTSTATUS cli_posix_whoami(struct cli_state *cli,
/* The following definitions come from libsmb/clilist.c */
+NTSTATUS is_bad_finfo_name(const struct cli_state *cli,
+ const struct file_info *finfo);
+
NTSTATUS cli_list_old(struct cli_state *cli,const char *Mask,uint16_t attribute,
NTSTATUS (*fn)(const char *, struct file_info *,
const char *, void *), void *state);
--
2.17.1

39
0001-CVE-2019-14833.patch Normal file
View File

@ -0,0 +1,39 @@
From e6de467a763b93152eef27726957a32879268fb7 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Thu, 19 Sep 2019 11:50:01 +1200
Subject: [PATCH 3/7] CVE-2019-14833: Use utf8 characters in the unacceptable
password
This shows that the "check password script" handling has a bug.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12438
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
---
selftest/knownfail.d/unacceptable-passwords | 1 +
selftest/target/Samba4.pm | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 100644 selftest/knownfail.d/unacceptable-passwords
diff --git a/selftest/knownfail.d/unacceptable-passwords b/selftest/knownfail.d/unacceptable-passwords
new file mode 100644
index 00000000000..75fa2fc32b8
--- /dev/null
+++ b/selftest/knownfail.d/unacceptable-passwords
@@ -0,0 +1 @@
+^samba.tests.samba_tool.user_check_password_script.samba.tests.samba_tool.user_check_password_script.UserCheckPwdTestCase.test_checkpassword_unacceptable\(chgdcpass:local\)
\ No newline at end of file
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index b565d466477..d7c22ce4e23 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1986,7 +1986,7 @@ sub provision_chgdcpass($$)
my $extra_provision_options = undef;
# This environment disallows the use of this password
# (and also removes the default AD complexity checks)
- my $unacceptable_password = "widk3Dsle32jxdBdskldsk55klASKQ";
+ my $unacceptable_password = "Pa脽脽word-widk3Dsle32jxdBdskldsk55klASKQ";
push (@{$extra_provision_options}, "--dns-backend=BIND9_DLZ");
my $ret = $self->provision($prefix,
"domain controller",
--
2.17.1

33
0001-CVE-2019-14847.patch Normal file
View File

@ -0,0 +1,33 @@
From ea39bdd6293041af668f1bfdfea39a725733bad3 Mon Sep 17 00:00:00 2001
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Date: Fri, 3 May 2019 17:27:51 +1200
Subject: [PATCH 5/7] CVE-2019-14847 dsdb/modules/dirsync: ensure attrs exist
(CID 1107212)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14040
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
(cherry picked from commit 23f72c4d712f8d1fec3d67a66d477709d5b0abe2)
---
source4/dsdb/samdb/ldb_modules/dirsync.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/source4/dsdb/samdb/ldb_modules/dirsync.c b/source4/dsdb/samdb/ldb_modules/dirsync.c
index b5510eccd24..62a66fef8d4 100644
--- a/source4/dsdb/samdb/ldb_modules/dirsync.c
+++ b/source4/dsdb/samdb/ldb_modules/dirsync.c
@@ -343,6 +343,10 @@ skip:
attr = dsdb_attribute_by_lDAPDisplayName(dsc->schema,
el->name);
+ if (attr == NULL) {
+ continue;
+ }
+
keep = false;
if (attr->linkID & 1) {
--
2.17.1

92
0001-CVE-2019-3824.patch Normal file
View File

@ -0,0 +1,92 @@
From 3674b0891afb016c83763520b87e9f190dcfe884 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@fedoraproject.org>
Date: Fri, 18 Jan 2019 16:37:24 +0100
Subject: [PATCH] CVE-2019-3824 ldb: Out of bound read in ldb_wildcard_compare
There is valgrind error in few tests tests/test-generic.sh
91 echo "Test wildcard match"
92 $VALGRIND ldbadd $LDBDIR/tests/test-wildcard.ldif || exit 1
93 $VALGRIND ldbsearch '(cn=test*multi)' || exit 1
95 $VALGRIND ldbsearch '(cn=*test_multi)' || exit 1
97 $VALGRIND ldbsearch '(cn=test*multi*test*multi)' || exit 1
e.g.
==3098== Memcheck, a memory error detector
==3098== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3098== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==3098== Command: ./bin/ldbsearch (cn=test*multi)
==3098==
==3098== Invalid read of size 1
==3098== at 0x483CEE7: memchr (vg_replace_strmem.c:890)
==3098== by 0x49A9073: memmem (in /usr/lib64/libc-2.28.9000.so)
==3098== by 0x485DFE9: ldb_wildcard_compare (ldb_match.c:313)
==3098== by 0x485DFE9: ldb_match_substring (ldb_match.c:360)
==3098== by 0x485DFE9: ldb_match_message (ldb_match.c:572)
==3098== by 0x558F8FA: search_func (ldb_kv_search.c:549)
==3098== by 0x48C78CA: ??? (in /usr/lib64/libtdb.so.1.3.17)
==3098== by 0x48C7A60: tdb_traverse_read (in /usr/lib64/libtdb.so.1.3.17)
==3098== by 0x557B7C4: ltdb_traverse_fn (ldb_tdb.c:274)
==3098== by 0x558FBFA: ldb_kv_search_full (ldb_kv_search.c:594)
==3098== by 0x558FBFA: ldb_kv_search (ldb_kv_search.c:854)
==3098== by 0x558E497: ldb_kv_callback (ldb_kv.c:1713)
==3098== by 0x48FCD58: tevent_common_invoke_timer_handler (in /usr/lib64/libtevent.so.0.9.38)
==3098== by 0x48FCEFD: tevent_common_loop_timer_delay (in /usr/lib64/libtevent.so.0.9.38)
==3098== by 0x48FE14A: ??? (in /usr/lib64/libtevent.so.0.9.38)
==3098== Address 0x4b4ab81 is 0 bytes after a block of size 129 alloc'd
==3098== at 0x483880B: malloc (vg_replace_malloc.c:309)
==3098== by 0x491048B: talloc_strndup (in /usr/lib64/libtalloc.so.2.1.15)
==3098== by 0x48593CA: ldb_casefold_default (ldb_utf8.c:59)
==3098== by 0x485F68D: ldb_handler_fold (attrib_handlers.c:64)
==3098== by 0x485DB88: ldb_wildcard_compare (ldb_match.c:257)
==3098== by 0x485DB88: ldb_match_substring (ldb_match.c:360)
==3098== by 0x485DB88: ldb_match_message (ldb_match.c:572)
==3098== by 0x558F8FA: search_func (ldb_kv_search.c:549)
==3098== by 0x48C78CA: ??? (in /usr/lib64/libtdb.so.1.3.17)
==3098== by 0x48C7A60: tdb_traverse_read (in /usr/lib64/libtdb.so.1.3.17)
==3098== by 0x557B7C4: ltdb_traverse_fn (ldb_tdb.c:274)
==3098== by 0x558FBFA: ldb_kv_search_full (ldb_kv_search.c:594)
==3098== by 0x558FBFA: ldb_kv_search (ldb_kv_search.c:854)
==3098== by 0x558E497: ldb_kv_callback (ldb_kv.c:1713)
==3098== by 0x48FCD58: tevent_common_invoke_timer_handler (in /usr/lib64/libtevent.so.0.9.38)
==3098==
# record 1
dn: cn=test_multi_test_multi_test_multi,o=University of Michigan,c=TEST
cn: test_multi_test_multi_test_multi
description: test multi wildcards matching
objectclass: person
sn: multi_test
name: test_multi_test_multi_test_multi
distinguishedName: cn=test_multi_test_multi_test_multi,o=University of Michiga
n,c=TEST
# returned 1 records
# 1 entries
# 0 referrals
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13773
Signed-off-by: Lukas Slebodnik <lslebodn@fedoraproject.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
---
lib/ldb/common/ldb_match.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c
index 25fe3f9c21b..8eeedfb12e0 100644
--- a/lib/ldb/common/ldb_match.c
+++ b/lib/ldb/common/ldb_match.c
@@ -308,9 +308,10 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
if (p == NULL) 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 */
g = memmem(p + cnk.length,
- val.length - (p - val.data),
+ end - (p + cnk.length),
(const uint8_t *)cnk.data,
cnk.length);
if (g) p = g;
--
2.24.0

36
0002-CVE-2019-10218.patch Normal file
View File

@ -0,0 +1,36 @@
From 167f78aa97af6502cb2027dc9dad40399b0a9c4f Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 6 Aug 2019 12:08:09 -0700
Subject: [PATCH 2/7] CVE-2019-10218 - s3: libsmb: Protect SMB2 client code
from evil server returned names.
Disconnect with NT_STATUS_INVALID_NETWORK_RESPONSE if so.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14071
Signed-off-by: Jeremy Allison <jra@samba.org>
---
source3/libsmb/cli_smb2_fnum.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index 1cfa50ffbac..3cdf68dc24b 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -1017,6 +1017,13 @@ NTSTATUS cli_smb2_list(struct cli_state *cli,
goto fail;
}
+ /* Protect against server attack. */
+ status = is_bad_finfo_name(cli, finfo);
+ if (!NT_STATUS_IS_OK(status)) {
+ smbXcli_conn_disconnect(cli->conn, status);
+ goto fail;
+ }
+
if (dir_check_ftype((uint32_t)finfo->mode,
(uint32_t)attribute)) {
/*
--
2.17.1

105
0002-CVE-2019-14833.patch Normal file
View File

@ -0,0 +1,105 @@
From 70078d4ddf3b842eeadee058dadeef82ec4edf0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Baumbach?= <bb@sernet.de>
Date: Tue, 6 Aug 2019 16:32:32 +0200
Subject: [PATCH 4/7] CVE-2019-14833 dsdb: send full password to check password
script
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
utf8_len represents the number of characters (not bytes) of the
password. If the password includes multi-byte characters it is required
to write the total number of bytes to the check password script.
Otherwise the last bytes of the password string would be ignored.
Therefore we rename utf8_len to be clear what it does and does
not represent.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12438
Signed-off-by: Bj枚rn Baumbach <bb@sernet.de>
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
---
selftest/knownfail.d/unacceptable-passwords | 1 -
source4/dsdb/common/util.c | 33 +++++++++++++++++----
2 files changed, 27 insertions(+), 7 deletions(-)
delete mode 100644 selftest/knownfail.d/unacceptable-passwords
diff --git a/selftest/knownfail.d/unacceptable-passwords b/selftest/knownfail.d/unacceptable-passwords
deleted file mode 100644
index 75fa2fc32b8..00000000000
--- a/selftest/knownfail.d/unacceptable-passwords
+++ /dev/null
@@ -1 +0,0 @@
-^samba.tests.samba_tool.user_check_password_script.samba.tests.samba_tool.user_check_password_script.UserCheckPwdTestCase.test_checkpassword_unacceptable\(chgdcpass:local\)
\ No newline at end of file
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 18f700370a3..c7893bff43b 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2088,21 +2088,36 @@ enum samr_ValidationStatus samdb_check_password(TALLOC_CTX *mem_ctx,
const uint32_t pwdProperties,
const uint32_t minPwdLength)
{
- const char *utf8_pw = (const char *)utf8_blob->data;
- size_t utf8_len = strlen_m(utf8_pw);
char *password_script = NULL;
+ const char *utf8_pw = (const char *)utf8_blob->data;
+
+ /*
+ * This looks strange because it is.
+ *
+ * The check for the number of characters in the password
+ * should clearly not be against the byte length, or else a
+ * single UTF8 character would count for more than one.
+ *
+ * We have chosen to use the number of 16-bit units that the
+ * password encodes to as the measure of length. This is not
+ * the same as the number of codepoints, if a password
+ * contains a character beyond the Basic Multilingual Plane
+ * (above 65535) it will count for more than one "character".
+ */
+
+ size_t password_characters_roughly = strlen_m(utf8_pw);
/* checks if the "minPwdLength" property is satisfied */
- if (minPwdLength > utf8_len) {
+ if (minPwdLength > password_characters_roughly) {
return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
}
- /* checks the password complexity */
+ /* We might not be asked to check the password complexity */
if (!(pwdProperties & DOMAIN_PASSWORD_COMPLEX)) {
return SAMR_VALIDATION_STATUS_SUCCESS;
}
- if (utf8_len == 0) {
+ if (password_characters_roughly == 0) {
return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
}
@@ -2110,6 +2125,7 @@ enum samr_ValidationStatus samdb_check_password(TALLOC_CTX *mem_ctx,
if (password_script != NULL && *password_script != '\0') {
int check_ret = 0;
int error = 0;
+ ssize_t nwritten = 0;
struct tevent_context *event_ctx = NULL;
struct tevent_req *req = NULL;
struct samba_runcmd_state *run_cmd = NULL;
@@ -2134,7 +2150,12 @@ enum samr_ValidationStatus samdb_check_password(TALLOC_CTX *mem_ctx,
tevent_timeval_current_ofs(10, 0),
100, 100, cmd, NULL);
run_cmd = tevent_req_data(req, struct samba_runcmd_state);
- if (write(run_cmd->fd_stdin, utf8_pw, utf8_len) != utf8_len) {
+ nwritten = write(run_cmd->fd_stdin,
+ utf8_blob->data,
+ utf8_blob->length);
+ if (nwritten != utf8_blob->length) {
+ close(run_cmd->fd_stdin);
+ run_cmd->fd_stdin = -1;
TALLOC_FREE(password_script);
TALLOC_FREE(event_ctx);
return SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR;
--
2.17.1

72
0002-CVE-2019-14847.patch Normal file
View File

@ -0,0 +1,72 @@
From bdb3e3f669bd991da819040e726e003e4e2b841d Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Tue, 15 Oct 2019 16:28:46 +1300
Subject: [PATCH 6/7] CVE-2019-14847 dsdb: Demonstrate the correct interaction
of ranged_results style attributes and dirsync
Incremental results are provided by a flag on the dirsync control, not
by changing the attribute name.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14040
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
---
selftest/knownfail.d/dirsync | 1 +
source4/dsdb/tests/python/dirsync.py | 26 ++++++++++++++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 selftest/knownfail.d/dirsync
diff --git a/selftest/knownfail.d/dirsync b/selftest/knownfail.d/dirsync
new file mode 100644
index 00000000000..bc49fe0d9bb
--- /dev/null
+++ b/selftest/knownfail.d/dirsync
@@ -0,0 +1 @@
+^samba4.ldap.dirsync.python\(ad_dc_ntvfs\).__main__.ExtendedDirsyncTests.test_dirsync_linkedattributes_range\(
\ No newline at end of file
diff --git a/source4/dsdb/tests/python/dirsync.py b/source4/dsdb/tests/python/dirsync.py
index 136f4d3bba6..b6f7022a50b 100755
--- a/source4/dsdb/tests/python/dirsync.py
+++ b/source4/dsdb/tests/python/dirsync.py
@@ -28,6 +28,7 @@ from samba.tests.subunitrun import TestProgram, SubunitOptions
import samba.getopt as options
import base64
+import ldb
from ldb import LdbError, SCOPE_BASE
from ldb import Message, MessageElement, Dn
from ldb import FLAG_MOD_ADD, FLAG_MOD_DELETE
@@ -590,6 +591,31 @@ class SimpleDirsyncTests(DirsyncBaseTests):
class ExtendedDirsyncTests(SimpleDirsyncTests):
+ def test_dirsync_linkedattributes_range(self):
+ self.ldb_simple = self.get_ldb_connection(self.simple_user, self.user_pass)
+ res = self.ldb_admin.search(self.base_dn,
+ attrs=["member;range=1-1"],
+ expression="(name=Administrators)",
+ controls=["dirsync:1:0:0"])
+
+ self.assertTrue(len(res) > 0)
+ self.assertTrue(res[0].get("member;range=1-1") is None)
+ self.assertTrue(res[0].get("member") is not None)
+ self.assertTrue(len(res[0].get("member")) > 0)
+
+ def test_dirsync_linkedattributes_range_user(self):
+ self.ldb_simple = self.get_ldb_connection(self.simple_user, self.user_pass)
+ try:
+ res = self.ldb_simple.search(self.base_dn,
+ attrs=["member;range=1-1"],
+ expression="(name=Administrators)",
+ controls=["dirsync:1:0:0"])
+ except LdbError as e:
+ (num, _) = e.args
+ self.assertEquals(num, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS)
+ else:
+ self.fail()
+
def test_dirsync_linkedattributes(self):
flag_incr_linked = 2147483648
self.ldb_simple = self.get_ldb_connection(self.simple_user, self.user_pass)
--
2.17.1

56
0002-CVE-2019-3824.patch Normal file
View File

@ -0,0 +1,56 @@
From 745b99fc6b75db33cdb0a58df1a3f2a5063bc76e Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Mon, 4 Feb 2019 11:22:34 +1300
Subject: [PATCH] CVE-2019-3824 ldb: Extra comments to clarify no pointer wrap
in wildcard processing
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13773
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
---
lib/ldb/common/ldb_match.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c
index 8eeedfb12e0..1920b661f75 100644
--- a/lib/ldb/common/ldb_match.c
+++ b/lib/ldb/common/ldb_match.c
@@ -306,12 +306,33 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
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 ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) {
uint8_t *g;
uint8_t *end = val.data + val.length;
do { /* greedy */
- g = memmem(p + cnk.length,
- end - (p + cnk.length),
+
+ /*
+ * 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;
--
2.24.0

112
0003-CVE-2019-14847.patch Normal file
View File

@ -0,0 +1,112 @@
From 77b10b360f4ffb7ac90bc5fce0a80306515c1aca Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Tue, 15 Oct 2019 15:44:34 +1300
Subject: [PATCH 7/7] CVE-2019-14847 dsdb: Correct behaviour of ranged_results
when combined with dirsync
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14040
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
---
selftest/knownfail.d/dirsync | 1 -
source4/dsdb/samdb/ldb_modules/dirsync.c | 11 ++++----
.../dsdb/samdb/ldb_modules/ranged_results.c | 25 ++++++++++++++++---
3 files changed, 28 insertions(+), 9 deletions(-)
delete mode 100644 selftest/knownfail.d/dirsync
diff --git a/selftest/knownfail.d/dirsync b/selftest/knownfail.d/dirsync
deleted file mode 100644
index bc49fe0d9bb..00000000000
--- a/selftest/knownfail.d/dirsync
+++ /dev/null
@@ -1 +0,0 @@
-^samba4.ldap.dirsync.python\(ad_dc_ntvfs\).__main__.ExtendedDirsyncTests.test_dirsync_linkedattributes_range\(
\ No newline at end of file
diff --git a/source4/dsdb/samdb/ldb_modules/dirsync.c b/source4/dsdb/samdb/ldb_modules/dirsync.c
index 62a66fef8d4..4ac5faad403 100644
--- a/source4/dsdb/samdb/ldb_modules/dirsync.c
+++ b/source4/dsdb/samdb/ldb_modules/dirsync.c
@@ -998,7 +998,7 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req
}
/*
- * check if there's an extended dn control
+ * check if there's a dirsync control
*/
control = ldb_request_get_control(req, LDB_CONTROL_DIRSYNC_OID);
if (control == NULL) {
@@ -1327,11 +1327,12 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req
}
/*
- * Remove our control from the list of controls
+ * Mark dirsync control as uncritical (done)
+ *
+ * We need this so ranged_results knows how to behave with
+ * dirsync
*/
- if (!ldb_save_controls(control, req, NULL)) {
- return ldb_operr(ldb);
- }
+ control->critical = false;
dsc->schema = dsdb_get_schema(ldb, dsc);
/*
* At the begining we make the hypothesis that we will return a complete
diff --git a/source4/dsdb/samdb/ldb_modules/ranged_results.c b/source4/dsdb/samdb/ldb_modules/ranged_results.c
index 13bf3a2d0a9..98438799997 100644
--- a/source4/dsdb/samdb/ldb_modules/ranged_results.c
+++ b/source4/dsdb/samdb/ldb_modules/ranged_results.c
@@ -35,14 +35,14 @@
struct rr_context {
struct ldb_module *module;
struct ldb_request *req;
+ bool dirsync_in_use;
};
static struct rr_context *rr_init_context(struct ldb_module *module,
struct ldb_request *req)
{
- struct rr_context *ac;
-
- ac = talloc_zero(req, struct rr_context);
+ struct ldb_control *dirsync_control = NULL;
+ struct rr_context *ac = talloc_zero(req, struct rr_context);
if (ac == NULL) {
ldb_set_errstring(ldb_module_get_ctx(module), "Out of Memory");
return NULL;
@@ -51,6 +51,16 @@ static struct rr_context *rr_init_context(struct ldb_module *module,
ac->module = module;
ac->req = req;
+ /*
+ * check if there's a dirsync control (as there is an
+ * interaction between these modules)
+ */
+ dirsync_control = ldb_request_get_control(req,
+ LDB_CONTROL_DIRSYNC_OID);
+ if (dirsync_control != NULL) {
+ ac->dirsync_in_use = true;
+ }
+
return ac;
}
@@ -82,6 +92,15 @@ static int rr_search_callback(struct ldb_request *req, struct ldb_reply *ares)
ares->response, ares->error);
}
+ if (ac->dirsync_in_use) {
+ /*
+ * We return full attribute values when mixed with
+ * dirsync
+ */
+ return ldb_module_send_entry(ac->req,
+ ares->message,
+ ares->controls);
+ }
/* LDB_REPLY_ENTRY */
temp_ctx = talloc_new(ac->req);
--
2.17.1

35
0003-CVE-2019-3824.patch Normal file
View File

@ -0,0 +1,35 @@
From 9427806f7298d71bd7edfbdda7506ec63f15dda1 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Mon, 4 Feb 2019 11:22:50 +1300
Subject: [PATCH] CVE-2019-3824 ldb: Improve code style and layout in wildcard
processing
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13773
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
---
lib/ldb/common/ldb_match.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c
index 1920b661f75..ab0a89888f0 100644
--- a/lib/ldb/common/ldb_match.c
+++ b/lib/ldb/common/ldb_match.c
@@ -333,9 +333,11 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
g = memmem(haystack,
haystacklen,
- (const uint8_t *)cnk.data,
- cnk.length);
- if (g) p = g;
+ (const uint8_t *)cnk.data,
+ cnk.length);
+ if (g) {
+ p = g;
+ }
} while(g);
}
val.length = val.length - (p - (uint8_t *)(val.data)) - cnk.length;
--
2.24.0

32
0004-CVE-2019-3824.patch Normal file
View File

@ -0,0 +1,32 @@
From 8d34d172092f71baad0d777567e49aebfa07313d Mon Sep 17 00:00:00 2001
From: Gary Lockyer <gary@catalyst.net.nz>
Date: Tue, 19 Feb 2019 10:25:24 +1300
Subject: [PATCH] CVE-2019-3824 ldb: ldb_parse_tree use talloc_zero
Initialise the created ldb_parse_tree with talloc_zero, this ensures
that it is correctly initialised if inadvertently passed to a function
expecting a different operation type.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13773
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
lib/ldb/common/ldb_parse.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/ldb/common/ldb_parse.c b/lib/ldb/common/ldb_parse.c
index 5fa5a74afa9..db420091311 100644
--- a/lib/ldb/common/ldb_parse.c
+++ b/lib/ldb/common/ldb_parse.c
@@ -389,7 +389,7 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char *
struct ldb_parse_tree *ret;
enum ldb_parse_op filtertype;
- ret = talloc(mem_ctx, struct ldb_parse_tree);
+ ret = talloc_zero(mem_ctx, struct ldb_parse_tree);
if (!ret) {
errno = ENOMEM;
return NULL;
--
2.24.0

38
0005-CVE-2019-3824.patch Normal file
View File

@ -0,0 +1,38 @@
From 34383981a0c40860f71a4451ff8fd752e1b67666 Mon Sep 17 00:00:00 2001
From: Gary Lockyer <gary@catalyst.net.nz>
Date: Tue, 19 Feb 2019 10:26:25 +1300
Subject: [PATCH] CVE-2019-3824 ldb: wildcard_match check tree operation
Check the operation type of the passed parse tree, and return
LDB_INAPPROPRIATE_MATCH if the operation is not LDB_OP_SUBSTRING.
A query of "attribute=*" gets parsed as LDB_OP_PRESENT, checking the
operation and failing ldb_wildcard_match should help prevent confusion
writing tests.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13773
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
lib/ldb/common/ldb_match.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c
index ab0a89888f0..59f48b52b70 100644
--- a/lib/ldb/common/ldb_match.c
+++ b/lib/ldb/common/ldb_match.c
@@ -244,6 +244,11 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
uint8_t *save_p = NULL;
unsigned int c = 0;
+ if (tree->operation != LDB_OP_SUBSTRING) {
+ *matched = false;
+ return LDB_ERR_INAPPROPRIATE_MATCHING;
+ }
+
a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr);
if (!a) {
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
--
2.24.0

34
0006-CVE-2019-3824.patch Normal file
View File

@ -0,0 +1,34 @@
From 42f0f57eb819ce6b68a8c5b3b53123b83ec917e3 Mon Sep 17 00:00:00 2001
From: Gary Lockyer <gary@catalyst.net.nz>
Date: Tue, 19 Feb 2019 10:26:56 +1300
Subject: [PATCH] CVE-2019-3824 ldb: wildcard_match end of data check
ldb_handler_copy and ldb_val_dup over allocate by one and add a trailing '\0'
to the data, to make them safe to use the C string functions on.
However testing for the trailing '\0' is not the correct way to test for
the end of a value, the length should be checked instead.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13773
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
lib/ldb/common/ldb_match.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c
index 59f48b52b70..829afa77e71 100644
--- a/lib/ldb/common/ldb_match.c
+++ b/lib/ldb/common/ldb_match.c
@@ -353,7 +353,7 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
}
/* last chunk may not have reached end of string */
- if ( (! tree->u.substring.end_with_wildcard) && (*(val.data) != 0) ) goto mismatch;
+ if ( (! tree->u.substring.end_with_wildcard) && (val.length != 0) ) goto mismatch;
talloc_free(save_p);
*matched = true;
return LDB_SUCCESS;
--
2.24.0

270
0007-CVE-2019-3824.patch Normal file
View File

@ -0,0 +1,270 @@
From 45b75db50f5c1a7c8c38af59a62fccee5401c845 Mon Sep 17 00:00:00 2001
From: Gary Lockyer <gary@catalyst.net.nz>
Date: Tue, 19 Feb 2019 10:24:38 +1300
Subject: [PATCH] CVE-2019-3824 ldb: Add tests for ldb_wildcard_match
Add cmocka tests for ldb_wildcard_match.
Running test_wildcard_match under valgrind reproduces
CVE-2019-3824 out of bounds read in wildcard compare (bug 13773)
valgrind --suppressions=lib/ldb/tests/ldb_match_test.valgrind\
bin/ldb_match_test
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13773
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
lib/ldb/tests/ldb_match_test.c | 191 ++++++++++++++++++++++++++
lib/ldb/tests/ldb_match_test.valgrind | 16 +++
lib/ldb/wscript | 8 +-
3 files changed, 214 insertions(+), 1 deletion(-)
create mode 100644 lib/ldb/tests/ldb_match_test.c
create mode 100644 lib/ldb/tests/ldb_match_test.valgrind
diff --git a/lib/ldb/tests/ldb_match_test.c b/lib/ldb/tests/ldb_match_test.c
new file mode 100644
index 00000000000..e09f50c86ba
--- /dev/null
+++ b/lib/ldb/tests/ldb_match_test.c
@@ -0,0 +1,191 @@
+/*
+ * Tests exercising the ldb match operations.
+ *
+ *
+ * Copyright (C) Catalyst.NET Ltd 2017
+ *
+ * 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/>.
+ *
+ */
+
+/*
+ * from cmocka.c:
+ * These headers or their equivalents should be included prior to
+ * including
+ * this header file.
+ *
+ * #include <stdarg.h>
+ * #include <stddef.h>
+ * #include <setjmp.h>
+ *
+ * This allows test applications to use custom definitions of C standard
+ * library functions and types.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "../common/ldb_match.c"
+
+#include "../include/ldb.h"
+
+struct ldbtest_ctx {
+ struct tevent_context *ev;
+ struct ldb_context *ldb;
+};
+
+static int ldb_test_canonicalise(
+ struct ldb_context *ldb,
+ void *mem_ctx,
+ const struct ldb_val *in,
+ struct ldb_val *out)
+{
+ out->length = in->length;
+ out->data = in->data;
+ return 0;
+}
+
+static int setup(void **state)
+{
+ struct ldbtest_ctx *test_ctx;
+ struct ldb_schema_syntax *syntax = NULL;
+ int ret;
+
+ test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
+ assert_non_null(test_ctx);
+
+ test_ctx->ev = tevent_context_init(test_ctx);
+ assert_non_null(test_ctx->ev);
+
+ test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
+ assert_non_null(test_ctx->ldb);
+
+ syntax = talloc_zero(test_ctx, struct ldb_schema_syntax);
+ assert_non_null(syntax);
+ syntax->canonicalise_fn = ldb_test_canonicalise;
+
+ ret = ldb_schema_attribute_add_with_syntax(
+ test_ctx->ldb, "a", LDB_ATTR_FLAG_FIXED, syntax);
+ assert_int_equal(LDB_SUCCESS, ret);
+
+ *state = test_ctx;
+ return 0;
+}
+
+static int teardown(void **state)
+{
+ talloc_free(*state);
+ return 0;
+}
+
+
+/*
+ * The wild card pattern "attribute=*" is parsed as an LDB_OP_PRESENT operation
+ * rather than a LDB_OP_????
+ *
+ * This test serves to document that behaviour, and to confirm that
+ * ldb_wildcard_compare handles this case appropriately.
+ */
+static void test_wildcard_match_star(void **state)
+{
+ struct ldbtest_ctx *ctx = *state;
+ bool matched = false;
+ int ret;
+
+ uint8_t value[] = "The value.......end";
+ struct ldb_val val = {
+ .data = value,
+ .length = (sizeof(value))
+ };
+ struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "a=*");
+ assert_non_null(tree);
+
+ ret = ldb_wildcard_compare(ctx->ldb, tree, val, &matched);
+ assert_false(matched);
+ assert_int_equal(LDB_ERR_INAPPROPRIATE_MATCHING, ret);
+}
+
+/*
+ * Test basic wild card matching
+ *
+ */
+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))
+ };
+ 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);
+}
+
+
+/*
+ * ldb_handler_copy and ldb_val_dup over allocate by one and add a trailing '\0'
+ * to the data, to make them safe to use the C string functions on.
+ *
+ * However testing for the trailing '\0' is not the correct way to test for
+ * the end of a value, the length should be checked instead.
+ */
+static void test_wildcard_match_end_condition(void **state)
+{
+ struct ldbtest_ctx *ctx = *state;
+ bool matched = false;
+
+ uint8_t value[] = "hellomynameisbobx";
+ struct ldb_val val = {
+ .data = talloc_memdup(NULL, value, sizeof(value)),
+ .length = (sizeof(value) - 2)
+ };
+ struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "a=*hello*mynameis*bob");
+ assert_non_null(tree);
+
+ ldb_wildcard_compare(ctx->ldb, tree, val, &matched);
+ assert_true(matched);
+}
+
+/*
+ * Note: to run under valgrind use:
+ * valgrind \
+ * --suppressions=lib/ldb/tests/ldb_match_test.valgrind \
+ * bin/ldb_match_test
+ */
+int main(int argc, const char **argv)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(
+ test_wildcard_match_star,
+ setup,
+ teardown),
+ cmocka_unit_test_setup_teardown(
+ test_wildcard_match,
+ setup,
+ teardown),
+ cmocka_unit_test_setup_teardown(
+ test_wildcard_match_end_condition,
+ setup,
+ teardown),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/lib/ldb/tests/ldb_match_test.valgrind b/lib/ldb/tests/ldb_match_test.valgrind
new file mode 100644
index 00000000000..660bd5a6b46
--- /dev/null
+++ b/lib/ldb/tests/ldb_match_test.valgrind
@@ -0,0 +1,16 @@
+{
+ Memory allocated in set-up
+ Memcheck:Leak
+ match-leak-kinds: possible
+ fun:malloc
+ ...
+ fun:setup
+}
+{
+ Memory allocated by ldb_init
+ Memcheck:Leak
+ match-leak-kinds: possible
+ fun:malloc
+ ...
+ fun:ldb_init
+}
diff --git a/lib/ldb/wscript b/lib/ldb/wscript
index 6e224e7b4b7..5355585f69c 100644
--- a/lib/ldb/wscript
+++ b/lib/ldb/wscript
@@ -500,6 +500,11 @@ def build(bld):
deps='cmocka ldb',
install=False)
+ bld.SAMBA_BINARY('ldb_match_test',
+ source='tests/ldb_match_test.c',
+ deps='cmocka ldb',
+ install=False)
+
if bld.CONFIG_SET('HAVE_LMDB'):
bld.SAMBA_BINARY('ldb_mdb_mod_op_test',
source='tests/ldb_mod_op_test.c',
@@ -567,7 +572,8 @@ def test(ctx):
# we don't want to run ldb_lmdb_size_test (which proves we can
# 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_mdb_kv_ops_test',
+ 'ldb_match_test']
for test_exe in test_exes:
cmd = os.path.join(Utils.g_module.blddir, test_exe)

398
CVE-2018-16852-1.patch Normal file
View File

@ -0,0 +1,398 @@
From f40e1b3b42ce23b574a4c530545ff8170ddc7330 Mon Sep 17 00:00:00 2001
From: Gary Lockyer <gary@catalyst.net.nz>
Date: Tue, 6 Nov 2018 12:10:07 +1300
Subject: [PATCH 04/17] CVE-2018-16852 dcerpc dnsserver: Verification tests
Tests to verify
Bug 13669 - (CVE-2018-16852) NULL
pointer de-reference in Samba AD DC DNS management
The presence of the ZONE_MASTER_SERVERS property or the
ZONE_SCAVENGING_SERVERS property in a zone record causes the server to
follow a null pointer and terminate.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13669
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
---
selftest/knownfail.d/bug13669 | 4 +
.../tests/rpc_dns_server_dnsutils_test.c | 304 ++++++++++++++++++
source4/rpc_server/wscript_build | 17 +-
source4/selftest/tests.py | 2 +
4 files changed, 325 insertions(+), 2 deletions(-)
create mode 100644 selftest/knownfail.d/bug13669
create mode 100644 source4/rpc_server/tests/rpc_dns_server_dnsutils_test.c
diff --git a/selftest/knownfail.d/bug13669 b/selftest/knownfail.d/bug13669
new file mode 100644
index 00000000000..74c8c130674
--- /dev/null
+++ b/selftest/knownfail.d/bug13669
@@ -0,0 +1,4 @@
+^samba4.dcerpc.dnsserver.dnsutils.test_dnsserver_init_zoneinfo_master_servers_empty
+^samba4.dcerpc.dnsserver.dnsutils.test_dnsserver_init_zoneinfo_master_servers
+^samba4.dcerpc.dnsserver.dnsutils.test_dnsserver_init_zoneinfo_scavenging_servers_empty
+^samba4.dcerpc.dnsserver.dnsutils.test_dnsserver_init_zoneinfo_scavenging_servers
diff --git a/source4/rpc_server/tests/rpc_dns_server_dnsutils_test.c b/source4/rpc_server/tests/rpc_dns_server_dnsutils_test.c
new file mode 100644
index 00000000000..89721135658
--- /dev/null
+++ b/source4/rpc_server/tests/rpc_dns_server_dnsutils_test.c
@@ -0,0 +1,304 @@
+/*
+ * Unit tests for source4/rpc_server/dnsserver/dnsutils.c
+ *
+ * Copyright (C) Catalyst.NET Ltd 2018
+ *
+ * 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/>.
+ *
+ */
+
+/*
+ * from cmocka.c:
+ * These headers or their equivalents should be included prior to
+ * including
+ * this header file.
+ *
+ * #include <stdarg.h>
+ * #include <stddef.h>
+ * #include <setjmp.h>
+ *
+ * This allows test applications to use custom definitions of C standard
+ * library functions and types.
+ *
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+
+#include "../dnsserver/dnsutils.c"
+
+
+/*
+ * Test setting of an empty ZONE_MASTER_SERVERS property
+ */
+static void test_dnsserver_init_zoneinfo_master_servers_empty(void **state)
+{
+ struct dnsserver_zone *zone = NULL;
+ struct dnsserver_serverinfo *serverinfo = NULL;
+ struct dnsserver_zoneinfo *zoneinfo = NULL;
+ struct dnsp_DnsProperty *property = NULL;
+
+ TALLOC_CTX *ctx = talloc_new(NULL);
+
+ /*
+ * Setup the zone data
+ */
+ zone = talloc_zero(ctx, struct dnsserver_zone);
+ assert_non_null(zone);
+ zone->name = "test";
+
+ /*
+ * Set up an empty ZONE_MASTER_SERVERS property
+ */
+ property = talloc_zero_array(ctx, struct dnsp_DnsProperty, 1);
+ assert_non_null(property);
+ property->id = DSPROPERTY_ZONE_MASTER_SERVERS;
+ property->data.master_servers.addrCount = 0;
+ property->data.master_servers.addr = NULL;
+
+ zone->tmp_props = property;
+ zone->num_props = 1;
+
+
+ /*
+ * Setup the server info
+ */
+ serverinfo = talloc_zero(ctx, struct dnsserver_serverinfo);
+ assert_non_null(serverinfo);
+
+ /*
+ * call dnsserver_init_zoneinfo
+ */
+ zoneinfo = dnsserver_init_zoneinfo(zone, serverinfo);
+
+ /*
+ * Check results
+ */
+ assert_non_null(zoneinfo);
+ assert_non_null(zoneinfo->aipLocalMasters);
+ assert_int_equal(zoneinfo->aipLocalMasters->AddrCount, 0);
+ assert_null(zoneinfo->aipLocalMasters->AddrArray);
+
+ TALLOC_FREE(ctx);
+}
+
+/*
+ * Test setting of a non empty ZONE_MASTER_SERVERS property
+ */
+static void test_dnsserver_init_zoneinfo_master_servers(void **state)
+{
+ struct dnsserver_zone *zone = NULL;
+ struct dnsserver_serverinfo *serverinfo = NULL;
+ struct dnsserver_zoneinfo *zoneinfo = NULL;
+ struct dnsp_DnsProperty *property = NULL;
+
+ TALLOC_CTX *ctx = talloc_new(NULL);
+
+ /*
+ * Setup the zone data
+ */
+ zone = talloc_zero(ctx, struct dnsserver_zone);
+ assert_non_null(zone);
+ zone->name = "test";
+
+ /*
+ * Set up an empty ZONE_MASTER_SERVERS property
+ */
+ property = talloc_zero_array(ctx, struct dnsp_DnsProperty, 1);
+ assert_non_null(property);
+ property->id = DSPROPERTY_ZONE_MASTER_SERVERS;
+ property->data.master_servers.addrCount = 4;
+ property->data.master_servers.addr =
+ talloc_zero_array(ctx, uint32_t, 4);
+ property->data.master_servers.addr[0] = 1000;
+ property->data.master_servers.addr[1] = 1001;
+ property->data.master_servers.addr[2] = 1002;
+ property->data.master_servers.addr[3] = 1003;
+
+ zone->tmp_props = property;
+ zone->num_props = 1;
+
+
+ /*
+ * Setup the server info
+ */
+ serverinfo = talloc_zero(ctx, struct dnsserver_serverinfo);
+ assert_non_null(serverinfo);
+
+ /*
+ * call dnsserver_init_zoneinfo
+ */
+ zoneinfo = dnsserver_init_zoneinfo(zone, serverinfo);
+
+ /*
+ * Check results
+ */
+ assert_non_null(zoneinfo);
+ assert_non_null(zoneinfo->aipLocalMasters);
+ assert_int_equal(zoneinfo->aipLocalMasters->AddrCount, 4);
+ assert_non_null(zoneinfo->aipLocalMasters->AddrArray);
+ assert_int_equal(zoneinfo->aipLocalMasters->AddrArray[0], 1000);
+ assert_int_equal(zoneinfo->aipLocalMasters->AddrArray[1], 1001);
+ assert_int_equal(zoneinfo->aipLocalMasters->AddrArray[2], 1002);
+ assert_int_equal(zoneinfo->aipLocalMasters->AddrArray[3], 1003);
+
+ /*
+ * Ensure that we're working with a copy of the property data
+ * and not a reference.
+ * The pointers should be different, and we should be able to change
+ * the values in the property without affecting the zoneinfo data
+ */
+ assert_true(zoneinfo->aipLocalMasters->AddrArray !=
+ property->data.master_servers.addr);
+ property->data.master_servers.addr[0] = 0;
+ property->data.master_servers.addr[1] = 1;
+ property->data.master_servers.addr[2] = 2;
+ property->data.master_servers.addr[3] = 3;
+ assert_int_equal(zoneinfo->aipLocalMasters->AddrArray[0], 1000);
+ assert_int_equal(zoneinfo->aipLocalMasters->AddrArray[1], 1001);
+ assert_int_equal(zoneinfo->aipLocalMasters->AddrArray[2], 1002);
+ assert_int_equal(zoneinfo->aipLocalMasters->AddrArray[3], 1003);
+
+ TALLOC_FREE(ctx);
+}
+
+/*
+ * Test setting of an empty ZONE_SCAVENGING_SERVERS property
+ */
+static void test_dnsserver_init_zoneinfo_scavenging_servers_empty(void **state)
+{
+ struct dnsserver_zone *zone = NULL;
+ struct dnsserver_serverinfo *serverinfo = NULL;
+ struct dnsserver_zoneinfo *zoneinfo = NULL;
+ struct dnsp_DnsProperty *property = NULL;
+
+ TALLOC_CTX *ctx = talloc_new(NULL);
+
+ /*
+ * Setup the zone data
+ */
+ zone = talloc_zero(ctx, struct dnsserver_zone);
+ assert_non_null(zone);
+ zone->name = "test";
+
+ property = talloc_zero_array(ctx, struct dnsp_DnsProperty, 1);
+ assert_non_null(property);
+ property->id = DSPROPERTY_ZONE_SCAVENGING_SERVERS;
+ property->data.servers.addrCount = 0;
+ property->data.servers.addr = NULL;
+
+ zone->tmp_props = property;
+ zone->num_props = 1;
+
+
+ serverinfo = talloc_zero(ctx, struct dnsserver_serverinfo);
+ assert_non_null(serverinfo);
+
+ zoneinfo = dnsserver_init_zoneinfo(zone, serverinfo);
+
+ assert_non_null(zoneinfo);
+ assert_non_null(zoneinfo->aipScavengeServers);
+ assert_int_equal(zoneinfo->aipScavengeServers->AddrCount, 0);
+ assert_null(zoneinfo->aipScavengeServers->AddrArray);
+
+ TALLOC_FREE(ctx);
+}
+
+/*
+ * Test setting of a non empty ZONE_SCAVENGING_SERVERS property
+ */
+static void test_dnsserver_init_zoneinfo_scavenging_servers(void **state)
+{
+ struct dnsserver_zone *zone = NULL;
+ struct dnsserver_serverinfo *serverinfo = NULL;
+ struct dnsserver_zoneinfo *zoneinfo = NULL;
+ struct dnsp_DnsProperty *property = NULL;
+
+ TALLOC_CTX *ctx = talloc_new(NULL);
+
+ /*
+ * Setup the zone data
+ */
+ zone = talloc_zero(ctx, struct dnsserver_zone);
+ assert_non_null(zone);
+ zone->name = "test";
+
+ property = talloc_zero_array(ctx, struct dnsp_DnsProperty, 1);
+ assert_non_null(property);
+ property->id = DSPROPERTY_ZONE_SCAVENGING_SERVERS;
+ property->data.servers.addrCount = 4;
+ property->data.servers.addr = talloc_zero_array(ctx, uint32_t, 4);
+ property->data.servers.addr[0] = 1000;
+ property->data.servers.addr[1] = 1001;
+ property->data.servers.addr[2] = 1002;
+ property->data.servers.addr[3] = 1003;
+
+ zone->tmp_props = property;
+ zone->num_props = 1;
+
+
+ serverinfo = talloc_zero(ctx, struct dnsserver_serverinfo);
+ assert_non_null(serverinfo);
+
+ zoneinfo = dnsserver_init_zoneinfo(zone, serverinfo);
+
+ assert_non_null(zoneinfo);
+ assert_non_null(zoneinfo->aipScavengeServers);
+ assert_int_equal(zoneinfo->aipScavengeServers->AddrCount, 4);
+ assert_non_null(zoneinfo->aipScavengeServers->AddrArray);
+ assert_non_null(zoneinfo->aipScavengeServers->AddrArray);
+ assert_int_equal(zoneinfo->aipScavengeServers->AddrArray[0], 1000);
+ assert_int_equal(zoneinfo->aipScavengeServers->AddrArray[1], 1001);
+ assert_int_equal(zoneinfo->aipScavengeServers->AddrArray[2], 1002);
+ assert_int_equal(zoneinfo->aipScavengeServers->AddrArray[3], 1003);
+
+ /*
+ * Ensure that we're working with a copy of the property data
+ * and not a reference.
+ * The pointers should be different, and we should be able to change
+ * the values in the property without affecting the zoneinfo data
+ */
+ assert_true(zoneinfo->aipScavengeServers->AddrArray !=
+ property->data.servers.addr);
+ property->data.servers.addr[0] = 0;
+ property->data.servers.addr[1] = 1;
+ property->data.servers.addr[2] = 2;
+ property->data.servers.addr[3] = 3;
+ assert_int_equal(zoneinfo->aipScavengeServers->AddrArray[0], 1000);
+ assert_int_equal(zoneinfo->aipScavengeServers->AddrArray[1], 1001);
+ assert_int_equal(zoneinfo->aipScavengeServers->AddrArray[2], 1002);
+ assert_int_equal(zoneinfo->aipScavengeServers->AddrArray[3], 1003);
+
+
+ TALLOC_FREE(ctx);
+}
+int main(int argc, const char **argv)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(
+ test_dnsserver_init_zoneinfo_master_servers_empty),
+ cmocka_unit_test(
+ test_dnsserver_init_zoneinfo_master_servers),
+ cmocka_unit_test(
+ test_dnsserver_init_zoneinfo_scavenging_servers_empty),
+ cmocka_unit_test(
+ test_dnsserver_init_zoneinfo_scavenging_servers),
+ };
+
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build
index 8e05eb8a0c3..14b68c7ce0f 100644
--- a/source4/rpc_server/wscript_build
+++ b/source4/rpc_server/wscript_build
@@ -3,7 +3,7 @@
bld.SAMBA_SUBSYSTEM('DCERPC_SHARE',
source='common/share_info.c',
autoproto='common/share.h',
- deps='ldb',
+ deps='ldb share',
enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER'),
)
@@ -163,7 +163,7 @@ bld.SAMBA_MODULE('dcerpc_dnsserver',
source='dnsserver/dcerpc_dnsserver.c dnsserver/dnsutils.c dnsserver/dnsdata.c dnsserver/dnsdb.c',
subsystem='dcerpc_server',
init_function='dcerpc_server_dnsserver_init',
- deps='DCERPC_COMMON dnsserver_common'
+ deps='DCERPC_COMMON dnsserver_common netif'
)
@@ -176,3 +176,16 @@ bld.SAMBA_MODULE('service_dcerpc',
deps='dcerpc_server'
)
+if bld.CONFIG_GET('ENABLE_SELFTEST'):
+ bld.SAMBA_BINARY(
+ 'test_rpc_dns_server_dnsutils',
+ source='tests/rpc_dns_server_dnsutils_test.c',
+ deps='''
+ dnsserver_common
+ DCERPC_COMMON
+ cmocka
+ talloc
+ ''',
+ install=False,
+ enabled=bld.AD_DC_BUILD_IS_ENABLED()
+ )
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 9dec0adb05c..18b2c1162b0 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -1164,3 +1164,5 @@ plantestsuite("samba4.dsdb.samdb.ldb_modules.audit_util", "none",
[os.path.join(bindir(), "test_audit_util")])
plantestsuite("samba4.dsdb.samdb.ldb_modules.audit_log", "none",
[os.path.join(bindir(), "test_audit_log")])
+plantestsuite("samba4.dcerpc.dnsserver.dnsutils", "none",
+ [os.path.join(bindir(), "test_rpc_dns_server_dnsutils")])
--
2.17.1

124
CVE-2018-16852-2.patch Normal file
View File

@ -0,0 +1,124 @@
From 05f867db81f118215445f2c49eda4b9c3451d14a Mon Sep 17 00:00:00 2001
From: Gary Lockyer <gary@catalyst.net.nz>
Date: Tue, 6 Nov 2018 12:16:30 +1300
Subject: [PATCH 05/17] CVE-2018-16852 dcerpc dnsserver: Ensure properties are
handled correctly
Fixes for
Bug 13669 - (CVE-2018-16852) NULL
pointer de-reference in Samba AD DC DNS management
The presence of the ZONE_MASTER_SERVERS property or the
ZONE_SCAVENGING_SERVERS property in a zone record causes the server to
follow a null pointer and terminate.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13669
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
selftest/knownfail.d/bug13669 | 4 --
source4/rpc_server/dnsserver/dnsutils.c | 64 +++++++++++++++++++++----
2 files changed, 56 insertions(+), 12 deletions(-)
delete mode 100644 selftest/knownfail.d/bug13669
diff --git a/selftest/knownfail.d/bug13669 b/selftest/knownfail.d/bug13669
deleted file mode 100644
index 74c8c130674..00000000000
--- a/selftest/knownfail.d/bug13669
+++ /dev/null
@@ -1,4 +0,0 @@
-^samba4.dcerpc.dnsserver.dnsutils.test_dnsserver_init_zoneinfo_master_servers_empty
-^samba4.dcerpc.dnsserver.dnsutils.test_dnsserver_init_zoneinfo_master_servers
-^samba4.dcerpc.dnsserver.dnsutils.test_dnsserver_init_zoneinfo_scavenging_servers_empty
-^samba4.dcerpc.dnsserver.dnsutils.test_dnsserver_init_zoneinfo_scavenging_servers
diff --git a/source4/rpc_server/dnsserver/dnsutils.c b/source4/rpc_server/dnsserver/dnsutils.c
index a1c749074af..e4055c99e74 100644
--- a/source4/rpc_server/dnsserver/dnsutils.c
+++ b/source4/rpc_server/dnsserver/dnsutils.c
@@ -209,6 +209,46 @@ struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx,
}
+/*
+ * Helper function to copy a dnsp_ip4_array struct to an IP4_ARRAY struct.
+ * The new structure and it's data are allocated on the supplied talloc context
+ */
+static struct IP4_ARRAY *copy_ip4_array(
+ TALLOC_CTX *ctx,
+ const char *name,
+ struct dnsp_ip4_array array) {
+
+ struct IP4_ARRAY *ip4_array = NULL;
+ unsigned int i;
+
+ ip4_array = talloc_zero(ctx, struct IP4_ARRAY);
+ if (ip4_array == NULL) {
+ DBG_ERR("Out of memory copying property [%s]\n",
+ name);
+ return NULL;
+ }
+
+ ip4_array->AddrCount = array.addrCount;
+ if (ip4_array->AddrCount == 0) {
+ return ip4_array;
+ }
+
+ ip4_array->AddrArray = talloc_array(ip4_array, uint32_t,
+ ip4_array->AddrCount);
+ if (ip4_array->AddrArray == NULL) {
+ TALLOC_FREE(ip4_array);
+ DBG_ERR("Out of memory copying property [%s] values\n",
+ name);
+ return NULL;
+ }
+
+ for (i = 0; i < ip4_array->AddrCount; i++) {
+ ip4_array->AddrArray[i] = array.addr[i];
+ }
+
+ return ip4_array;
+}
+
struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
struct dnsserver_serverinfo *serverinfo)
{
@@ -309,20 +349,28 @@ struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
prop->aging_enabled;
break;
case DSPROPERTY_ZONE_SCAVENGING_SERVERS:
- zoneinfo->aipScavengeServers->AddrCount =
- prop->servers.addrCount;
- zoneinfo->aipScavengeServers->AddrArray =
- prop->servers.addr;
+ zoneinfo->aipScavengeServers =
+ copy_ip4_array(zoneinfo,
+ "ZONE_SCAVENGING_SERVERS",
+ prop->servers);
+ if (zoneinfo->aipScavengeServers == NULL) {
+ TALLOC_FREE(zoneinfo);
+ return NULL;
+ }
break;
case DSPROPERTY_ZONE_AGING_ENABLED_TIME:
zoneinfo->dwAvailForScavengeTime =
prop->next_scavenging_cycle_hours;
break;
case DSPROPERTY_ZONE_MASTER_SERVERS:
- zoneinfo->aipLocalMasters->AddrCount =
- prop->master_servers.addrCount;
- zoneinfo->aipLocalMasters->AddrArray =
- prop->master_servers.addr;
+ zoneinfo->aipLocalMasters =
+ copy_ip4_array(zoneinfo,
+ "ZONE_MASTER_SERVERS",
+ prop->master_servers);
+ if (zoneinfo->aipLocalMasters == NULL) {
+ TALLOC_FREE(zoneinfo);
+ return NULL;
+ }
break;
case DSPROPERTY_ZONE_EMPTY:
case DSPROPERTY_ZONE_SECURE_TIME:
--
2.17.1

328
CVE-2018-16852-3.patch Normal file
View File

@ -0,0 +1,328 @@
From c78ca8b9b48a19e71f4d6ddd2e300f282fb0b247 Mon Sep 17 00:00:00 2001
From: Gary Lockyer <gary@catalyst.net.nz>
Date: Wed, 7 Nov 2018 15:08:04 +1300
Subject: [PATCH 06/17] CVE-2018-16852 dcerpc dnsserver: refactor common
properties handling
dnsserver_common.c and dnsutils.c both share similar code to process
zone properties. This patch extracts the common code and moves it to
dnsserver_common.c.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13669
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
source4/dns_server/dnsserver_common.c | 129 +++++++++++++++++-------
source4/dns_server/dnsserver_common.h | 3 +
source4/rpc_server/dnsserver/dnsutils.c | 107 ++------------------
3 files changed, 104 insertions(+), 135 deletions(-)
diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c
index bbbfe920f4e..cc24a6c1b52 100644
--- a/source4/dns_server/dnsserver_common.c
+++ b/source4/dns_server/dnsserver_common.c
@@ -742,6 +742,94 @@ bool dns_name_is_static(struct dnsp_DnssrvRpcRecord *records,
return false;
}
+/*
+ * Helper function to copy a dnsp_ip4_array struct to an IP4_ARRAY struct.
+ * The new structure and it's data are allocated on the supplied talloc context
+ */
+static struct IP4_ARRAY *copy_ip4_array(TALLOC_CTX *ctx,
+ const char *name,
+ struct dnsp_ip4_array array)
+{
+
+ struct IP4_ARRAY *ip4_array = NULL;
+ unsigned int i;
+
+ ip4_array = talloc_zero(ctx, struct IP4_ARRAY);
+ if (ip4_array == NULL) {
+ DBG_ERR("Out of memory copying property [%s]\n", name);
+ return NULL;
+ }
+
+ ip4_array->AddrCount = array.addrCount;
+ if (ip4_array->AddrCount == 0) {
+ return ip4_array;
+ }
+
+ ip4_array->AddrArray =
+ talloc_array(ip4_array, uint32_t, ip4_array->AddrCount);
+ if (ip4_array->AddrArray == NULL) {
+ TALLOC_FREE(ip4_array);
+ DBG_ERR("Out of memory copying property [%s] values\n", name);
+ return NULL;
+ }
+
+ for (i = 0; i < ip4_array->AddrCount; i++) {
+ ip4_array->AddrArray[i] = array.addr[i];
+ }
+
+ return ip4_array;
+}
+
+bool dns_zoneinfo_load_zone_property(struct dnsserver_zoneinfo *zoneinfo,
+ struct dnsp_DnsProperty *prop)
+{
+ switch (prop->id) {
+ case DSPROPERTY_ZONE_TYPE:
+ zoneinfo->dwZoneType = prop->data.zone_type;
+ break;
+ case DSPROPERTY_ZONE_ALLOW_UPDATE:
+ zoneinfo->fAllowUpdate = prop->data.allow_update_flag;
+ break;
+ case DSPROPERTY_ZONE_NOREFRESH_INTERVAL:
+ zoneinfo->dwNoRefreshInterval = prop->data.norefresh_hours;
+ break;
+ case DSPROPERTY_ZONE_REFRESH_INTERVAL:
+ zoneinfo->dwRefreshInterval = prop->data.refresh_hours;
+ break;
+ case DSPROPERTY_ZONE_AGING_STATE:
+ zoneinfo->fAging = prop->data.aging_enabled;
+ break;
+ case DSPROPERTY_ZONE_SCAVENGING_SERVERS:
+ zoneinfo->aipScavengeServers = copy_ip4_array(
+ zoneinfo, "ZONE_SCAVENGING_SERVERS", prop->data.servers);
+ if (zoneinfo->aipScavengeServers == NULL) {
+ return false;
+ }
+ break;
+ case DSPROPERTY_ZONE_AGING_ENABLED_TIME:
+ zoneinfo->dwAvailForScavengeTime =
+ prop->data.next_scavenging_cycle_hours;
+ break;
+ case DSPROPERTY_ZONE_MASTER_SERVERS:
+ zoneinfo->aipLocalMasters = copy_ip4_array(
+ zoneinfo, "ZONE_MASTER_SERVERS", prop->data.master_servers);
+ if (zoneinfo->aipLocalMasters == NULL) {
+ return false;
+ }
+ break;
+ case DSPROPERTY_ZONE_EMPTY:
+ case DSPROPERTY_ZONE_SECURE_TIME:
+ case DSPROPERTY_ZONE_DELETED_FROM_HOSTNAME:
+ case DSPROPERTY_ZONE_AUTO_NS_SERVERS:
+ case DSPROPERTY_ZONE_DCPROMO_CONVERT:
+ case DSPROPERTY_ZONE_SCAVENGING_SERVERS_DA:
+ case DSPROPERTY_ZONE_MASTER_SERVERS_DA:
+ case DSPROPERTY_ZONE_NS_SERVERS_DA:
+ case DSPROPERTY_ZONE_NODE_DBFLAGS:
+ break;
+ }
+ return true;
+}
WERROR dns_get_zone_properties(struct ldb_context *samdb,
TALLOC_CTX *mem_ctx,
struct ldb_dn *zone_dn,
@@ -774,6 +862,7 @@ WERROR dns_get_zone_properties(struct ldb_context *samdb,
}
for (i = 0; i < element->num_values; i++) {
+ bool valid_property;
prop = talloc_zero(mem_ctx, struct dnsp_DnsProperty);
if (prop == NULL) {
return WERR_NOT_ENOUGH_MEMORY;
@@ -787,42 +876,10 @@ WERROR dns_get_zone_properties(struct ldb_context *samdb,
return DNS_ERR(SERVER_FAILURE);
}
- switch (prop->id) {
- case DSPROPERTY_ZONE_AGING_STATE:
- zoneinfo->fAging = prop->data.aging_enabled;
- break;
- case DSPROPERTY_ZONE_NOREFRESH_INTERVAL:
- zoneinfo->dwNoRefreshInterval =
- prop->data.norefresh_hours;
- break;
- case DSPROPERTY_ZONE_REFRESH_INTERVAL:
- zoneinfo->dwRefreshInterval = prop->data.refresh_hours;
- break;
- case DSPROPERTY_ZONE_ALLOW_UPDATE:
- zoneinfo->fAllowUpdate = prop->data.allow_update_flag;
- break;
- case DSPROPERTY_ZONE_AGING_ENABLED_TIME:
- zoneinfo->dwAvailForScavengeTime =
- prop->data.next_scavenging_cycle_hours;
- break;
- case DSPROPERTY_ZONE_SCAVENGING_SERVERS:
- zoneinfo->aipScavengeServers->AddrCount =
- prop->data.servers.addrCount;
- zoneinfo->aipScavengeServers->AddrArray =
- prop->data.servers.addr;
- break;
- case DSPROPERTY_ZONE_EMPTY:
- case DSPROPERTY_ZONE_TYPE:
- case DSPROPERTY_ZONE_SECURE_TIME:
- case DSPROPERTY_ZONE_DELETED_FROM_HOSTNAME:
- case DSPROPERTY_ZONE_MASTER_SERVERS:
- case DSPROPERTY_ZONE_AUTO_NS_SERVERS:
- case DSPROPERTY_ZONE_DCPROMO_CONVERT:
- case DSPROPERTY_ZONE_SCAVENGING_SERVERS_DA:
- case DSPROPERTY_ZONE_MASTER_SERVERS_DA:
- case DSPROPERTY_ZONE_NS_SERVERS_DA:
- case DSPROPERTY_ZONE_NODE_DBFLAGS:
- break;
+ valid_property =
+ dns_zoneinfo_load_zone_property(zoneinfo, prop);
+ if (!valid_property) {
+ return DNS_ERR(SERVER_FAILURE);
}
}
diff --git a/source4/dns_server/dnsserver_common.h b/source4/dns_server/dnsserver_common.h
index 380f61b8dbc..60ecde4fa91 100644
--- a/source4/dns_server/dnsserver_common.h
+++ b/source4/dns_server/dnsserver_common.h
@@ -87,4 +87,7 @@ NTSTATUS dns_common_zones(struct ldb_context *samdb,
TALLOC_CTX *mem_ctx,
struct ldb_dn *base_dn,
struct dns_server_zone **zones_ret);
+
+bool dns_zoneinfo_load_zone_property(struct dnsserver_zoneinfo *zoneinfo,
+ struct dnsp_DnsProperty *prop);
#endif /* __DNSSERVER_COMMON_H__ */
diff --git a/source4/rpc_server/dnsserver/dnsutils.c b/source4/rpc_server/dnsserver/dnsutils.c
index e4055c99e74..bb52a1797a9 100644
--- a/source4/rpc_server/dnsserver/dnsutils.c
+++ b/source4/rpc_server/dnsserver/dnsutils.c
@@ -25,6 +25,7 @@
#include "dsdb/samdb/samdb.h"
#include "lib/socket/netif.h"
#include "lib/util/util_net.h"
+#include "dnsserver_common.h"
static struct DNS_ADDR_ARRAY *fill_dns_addr_array(TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx,
@@ -208,47 +209,6 @@ struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx,
return serverinfo;
}
-
-/*
- * Helper function to copy a dnsp_ip4_array struct to an IP4_ARRAY struct.
- * The new structure and it's data are allocated on the supplied talloc context
- */
-static struct IP4_ARRAY *copy_ip4_array(
- TALLOC_CTX *ctx,
- const char *name,
- struct dnsp_ip4_array array) {
-
- struct IP4_ARRAY *ip4_array = NULL;
- unsigned int i;
-
- ip4_array = talloc_zero(ctx, struct IP4_ARRAY);
- if (ip4_array == NULL) {
- DBG_ERR("Out of memory copying property [%s]\n",
- name);
- return NULL;
- }
-
- ip4_array->AddrCount = array.addrCount;
- if (ip4_array->AddrCount == 0) {
- return ip4_array;
- }
-
- ip4_array->AddrArray = talloc_array(ip4_array, uint32_t,
- ip4_array->AddrCount);
- if (ip4_array->AddrArray == NULL) {
- TALLOC_FREE(ip4_array);
- DBG_ERR("Out of memory copying property [%s] values\n",
- name);
- return NULL;
- }
-
- for (i = 0; i < ip4_array->AddrCount; i++) {
- ip4_array->AddrArray[i] = array.addr[i];
- }
-
- return ip4_array;
-}
-
struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
struct dnsserver_serverinfo *serverinfo)
{
@@ -257,8 +217,7 @@ struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
const char *revzone = "in-addr.arpa";
const char *revzone6 = "ip6.arpa";
int len1, len2;
- union dnsPropertyData *prop = NULL;
- int i=0;
+ unsigned int i = 0;
zoneinfo = talloc_zero(zone, struct dnsserver_zoneinfo);
if (zoneinfo == NULL) {
@@ -326,62 +285,12 @@ struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
zoneinfo->dwLastXfrResult = 0;
for(i=0; i<zone->num_props; i++){
- prop=&(zone->tmp_props[i].data);
- switch (zone->tmp_props[i].id) {
- case DSPROPERTY_ZONE_TYPE:
- zoneinfo->dwZoneType =
- prop->zone_type;
- break;
- case DSPROPERTY_ZONE_ALLOW_UPDATE:
- zoneinfo->fAllowUpdate =
- prop->allow_update_flag;
- break;
- case DSPROPERTY_ZONE_NOREFRESH_INTERVAL:
- zoneinfo->dwNoRefreshInterval =
- prop->norefresh_hours;
- break;
- case DSPROPERTY_ZONE_REFRESH_INTERVAL:
- zoneinfo->dwRefreshInterval =
- prop->refresh_hours;
- break;
- case DSPROPERTY_ZONE_AGING_STATE:
- zoneinfo->fAging =
- prop->aging_enabled;
- break;
- case DSPROPERTY_ZONE_SCAVENGING_SERVERS:
- zoneinfo->aipScavengeServers =
- copy_ip4_array(zoneinfo,
- "ZONE_SCAVENGING_SERVERS",
- prop->servers);
- if (zoneinfo->aipScavengeServers == NULL) {
- TALLOC_FREE(zoneinfo);
- return NULL;
- }
- break;
- case DSPROPERTY_ZONE_AGING_ENABLED_TIME:
- zoneinfo->dwAvailForScavengeTime =
- prop->next_scavenging_cycle_hours;
- break;
- case DSPROPERTY_ZONE_MASTER_SERVERS:
- zoneinfo->aipLocalMasters =
- copy_ip4_array(zoneinfo,
- "ZONE_MASTER_SERVERS",
- prop->master_servers);
- if (zoneinfo->aipLocalMasters == NULL) {
- TALLOC_FREE(zoneinfo);
- return NULL;
- }
- break;
- case DSPROPERTY_ZONE_EMPTY:
- case DSPROPERTY_ZONE_SECURE_TIME:
- case DSPROPERTY_ZONE_DELETED_FROM_HOSTNAME:
- case DSPROPERTY_ZONE_AUTO_NS_SERVERS:
- case DSPROPERTY_ZONE_DCPROMO_CONVERT:
- case DSPROPERTY_ZONE_SCAVENGING_SERVERS_DA:
- case DSPROPERTY_ZONE_MASTER_SERVERS_DA:
- case DSPROPERTY_ZONE_NS_SERVERS_DA:
- case DSPROPERTY_ZONE_NODE_DBFLAGS:
- break;
+ bool valid_property;
+ valid_property = dns_zoneinfo_load_zone_property(
+ zoneinfo, &zone->tmp_props[i]);
+ if (!valid_property) {
+ TALLOC_FREE(zoneinfo);
+ return NULL;
}
}
--
2.17.1

68
CVE-2018-16857-1.patch Normal file
View File

@ -0,0 +1,68 @@
From 862d4909eccd18942e3de8e8b0dc6e1594ec27f1 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Sun, 2 Sep 2018 17:34:03 +1200
Subject: [PATCH 09/17] CVE-2018-16857 selftest: Prepare to allow override of
lockout duration in password_lockout tests
This will make it easier to avoid flapping tests.
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
(cherry picked from commit a740a6131c967f9640b19a6964fd5d6f85ce853a)
Backported as a dependency for:
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683
---
source4/dsdb/tests/python/password_lockout.py | 9 ++++-----
source4/dsdb/tests/python/password_lockout_base.py | 11 +++++++++--
2 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/source4/dsdb/tests/python/password_lockout.py b/source4/dsdb/tests/python/password_lockout.py
index ec6cf13fe66..e817e656a2a 100755
--- a/source4/dsdb/tests/python/password_lockout.py
+++ b/source4/dsdb/tests/python/password_lockout.py
@@ -616,15 +616,14 @@ userPassword: thatsAcomplPASS2XYZ
initial_lastlogon_relation='greater')
def use_pso_lockout_settings(self, creds):
+
# create a PSO with the lockout settings the test cases normally expect
+ #
+ # Some test cases sleep() for self.account_lockout_duration
pso = PasswordSettings("lockout-PSO", self.ldb, lockout_attempts=3,
- lockout_duration=3)
+ lockout_duration=self.account_lockout_duration)
self.addCleanup(self.ldb.delete, pso.dn)
- # the test cases should sleep() for the PSO's lockoutDuration/obsvWindow
- self.account_lockout_duration = 3
- self.lockout_observation_window = 3
-
userdn = "cn=%s,cn=users,%s" % (creds.get_username(), self.base_dn)
pso.apply_to(userdn)
diff --git a/source4/dsdb/tests/python/password_lockout_base.py b/source4/dsdb/tests/python/password_lockout_base.py
index 4a320684702..9d82e088bb8 100644
--- a/source4/dsdb/tests/python/password_lockout_base.py
+++ b/source4/dsdb/tests/python/password_lockout_base.py
@@ -323,8 +323,15 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
""")
self.base_dn = self.ldb.domain_dn()
- self.account_lockout_duration = 3
- self.lockout_observation_window = 3
+
+ #
+ # Some test cases sleep() for self.account_lockout_duration
+ # so allow it to be controlled via the subclass
+ #
+ if not hasattr(self, 'account_lockout_duration'):
+ self.account_lockout_duration = 3
+ if not hasattr(self, 'lockout_observation_window'):
+ self.lockout_observation_window = 3
self.update_lockout_settings(threshold=3,
duration=self.account_lockout_duration,
observation_window=self.lockout_observation_window)
--
2.17.1

31
CVE-2018-16857-2.patch Normal file
View File

@ -0,0 +1,31 @@
From 31198d39a76474d55c3d391e04d76758ee115d8e Mon Sep 17 00:00:00 2001
From: Joe Guo <joeg@catalyst.net.nz>
Date: Mon, 30 Jul 2018 18:21:29 +1200
Subject: [PATCH 10/17] CVE-2018-16857 PEP8: fix E305: expected 2 blank lines
after class or function definition, found 1
Signed-off-by: Joe Guo <joeg@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Partial backport of commit 115f2a71b88 (only password_lockout.py
change) as a dependency for:
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683
---
source4/dsdb/tests/python/password_lockout.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/source4/dsdb/tests/python/password_lockout.py b/source4/dsdb/tests/python/password_lockout.py
index e817e656a2a..d8710866f39 100755
--- a/source4/dsdb/tests/python/password_lockout.py
+++ b/source4/dsdb/tests/python/password_lockout.py
@@ -1400,6 +1400,7 @@ userPassword: """ + userpass + """
self._test_samr_password_change(self.lockout1ntlm_creds,
other_creds=self.lockout2ntlm_creds)
+
host_url = "ldap://%s" % host
TestProgram(module=__name__, opts=subunitopts)
--
2.17.1

366
CVE-2018-16857-3.patch Normal file
View File

@ -0,0 +1,366 @@
From 4d0fd1a421ad4a3ca19ed954ee91fcc36413b017 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Sun, 2 Sep 2018 18:03:06 +1200
Subject: [PATCH 11/17] CVE-2018-16857 selftest: Split up password_lockout into
tests with and without a call to sleep()
This means we can have a long observation window for many of the tests and
so make them much more reliable. Many of these cause frustrating flapping
failures in our CI systems.
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Mon Sep 3 06:14:55 CEST 2018 on sn-devel-144
(cherry picked from commit 74357bf347348d3a8b7483c58e5250e98f7e8810)
Backported as a dependency for:
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683
---
source4/dsdb/tests/python/password_lockout.py | 299 +++++++++---------
1 file changed, 157 insertions(+), 142 deletions(-)
diff --git a/source4/dsdb/tests/python/password_lockout.py b/source4/dsdb/tests/python/password_lockout.py
index d8710866f39..0022dee21ba 100755
--- a/source4/dsdb/tests/python/password_lockout.py
+++ b/source4/dsdb/tests/python/password_lockout.py
@@ -88,6 +88,42 @@ class PasswordTests(password_lockout_base.BasePasswordTestCase):
self.lockout2ntlm_ldb = self._readd_user(self.lockout2ntlm_creds,
lockOutObservationWindow=self.lockout_observation_window)
+
+ def use_pso_lockout_settings(self, creds):
+
+ # create a PSO with the lockout settings the test cases normally expect
+ #
+ # Some test cases sleep() for self.account_lockout_duration
+ pso = PasswordSettings("lockout-PSO", self.ldb, lockout_attempts=3,
+ lockout_duration=self.account_lockout_duration)
+ self.addCleanup(self.ldb.delete, pso.dn)
+
+ userdn = "cn=%s,cn=users,%s" % (creds.get_username(), self.base_dn)
+ pso.apply_to(userdn)
+
+ # update the global lockout settings to be wildly different to what
+ # the test cases normally expect
+ self.update_lockout_settings(threshold=10, duration=600,
+ observation_window=600)
+
+ def _reset_samr(self, res):
+
+ # Now reset the lockout, by removing ACB_AUTOLOCK (which removes the lock, despite being a generated attribute)
+ samr_user = self._open_samr_user(res)
+ acb_info = self.samr.QueryUserInfo(samr_user, 16)
+ acb_info.acct_flags &= ~samr.ACB_AUTOLOCK
+ self.samr.SetUserInfo(samr_user, 16, acb_info)
+ self.samr.Close(samr_user)
+
+
+class PasswordTestsWithoutSleep(PasswordTests):
+ def setUp(self):
+ # The tests in this class do not sleep, so we can have a
+ # longer window and not flap on slower hosts
+ self.account_lockout_duration = 30
+ self.lockout_observation_window = 30
+ super(PasswordTestsWithoutSleep, self).setUp()
+
def _reset_ldap_lockoutTime(self, res):
self.ldb.modify_ldif("""
dn: """ + str(res[0].dn) + """
@@ -615,22 +651,130 @@ userPassword: thatsAcomplPASS2XYZ
"samr",
initial_lastlogon_relation='greater')
- def use_pso_lockout_settings(self, creds):
+ def test_multiple_logon_krb5(self):
+ self._test_multiple_logon(self.lockout1krb5_creds)
- # create a PSO with the lockout settings the test cases normally expect
- #
- # Some test cases sleep() for self.account_lockout_duration
- pso = PasswordSettings("lockout-PSO", self.ldb, lockout_attempts=3,
- lockout_duration=self.account_lockout_duration)
- self.addCleanup(self.ldb.delete, pso.dn)
+ def test_multiple_logon_ntlm(self):
+ self._test_multiple_logon(self.lockout1ntlm_creds)
- userdn = "cn=%s,cn=users,%s" % (creds.get_username(), self.base_dn)
- pso.apply_to(userdn)
+ def _test_samr_password_change(self, creds, other_creds, lockout_threshold=3):
+ """Tests user lockout by using bad password in SAMR password_change"""
- # update the global lockout settings to be wildly different to what
- # the test cases normally expect
- self.update_lockout_settings(threshold=10, duration=600,
- observation_window=600)
+ # create a connection for SAMR using another user's credentials
+ lp = self.get_loadparm()
+ net = Net(other_creds, lp, server=self.host)
+
+ # work out the initial account values for this user
+ username = creds.get_username()
+ userdn = "cn=%s,cn=users,%s" % (username, self.base_dn)
+ res = self._check_account(userdn,
+ badPwdCount=0,
+ badPasswordTime=("greater", 0),
+ badPwdCountOnly=True)
+ badPasswordTime = int(res[0]["badPasswordTime"][0])
+ logonCount = int(res[0]["logonCount"][0])
+ lastLogon = int(res[0]["lastLogon"][0])
+ lastLogonTimestamp = int(res[0]["lastLogonTimestamp"][0])
+
+ # prove we can change the user password (using the correct password)
+ new_password = "thatsAcomplPASS2"
+ net.change_password(newpassword=new_password.encode('utf-8'),
+ username=username,
+ oldpassword=creds.get_password())
+ creds.set_password(new_password)
+
+ # try entering 'x' many bad passwords in a row to lock the user out
+ new_password = "thatsAcomplPASS3"
+ for i in range(lockout_threshold):
+ badPwdCount = i + 1
+ try:
+ print("Trying bad password, attempt #%u" % badPwdCount)
+ net.change_password(newpassword=new_password.encode('utf-8'),
+ username=creds.get_username(),
+ oldpassword="bad-password")
+ self.fail("Invalid SAMR change_password accepted")
+ except NTSTATUSError as e:
+ enum = ctypes.c_uint32(e[0]).value
+ self.assertEquals(enum, ntstatus.NT_STATUS_WRONG_PASSWORD)
+
+ # check the status of the account is updated after each bad attempt
+ account_flags = 0
+ lockoutTime = None
+ if badPwdCount >= lockout_threshold:
+ account_flags = dsdb.UF_LOCKOUT
+ lockoutTime = ("greater", badPasswordTime)
+
+ res = self._check_account(userdn,
+ badPwdCount=badPwdCount,
+ badPasswordTime=("greater", badPasswordTime),
+ logonCount=logonCount,
+ lastLogon=lastLogon,
+ lastLogonTimestamp=lastLogonTimestamp,
+ lockoutTime=lockoutTime,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
+ msDSUserAccountControlComputed=account_flags)
+ badPasswordTime = int(res[0]["badPasswordTime"][0])
+
+ # the user is now locked out
+ lockoutTime = int(res[0]["lockoutTime"][0])
+
+ # check the user remains locked out regardless of whether they use a
+ # good or a bad password now
+ for password in (creds.get_password(), "bad-password"):
+ try:
+ print("Trying password %s" % password)
+ net.change_password(newpassword=new_password.encode('utf-8'),
+ username=creds.get_username(),
+ oldpassword=password)
+ self.fail("Invalid SAMR change_password accepted")
+ except NTSTATUSError as e:
+ enum = ctypes.c_uint32(e[0]).value
+ self.assertEquals(enum, ntstatus.NT_STATUS_ACCOUNT_LOCKED_OUT)
+
+ res = self._check_account(userdn,
+ badPwdCount=lockout_threshold,
+ badPasswordTime=badPasswordTime,
+ logonCount=logonCount,
+ lastLogon=lastLogon,
+ lastLogonTimestamp=lastLogonTimestamp,
+ lockoutTime=lockoutTime,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
+ msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
+
+ # reset the user account lockout
+ self._reset_samr(res)
+
+ # check bad password counts are reset
+ res = self._check_account(userdn,
+ badPwdCount=0,
+ badPasswordTime=badPasswordTime,
+ logonCount=logonCount,
+ lockoutTime=0,
+ lastLogon=lastLogon,
+ lastLogonTimestamp=lastLogonTimestamp,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
+ msDSUserAccountControlComputed=0)
+
+ # check we can change the user password successfully now
+ net.change_password(newpassword=new_password.encode('utf-8'),
+ username=username,
+ oldpassword=creds.get_password())
+ creds.set_password(new_password)
+
+ def test_samr_change_password(self):
+ self._test_samr_password_change(self.lockout1ntlm_creds,
+ other_creds=self.lockout2ntlm_creds)
+
+ # same as above, but use a PSO to enforce the lockout
+ def test_pso_samr_change_password(self):
+ self.use_pso_lockout_settings(self.lockout1ntlm_creds)
+ self._test_samr_password_change(self.lockout1ntlm_creds,
+ other_creds=self.lockout2ntlm_creds)
+
+
+class PasswordTestsWithSleep(PasswordTests):
+ def setUp(self):
+ super(PasswordTestsWithSleep, self).setUp()
def _test_unicodePwd_lockout_with_clear_change(self, creds, other_ldb,
initial_logoncount_relation=None):
@@ -1065,12 +1209,6 @@ unicodePwd:: """ + base64.b64encode(new_utf16).decode('utf8') + """
self.use_pso_lockout_settings(self.lockout1ntlm_creds)
self._test_login_lockout(self.lockout1ntlm_creds)
- def test_multiple_logon_krb5(self):
- self._test_multiple_logon(self.lockout1krb5_creds)
-
- def test_multiple_logon_ntlm(self):
- self._test_multiple_logon(self.lockout1ntlm_creds)
-
def _testing_add_user(self, creds, lockOutObservationWindow=0):
username = creds.get_username()
userpass = creds.get_password()
@@ -1251,15 +1389,6 @@ userPassword: """ + userpass + """
msDSUserAccountControlComputed=0)
return ldb
- def _reset_samr(self, res):
-
- # Now reset the lockout, by removing ACB_AUTOLOCK (which removes the lock, despite being a generated attribute)
- samr_user = self._open_samr_user(res)
- acb_info = self.samr.QueryUserInfo(samr_user, 16)
- acb_info.acct_flags &= ~samr.ACB_AUTOLOCK
- self.samr.SetUserInfo(samr_user, 16, acb_info)
- self.samr.Close(samr_user)
-
def test_lockout_observation_window(self):
lockout3krb5_creds = self.insta_creds(self.template_creds,
username="lockout3krb5",
@@ -1286,120 +1415,6 @@ userPassword: """ + userpass + """
self._testing_add_user(lockout4ntlm_creds,
lockOutObservationWindow=self.lockout_observation_window)
- def _test_samr_password_change(self, creds, other_creds, lockout_threshold=3):
- """Tests user lockout by using bad password in SAMR password_change"""
-
- # create a connection for SAMR using another user's credentials
- lp = self.get_loadparm()
- net = Net(other_creds, lp, server=self.host)
-
- # work out the initial account values for this user
- username = creds.get_username()
- userdn = "cn=%s,cn=users,%s" % (username, self.base_dn)
- res = self._check_account(userdn,
- badPwdCount=0,
- badPasswordTime=("greater", 0),
- badPwdCountOnly=True)
- badPasswordTime = int(res[0]["badPasswordTime"][0])
- logonCount = int(res[0]["logonCount"][0])
- lastLogon = int(res[0]["lastLogon"][0])
- lastLogonTimestamp = int(res[0]["lastLogonTimestamp"][0])
-
- # prove we can change the user password (using the correct password)
- new_password = "thatsAcomplPASS2"
- net.change_password(newpassword=new_password.encode('utf-8'),
- username=username,
- oldpassword=creds.get_password())
- creds.set_password(new_password)
-
- # try entering 'x' many bad passwords in a row to lock the user out
- new_password = "thatsAcomplPASS3"
- for i in range(lockout_threshold):
- badPwdCount = i + 1
- try:
- print("Trying bad password, attempt #%u" % badPwdCount)
- net.change_password(newpassword=new_password.encode('utf-8'),
- username=creds.get_username(),
- oldpassword="bad-password")
- self.fail("Invalid SAMR change_password accepted")
- except NTSTATUSError as e:
- enum = ctypes.c_uint32(e[0]).value
- self.assertEquals(enum, ntstatus.NT_STATUS_WRONG_PASSWORD)
-
- # check the status of the account is updated after each bad attempt
- account_flags = 0
- lockoutTime = None
- if badPwdCount >= lockout_threshold:
- account_flags = dsdb.UF_LOCKOUT
- lockoutTime = ("greater", badPasswordTime)
-
- res = self._check_account(userdn,
- badPwdCount=badPwdCount,
- badPasswordTime=("greater", badPasswordTime),
- logonCount=logonCount,
- lastLogon=lastLogon,
- lastLogonTimestamp=lastLogonTimestamp,
- lockoutTime=lockoutTime,
- userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
- msDSUserAccountControlComputed=account_flags)
- badPasswordTime = int(res[0]["badPasswordTime"][0])
-
- # the user is now locked out
- lockoutTime = int(res[0]["lockoutTime"][0])
-
- # check the user remains locked out regardless of whether they use a
- # good or a bad password now
- for password in (creds.get_password(), "bad-password"):
- try:
- print("Trying password %s" % password)
- net.change_password(newpassword=new_password.encode('utf-8'),
- username=creds.get_username(),
- oldpassword=password)
- self.fail("Invalid SAMR change_password accepted")
- except NTSTATUSError as e:
- enum = ctypes.c_uint32(e[0]).value
- self.assertEquals(enum, ntstatus.NT_STATUS_ACCOUNT_LOCKED_OUT)
-
- res = self._check_account(userdn,
- badPwdCount=lockout_threshold,
- badPasswordTime=badPasswordTime,
- logonCount=logonCount,
- lastLogon=lastLogon,
- lastLogonTimestamp=lastLogonTimestamp,
- lockoutTime=lockoutTime,
- userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
- msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
-
- # reset the user account lockout
- self._reset_samr(res)
-
- # check bad password counts are reset
- res = self._check_account(userdn,
- badPwdCount=0,
- badPasswordTime=badPasswordTime,
- logonCount=logonCount,
- lockoutTime=0,
- lastLogon=lastLogon,
- lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
- msDSUserAccountControlComputed=0)
-
- # check we can change the user password successfully now
- net.change_password(newpassword=new_password.encode('utf-8'),
- username=username,
- oldpassword=creds.get_password())
- creds.set_password(new_password)
-
- def test_samr_change_password(self):
- self._test_samr_password_change(self.lockout1ntlm_creds,
- other_creds=self.lockout2ntlm_creds)
-
- # same as above, but use a PSO to enforce the lockout
- def test_pso_samr_change_password(self):
- self.use_pso_lockout_settings(self.lockout1ntlm_creds)
- self._test_samr_password_change(self.lockout1ntlm_creds,
- other_creds=self.lockout2ntlm_creds)
-
host_url = "ldap://%s" % host
--
2.17.1

183
CVE-2018-16857-4.patch Normal file
View File

@ -0,0 +1,183 @@
From fe8e05a9ea8185325ff87ac73ef0106a85cd662a Mon Sep 17 00:00:00 2001
From: Joe Guo <joeg@catalyst.net.nz>
Date: Mon, 30 Jul 2018 18:15:34 +1200
Subject: [PATCH 12/17] CVE-2018-16857 PEP8: fix E127: continuation line
over-indented for visual indent
Signed-off-by: Joe Guo <joeg@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Partial backport of commit bbb9f57603d (only password_lockout_base.py
change) as a dependency for:
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683
---
.../tests/python/password_lockout_base.py | 36 +++++++++----------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/source4/dsdb/tests/python/password_lockout_base.py b/source4/dsdb/tests/python/password_lockout_base.py
index 9d82e088bb8..1b408c75166 100644
--- a/source4/dsdb/tests/python/password_lockout_base.py
+++ b/source4/dsdb/tests/python/password_lockout_base.py
@@ -390,7 +390,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=("greater", 0),
lastLogonTimestamp=("greater", 0),
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount = int(res[0]["logonCount"][0])
@@ -421,7 +421,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg='lastlogontimestamp with wrong password')
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -440,7 +440,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=('greater', lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg='LLTimestamp is updated to lastlogon')
@@ -461,7 +461,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -483,7 +483,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -508,7 +508,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=("greater", badPasswordTime),
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
badPasswordTime = int(res[0]["badPasswordTime"][0])
lockoutTime = int(res[0]["lockoutTime"][0])
@@ -530,7 +530,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# The wrong password
@@ -550,7 +550,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# The correct password, but we are locked out
@@ -570,7 +570,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# wait for the lockout to end
@@ -585,7 +585,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
# The correct password after letting the timeout expire
@@ -605,7 +605,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=0,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg="lastLogon is way off")
@@ -629,7 +629,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -650,7 +650,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -664,7 +664,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
# The wrong password
@@ -684,7 +684,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -700,7 +700,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=("greater", lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
def _test_multiple_logon(self, creds):
@@ -734,7 +734,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=("greater", 0),
lastLogonTimestamp=("greater", 0),
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount = int(res[0]["logonCount"][0])
@@ -774,5 +774,5 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=(lastlogon_relation, lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
--
2.17.1

221
CVE-2018-16857-5.patch Normal file
View File

@ -0,0 +1,221 @@
From 9cb6b4e9131afac71a39a2f6a3c142723cb6ca19 Mon Sep 17 00:00:00 2001
From: Joe Guo <joeg@catalyst.net.nz>
Date: Mon, 30 Jul 2018 18:19:21 +1200
Subject: [PATCH 13/17] CVE-2018-16857 PEP8: fix E251: unexpected spaces around
keyword / parameter equals
Signed-off-by: Joe Guo <joeg@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Partial backport of commit 1ccc36b4010cd63 (only password_lockout_base.py
change) as a dependency for:
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683
---
.../tests/python/password_lockout_base.py | 60 +++++++------------
1 file changed, 20 insertions(+), 40 deletions(-)
diff --git a/source4/dsdb/tests/python/password_lockout_base.py b/source4/dsdb/tests/python/password_lockout_base.py
index 1b408c75166..48a74018624 100644
--- a/source4/dsdb/tests/python/password_lockout_base.py
+++ b/source4/dsdb/tests/python/password_lockout_base.py
@@ -93,8 +93,7 @@ class BasePasswordTestCase(PasswordTestCase):
logonCount=0,
lastLogon=0,
lastLogonTimestamp=("absent", None),
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
def _check_account(self, dn,
@@ -389,8 +388,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=(logoncount_relation, 0),
lastLogon=("greater", 0),
lastLogonTimestamp=("greater", 0),
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount = int(res[0]["logonCount"][0])
@@ -420,8 +418,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg='lastlogontimestamp with wrong password')
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -439,8 +436,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=(logoncount_relation, logonCount),
lastLogon=('greater', lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg='LLTimestamp is updated to lastlogon')
@@ -460,8 +456,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -482,8 +477,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -507,8 +501,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=("greater", badPasswordTime),
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
badPasswordTime = int(res[0]["badPasswordTime"][0])
lockoutTime = int(res[0]["lockoutTime"][0])
@@ -529,8 +522,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# The wrong password
@@ -549,8 +541,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# The correct password, but we are locked out
@@ -569,8 +560,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# wait for the lockout to end
@@ -584,8 +574,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=lockoutTime,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
# The correct password after letting the timeout expire
@@ -604,8 +593,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=(lastlogon_relation, lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=0,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg="lastLogon is way off")
@@ -628,8 +616,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -649,8 +636,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -663,8 +649,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
# The wrong password
@@ -683,8 +668,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
@@ -699,8 +683,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=0,
lastLogon=("greater", lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
def _test_multiple_logon(self, creds):
@@ -733,8 +716,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=(logoncount_relation, 0),
lastLogon=("greater", 0),
lastLogonTimestamp=("greater", 0),
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount = int(res[0]["logonCount"][0])
@@ -754,8 +736,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=(logoncount_relation, logonCount),
lastLogon=(lastlogon_relation, lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg=("second logon, firstlogon was %s" %
firstLogon))
@@ -773,6 +754,5 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=(logoncount_relation, logonCount),
lastLogon=(lastlogon_relation, lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
--
2.17.1

104
CVE-2018-16857-6.patch Normal file
View File

@ -0,0 +1,104 @@
From ec9cc4ed5a05490297cde3fcaac50eeeaaca8469 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale@catalyst.net.nz>
Date: Tue, 13 Nov 2018 11:49:56 +1300
Subject: [PATCH 14/17] CVE-2018-16857 tests: Sanity-check password lockout
works with default values
Sanity-check that when we use the default lockOutObservationWindow that
user lockout actually works.
The easiest way to do this is to reuse the _test_login_lockout()
test-case, but stop at the point where we wait for the lockout duration
to expire (because we don't want the test to wait 30 mins).
This highlights a problem currently where the default values don't work.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683
Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
selftest/knownfail.d/password_lockout | 4 +++
source4/dsdb/tests/python/password_lockout.py | 30 +++++++++++++++++++
.../tests/python/password_lockout_base.py | 6 +++-
3 files changed, 39 insertions(+), 1 deletion(-)
create mode 100644 selftest/knownfail.d/password_lockout
diff --git a/selftest/knownfail.d/password_lockout b/selftest/knownfail.d/password_lockout
new file mode 100644
index 00000000000..305bcbdef25
--- /dev/null
+++ b/selftest/knownfail.d/password_lockout
@@ -0,0 +1,4 @@
+samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTestsWithDefaults.test_pso_login_lockout_krb5\(ad_dc_ntvfs\)
+samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTestsWithDefaults.test_pso_login_lockout_ntlm\(ad_dc_ntvfs\)
+samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTestsWithDefaults.test_login_lockout_ntlm\(ad_dc_ntvfs\)
+samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTestsWithDefaults.test_login_lockout_krb5\(ad_dc_ntvfs\)
diff --git a/source4/dsdb/tests/python/password_lockout.py b/source4/dsdb/tests/python/password_lockout.py
index 0022dee21ba..b09a732e179 100755
--- a/source4/dsdb/tests/python/password_lockout.py
+++ b/source4/dsdb/tests/python/password_lockout.py
@@ -1415,6 +1415,36 @@ userPassword: """ + userpass + """
self._testing_add_user(lockout4ntlm_creds,
lockOutObservationWindow=self.lockout_observation_window)
+class PasswordTestsWithDefaults(PasswordTests):
+ def setUp(self):
+ # The tests in this class do not sleep, so we can use the default
+ # timeout windows here
+ self.account_lockout_duration = 30 * 60
+ self.lockout_observation_window = 30 * 60
+ super(PasswordTestsWithDefaults, self).setUp()
+
+ # sanity-check that user lockout works with the default settings (we just
+ # check the user is locked out - we don't wait for the lockout to expire)
+ def test_login_lockout_krb5(self):
+ self._test_login_lockout(self.lockout1krb5_creds,
+ wait_lockout_duration=False)
+
+ def test_login_lockout_ntlm(self):
+ self._test_login_lockout(self.lockout1ntlm_creds,
+ wait_lockout_duration=False)
+
+ # Repeat the login lockout tests using PSOs
+ def test_pso_login_lockout_krb5(self):
+ """Check the PSO lockout settings get applied to the user correctly"""
+ self.use_pso_lockout_settings(self.lockout1krb5_creds)
+ self._test_login_lockout(self.lockout1krb5_creds,
+ wait_lockout_duration=False)
+
+ def test_pso_login_lockout_ntlm(self):
+ """Check the PSO lockout settings get applied to the user correctly"""
+ self.use_pso_lockout_settings(self.lockout1ntlm_creds)
+ self._test_login_lockout(self.lockout1ntlm_creds,
+ wait_lockout_duration=False)
host_url = "ldap://%s" % host
diff --git a/source4/dsdb/tests/python/password_lockout_base.py b/source4/dsdb/tests/python/password_lockout_base.py
index 48a74018624..e8ac46dcd97 100644
--- a/source4/dsdb/tests/python/password_lockout_base.py
+++ b/source4/dsdb/tests/python/password_lockout_base.py
@@ -365,7 +365,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
def tearDown(self):
super(BasePasswordTestCase, self).tearDown()
- def _test_login_lockout(self, creds):
+ def _test_login_lockout(self, creds, wait_lockout_duration=True):
username = creds.get_username()
userpass = creds.get_password()
userdn = "cn=%s,cn=users,%s" % (username, self.base_dn)
@@ -563,6 +563,10 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
+ # if we're just checking the user gets locked out, we can stop here
+ if not wait_lockout_duration:
+ return
+
# wait for the lockout to end
time.sleep(self.account_lockout_duration + 1)
print(self.account_lockout_duration + 1)
--
2.17.1

58
CVE-2018-16857-7.patch Normal file
View File

@ -0,0 +1,58 @@
From 4f86beeaf3408383385ee99a74520a805dd63c0f Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale@catalyst.net.nz>
Date: Tue, 13 Nov 2018 12:24:16 +1300
Subject: [PATCH 15/17] CVE-2018-16857 dsdb/util: Correctly treat
lockOutObservationWindow as 64-bit int
Commit 442a38c918ae1666b35 refactored some code into a new
get_lockout_observation_window() function. However, in moving the code,
an ldb_msg_find_attr_as_int64() inadvertently got converted to a
ldb_msg_find_attr_as_int().
ldb_msg_find_attr_as_int() will only work for values up to -2147483648
(about 3.5 minutes in MS timestamp form). Unfortunately, the automated
tests used a low enough timeout that they still worked, however,
password lockout would not work with the Samba default settings.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683
Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
selftest/knownfail.d/password_lockout | 2 --
source4/dsdb/common/util.c | 10 +++++-----
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/selftest/knownfail.d/password_lockout b/selftest/knownfail.d/password_lockout
index 305bcbdef25..a4e37a84c21 100644
--- a/selftest/knownfail.d/password_lockout
+++ b/selftest/knownfail.d/password_lockout
@@ -1,4 +1,2 @@
samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTestsWithDefaults.test_pso_login_lockout_krb5\(ad_dc_ntvfs\)
samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTestsWithDefaults.test_pso_login_lockout_ntlm\(ad_dc_ntvfs\)
-samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTestsWithDefaults.test_login_lockout_ntlm\(ad_dc_ntvfs\)
-samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTestsWithDefaults.test_login_lockout_krb5\(ad_dc_ntvfs\)
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 193fa2ae653..438a29e1773 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -5400,12 +5400,12 @@ static int64_t get_lockout_observation_window(struct ldb_message *domain_msg,
struct ldb_message *pso_msg)
{
if (pso_msg != NULL) {
- return ldb_msg_find_attr_as_int(pso_msg,
- "msDS-LockoutObservationWindow",
- 0);
+ return ldb_msg_find_attr_as_int64(pso_msg,
+ "msDS-LockoutObservationWindow",
+ 0);
} else {
- return ldb_msg_find_attr_as_int(domain_msg,
- "lockOutObservationWindow", 0);
+ return ldb_msg_find_attr_as_int64(domain_msg,
+ "lockOutObservationWindow", 0);
}
}
--
2.17.1

47
CVE-2018-16857-8.patch Normal file
View File

@ -0,0 +1,47 @@
From d12b02c78842786969557b9be7c953e9594d90dd Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale@catalyst.net.nz>
Date: Tue, 13 Nov 2018 13:19:04 +1300
Subject: [PATCH 16/17] CVE-2018-16857 dsdb/util: Fix lockOutObservationWindow
for PSOs
Fix a remaining place where we were trying to read the
msDS-LockoutObservationWindow as an int instead of an int64.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683
Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
selftest/knownfail.d/password_lockout | 2 --
source4/dsdb/common/util.c | 6 +++---
2 files changed, 3 insertions(+), 5 deletions(-)
delete mode 100644 selftest/knownfail.d/password_lockout
diff --git a/selftest/knownfail.d/password_lockout b/selftest/knownfail.d/password_lockout
deleted file mode 100644
index a4e37a84c21..00000000000
--- a/selftest/knownfail.d/password_lockout
+++ /dev/null
@@ -1,2 +0,0 @@
-samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTestsWithDefaults.test_pso_login_lockout_krb5\(ad_dc_ntvfs\)
-samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTestsWithDefaults.test_pso_login_lockout_ntlm\(ad_dc_ntvfs\)
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 438a29e1773..8d863f85a29 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -5361,9 +5361,9 @@ int samdb_result_effective_badPwdCount(struct ldb_context *sam_ldb,
if (res != NULL) {
lockOutObservationWindow =
- ldb_msg_find_attr_as_int(res->msgs[0],
- "msDS-LockoutObservationWindow",
- 0);
+ ldb_msg_find_attr_as_int64(res->msgs[0],
+ "msDS-LockoutObservationWindow",
+ 0);
talloc_free(res);
} else {
--
2.17.1

59
CVE-2018-16857-9.patch Normal file
View File

@ -0,0 +1,59 @@
From 60b2cd50f4d0554cc5ca8c53b2d1fa89e56a6d06 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale@catalyst.net.nz>
Date: Tue, 13 Nov 2018 13:22:41 +1300
Subject: [PATCH 17/17] CVE-2018-16857 dsdb/util: Add better default
lockOutObservationWindow
Clearly the lockOutObservationWindow value is important, and using a
default value of zero doesn't work very well.
This patch adds a better default value (the domain default setting of 30
minutes).
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683
Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
source4/dsdb/common/util.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 8d863f85a29..18f700370a3 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -56,6 +56,9 @@
*/
#include "dsdb/samdb/ldb_modules/util.h"
+/* default is 30 minutes: -1e7 * 30 * 60 */
+#define DEFAULT_OBSERVATION_WINDOW -18000000000
+
/*
search the sam for the specified attributes in a specific domain, filter on
objectSid being in domain_sid.
@@ -5363,7 +5366,7 @@ int samdb_result_effective_badPwdCount(struct ldb_context *sam_ldb,
lockOutObservationWindow =
ldb_msg_find_attr_as_int64(res->msgs[0],
"msDS-LockoutObservationWindow",
- 0);
+ DEFAULT_OBSERVATION_WINDOW);
talloc_free(res);
} else {
@@ -5402,10 +5405,11 @@ static int64_t get_lockout_observation_window(struct ldb_message *domain_msg,
if (pso_msg != NULL) {
return ldb_msg_find_attr_as_int64(pso_msg,
"msDS-LockoutObservationWindow",
- 0);
+ DEFAULT_OBSERVATION_WINDOW);
} else {
return ldb_msg_find_attr_as_int64(domain_msg,
- "lockOutObservationWindow", 0);
+ "lockOutObservationWindow",
+ DEFAULT_OBSERVATION_WINDOW);
}
}
--
2.17.1

36
CVE-2018-16860.patch Normal file
View File

@ -0,0 +1,36 @@
From 43958af1d50f0185e21e6cd74110c455ee8996af Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Wed, 30 Jan 2019 23:49:07 +0200
Subject: [PATCH] CVE-2018-16860 Heimdal KDC: Reject PA-S4U2Self with unkeyed
checksum
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13685
Signed-off-by: Isaac Boukris <iboukris@gmail.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Autobuild-User(master): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(master): Tue May 14 11:45:13 UTC 2019 on sn-devel-184
---
source4/heimdal/kdc/krb5tgs.c | 7 +
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index a888788bb6f..ff7d93138c0 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -1925,6 +1925,13 @@ tgs_build_reply(krb5_context context,
goto out;
}
+ if (!krb5_checksum_is_keyed(context, self.cksum.cksumtype)) {
+ free_PA_S4U2Self(&self);
+ kdc_log(context, config, 0, "Reject PA-S4U2Self with unkeyed checksum");
+ ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
+ goto out;
+ }
+
ret = _krb5_s4u2self_to_checksumdata(context, &self, &datack);
if (ret)
goto out;

75
CVE-2019-10197-1.patch Normal file
View File

@ -0,0 +1,75 @@
From 5e94fe726e9af81374c697ce603b3728ccaaebf3 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Fri, 12 Jul 2019 12:10:35 -0700
Subject: [PATCH 1/6] CVE-2019-10197: smbd: separate out impersonation debug
info into a new function.
Will be called on elsewhere on successful impersonation.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
source3/smbd/uid.c | 37 +++++++++++++++++++++++--------------
1 file changed, 23 insertions(+), 14 deletions(-)
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index a4bcb747d37e..ce8e8d92131c 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -279,6 +279,28 @@ static bool check_user_ok(connection_struct *conn,
return(True);
}
+static void print_impersonation_info(connection_struct *conn)
+{
+ struct smb_filename *cwdfname = NULL;
+
+ if (!CHECK_DEBUGLVL(DBGLVL_INFO)) {
+ return;
+ }
+
+ cwdfname = vfs_GetWd(talloc_tos(), conn);
+ if (cwdfname == NULL) {
+ return;
+ }
+
+ DBG_INFO("Impersonated user: uid=(%d,%d), gid=(%d,%d), cwd=[%s]\n",
+ (int)getuid(),
+ (int)geteuid(),
+ (int)getgid(),
+ (int)getegid(),
+ cwdfname->base_name);
+ TALLOC_FREE(cwdfname);
+}
+
/****************************************************************************
Become the user of a connection number without changing the security context
stack, but modify the current_user entries.
@@ -415,20 +437,7 @@ static bool change_to_user_internal(connection_struct *conn,
current_user.done_chdir = true;
}
- if (CHECK_DEBUGLVL(DBGLVL_INFO)) {
- struct smb_filename *cwdfname = vfs_GetWd(talloc_tos(), conn);
- if (cwdfname == NULL) {
- return false;
- }
- DBG_INFO("Impersonated user: uid=(%d,%d), gid=(%d,%d), cwd=[%s]\n",
- (int)getuid(),
- (int)geteuid(),
- (int)getgid(),
- (int)getegid(),
- cwdfname->base_name);
- TALLOC_FREE(cwdfname);
- }
-
+ print_impersonation_info(conn);
return true;
}
--
2.17.1

36
CVE-2019-10197-2.patch Normal file
View File

@ -0,0 +1,36 @@
From b4cd0dcbc38ae61cfb075e5f659384df889e99f7 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Thu, 11 Jul 2019 17:01:29 +0200
Subject: [PATCH 2/6] CVE-2019-10197: smbd: make sure that
change_to_user_internal() always resets current_user.done_chdir
We should not leave current_user.done_chdir as true if we didn't call
chdir_current_service() with success.
This caused problems in when calling vfs_ChDir() in pop_conn_ctx() when
chdir_current_service() worked once on one share but later failed on another
share.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
---
source3/smbd/uid.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index ce8e8d92131c..77a81f602988 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -427,6 +427,7 @@ static bool change_to_user_internal(connection_struct *conn,
current_user.conn = conn;
current_user.vuid = vuid;
current_user.need_chdir = conn->tcon_done;
+ current_user.done_chdir = false;
if (current_user.need_chdir) {
ok = chdir_current_service(conn);
--
2.17.1

30
CVE-2019-10197-3.patch Normal file
View File

@ -0,0 +1,30 @@
From b1496ce793129302c9959ebc6330219c6a3143f0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Tue, 18 Jun 2019 14:04:08 +0200
Subject: [PATCH 3/6] CVE-2019-10197: smbd: make sure we reset
current_user.{need,done}_chdir in become_root()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035
Signed-off-by: Stefan Metzmacher <metze@samba.org>
---
source3/smbd/uid.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 77a81f602988..50868ba8572a 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -624,6 +624,9 @@ void smbd_become_root(void)
}
push_conn_ctx();
set_root_sec_ctx();
+
+ current_user.need_chdir = false;
+ current_user.done_chdir = false;
}
/* Unbecome the root user */
--
2.17.1

49
CVE-2019-10197-4.patch Normal file
View File

@ -0,0 +1,49 @@
From 03a0719d6d5c1a81b44bc3cedc76563a1eb04491 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Tue, 30 Jul 2019 17:16:59 +0200
Subject: [PATCH 4/6] CVE-2019-10197: selftest: make fsrvp_share its own
independent subdirectory
The next patch will otherwise break the fsrvp related tests.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035
Signed-off-by: Stefan Metzmacher <metze@samba.org>
---
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 9d88253c9fe7..f7eb314138a0 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1540,6 +1540,9 @@ sub provision($$$$$$$$$)
my $widelinks_linkdir="$shrdir/widelinks_foo";
push(@dirs,$widelinks_linkdir);
+ my $fsrvp_shrdir="$shrdir/fsrvp";
+ push(@dirs,$fsrvp_shrdir);
+
my $shadow_tstdir="$shrdir/shadow";
push(@dirs,$shadow_tstdir);
my $shadow_mntdir="$shadow_tstdir/mount";
@@ -2083,14 +2086,14 @@ sub provision($$$$$$$$$)
guest ok = yes
[fsrvp_share]
- path = $shrdir
+ path = $fsrvp_shrdir
comment = fake shapshots using rsync
vfs objects = shell_snap shadow_copy2
shell_snap:check path command = $fake_snap_pl --check
shell_snap:create command = $fake_snap_pl --create
shell_snap:delete command = $fake_snap_pl --delete
# a relative path here fails, the snapshot dir is no longer found
- shadow:snapdir = $shrdir/.snapshots
+ shadow:snapdir = $fsrvp_shrdir/.snapshots
[shadow1]
path = $shadow_shrdir
--
2.17.1

111
CVE-2019-10197-5.patch Normal file
View File

@ -0,0 +1,111 @@
From 409447f3258b87745a2248570278b1c6da8991f4 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Tue, 16 Jul 2019 15:40:38 +0200
Subject: [PATCH 5/6] CVE-2019-10197: test_smbclient_s3.sh: add regression test
for the no permission on share root problem
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035
Signed-off-by: Stefan Metzmacher <metze@samba.org>
---
selftest/knownfail.d/CVE-2019-10197 | 1 +
selftest/target/Samba3.pm | 12 +++++++++
source3/script/tests/test_smbclient_s3.sh | 30 +++++++++++++++++++++++
3 files changed, 43 insertions(+)
create mode 100644 selftest/knownfail.d/CVE-2019-10197
diff --git a/selftest/knownfail.d/CVE-2019-10197 b/selftest/knownfail.d/CVE-2019-10197
new file mode 100644
index 000000000000..f7056bbf3ad4
--- /dev/null
+++ b/selftest/knownfail.d/CVE-2019-10197
@@ -0,0 +1 @@
+^samba3.blackbox.smbclient_s3.*.noperm.share.regression
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index f7eb314138a0..2f491441815f 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1516,6 +1516,9 @@ sub provision($$$$$$$$$)
my $ro_shrdir="$shrdir/root-tmp";
push(@dirs,$ro_shrdir);
+ my $noperm_shrdir="$shrdir/noperm-tmp";
+ push(@dirs,$noperm_shrdir);
+
my $msdfs_shrdir="$shrdir/msdfsshare";
push(@dirs,$msdfs_shrdir);
@@ -1586,6 +1589,11 @@ sub provision($$$$$$$$$)
chmod 0755, $piddir;
+ ##
+ ## Create a directory without permissions to enter
+ ##
+ chmod 0000, $noperm_shrdir;
+
##
## create ro and msdfs share layout
##
@@ -1902,6 +1910,10 @@ sub provision($$$$$$$$$)
[ro-tmp]
path = $ro_shrdir
guest ok = yes
+[noperm]
+ path = $noperm_shrdir
+ wide links = yes
+ guest ok = yes
[write-list-tmp]
path = $shrdir
read only = yes
diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh
index bf033ccd2fbf..0bae1d78fac9 100755
--- a/source3/script/tests/test_smbclient_s3.sh
+++ b/source3/script/tests/test_smbclient_s3.sh
@@ -1329,6 +1329,32 @@ EOF
fi
}
+#
+# Regression test for CVE-2019-10197
+# we should always get ACCESS_DENIED
+#
+test_noperm_share_regression()
+{
+ cmd='$SMBCLIENT -U$USERNAME%$PASSWORD //$SERVER/noperm -I $SERVER_IP $LOCAL_ADDARGS -c "ls;ls" 2>&1'
+ eval echo "$cmd"
+ out=`eval $cmd`
+ ret=$?
+ if [ $ret -eq 0 ] ; then
+ echo "$out"
+ echo "failed accessing no perm share should not work"
+ return 1
+ fi
+
+ num=`echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' | wc -l`
+ if [ "$num" -ne "2" ] ; then
+ echo "$out"
+ echo "failed num[$num] - two NT_STATUS_ACCESS_DENIED lines expected"
+ return 1
+ fi
+
+ return 0
+}
+
# Test smbclient deltree command
test_deltree()
{
@@ -1857,6 +1883,10 @@ testit "follow local symlinks" \
test_local_symlinks || \
failed=`expr $failed + 1`
+testit "noperm share regression" \
+ test_noperm_share_regression || \
+ failed=`expr $failed + 1`
+
testit "smbclient deltree command" \
test_deltree || \
failed=`expr $failed + 1`
--
2.17.1

87
CVE-2019-10197-6.patch Normal file
View File

@ -0,0 +1,87 @@
From 501e034aa5b6ba50bf14e41c59674fbbc28a2e9c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Thu, 11 Jul 2019 17:02:15 +0200
Subject: [PATCH 6/6] CVE-2019-10197: smbd: split change_to_user_impersonate()
out of change_to_user_internal()
This makes sure we always call chdir_current_service() even
when we still impersonated the user. Which is important
in order to run the SMB* request within the correct working directory
and only if the user has permissions to enter that directory.
It makes sure we always update conn->lastused_count
in chdir_current_service() for each request.
Note that vfs_ChDir() (called from chdir_current_service())
maintains its own cache and avoids calling SMB_VFS_CHDIR()
if possible.
It means we still avoid syscalls if we get a multiple requests
for the same session/tcon tuple.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
---
selftest/knownfail.d/CVE-2019-10197 | 1 -
source3/smbd/uid.c | 21 +++++++++++++++++----
2 files changed, 17 insertions(+), 5 deletions(-)
delete mode 100644 selftest/knownfail.d/CVE-2019-10197
diff --git a/selftest/knownfail.d/CVE-2019-10197 b/selftest/knownfail.d/CVE-2019-10197
deleted file mode 100644
index f7056bbf3ad4..000000000000
--- a/selftest/knownfail.d/CVE-2019-10197
+++ /dev/null
@@ -1 +0,0 @@
-^samba3.blackbox.smbclient_s3.*.noperm.share.regression
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 50868ba8572a..5c39baade5cf 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -306,9 +306,9 @@ static void print_impersonation_info(connection_struct *conn)
stack, but modify the current_user entries.
****************************************************************************/
-static bool change_to_user_internal(connection_struct *conn,
- const struct auth_session_info *session_info,
- uint64_t vuid)
+static bool change_to_user_impersonate(connection_struct *conn,
+ const struct auth_session_info *session_info,
+ uint64_t vuid)
{
int snum;
gid_t gid;
@@ -321,7 +321,6 @@ static bool change_to_user_internal(connection_struct *conn,
if ((current_user.conn == conn) &&
(current_user.vuid == vuid) &&
- (current_user.need_chdir == conn->tcon_done) &&
(current_user.ut.uid == session_info->unix_token->uid))
{
DBG_INFO("Skipping user change - already user\n");
@@ -426,6 +425,20 @@ static bool change_to_user_internal(connection_struct *conn,
current_user.conn = conn;
current_user.vuid = vuid;
+ return true;
+}
+
+static bool change_to_user_internal(connection_struct *conn,
+ const struct auth_session_info *session_info,
+ uint64_t vuid)
+{
+ bool ok;
+
+ ok = change_to_user_impersonate(conn, session_info, vuid);
+ if (!ok) {
+ return false;
+ }
+
current_user.need_chdir = conn->tcon_done;
current_user.done_chdir = false;
--
2.17.1

390
CVE-2019-14861.patch Normal file
View File

@ -0,0 +1,390 @@
From 9501741466ba2c0740ffc703c5d242d6b41510e8 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Tue, 29 Oct 2019 17:25:28 +1300
Subject: [PATCH 1/9] CVE-2019-14861: s4-rpc/dnsserver: Confirm sort behaviour
in dcesrv_DnssrvEnumRecords
The sort behaviour for child records is not correct in Samba so
we add a flapping entry.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14138
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
---
python/samba/tests/dcerpc/dnsserver.py | 101 +++++++++++++++++++++++++
selftest/flapping.d/dnsserver | 2 +
2 files changed, 103 insertions(+)
create mode 100644 selftest/flapping.d/dnsserver
diff --git a/python/samba/tests/dcerpc/dnsserver.py b/python/samba/tests/dcerpc/dnsserver.py
index 7264a290ef2..14ce308e38f 100644
--- a/python/samba/tests/dcerpc/dnsserver.py
+++ b/python/samba/tests/dcerpc/dnsserver.py
@@ -156,6 +156,107 @@ class DnsserverTests(RpcInterfaceTestCase):
None)
super(DnsserverTests, self).tearDown()
+ def test_enum_is_sorted(self):
+ """
+ Confirm the zone is sorted
+ """
+
+ record_str = "192.168.50.50"
+ record_type_str = "A"
+ self.add_record(self.custom_zone, "atestrecord-1", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-2", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-3", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-4", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-0", record_type_str, record_str)
+
+ # This becomes an extra A on the zone itself by server-side magic
+ self.add_record(self.custom_zone, self.custom_zone, record_type_str, record_str)
+
+ _, result = self.conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
+ 0,
+ self.server,
+ self.custom_zone,
+ "@",
+ None,
+ self.record_type_int(record_type_str),
+ dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA,
+ None,
+ None)
+
+ self.assertEqual(len(result.rec), 6)
+ self.assertEqual(result.rec[0].dnsNodeName.str, "")
+ self.assertEqual(result.rec[1].dnsNodeName.str, "atestrecord-0")
+ self.assertEqual(result.rec[2].dnsNodeName.str, "atestrecord-1")
+ self.assertEqual(result.rec[3].dnsNodeName.str, "atestrecord-2")
+ self.assertEqual(result.rec[4].dnsNodeName.str, "atestrecord-3")
+ self.assertEqual(result.rec[5].dnsNodeName.str, "atestrecord-4")
+
+ def test_enum_is_sorted_children_prefix_first(self):
+ """
+ Confirm the zone returns the selected prefix first but no more
+ as Samba is flappy for the full sort
+ """
+
+ record_str = "192.168.50.50"
+ record_type_str = "A"
+ self.add_record(self.custom_zone, "atestrecord-1.a.b", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-2.a.b", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-3.a.b", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-4.a.b", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-0.a.b", record_type_str, record_str)
+
+ # Not expected to be returned
+ self.add_record(self.custom_zone, "atestrecord-0.b.b", record_type_str, record_str)
+
+ _, result = self.conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
+ 0,
+ self.server,
+ self.custom_zone,
+ "a.b",
+ None,
+ self.record_type_int(record_type_str),
+ dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA,
+ None,
+ None)
+
+ self.assertEqual(len(result.rec), 6)
+ self.assertEqual(result.rec[0].dnsNodeName.str, "")
+
+ def test_enum_is_sorted_children(self):
+ """
+ Confirm the zone is sorted
+ """
+
+ record_str = "192.168.50.50"
+ record_type_str = "A"
+ self.add_record(self.custom_zone, "atestrecord-1.a.b", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-2.a.b", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-3.a.b", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-4.a.b", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-0.a.b", record_type_str, record_str)
+
+ # Not expected to be returned
+ self.add_record(self.custom_zone, "atestrecord-0.b.b", record_type_str, record_str)
+
+ _, result = self.conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
+ 0,
+ self.server,
+ self.custom_zone,
+ "a.b",
+ None,
+ self.record_type_int(record_type_str),
+ dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA,
+ None,
+ None)
+
+ self.assertEqual(len(result.rec), 6)
+ self.assertEqual(result.rec[0].dnsNodeName.str, "")
+ self.assertEqual(result.rec[1].dnsNodeName.str, "atestrecord-0")
+ self.assertEqual(result.rec[2].dnsNodeName.str, "atestrecord-1")
+ self.assertEqual(result.rec[3].dnsNodeName.str, "atestrecord-2")
+ self.assertEqual(result.rec[4].dnsNodeName.str, "atestrecord-3")
+ self.assertEqual(result.rec[5].dnsNodeName.str, "atestrecord-4")
+
# This test fails against Samba (but passes against Windows),
# because Samba does not return the record when we enum records.
# Records can be given DNS_RANK_NONE when the zone they are in
diff --git a/selftest/flapping.d/dnsserver b/selftest/flapping.d/dnsserver
new file mode 100644
index 00000000000..9b33e8522a3
--- /dev/null
+++ b/selftest/flapping.d/dnsserver
@@ -0,0 +1,2 @@
+# This is not stable in samba due to a bug
+^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_enum_is_sorted_children
\ No newline at end of file
--
2.17.1
From 51fa9a6a805e4221120847ee9dcab6796021175a Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Mon, 21 Oct 2019 12:12:10 +1300
Subject: [PATCH 2/9] CVE-2019-14861: s4-rpc_server: Remove special case for @
in dns_build_tree()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14138
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
---
source4/rpc_server/dnsserver/dnsdata.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/source4/rpc_server/dnsserver/dnsdata.c b/source4/rpc_server/dnsserver/dnsdata.c
index 59e29f029a6..f991f4042e3 100644
--- a/source4/rpc_server/dnsserver/dnsdata.c
+++ b/source4/rpc_server/dnsserver/dnsdata.c
@@ -795,10 +795,11 @@ struct dns_tree *dns_build_tree(TALLOC_CTX *mem_ctx, const char *name, struct ld
for (i=0; i<res->count; i++) {
ptr = ldb_msg_find_attr_as_string(res->msgs[i], "name", NULL);
- if (strcmp(ptr, "@") == 0) {
- base->data = res->msgs[i];
- continue;
- } else if (strcasecmp(ptr, name) == 0) {
+ /*
+ * This might be the sub-domain in the zone being
+ * requested, or @ for the root of the zone
+ */
+ if (strcasecmp(ptr, name) == 0) {
base->data = res->msgs[i];
continue;
}
--
2.17.1
From 16405fecc403517574915a49de5f4abcaa964e21 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Tue, 29 Oct 2019 14:15:36 +1300
Subject: [PATCH 3/9] CVE-2019-14861: s4-rpc/dnsserver: Avoid crash in
ldb_qsort() via dcesrv_DnssrvEnumRecords)
dns_name_compare() had logic to put @ and the top record in the tree being
enumerated first, but if a domain had both then this would break the
older qsort() implementation in ldb_qsort() and cause a read of memory
before the base pointer.
By removing this special case (not required as the base pointer
is already seperatly located, no matter were it is in the
returned records) the crash is avoided.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14138
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
---
.../rpc_server/dnsserver/dcerpc_dnsserver.c | 21 ++++++++++++-------
source4/rpc_server/dnsserver/dnsdata.c | 19 ++---------------
source4/rpc_server/dnsserver/dnsserver.h | 4 ++--
3 files changed, 17 insertions(+), 27 deletions(-)
diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
index 353754f9261..c0bf3425dae 100644
--- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
+++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
@@ -1733,6 +1733,7 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
struct DNS_RPC_RECORDS_ARRAY *recs;
char **add_names = NULL;
char *rname;
+ const char *preference_name = NULL;
int add_count = 0;
int i, ret, len;
WERROR status;
@@ -1749,6 +1750,7 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
LDB_SCOPE_ONELEVEL, attrs,
"(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
+ preference_name = "@";
} else {
char *encoded_name
= ldb_binary_encode_string(tmp_ctx, name);
@@ -1756,6 +1758,7 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
LDB_SCOPE_ONELEVEL, attrs,
"(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
encoded_name, encoded_name);
+ preference_name = name;
}
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
@@ -1769,16 +1772,18 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
- /* Sort the names, so that the first record is the parent record */
- ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
- (ldb_qsort_cmp_fn_t)dns_name_compare);
+ /*
+ * Sort the names, so that the records are in order by the child
+ * component below "name".
+ *
+ * A full tree sort is not required, so we pass in "name" so
+ * we know which level to sort, as only direct children are
+ * eventually returned
+ */
+ LDB_TYPESAFE_QSORT(res->msgs, res->count, name, dns_name_compare);
/* Build a tree of name components from dns name */
- if (strcasecmp(name, z->name) == 0) {
- tree = dns_build_tree(tmp_ctx, "@", res);
- } else {
- tree = dns_build_tree(tmp_ctx, name, res);
- }
+ tree = dns_build_tree(tmp_ctx, preference_name, res);
W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
/* Find the parent record in the tree */
diff --git a/source4/rpc_server/dnsserver/dnsdata.c b/source4/rpc_server/dnsserver/dnsdata.c
index f991f4042e3..acdb87752f8 100644
--- a/source4/rpc_server/dnsserver/dnsdata.c
+++ b/source4/rpc_server/dnsserver/dnsdata.c
@@ -1052,8 +1052,8 @@ WERROR dns_fill_records_array(TALLOC_CTX *mem_ctx,
}
-int dns_name_compare(const struct ldb_message **m1, const struct ldb_message **m2,
- char *search_name)
+int dns_name_compare(struct ldb_message * const *m1, struct ldb_message * const *m2,
+ const char *search_name)
{
const char *name1, *name2;
const char *ptr1, *ptr2;
@@ -1064,21 +1064,6 @@ int dns_name_compare(const struct ldb_message **m1, const struct ldb_message **m
return 0;
}
- /* '@' record and the search_name record gets preference */
- if (name1[0] == '@') {
- return -1;
- }
- if (search_name && strcasecmp(name1, search_name) == 0) {
- return -1;
- }
-
- if (name2[0] == '@') {
- return 1;
- }
- if (search_name && strcasecmp(name2, search_name) == 0) {
- return 1;
- }
-
/* Compare the last components of names.
* If search_name is not NULL, compare the second last components of names */
ptr1 = strrchr(name1, '.');
diff --git a/source4/rpc_server/dnsserver/dnsserver.h b/source4/rpc_server/dnsserver/dnsserver.h
index 93f1d72f2ef..690ab87ed10 100644
--- a/source4/rpc_server/dnsserver/dnsserver.h
+++ b/source4/rpc_server/dnsserver/dnsserver.h
@@ -188,8 +188,8 @@ struct DNS_ADDR_ARRAY *dns_addr_array_copy(TALLOC_CTX *mem_ctx, struct DNS_ADDR_
int dns_split_name_components(TALLOC_CTX *mem_ctx, const char *name, char ***components);
char *dns_split_node_name(TALLOC_CTX *mem_ctx, const char *node_name, const char *zone_name);
-int dns_name_compare(const struct ldb_message **m1, const struct ldb_message **m2,
- char *search_name);
+int dns_name_compare(struct ldb_message * const *m1, struct ldb_message * const *m2,
+ const char *search_name);
bool dns_record_match(struct dnsp_DnssrvRpcRecord *rec1, struct dnsp_DnssrvRpcRecord *rec2);
void dnsp_to_dns_copy(TALLOC_CTX *mem_ctx, struct dnsp_DnssrvRpcRecord *dnsp,
--
2.17.1
From 90073f0abc495c4b5bd05322b71667c534ee9dd8 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Wed, 30 Oct 2019 11:50:57 +1300
Subject: [PATCH 4/9] CVE-2019-14861: Test to demonstrate the bug
This test does not fail every time, but when it does it casues a segfault which
takes out the rpc_server master process, as this hosts the dnsserver pipe.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14138
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
---
python/samba/tests/dcerpc/dnsserver.py | 47 ++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/python/samba/tests/dcerpc/dnsserver.py b/python/samba/tests/dcerpc/dnsserver.py
index 14ce308e38f..a9b8a4ace91 100644
--- a/python/samba/tests/dcerpc/dnsserver.py
+++ b/python/samba/tests/dcerpc/dnsserver.py
@@ -191,6 +191,53 @@ class DnsserverTests(RpcInterfaceTestCase):
self.assertEqual(result.rec[4].dnsNodeName.str, "atestrecord-3")
self.assertEqual(result.rec[5].dnsNodeName.str, "atestrecord-4")
+ def test_enum_is_sorted_with_zone_dup(self):
+ """
+ Confirm the zone is sorted
+ """
+
+ record_str = "192.168.50.50"
+ record_type_str = "A"
+ self.add_record(self.custom_zone, "atestrecord-1", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-2", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-3", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-4", record_type_str, record_str)
+ self.add_record(self.custom_zone, "atestrecord-0", record_type_str, record_str)
+
+ # This triggers a bug in old Samba
+ self.add_record(self.custom_zone, self.custom_zone + "1", record_type_str, record_str)
+
+ dn, record = self.get_record_from_db(self.custom_zone, self.custom_zone + "1")
+
+ new_dn = ldb.Dn(self.samdb, str(dn))
+ new_dn.set_component(0, "dc", self.custom_zone)
+ self.samdb.rename(dn, new_dn)
+
+ _, result = self.conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
+ 0,
+ self.server,
+ self.custom_zone,
+ "@",
+ None,
+ self.record_type_int(record_type_str),
+ dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA,
+ None,
+ None)
+
+ self.assertEqual(len(result.rec), 7)
+ self.assertEqual(result.rec[0].dnsNodeName.str, "")
+ self.assertEqual(result.rec[1].dnsNodeName.str, "atestrecord-0")
+ self.assertEqual(result.rec[2].dnsNodeName.str, "atestrecord-1")
+ self.assertEqual(result.rec[3].dnsNodeName.str, "atestrecord-2")
+ self.assertEqual(result.rec[4].dnsNodeName.str, "atestrecord-3")
+ self.assertEqual(result.rec[5].dnsNodeName.str, "atestrecord-4")
+
+ # Windows doesn't reload the zone fast enough, but doesn't
+ # have the bug anyway, it will sort last on both names (where
+ # it should)
+ if result.rec[6].dnsNodeName.str != (self.custom_zone + "1"):
+ self.assertEqual(result.rec[6].dnsNodeName.str, self.custom_zone)
+
def test_enum_is_sorted_children_prefix_first(self):
"""
Confirm the zone returns the selected prefix first but no more
--
2.17.1

285
CVE-2019-14870.patch Normal file
View File

@ -0,0 +1,285 @@
From 5249cad8b435d162584f010f492568d6f4526662 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Wed, 30 Oct 2019 15:59:16 +0100
Subject: [PATCH 7/9] CVE-2019-14870: heimdal: add S4U test for
delegation_not_allowed
Signed-off-by: Isaac Boukris <iboukris@gmail.com>
---
selftest/knownfail.d/heimdal_not_delegated | 1 +
source4/selftest/tests.py | 1 +
testprogs/blackbox/test_s4u_heimdal.sh | 73 ++++++++++++++++++++++
3 files changed, 75 insertions(+)
create mode 100644 selftest/knownfail.d/heimdal_not_delegated
create mode 100755 testprogs/blackbox/test_s4u_heimdal.sh
diff --git a/selftest/knownfail.d/heimdal_not_delegated b/selftest/knownfail.d/heimdal_not_delegated
new file mode 100644
index 00000000000..bfc382a3fc2
--- /dev/null
+++ b/selftest/knownfail.d/heimdal_not_delegated
@@ -0,0 +1 @@
+^samba4.blackbox.krb5.s4u
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 9c3c77f1c56..2ec0bee923b 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -425,6 +425,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])
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
new file mode 100755
index 00000000000..0e12c7ec096
--- /dev/null
+++ b/testprogs/blackbox/test_s4u_heimdal.sh
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+if [ $# -lt 5 ]; then
+cat <<EOF
+Usage: test_kinit.sh SERVER USERNAME PASSWORD REALM DOMAIN PREFIX
+EOF
+exit 1;
+fi
+
+SERVER=$1
+USERNAME=$2
+PASSWORD=$3
+REALM=$4
+DOMAIN=$5
+PREFIX=$6
+shift 6
+failed=0
+
+
+samba_tool="$VALGRIND $PYTHON $BINDIR/samba-tool"
+
+samba4kinit=kinit
+if test -x $BINDIR/samba4kinit; then
+ samba4kinit=$BINDIR/samba4kinit
+fi
+
+samba4kgetcred=kgetcred
+if test -x $BINDIR/samba4kgetcred; then
+ samba4kgetcred=$BINDIR/samba4kgetcred
+fi
+
+. `dirname $0`/subunit.sh
+. `dirname $0`/common_test_fns.inc
+
+ocache="$PREFIX/tmpoutcache"
+KRB5CCNAME_PATH="$PREFIX/tmpccache"
+KRB5CCNAME="FILE:$KRB5CCNAME_PATH"
+export KRB5CCNAME
+rm -rf $KRB5CCNAME_PATH
+
+princ=test_impersonate_princ
+impersonator=test_impersonator
+target="CIFS/$SERVER.$REALM"
+
+
+testit "add impersonator principal" $samba_tool user add $impersonator $PASSWORD || failed=`expr $failed + 1`
+testit "become a service" $samba_tool spn add "HOST/$impersonator" $impersonator || failed=`expr $failed + 1`
+
+testit "set TrustedToAuthForDelegation" $samba_tool delegation for-any-protocol $impersonator on || failed=`expr $failed + 1`
+testit "add msDS-AllowedToDelegateTo" $samba_tool delegation add-service $impersonator $target || failed=`expr $failed + 1`
+
+testit "add a new principal" $samba_tool user add $princ --random-password || failed=`expr $failed + 1`
+testit "set not-delegated flag" $samba_tool user sensitive $princ on || failed=`expr $failed + 1`
+
+
+echo $PASSWORD > $PREFIX/tmppassfile
+testit "kinit with password" $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`
+
+testit "test S4U2Self with sensitive user" $samba4kgetcred --out-cache=$ocache --forwardable --impersonate=$princ $impersonator || failed=`expr $failed + 1`
+testit_expect_failure "test S4U2Proxy with sensitive user" $samba4kgetcred --out-cache=$ocache --delegation-credential-cache=${ocache} $target || failed=`expr $failed + 1`
+
+rm -f $ocache
+testit "unset not-delegated flag" $samba_tool user sensitive $princ off || failed=`expr $failed + 1`
+
+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`
+
+
+rm -f $ocache $PREFIX/tmpccache tmppassfile
+exit $failed
--
2.17.1
From d0d4954b9b4643678b6f465959dd69de0faafd07 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Mon, 28 Oct 2019 02:54:09 +0200
Subject: [PATCH 8/9] CVE-2019-14870: heimdal: enforce delegation_not_allowed
in S4U2Self
Signed-off-by: Isaac Boukris <iboukris@gmail.com>
---
selftest/knownfail.d/heimdal_not_delegated | 1 -
source4/heimdal/kdc/krb5tgs.c | 58 ++++++++++++++--------
2 files changed, 36 insertions(+), 23 deletions(-)
delete mode 100644 selftest/knownfail.d/heimdal_not_delegated
diff --git a/selftest/knownfail.d/heimdal_not_delegated b/selftest/knownfail.d/heimdal_not_delegated
deleted file mode 100644
index bfc382a3fc2..00000000000
--- a/selftest/knownfail.d/heimdal_not_delegated
+++ /dev/null
@@ -1 +0,0 @@
-^samba4.blackbox.krb5.s4u
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index ff7d93138c0..ee3ac3d8f53 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -1975,30 +1975,42 @@ server_lookup:
if (ret)
goto out;
+ ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags,
+ NULL, &s4u2self_impersonated_clientdb,
+ &s4u2self_impersonated_client);
+ if (ret) {
+ const char *msg;
+
+ /*
+ * If the client belongs to the same realm as our krbtgt, it
+ * should exist in the local database.
+ *
+ */
+
+ if (ret == HDB_ERR_NOENTRY)
+ ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+ msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 1,
+ "S2U4Self principal to impersonate %s not found in database: %s",
+ tpn, msg);
+ krb5_free_error_message(context, msg);
+ goto out;
+ }
+
+ /* Ignore pw_end attributes (as Windows does),
+ * since S4U2Self is not password authentication. */
+ free(s4u2self_impersonated_client->entry.pw_end);
+ s4u2self_impersonated_client->entry.pw_end = NULL;
+
+ ret = kdc_check_flags(context, config, s4u2self_impersonated_client, tpn,
+ NULL, NULL, FALSE);
+ if (ret)
+ 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_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags,
- NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client);
- if (ret) {
- const char *msg;
-
- /*
- * If the client belongs to the same realm as our krbtgt, it
- * should exist in the local database.
- *
- */
-
- if (ret == HDB_ERR_NOENTRY)
- ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
- msg = krb5_get_error_message(context, ret);
- kdc_log(context, config, 1,
- "S2U4Self principal to impersonate %s not found in database: %s",
- tpn, msg);
- krb5_free_error_message(context, msg);
- goto out;
- }
ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, &p);
if (ret) {
kdc_log(context, config, 0, "PAC generation failed for -- %s",
@@ -2034,10 +2046,12 @@ server_lookup:
/*
* If the service isn't trusted for authentication to
- * delegation, remove the forward flag.
+ * delegation or if the impersonate client is disallowed
+ * forwardable, remove the forwardable flag.
*/
- if (client->entry.flags.trusted_for_delegation) {
+ if (client->entry.flags.trusted_for_delegation &&
+ s4u2self_impersonated_client->entry.flags.forwardable) {
str = "[forwardable]";
} else {
b->kdc_options.forwardable = 0;
--
2.17.1
From 277ab21fcf31bf60458410994e188d9c236963a3 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Thu, 21 Nov 2019 11:12:48 +0100
Subject: [PATCH 9/9] CVE-2019-14870: mit-kdc: enforce delegation_not_allowed
flag
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14187
Signed-off-by: Isaac Boukris <iboukris@samba.org>
---
source4/kdc/mit_samba.c | 5 +++++
source4/kdc/sdb_to_kdb.c | 17 ++++++-----------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
index eacca0903ec..06e680b60e2 100644
--- a/source4/kdc/mit_samba.c
+++ b/source4/kdc/mit_samba.c
@@ -304,6 +304,11 @@ 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;
diff --git a/source4/kdc/sdb_to_kdb.c b/source4/kdc/sdb_to_kdb.c
index 74d882738f8..b7253ade122 100644
--- a/source4/kdc/sdb_to_kdb.c
+++ b/source4/kdc/sdb_to_kdb.c
@@ -36,18 +36,13 @@ static int SDBFlags_to_kflags(const struct SDBFlags *s,
if (s->initial) {
*k |= KRB5_KDB_DISALLOW_TGT_BASED;
}
- /*
- * Do not set any disallow rules for forwardable, proxiable,
- * renewable, postdate and server.
- *
- * The KDC will take care setting the flags based on the incoming
- * ticket.
- */
- if (s->forwardable) {
- ;
+ /* The forwardable and proxiable flags are set according to client and
+ * server attributes. */
+ if (!s->forwardable) {
+ *k |= KRB5_KDB_DISALLOW_FORWARDABLE;
}
- if (s->proxiable) {
- ;
+ if (!s->proxiable) {
+ *k |= KRB5_KDB_DISALLOW_PROXIABLE;
}
if (s->renewable) {
;
--
2.17.1

View File

@ -50,7 +50,7 @@
Name: samba
Version: 4.9.1
Release: 4
Release: 7
Summary: A suite for Linux to interoperate with Windows
License: GPLv3+ and LGPLv3+
URL: http://www.samba.org/
@ -80,6 +80,41 @@ Patch6011: CVE-2018-16841-1.patch
Patch6012: CVE-2018-16841-2.patch
Patch6013: CVE-2019-12435-1.patch
Patch6014: CVE-2019-12435-2.patch
Patch6015: CVE-2018-16852-1.patch
Patch6016: CVE-2018-16852-2.patch
Patch6017: CVE-2018-16852-3.patch
Patch6018: CVE-2018-16857-1.patch
Patch6019: CVE-2018-16857-2.patch
Patch6020: CVE-2018-16857-3.patch
Patch6021: CVE-2018-16857-4.patch
Patch6022: CVE-2018-16857-5.patch
Patch6023: CVE-2018-16857-6.patch
Patch6024: CVE-2018-16857-7.patch
Patch6025: CVE-2018-16857-8.patch
Patch6026: CVE-2018-16857-9.patch
Patch6027: CVE-2019-10197-1.patch
Patch6028: CVE-2019-10197-2.patch
Patch6029: CVE-2019-10197-3.patch
Patch6030: CVE-2019-10197-4.patch
Patch6031: CVE-2019-10197-5.patch
Patch6032: CVE-2019-10197-6.patch
Patch6033: 0001-CVE-2019-14847.patch
Patch6034: 0002-CVE-2019-14847.patch
Patch6035: 0003-CVE-2019-14847.patch
Patch6036: 0001-CVE-2019-14833.patch
Patch6037: 0002-CVE-2019-14833.patch
Patch6038: 0001-CVE-2019-10218.patch
Patch6039: 0002-CVE-2019-10218.patch
Patch6040: 0001-CVE-2019-3824.patch
Patch6041: 0002-CVE-2019-3824.patch
Patch6042: 0003-CVE-2019-3824.patch
Patch6043: 0004-CVE-2019-3824.patch
Patch6044: 0005-CVE-2019-3824.patch
Patch6045: 0006-CVE-2019-3824.patch
Patch6046: 0007-CVE-2019-3824.patch
Patch6047: CVE-2019-14861.patch
Patch6048: CVE-2019-14870.patch
Patch6049: CVE-2018-16860.patch
BuildRequires: avahi-devel cups-devel dbus-devel docbook-style-xsl e2fsprogs-devel gawk gnupg2 gpgme-devel
BuildRequires: jansson-devel krb5-devel >= %{required_mit_krb5} libacl-devel libaio-devel libarchive-devel
@ -580,29 +615,34 @@ then
exit -1
fi
touch %{buildroot}%{_libexecdir}/samba/cups_backend_smb
pushd %{buildroot}
touch .%{_libexecdir}/samba/cups_backend_smb
install -dm755 %{buildroot}%{_sysconfdir}/logrotate.d
install -m644 %{SOURCE3} %{buildroot}%{_sysconfdir}/logrotate.d/samba
install -dm755 .%{_sysconfdir}/logrotate.d
install -m644 %{SOURCE3} .%{_sysconfdir}/logrotate.d/samba
install -m644 %{SOURCE4} %{buildroot}%{_sysconfdir}/samba/smb.conf
install -m644 %{SOURCE5} %{buildroot}%{_sysconfdir}/samba/smb.conf.example
install -m644 %{SOURCE4} .%{_sysconfdir}/samba/smb.conf
install -m644 %{SOURCE5} .%{_sysconfdir}/samba/smb.conf.example
install -dm755 %{buildroot}%{_sysconfdir}/security
install -m644 %{SOURCE6} %{buildroot}%{_sysconfdir}/security/pam_winbind.conf
install -dm755 .%{_sysconfdir}/security
install -m644 %{SOURCE6} .%{_sysconfdir}/security/pam_winbind.conf
install -dm755 %{buildroot}%{_sysconfdir}/pam.d
install -m644 %{SOURCE7} %{buildroot}%{_sysconfdir}/pam.d/samba
install -dm755 .%{_sysconfdir}/pam.d
install -m644 %{SOURCE7} .%{_sysconfdir}/pam.d/samba
echo 127.0.0.1 localhost > %{buildroot}%{_sysconfdir}/samba/lmhosts
echo 127.0.0.1 localhost > .%{_sysconfdir}/samba/lmhosts
install -dm755 %{buildroot}%{_sysconfdir}/openldap/schema
install -m644 examples/LDAP/samba.schema %{buildroot}%{_sysconfdir}/openldap/schema/samba.schema
install -dm755 .%{_sysconfdir}/openldap/schema
install -m644 %{_builddir}/%{name}-%{version}/examples/LDAP/samba.schema \
%{buildroot}%{_sysconfdir}/openldap/schema/samba.schema
install -m744 packaging/printing/smbprint %{buildroot}%{_bindir}/smbprint
install -m744 %{_builddir}/%{name}-%{version}/packaging/printing/smbprint \
%{buildroot}%{_bindir}/smbprint
install -dm755 %{buildroot}%{_tmpfilesdir}
install -m644 packaging/systemd/samba.conf.tmp %{buildroot}%{_tmpfilesdir}/samba.conf
install -m644 %{_builddir}/%{name}-%{version}/packaging/systemd/samba.conf.tmp \
%{buildroot}%{_tmpfilesdir}/samba.conf
popd
echo "d /run/samba 755 root root" >> %{buildroot}%{_tmpfilesdir}/samba.conf
%if %with_clustering_support
@ -915,9 +955,9 @@ fi
%{_libdir}/%{name}/libsmbpasswdparser-samba4.so
%{_libdir}/%{name}/libxattr-tdb-samba4.so
%{_bindir}/smbstatus
%{_sbindir}/eventlogadm
%{_sbindir}/nmbd
%{_sbindir}/smbd
%{_sbindir}/nmbd
%{_sbindir}/eventlogadm
%if %{with_dc}
%{_libdir}/samba/vfs/dfs_samba4.so
%{_libdir}/samba/libdfs-server-ad-samba4.so
@ -998,6 +1038,7 @@ fi
%{_libdir}/libsmbldap.so.*
%{_libdir}/libtevent-util.so.*
%{_libdir}/libdcerpc.so.*
%{_bindir}/cifsdd
%{_bindir}/dbwrap_tool
%{_bindir}/findsmb
@ -1013,6 +1054,7 @@ fi
%exclude %{_bindir}/smbpasswd
%exclude %{_bindir}/smbstatus
%exclude %{_bindir}/smbtorture
%dir %{_libexecdir}/samba
%ghost %{_libexecdir}/samba/cups_backend_smb
@ -1113,8 +1155,8 @@ fi
%dir /var/lib/samba/lock
%attr(755,root,root) %dir %{_sysconfdir}/samba
%config(noreplace) %{_sysconfdir}/samba/smb.conf
%{_sysconfdir}/samba/smb.conf.example
%config(noreplace) %{_sysconfdir}/samba/lmhosts
%{_sysconfdir}/samba/smb.conf.example
%config(noreplace) %{_sysconfdir}/sysconfig/samba
%{_libdir}/samba/libpopt-samba3-samba4.so
%if %{with_intel_aes_accel}
@ -2383,14 +2425,13 @@ fi
%doc ctdb/README
%doc ctdb/doc/examples
%config(noreplace, missingok) %{_sysconfdir}/sysconfig/ctdb
%dir %{_sysconfdir}/ctdb
%config(noreplace) %{_sysconfdir}/ctdb/ctdb.conf
%config(noreplace) %{_sysconfdir}/ctdb/*.sh
%config(noreplace) %{_sysconfdir}/ctdb/ctdb.conf
%{_sysconfdir}/ctdb/functions
%{_sysconfdir}/ctdb/nfs-linux-kernel-callout
%{_sysconfdir}/ctdb/statd-callout
%{_sysconfdir}/ctdb/nfs-linux-kernel-callout
%config %{_sysconfdir}/sudoers.d/ctdb
%dir %{_sysconfdir}/ctdb/events
@ -2399,40 +2440,22 @@ fi
%dir %{_sysconfdir}/ctdb/nfs-checks.d
%{_sysconfdir}/ctdb/nfs-checks.d/README
%config(noreplace) %{_sysconfdir}/ctdb/nfs-checks.d/00.portmapper.check
%config(noreplace) %{_sysconfdir}/ctdb/nfs-checks.d/10.status.check
%config(noreplace) %{_sysconfdir}/ctdb/nfs-checks.d/20.nfs.check
%config(noreplace) %{_sysconfdir}/ctdb/nfs-checks.d/30.nlockmgr.check
%config(noreplace) %{_sysconfdir}/ctdb/nfs-checks.d/40.mountd.check
%config(noreplace) %{_sysconfdir}/ctdb/nfs-checks.d/50.rquotad.check
%config(noreplace) %{_sysconfdir}/ctdb/nfs-checks.d/*.check
%{_bindir}/ctdb
%{_bindir}/ctdb_diagnostics
%{_bindir}/ltdbtool
%{_bindir}/onnode
%{_bindir}/ping_pong
%{_sbindir}/ctdbd
%{_sbindir}/ctdbd_wrapper
%{_bindir}/ctdb
%{_bindir}/ping_pong
%{_bindir}/ltdbtool
%{_bindir}/ctdb_diagnostics
%{_bindir}/onnode
%dir %{_libexecdir}/ctdb
%{_libexecdir}/ctdb/ctdb-config
%{_libexecdir}/ctdb/ctdb-event
%{_libexecdir}/ctdb/ctdb-eventd
%{_libexecdir}/ctdb/ctdb_killtcp
%{_libexecdir}/ctdb/ctdb_lock_helper
%{_libexecdir}/ctdb/ctdb_lvs
%{_libexecdir}/ctdb/ctdb_mutex_fcntl_helper
%{_libexecdir}/ctdb/ctdb_natgw
%{_libexecdir}/ctdb/ctdb-path
%{_libexecdir}/ctdb/ctdb_recovery_helper
%{_libexecdir}/ctdb/ctdb_takeover_helper
%{_libexecdir}/ctdb/ctdb*
%{_libexecdir}/ctdb/smnotify
%dir %{_localstatedir}/lib/ctdb/
%{_tmpfilesdir}/ctdb.conf
%{_unitdir}/ctdb.service
%dir %{_datadir}/ctdb
@ -2463,56 +2486,9 @@ fi
%dir %{_libexecdir}/ctdb
%dir %{_libexecdir}/ctdb/tests
%{_libexecdir}/ctdb/tests/cmdline_test
%{_libexecdir}/ctdb/tests/comm_client_test
%{_libexecdir}/ctdb/tests/comm_server_test
%{_libexecdir}/ctdb/tests/comm_test
%{_libexecdir}/ctdb/tests/conf_test
%{_libexecdir}/ctdb/tests/ctdb_packet_parse
%{_libexecdir}/ctdb/tests/ctdb_takeover_tests
%{_libexecdir}/ctdb/tests/db_hash_test
%{_libexecdir}/ctdb/tests/dummy_client
%{_libexecdir}/ctdb/tests/errcode
%{_libexecdir}/ctdb/tests/event_protocol_test
%{_libexecdir}/ctdb/tests/event_script_test
%{_libexecdir}/ctdb/tests/fake_ctdbd
%{_libexecdir}/ctdb/tests/fetch_loop
%{_libexecdir}/ctdb/tests/fetch_loop_key
%{_libexecdir}/ctdb/tests/fetch_readonly
%{_libexecdir}/ctdb/tests/fetch_readonly_loop
%{_libexecdir}/ctdb/tests/fetch_ring
%{_libexecdir}/ctdb/tests/g_lock_loop
%{_libexecdir}/ctdb/tests/hash_count_test
%{_libexecdir}/ctdb/tests/line_test
%{_libexecdir}/ctdb/tests/lock_tdb
%{_libexecdir}/ctdb/tests/message_ring
%{_libexecdir}/ctdb/tests/pidfile_test
%{_libexecdir}/ctdb/tests/pkt_read_test
%{_libexecdir}/ctdb/tests/pkt_write_test
%{_libexecdir}/ctdb/tests/porting_tests
%{_libexecdir}/ctdb/tests/protocol_basic_test
%{_libexecdir}/ctdb/tests/protocol_ctdb_compat_test
%{_libexecdir}/ctdb/tests/protocol_ctdb_test
%{_libexecdir}/ctdb/tests/protocol_types_compat_test
%{_libexecdir}/ctdb/tests/protocol_types_test
%{_libexecdir}/ctdb/tests/protocol_util_test
%{_libexecdir}/ctdb/tests/rb_test
%{_libexecdir}/ctdb/tests/reqid_test
%{_libexecdir}/ctdb/tests/run_event_test
%{_libexecdir}/ctdb/tests/run_proc_test
%{_libexecdir}/ctdb/tests/sigcode
%{_libexecdir}/ctdb/tests/sock_daemon_test
%{_libexecdir}/ctdb/tests/sock_io_test
%{_libexecdir}/ctdb/tests/srvid_test
%{_libexecdir}/ctdb/tests/test_mutex_raw
%{_libexecdir}/ctdb/tests/transaction_loop
%{_libexecdir}/ctdb/tests/tunnel_cmd
%{_libexecdir}/ctdb/tests/tunnel_test
%{_libexecdir}/ctdb/tests/update_record
%{_libexecdir}/ctdb/tests/update_record_persistent
%{_libexecdir}/ctdb/tests/*
%dir %{_datadir}/ctdb/tests
%dir %{_datadir}/ctdb/tests/complex
%{_datadir}/ctdb/tests/complex/*
%exclude %{_datadir}/ctdb/tests/complex/scripts
@ -3246,11 +3222,29 @@ fi
%{_mandir}/man8/smbpasswd.8*
%changelog
* Sat Dec 21 2019 openEuler Buildteam <buildteam@openeuler.org> - 4.9.1-7
- Type:bugfix
- Id:NA
- SUG:NA
- DESC:fix CVE
* Thu Dec 19 2019 openEuler Buildteam <buildteam@openeuler.org> - 4.9.1-6
- Type:bugfix
- Id:NA
- SUG:NA
- DESC:modify the changelog message
* Tue Dec 3 2019 openEuler Buildteam <buildteam@openeuler.org> - 4.9.1-5
- Type: NA
- ID: NA
- SUG: NA
- DESC: optimize the spec file
* Thu Nov 21 2019 openEuler Buildteam <buildteam@openeuler.org> - 4.9.1-4
- Type: enhancement
- ID: NA
- SUG: NA
- DESC:modify spec file to solve fossid
- DESC:modify spec file
* Mon Sep 23 2019 huzhiyu<huzhiyu1@huawei.com> - 4.9.1-3
- Package init