[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