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

Karolin Seeger kseeger at samba.org
Mon Nov 11 03:47:31 MST 2013


The branch, v4-0-test has been updated
       via  0a52101 VERSION: Bump version number up to 4.0.12...
       via  98712df Merge tag 'samba-4.0.11' into v4-0-test
       via  a8e0112 VERSION: Disable git snapshots for the 4.0.11 release.
       via  90b9835 WHATSNEW: Add release notes for Samba 4.0.11.
       via  66fb9ec CVE-2013-4476: s4:libtls: check for safe permissions of tls private key file (key.pem)
       via  c417cb7 CVE-2013-4476: s4:libtls: Create tls private key file (key.pem) with mode 0600
       via  c1e106b CVE-2013-4476: selftest/Samba4: use umask 0077 within mk_keyblobs()
       via  367f017 CVE-2013-4476: samba-tool provision: create ${private_dir}/tls with mode 0700
       via  e74797c CVE-2013-4476: lib-util: split out file_save_mode() from file_save()
       via  13566a5 CVE-2013-4476: lib-util: add file_check_permissions()
       via  761096f Add regression test for bug #10229 - No access check verification on stream files.
       via  a6d74c4 Fix bug #10229 - No access check verification on stream files.
      from  de4e721 s4-dns: dlz_bind9: Create dns-HOSTNAME account disabled

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit 0a52101416d4a4be75b2515d352137550d04b368
Author: Karolin Seeger <kseeger at samba.org>
Date:   Mon Nov 11 11:46:21 2013 +0100

    VERSION: Bump version number up to 4.0.12...
    
    and re-enable git snapshots.
    
    Signed-off-by: Karolin Seeger <kseeger at samba.org>

commit 98712df3ddf6cca5614f273eb21336c62a9157f7
Merge: de4e72152d83cf03e86c3531f43a9f2bed4967ac a8e0112c7c540307e263d00306cb06f473547cea
Author: Karolin Seeger <kseeger at samba.org>
Date:   Mon Nov 11 11:45:52 2013 +0100

    Merge tag 'samba-4.0.11' into v4-0-test
    
    samba: tag release samba-4.0.11

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

Summary of changes:
 VERSION                            |    2 +-
 WHATSNEW.txt                       |   77 +++++++++++++++-
 lib/util/samba_util.h              |   11 ++
 lib/util/util.c                    |   44 +++++++++
 lib/util/util_file.c               |   16 ++-
 python/samba/provision/__init__.py |    2 +-
 selftest/knownfail                 |    1 +
 selftest/target/Samba4.pm          |    6 +-
 source3/smbd/open.c                |   57 +++++++++++
 source4/lib/tls/tls.c              |   17 ++++
 source4/lib/tls/tls_tstream.c      |   16 +++
 source4/lib/tls/tlscert.c          |    2 +-
 source4/torture/raw/streams.c      |  181 ++++++++++++++++++++++++++++++++++++
 13 files changed, 421 insertions(+), 11 deletions(-)


Changeset truncated at 500 lines:

diff --git a/VERSION b/VERSION
index eb74a75..576d58f 100644
--- a/VERSION
+++ b/VERSION
@@ -25,7 +25,7 @@
 ########################################################
 SAMBA_VERSION_MAJOR=4
 SAMBA_VERSION_MINOR=0
-SAMBA_VERSION_RELEASE=11
+SAMBA_VERSION_RELEASE=12
 
 ########################################################
 # If a official release has a serious bug              #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 3b9462b..20b6e7f 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,4 +1,77 @@
                    ==============================
