[SCM] Samba Shared Repository - branch v4-11-test updated

Karolin Seeger kseeger at samba.org
Tue Oct 29 10:11:19 UTC 2019


The branch, v4-11-test has been updated
       via  e704eee3083 VERSION: Bump version up to 4.11.3.
       via  685c2d56a25 Merge tag 'samba-4.11.2' into v4-11-test
       via  df2b97d12e6 VERSION: Disable GIT_SNAPSHOT for the 4.11.2 release.
       via  3815f9bfda8 WHATSNEW: Add release notes for Samba 4.11.2.
       via  e33b8c56510 CVE-2019-14847 dsdb: Correct behaviour of ranged_results when combined with dirsync
       via  4087d16945f CVE-2019-14847 dsdb: Demonstrate the correct interaction of ranged_results style attributes and dirsync
       via  b3a71bf847e CVE-2019-14833 dsdb: send full password to check password script
       via  e0e8830b88e CVE-2019-14833: Use utf8 characters in the unacceptable password
       via  914c985e66a CVE-2019-10218 - s3: libsmb: Protect SMB2 client code from evil server returned names.
       via  07df3dfa6bf CVE-2019-10218 - s3: libsmb: Protect SMB1 client code from evil server returned names.
       via  193d6f5e8cc VERSION: Bump version up to 4.11.2...
      from  7b8309398be VERSION: Bump version up to 4.11.2...

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-11-test


- Log -----------------------------------------------------------------
commit e704eee3083658f7dcdd4238295f8e0b229a1688
Author: Karolin Seeger <kseeger at samba.org>
Date:   Tue Oct 29 11:10:52 2019 +0100

    VERSION: Bump version up to 4.11.3.
    
    Signed-off-by: Karolin Seeger <kseeger at samba.org>

commit 685c2d56a25f54c22bfb1a00f1c49386667b9998
Merge: 7b8309398be df2b97d12e6
Author: Karolin Seeger <kseeger at samba.org>
Date:   Tue Oct 29 11:10:20 2019 +0100

    Merge tag 'samba-4.11.2' into v4-11-test
    
    samba: tag release samba-4.11.2

-----------------------------------------------------------------------

Summary of changes:
 VERSION                                         |  2 +-
 WHATSNEW.txt                                    | 78 ++++++++++++++++++++++++-
 selftest/target/Samba4.pm                       |  2 +-
 source3/libsmb/cli_smb2_fnum.c                  |  7 +++
 source3/libsmb/clilist.c                        | 75 ++++++++++++++++++++++++
 source3/libsmb/proto.h                          |  3 +
 source4/dsdb/common/util.c                      | 30 ++++++++--
 source4/dsdb/samdb/ldb_modules/dirsync.c        | 11 ++--
 source4/dsdb/samdb/ldb_modules/ranged_results.c | 25 +++++++-
 source4/dsdb/tests/python/dirsync.py            | 26 +++++++++
 10 files changed, 241 insertions(+), 18 deletions(-)


Changeset truncated at 500 lines:

diff --git a/VERSION b/VERSION
index fbc941686eb..e9cc49c7f77 100644
--- a/VERSION
+++ b/VERSION
@@ -25,7 +25,7 @@
 ########################################################
 SAMBA_VERSION_MAJOR=4
 SAMBA_VERSION_MINOR=11
-SAMBA_VERSION_RELEASE=2
+SAMBA_VERSION_RELEASE=3
 
 ########################################################
 # If a official release has a serious bug              #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 2e61702b71b..8c6db3b3034 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,77 @@
+                   ==============================
+                   Release Notes for Samba 4.11.2
+                          October 29, 2019
+		   ==============================
+
+
+This is a security release in order to address the following defects:
+
+o CVE-2019-10218: Client code can return filenames containing path separators.          
+o CVE-2019-14833: Samba AD DC check password script does not receive the full
+		  password.
+o CVE-2019-14847: User with "get changes" permission can crash AD DC LDAP server
+		  via dirsync.
+
+=======
+Details
+=======
+
+o  CVE-2019-10218:
+   Malicious servers can cause Samba client code to return filenames containing
+   path separators to calling code.
+
+o  CVE-2019-14833:
+   When the password contains multi-byte (non-ASCII) characters, the check
+   password script does not receive the full password string.
+
+o  CVE-2019-14847:
+   Users with the "get changes" extended access right can crash the AD DC LDAP
+   server by requesting an attribute using the range= syntax.
+
+For more details and workarounds, please refer to the security advisories.
+
+
+Changes since 4.11.1:
+---------------------
+
+o  Jeremy Allison <jra at samba.org>
+   * BUG 14071: CVE-2019-10218 - s3: libsmb: Protect SMB1 and SMB2 client code
+     from evil server returned names.
+
+o  Andrew Bartlett <abartlet at samba.org>
+   * BUG 12438: CVE-2019-14833: Use utf8 characters in the unacceptable
+     password.
+   * BUG 14040: CVE-2019-14847 dsdb: Correct behaviour of ranged_results when
+     combined with dirsync.
+
+o  Björn Baumbach <bb at sernet.de>
+   * BUG 12438: CVE-2019-14833 dsdb: Send full password to check password
+     script.
+
+
+#######################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical IRC channel on irc.freenode.net.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored.  All bug reports should
+be filed under the "Samba 4.1 and newer" product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
+
                    ==============================
                    Release Notes for Samba 4.11.1
                           October 18, 2019
@@ -81,8 +155,8 @@ database (https://bugzilla.samba.org/).
 ======================================================================
 
 
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
+
 
                    ==============================
                    Release Notes for Samba 4.11.0
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 02cdfc18bad..195e9b88044 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1993,7 +1993,7 @@ sub provision_chgdcpass($$)
 	print "PROVISIONING CHGDCPASS...\n";
 	# 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";
 	my $extra_smb_conf = "
 	check password script = $self->{srcdir}/selftest/checkpassword_arg1.sh ${unacceptable_password}
 	allow dcerpc auth level connect:lsarpc = yes
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index 535beaab841..3fa322c243b 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -1442,6 +1442,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)) {
 				/*
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 6a647da58c8..48855d7112c 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -760,6 +760,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);
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index e521ed09999..3ebec827404 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2036,21 +2036,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;
 	}
 
@@ -2058,6 +2073,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;
 		int cps_stdin = -1;
@@ -2120,7 +2136,9 @@ enum samr_ValidationStatus samdb_check_password(TALLOC_CTX *mem_ctx,
 
 		cps_stdin = samba_runcmd_export_stdin(req);
 
-		if (write(cps_stdin, utf8_pw, utf8_len) != utf8_len) {
+		nwritten = write(cps_stdin, utf8_blob->data,
+				 utf8_blob->length);
+		if (nwritten != utf8_blob->length) {
 			close(cps_stdin);
 			cps_stdin = -1;
 			TALLOC_FREE(password_script);
diff --git a/source4/dsdb/samdb/ldb_modules/dirsync.c b/source4/dsdb/samdb/ldb_modules/dirsync.c
index 00f24bd6d59..96cec7774cf 100644
--- a/source4/dsdb/samdb/ldb_modules/dirsync.c
+++ b/source4/dsdb/samdb/ldb_modules/dirsync.c
@@ -1014,7 +1014,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) {
@@ -1343,11 +1343,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);
diff --git a/source4/dsdb/tests/python/dirsync.py b/source4/dsdb/tests/python/dirsync.py
index 8b46357c670..78117bc364b 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
@@ -588,6 +589,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)


-- 
Samba Shared Repository



More information about the samba-cvs mailing list