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

Karolin Seeger kseeger at samba.org
Mon Apr 8 10:29:48 UTC 2019


The branch, v4-9-test has been updated
       via  d162726a2e7 VERSION: Bump version up to 4.9.7.
       via  8ee79597846 Merge tag 'samba-4.9.6' into v4-9-test
       via  dd7b68d11c0 VERSION: Disable GIT_SNAPSHOT for the 4.9.6 release.
       via  424563dbdab WHATSNEW: Add release notes for Samba 4.9.6.
       via  d53121af802 CVE-2019-3880 s3: rpc: winreg: Remove implementations of SaveKey/RestoreKey.
       via  c92ac5ada09 CVE-2019-3870 pysmbd: Ensure a zero umask is set for smbd.mkdir()
       via  30db48655f7 CVE-2019-3870 pysmbd: Move umask manipuations as close as possible to users
       via  65a175aac08 CVE-2019-3870 pysmbd: Include tests to show the outside umask has no impact
       via  83cc536a420 CVE-2019-3870 tests: Add test to check file-permissions are correct after provision
       via  b708ce3f1ac CVE-2019-3870 tests: Extend smbd tests to check for umask being overwritten
       via  49231313afe VERSION: Bump version up to 4.9.6...
      from  d59cefc8c3b libcli: permit larger values of DataLength in SMB2_ENCRYPTION_CAPABILITIES of negotiate response

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


- Log -----------------------------------------------------------------
commit d162726a2e7d9008930dad5e129b93f9837e1d9a
Author: Karolin Seeger <kseeger at samba.org>
Date:   Mon Apr 8 12:29:27 2019 +0200

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

commit 8ee7959784613bfc1a5c4b82eb9257c8be4f8352
Merge: d59cefc8c3b dd7b68d11c0
Author: Karolin Seeger <kseeger at samba.org>
Date:   Mon Apr 8 12:29:09 2019 +0200

    Merge tag 'samba-4.9.6' into v4-9-test
    
    samba: tag release samba-4.9.6

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

Summary of changes:
 VERSION                                    |  2 +-
 WHATSNEW.txt                               | 66 ++++++++++++++++++++-
 python/samba/tests/ntacls_backup.py        | 17 +++++-
 python/samba/tests/posixacl.py             |  4 +-
 python/samba/tests/smbd_base.py            | 48 ++++++++++++++++
 source3/rpc_server/winreg/srv_winreg_nt.c  | 92 ++----------------------------
 source3/smbd/pysmbd.c                      | 45 +++++++--------
 source4/selftest/tests.py                  |  1 +
 source4/setup/tests/provision_fileperms.sh | 71 +++++++++++++++++++++++
 9 files changed, 226 insertions(+), 120 deletions(-)
 create mode 100644 python/samba/tests/smbd_base.py
 create mode 100755 source4/setup/tests/provision_fileperms.sh


Changeset truncated at 500 lines:

diff --git a/VERSION b/VERSION
index 94639913d30..c0a407a83f4 100644
--- a/VERSION
+++ b/VERSION
@@ -25,7 +25,7 @@
 ########################################################
 SAMBA_VERSION_MAJOR=4
 SAMBA_VERSION_MINOR=9
-SAMBA_VERSION_RELEASE=6
+SAMBA_VERSION_RELEASE=7
 
 ########################################################
 # If a official release has a serious bug              #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 46298bdbbbc..25f826e441b 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,65 @@
+                   =============================
+                   Release Notes for Samba 4.9.6
+                           April 8, 2019
+                   =============================
+
+
+This is a security release in order to address the following defects:
+
+o  CVE-2019-3870 (World writable files in Samba AD DC private/ dir)
+o  CVE-2019-3880 (Save registry file outside share as unprivileged user)
+
+
+=======
+Details
+=======
+
+o  CVE-2019-3870:
+   During the provision of a new Active Directory DC, some files in the private/
+   directory are created world-writable.
+
+o  CVE-2019-3880:
+   Authenticated users with write permission can trigger a symlink traversal to
+   write or detect files outside the Samba share.
+
+For more details and workarounds, please refer to the security advisories.
+
+
+Changes since 4.9.5:
+--------------------
+
+o  Andrew Bartlett <abartlet at samba.org>
+   * BUG 13834: CVE-2019-3870: pysmbd: Ensure a zero umask is set for
+     smbd.mkdir().
+
+o  Jeremy Allison <jra at samba.org>
+   * BUG 13851: CVE-2018-14629: rpc: winreg: Remove implementations of
+     SaveKey/RestoreKey.
+
+
+#######################################
+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.9.5
                            March 12, 2019