+                   Release Notes for Samba 4.0.11
+                          November 11, 2013
+                   ==============================
+
+
+This is a security release in order to address
+CVE-2013-4475 (ACLs are not checked on opening an alternate
+data stream on a file or directory) and
+CVE-2013-4476 (Private key in key.pem world readable).
+
+o  CVE-2013-4475:
+   Samba versions 3.2.0 and above (all versions of 3.2.x, 3.3.x,
+   3.4.x, 3.5.x, 3.6.x, 4.0.x and 4.1.x) do not check the underlying
+   file or directory ACL when opening an alternate data stream.
+
+   According to the SMB1 and SMB2+ protocols the ACL on an underlying
+   file or directory should control what access is allowed to alternate
+   data streams that are associated with the file or directory.
+
+   By default no version of Samba supports alternate data streams
+   on files or directories.
+
+   Samba can be configured to support alternate data streams by loading
+   either one of two virtual file system modues (VFS) vfs_streams_depot or
+   vfs_streams_xattr supplied with Samba, so this bug only affects Samba
+   servers configured this way.
+
+   To determine if your server is vulnerable, check for the strings
+   "streams_depot" or "streams_xattr" inside your smb.conf configuration
+   file.
+
+o  CVE-2013-4476:
+   In setups which provide ldap(s) and/or https services, the private
+   key for SSL/TLS encryption might be world readable. This typically
+   happens in active directory domain controller setups.
+
+
+Changes since 4.0.10:
+---------------------
+
+o   Jeremy Allison <jra at samba.org>
+    * BUGs 10234 + 10229: CVE-2013-4475: Fix access check verification on stream
+      files.
+
+
+o   Björn Baumbach <bb at sernet.de>
+    * BUG 10234: CVE-2013-4476: Private key in key.pem world readable.
+
+
+######################################################################
+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.0 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.0.10
                            October 8, 2013
                    ==============================
@@ -126,8 +199,8 @@ database (https://bugzilla.samba.org/).
 ======================================================================
 
 
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
+
 
                    =============================
                    Release Notes for Samba 4.0.9
diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h
index 4a6dd3b..311e99d 100644
--- a/lib/util/samba_util.h
+++ b/lib/util/samba_util.h
@@ -580,6 +580,8 @@ a line
 **/
 _PUBLIC_ void file_lines_slashcont(char **lines);
 
+_PUBLIC_ bool file_save_mode(const char *fname, const void *packet,
+			     size_t length, mode_t mode);
 /**
   save a lump of data into a file. Mostly used for debugging 
 */
@@ -623,6 +625,15 @@ _PUBLIC_ time_t file_modtime(const char *fname);
 _PUBLIC_ bool directory_exist(const char *dname);
 
 /**
+ Check file permissions.
+**/
+struct stat;
+_PUBLIC_ bool file_check_permissions(const char *fname,
+				     uid_t uid,
+				     mode_t file_perms,
+				     struct stat *pst);
+
+/**
  * Try to create the specified directory if it didn't exist.
  *
  * @retval true if the directory already existed and has the right permissions 
diff --git a/lib/util/util.c b/lib/util/util.c
index b50d28a..f63720c 100644
--- a/lib/util/util.c
+++ b/lib/util/util.c
@@ -119,6 +119,50 @@ _PUBLIC_ time_t file_modtime(const char *fname)
 }
 
 /**
+ Check file permissions.
+**/
+
+_PUBLIC_ bool file_check_permissions(const char *fname,
+				     uid_t uid,
+				     mode_t file_perms,
+				     struct stat *pst)
+{
+	int ret;
+	struct stat st;
+
+	if (pst == NULL) {
+		pst = &st;
+	}
+
+	ZERO_STRUCTP(pst);
+
+	ret = stat(fname, pst);
+	if (ret != 0) {
+		DEBUG(0, ("stat failed on file '%s': %s\n",
+			 fname, strerror(errno)));
+		return false;
+	}
+
+	if (pst->st_uid != uid && !uwrap_enabled()) {
+		DEBUG(0, ("invalid ownership of file '%s': "
+			 "owned by uid %u, should be %u\n",
+			 fname, (unsigned int)pst->st_uid,
+			 (unsigned int)uid));
+		return false;
+	}
+
+	if ((pst->st_mode & 0777) != file_perms) {
+		DEBUG(0, ("invalid permissions on file "
+			 "'%s': has 0%o should be 0%o\n", fname,
+			 (unsigned int)(pst->st_mode & 0777),
+			 (unsigned int)file_perms));
+		return false;
+	}
+
+	return true;
+}
+
+/**
  Check if a directory exists.
 **/
 
diff --git a/lib/util/util_file.c b/lib/util/util_file.c
index e031fc5..815cc2b 100644
--- a/lib/util/util_file.c
+++ b/lib/util/util_file.c
@@ -368,13 +368,11 @@ _PUBLIC_ void file_lines_slashcont(char **lines)
 	}
 }
 
-/**
-  save a lump of data into a file. Mostly used for debugging 
-*/
-_PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length)
+_PUBLIC_ bool file_save_mode(const char *fname, const void *packet,
+			     size_t length, mode_t mode)
 {
 	int fd;
-	fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+	fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, mode);
 	if (fd == -1) {
 		return false;
 	}
@@ -386,6 +384,14 @@ _PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length)
 	return true;
 }
 
+/**
+  save a lump of data into a file. Mostly used for debugging
+*/
+_PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length)
+{
+	return file_save_mode(fname, packet, length, 0644);
+}
+
 _PUBLIC_ int vfdprintf(int fd, const char *format, va_list ap)
 {
 	char *p;
diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py
index e0b3d22..0a54af8 100644
--- a/python/samba/provision/__init__.py
+++ b/python/samba/provision/__init__.py
@@ -2014,7 +2014,7 @@ def provision(logger, session_info, credentials, smbconf=None,
     if not os.path.exists(paths.private_dir):
         os.mkdir(paths.private_dir)
     if not os.path.exists(os.path.join(paths.private_dir, "tls")):
-        os.mkdir(os.path.join(paths.private_dir, "tls"))
+        os.makedirs(os.path.join(paths.private_dir, "tls"), 0700)
     if not os.path.exists(paths.state_dir):
         os.mkdir(paths.state_dir)
 
diff --git a/selftest/knownfail b/selftest/knownfail
index d249a25..e393635 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -128,6 +128,7 @@
 ^samba4.raw.streams.*.delete
 ^samba4.raw.streams.*.createdisp
 ^samba4.raw.streams.*.sumtab
+^samba4.raw.streams.*.perms
 ^samba4.raw.acls.INHERITFLAGS
 ^samba4.raw.acls.*.create_dir
 ^samba4.raw.acls.*.create_file
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 9fd2d40..0e798ba 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -227,7 +227,9 @@ sub mk_keyblobs($$)
 	my $admincertfile = "$tlsdir/admincert.pem";
 	my $admincertupnfile = "$tlsdir/admincertupn.pem";
 
-	mkdir($tlsdir, 0777);
+	mkdir($tlsdir, 0700);
+	my $oldumask = umask;
+	umask 0077;
 
 	#This is specified here to avoid draining entropy on every run
 	open(DHFILE, ">$dhfile");
@@ -418,6 +420,8 @@ Zd7J9s//rNFNa7waklFkDaY56+QWTFtdvxfE+KoHaqt6X8u6pqi7p3M4wDKQox+9Dx8yWFyq
 Wfz/8alZ5aMezCQzXJyIaJsCLeKABosSwHcpAFmxlQ==
 -----END CERTIFICATE-----
 EOF
+
+	umask $oldumask;
 }
 
 sub provision_raw_prepare($$$$$$$$$$)
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index a1b4e43..0282722 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -300,6 +300,44 @@ static NTSTATUS check_parent_access(struct connection_struct *conn,
 }
 
 /****************************************************************************
+ Ensure when opening a base file for a stream open that we have permissions
+ to do so given the access mask on the base file.
+****************************************************************************/
+
+static NTSTATUS check_base_file_access(struct connection_struct *conn,
+				struct smb_filename *smb_fname,
+				uint32_t access_mask)
+{
+	NTSTATUS status;
+
+	status = smbd_calculate_access_mask(conn, smb_fname,
+					access_mask,
+					&access_mask);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(10, ("smbd_calculate_access_mask "
+			"on file %s returned %s\n",
+			smb_fname_str_dbg(smb_fname),
+			nt_errstr(status)));
+		return status;
+	}
+
+	if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
+		uint32_t dosattrs;
+		if (!CAN_WRITE(conn)) {
+			return NT_STATUS_ACCESS_DENIED;
+		}
+		dosattrs = dos_mode(conn, smb_fname);
+		if (IS_DOS_READONLY(dosattrs)) {
+			return NT_STATUS_ACCESS_DENIED;
+		}
+	}
+
+	return smbd_check_access_rights(conn,
+					smb_fname,
+					access_mask);
+}
+
+/****************************************************************************
  fd support routines - attempt to do a dos_open.
 ****************************************************************************/
 