@@ -136,8 +198,8 @@ database (https://bugzilla.samba.org/).
 ======================================================================
 
 
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
+
 
                    =============================
                    Release Notes for Samba 4.9.4
diff --git a/python/samba/tests/ntacls_backup.py b/python/samba/tests/ntacls_backup.py
index 9ab264a27fd..b7defd35903 100644
--- a/python/samba/tests/ntacls_backup.py
+++ b/python/samba/tests/ntacls_backup.py
@@ -27,10 +27,10 @@ from samba import ntacls
 from samba.auth import system_session
 from samba.param import LoadParm
 from samba.dcerpc import security
-from samba.tests import TestCaseInTempDir
+from samba.tests.smbd_base import SmbdBaseTests
 
 
-class NtaclsBackupRestoreTests(TestCaseInTempDir):
+class NtaclsBackupRestoreTests(SmbdBaseTests):
     """
     Tests for NTACLs backup and restore.
     """
@@ -112,6 +112,12 @@ class NtaclsBackupRestoreTests(TestCaseInTempDir):
 
         dirpath = os.path.join(self.service_root, 'a-dir')
         smbd.mkdir(dirpath, self.service)
+        mode = os.stat(dirpath).st_mode
+
+        # This works in conjunction with the TEST_UMASK in smbd_base
+        # to ensure that permissions are not related to the umask
+        # but instead the smb.conf settings
+        self.assertEquals(mode & 0o777, 0o755)
         self.assertTrue(os.path.isdir(dirpath))
 
     def test_smbd_create_file(self):
@@ -123,6 +129,13 @@ class NtaclsBackupRestoreTests(TestCaseInTempDir):
         smbd.create_file(filepath, self.service)
         self.assertTrue(os.path.isfile(filepath))
 
+        mode = os.stat(filepath).st_mode
+
+        # This works in conjunction with the TEST_UMASK in smbd_base
+        # to ensure that permissions are not related to the umask
+        # but instead the smb.conf settings
+        self.assertEquals(mode & 0o777, 0o644)
+
         # As well as checking that unlink works, this removes the
         # fake xattrs from the dev/inode based DB
         smbd.unlink(filepath, self.service)
diff --git a/python/samba/tests/posixacl.py b/python/samba/tests/posixacl.py
index 8b48825fc6f..2005f4eef59 100644
--- a/python/samba/tests/posixacl.py
+++ b/python/samba/tests/posixacl.py
@@ -20,7 +20,7 @@
 
 from samba.ntacls import setntacl, getntacl, checkset_backend
 from samba.dcerpc import security, smb_acl, idmap
-from samba.tests import TestCaseInTempDir
+from samba.tests.smbd_base import SmbdBaseTests
 from samba import provision
 import os
 from samba.samba3 import smbd, passdb
@@ -32,7 +32,7 @@ DOM_SID = "S-1-5-21-2212615479-2695158682-2101375467"
 ACL = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)"
 
 
-class PosixAclMappingTests(TestCaseInTempDir):
+class PosixAclMappingTests(SmbdBaseTests):
 
     def setUp(self):
         super(PosixAclMappingTests, self).setUp()
diff --git a/python/samba/tests/smbd_base.py b/python/samba/tests/smbd_base.py
new file mode 100644
index 00000000000..b49bcc0828f
--- /dev/null
+++ b/python/samba/tests/smbd_base.py
@@ -0,0 +1,48 @@
+# Unix SMB/CIFS implementation. Common code for smbd python bindings tests
+# Copyright (C) Catalyst.Net Ltd 2019
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+from samba.tests import TestCaseInTempDir
+import os
+
+TEST_UMASK = 0o042
+
+class SmbdBaseTests(TestCaseInTempDir):
+
+    def get_umask(self):
+        # we can only get the umask by setting it to something
+        curr_umask = os.umask(0)
+        # restore the old setting
+        os.umask(curr_umask)
+        return curr_umask
+
+    def setUp(self):
+        super(SmbdBaseTests, self).setUp()
+        self.orig_umask = self.get_umask()
+
+        # set an arbitrary umask - the underlying smbd code should override
+        # this, but it allows us to check if umask is left unset
+        os.umask(TEST_UMASK)
+
+    def tearDown(self):
+        # the current umask should be what we set it to earlier - if it's not,
+        # it indicates the code has changed it and not restored it
+        self.assertEqual(self.get_umask(), TEST_UMASK,
+                         "umask unexpectedly overridden by test")
+
+        # restore the original umask value (before we interferred with it)
+        os.umask(self.orig_umask)
+
+        super(SmbdBaseTests, self).tearDown()
diff --git a/source3/rpc_server/winreg/srv_winreg_nt.c b/source3/rpc_server/winreg/srv_winreg_nt.c
index d9ee8d0602d..816c6bb2a12 100644
--- a/source3/rpc_server/winreg/srv_winreg_nt.c
+++ b/source3/rpc_server/winreg/srv_winreg_nt.c
@@ -639,46 +639,6 @@ WERROR _winreg_AbortSystemShutdown(struct pipes_struct *p,
 	return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
 }
 