@@ -3749,6 +3787,25 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
 		if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
 			DEBUG(10, ("Unable to stat stream: %s\n",
 				   smb_fname_str_dbg(smb_fname_base)));
+		} else {
+			/*
+			 * https://bugzilla.samba.org/show_bug.cgi?id=10229
+			 * We need to check if the requested access mask
+			 * could be used to open the underlying file (if
+			 * it existed), as we're passing in zero for the
+			 * access mask to the base filename.
+			 */
+			status = check_base_file_access(conn,
+							smb_fname_base,
+							access_mask);
+
+			if (!NT_STATUS_IS_OK(status)) {
+				DEBUG(10, ("Permission check "
+					"for base %s failed: "
+					"%s\n", smb_fname->base_name,
+					nt_errstr(status)));
+				goto fail;
+			}
 		}
 
 		/* Open the base file. */
diff --git a/source4/lib/tls/tls.c b/source4/lib/tls/tls.c
index db6d1eb..9a3e610 100644
--- a/source4/lib/tls/tls.c
+++ b/source4/lib/tls/tls.c
@@ -22,6 +22,7 @@
 */
 
 #include "includes.h"
+#include "system/filesys.h"
 #include "lib/events/events.h"
 #include "lib/socket/socket.h"
 #include "lib/tls/tls.h"
@@ -369,6 +370,7 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *
 {
 	struct tls_params *params;
 	int ret;
+	struct stat st;
 	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 	const char *keyfile = lpcfg_tls_keyfile(tmp_ctx, lp_ctx);
 	const char *certfile = lpcfg_tls_certfile(tmp_ctx, lp_ctx);
@@ -399,6 +401,21 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *
 		talloc_free(hostname);
 	}
 
+	if (file_exist(keyfile) &&
+	    !file_check_permissions(keyfile, geteuid(), 0600, &st))
+	{
+		DEBUG(0, ("Invalid permissions on TLS private key file '%s':\n"
+			  "owner uid %u should be %u, mode 0%o should be 0%o\n"
+			  "This is known as CVE-2013-4476.\n"
+			  "Removing all tls .pem files will cause an "
+			  "auto-regeneration with the correct permissions.\n",
+			  keyfile,
+			  (unsigned int)st.st_uid, geteuid(),
+			  (unsigned int)(st.st_mode & 0777), 0600));
+		talloc_free(tmp_ctx);
+		return NULL;
+	}
+
 	ret = gnutls_global_init();
 	if (ret < 0) goto init_failed;
 
diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c
index 6bb68fb..2cb75ed 100644
--- a/source4/lib/tls/tls_tstream.c
+++ b/source4/lib/tls/tls_tstream.c
@@ -19,6 +19,7 @@
 
 #include "includes.h"
 #include "system/network.h"
+#include "system/filesys.h"
 #include "../util/tevent_unix.h"
 #include "../lib/tsocket/tsocket.h"
 #include "../lib/tsocket/tsocket_internal.h"
@@ -1083,6 +1084,7 @@ NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx,
 	struct tstream_tls_params *tlsp;
 #if ENABLE_GNUTLS
 	int ret;
+	struct stat st;
 
 	if (!enabled || key_file == NULL || *key_file == 0) {
 		tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
@@ -1110,6 +1112,20 @@ NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx,
 				  key_file, cert_file, ca_file);
 	}
 
+	if (file_exist(key_file) &&
+	    !file_check_permissions(key_file, geteuid(), 0600, &st))
+	{
+		DEBUG(0, ("Invalid permissions on TLS private key file '%s':\n"
+			  "owner uid %u should be %u, mode 0%o should be 0%o\n"
+			  "This is known as CVE-2013-4476.\n"
+			  "Removing all tls .pem files will cause an "
+			  "auto-regeneration with the correct permissions.\n",
+			  key_file,
+			  (unsigned int)st.st_uid, geteuid(),
+			  (unsigned int)(st.st_mode & 0777), 0600));
+		return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+	}
+
 	ret = gnutls_certificate_allocate_credentials(&tlsp->x509_cred);
 	if (ret != GNUTLS_E_SUCCESS) {
 		DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
diff --git a/source4/lib/tls/tlscert.c b/source4/lib/tls/tlscert.c
index 0c780ea..8a19e0a 100644
--- a/source4/lib/tls/tlscert.c
+++ b/source4/lib/tls/tlscert.c
@@ -152,7 +152,7 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx,
 
 	bufsize = sizeof(buf);
 	TLSCHECK(gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buf, &bufsize));
-	if (!file_save(keyfile, buf, bufsize)) {
+	if (!file_save_mode(keyfile, buf, bufsize, 0600)) {
 		DEBUG(0,("Unable to save privatekey in %s parent dir exists ?\n", keyfile));
 		goto failed;
 	}
diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c
index 1611c64..61852f5 100644
--- a/source4/torture/raw/streams.c
+++ b/source4/torture/raw/streams.c
@@ -23,6 +23,8 @@
 #include "system/locale.h"
 #include "torture/torture.h"
 #include "libcli/raw/libcliraw.h"
+#include "libcli/security/dom_sid.h"
+#include "libcli/security/security_descriptor.h"
 #include "system/filesys.h"
 #include "libcli/libcli.h"
 #include "torture/util.h"
@@ -1885,6 +1887,184 @@ static bool test_stream_summary_tab(struct torture_context *tctx,
 	return ret;
 }
 
+/* Test how streams interact with base file permissions */
+/* Regression test for bug:
+   https://bugzilla.samba.org/show_bug.cgi?id=10229
+   bug #10229 - No access check verification on stream files.
+*/
+static bool test_stream_permissions(struct torture_context *tctx,
+					   struct smbcli_state *cli)
+{
+	NTSTATUS status;
+	bool ret = true;
+	union smb_open io;
+	const char *fname = BASEDIR "\\stream_permissions.txt";
+	const char *stream = "Stream One:$DATA";
+	const char *fname_stream;
+	union smb_fileinfo finfo;
+	union smb_setfileinfo sfinfo;
+	int fnum = -1;
+	union smb_fileinfo q;
+	union smb_setfileinfo set;
+	struct security_ace ace;
+	struct security_descriptor *sd;
+
+	torture_assert(tctx, torture_setup_dir(cli, BASEDIR),
+		"Failed to setup up test directory: " BASEDIR);
+
+	torture_comment(tctx, "(%s) testing permissions on streams\n", __location__);
+
+	fname_stream = talloc_asprintf(tctx, "%s:%s", fname, stream);
+
+	/* Create a file with a stream with attribute FILE_ATTRIBUTE_ARCHIVE. */
+	ret = create_file_with_stream(tctx, cli, fname_stream);
+	if (!ret) {
+		goto done;
+	}
+
+	ZERO_STRUCT(finfo);
+	finfo.generic.level = RAW_FILEINFO_BASIC_INFO;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list