-/*******************************************************************
- ********************************************************************/
-
-static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
-{
-	char *p = NULL;
-	int num_services = lp_numservices();
-	int snum = -1;
-	const char *share_path = NULL;
-	char *fname = *pp_fname;
-
-	/* convert to a unix path, stripping the C:\ along the way */
-
-	if (!(p = valid_share_pathname(ctx, fname))) {
-		return -1;
-	}
-
-	/* has to exist within a valid file share */
-
-	for (snum=0; snum<num_services; snum++) {
-		if (!lp_snum_ok(snum) || lp_printable(snum)) {
-			continue;
-		}
-
-		share_path = lp_path(talloc_tos(), snum);
-
-		/* make sure we have a path (e.g. [homes] ) */
-		if (strlen(share_path) == 0) {
-			continue;
-		}
-
-		if (strncmp(share_path, p, strlen(share_path)) == 0) {
-			break;
-		}
-	}
-
-	*pp_fname = p;
-	return (snum < num_services) ? snum : -1;
-}
-
 /*******************************************************************
  _winreg_RestoreKey
  ********************************************************************/
@@ -687,36 +647,11 @@ WERROR _winreg_RestoreKey(struct pipes_struct *p,
 			  struct winreg_RestoreKey *r)
 {
 	struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
-	char *fname = NULL;
-	int snum = -1;
 
-	if ( !regkey )
+	if ( !regkey ) {
 		return WERR_INVALID_HANDLE;
-
-	if ( !r->in.filename || !r->in.filename->name )
-		return WERR_INVALID_PARAMETER;
-
-	fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
-	if (!fname) {
-		return WERR_NOT_ENOUGH_MEMORY;
 	}
-
-	DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
-		 "\"%s\"\n", regkey->key->name, fname));
-
-	if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
-		return WERR_BAD_PATHNAME;
-
-	/* user must posses SeRestorePrivilege for this this proceed */
-
-	if ( !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_RESTORE)) {
-		return WERR_ACCESS_DENIED;
-	}
-
-	DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
-		 regkey->key->name, fname, lp_servicename(talloc_tos(), snum) ));
-
-	return reg_restorekey(regkey, fname);
+	return WERR_BAD_PATHNAME;
 }
 
 /*******************************************************************
@@ -727,30 +662,11 @@ WERROR _winreg_SaveKey(struct pipes_struct *p,
 		       struct winreg_SaveKey *r)
 {
 	struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
-	char *fname = NULL;
-	int snum = -1;
 
-	if ( !regkey )
+	if ( !regkey ) {
 		return WERR_INVALID_HANDLE;
-
-	if ( !r->in.filename || !r->in.filename->name )
-		return WERR_INVALID_PARAMETER;
-
-	fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
-	if (!fname) {
-		return WERR_NOT_ENOUGH_MEMORY;
 	}
-
-	DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
-		 regkey->key->name, fname));
-
-	if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
-		return WERR_BAD_PATHNAME;
-
-	DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
-		 regkey->key->name, fname, lp_servicename(talloc_tos(), snum) ));
-
-	return reg_savekey(regkey, fname);
+	return WERR_BAD_PATHNAME;
 }
 
 /*******************************************************************
diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
index 1431925efd0..845ea25f936 100644
--- a/source3/smbd/pysmbd.c
+++ b/source3/smbd/pysmbd.c
@@ -85,27 +85,19 @@ static int set_sys_acl_conn(const char *fname,
 {
 	int ret;
 	struct smb_filename *smb_fname = NULL;
-	mode_t saved_umask;
 
 	TALLOC_CTX *frame = talloc_stackframe();
 
-	/* we want total control over the permissions on created files,
-	   so set our umask to 0 */
-	saved_umask = umask(0);
-
 	smb_fname = synthetic_smb_fname_split(frame,
 					fname,
 					lp_posix_pathnames());
 	if (smb_fname == NULL) {
 		TALLOC_FREE(frame);
-		umask(saved_umask);
 		return -1;
 	}
 
 	ret = SMB_VFS_SYS_ACL_SET_FILE( conn, smb_fname, acltype, theacl);
 
-	umask(saved_umask);
-
 	TALLOC_FREE(frame);
 	return ret;
 }
@@ -132,22 +124,26 @@ static NTSTATUS init_files_struct(TALLOC_CTX *mem_ctx,
 	}
 	fsp->conn = conn;
 
-	/* we want total control over the permissions on created files,
-	   so set our umask to 0 */
-	saved_umask = umask(0);
-
 	smb_fname = synthetic_smb_fname_split(fsp,
 					      fname,
 					      lp_posix_pathnames());
 	if (smb_fname == NULL) {
-		umask(saved_umask);
 		return NT_STATUS_NO_MEMORY;
 	}
 
 	fsp->fsp_name = smb_fname;
+
+	/*
+	 * we want total control over the permissions on created files,
+	 * so set our umask to 0 (this matters if flags contains O_CREAT)
+	 */
+	saved_umask = umask(0);
+
 	fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, 00644);
+
+	umask(saved_umask);
+
 	if (fsp->fh->fd == -1) {
-		umask(saved_umask);
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
@@ -157,7 +153,6 @@ static NTSTATUS init_files_struct(TALLOC_CTX *mem_ctx,
 		DEBUG(0,("Error doing fstat on open file %s (%s)\n",
 			 smb_fname_str_dbg(smb_fname),
 			 strerror(errno) ));
-		umask(saved_umask);
 		return map_nt_error_from_unix(errno);
 	}
 
@@ -444,7 +439,6 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args, PyObject *kwargs)
 	char *fname, *service = NULL;
 	int uid, gid;
 	TALLOC_CTX *frame;
-	mode_t saved_umask;
 	struct smb_filename *smb_fname = NULL;
 
 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sii|z",
@@ -460,10 +454,6 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args, PyObject *kwargs)
 		return NULL;
 	}
 
-	/* we want total control over the permissions on created files,
-	   so set our umask to 0 */
-	saved_umask = umask(0);
-
 	smb_fname = synthetic_smb_fname(talloc_tos(),
 					fname,
 					NULL,
@@ -471,7 +461,6 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args, PyObject *kwargs)
 					lp_posix_pathnames() ?
 						SMB_FILENAME_POSIX_PATH : 0);
 	if (smb_fname == NULL) {
-		umask(saved_umask);
 		TALLOC_FREE(frame);
 		errno = ENOMEM;
 		return PyErr_SetFromErrno(PyExc_OSError);
@@ -479,14 +468,11 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args, PyObject *kwargs)
 
 	ret = SMB_VFS_CHOWN(conn, smb_fname, uid, gid);
 	if (ret != 0) {
-		umask(saved_umask);
 		TALLOC_FREE(frame);
 		errno = ret;
 		return PyErr_SetFromErrno(PyExc_OSError);
 	}
 
-	umask(saved_umask);
-
 	TALLOC_FREE(frame);
 
 	Py_RETURN_NONE;
@@ -753,6 +739,8 @@ static PyObject *py_smbd_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
 	TALLOC_CTX *frame = talloc_stackframe();
 	struct connection_struct *conn = NULL;
 	struct smb_filename *smb_fname = NULL;
+	int ret;
+	mode_t saved_umask;
 
 	if (!PyArg_ParseTupleAndKeywords(args,
 					 kwargs,
@@ -783,8 +771,15 @@ static PyObject *py_smbd_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
 		return NULL;
 	}
 
+	/* we want total control over the permissions on created files,
+	   so set our umask to 0 */
+	saved_umask = umask(0);
+
+	ret = SMB_VFS_MKDIR(conn, smb_fname, 00755);
+
+	umask(saved_umask);
 
-	if (SMB_VFS_MKDIR(conn, smb_fname, 00755) == -1) {
+	if (ret == -1) {
 		DBG_ERR("mkdir error=%d (%s)\n", errno, strerror(errno));
 		TALLOC_FREE(frame);
 		return NULL;
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 18b2c1162b0..d6fb388dc33 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -904,6 +904,7 @@ plantestsuite_loadlist("samba4.deletetest.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [
 plantestsuite("samba4.blackbox.samba3dump", "none", [os.path.join(samba4srcdir, "selftest/test_samba3dump.sh")])
 plantestsuite("samba4.blackbox.upgrade", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_s3upgrade.sh"), '$PREFIX/provision'])
 plantestsuite("samba4.blackbox.provision.py", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_provision.sh"), '$PREFIX/provision'])
+plantestsuite("samba4.blackbox.provision_fileperms", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/provision_fileperms.sh"), '$PREFIX/provision'])
 plantestsuite("samba4.blackbox.supported_features", "none",
               ["PYTHON=%s" % python,
                os.path.join(samba4srcdir,
diff --git a/source4/setup/tests/provision_fileperms.sh b/source4/setup/tests/provision_fileperms.sh
new file mode 100755
index 00000000000..0b3ef0321fb
--- /dev/null
+++ b/source4/setup/tests/provision_fileperms.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+if [ $# -lt 1 ]; then
+cat <<EOF


-- 
Samba Shared Repository



More information about the samba-cvs mailing list