* [PATCH] Security updates for samba 3.6.25 @ 2017-05-28 9:22 Matthias Fischer 2017-05-29 16:57 ` Michael Tremer 0 siblings, 1 reply; 4+ messages in thread From: Matthias Fischer @ 2017-05-28 9:22 UTC (permalink / raw) To: development [-- Attachment #1: Type: text/plain, Size: 63915 bytes --] Based on: https://anonscm.debian.org/cgit/pkg-samba/samba.git/commit/?h=wheezy&id=762a3afd8eb45526e44cd0b2ae8a5b1a058ec647 https://www.samba.org/samba/history/security.html https://www.samba.org/samba/samba/ftp/patches/security/ Fixes current CVE-2017-7494 and some more... Removed three 'unrecognized' configure-options. Some 'lfs'-tuning was made, too. I altered 'PAK_VER' from "64" to "65" - if not necessary, please change back. Best, Matthias Signed-off-by: Matthias Fischer <matthias.fischer(a)ipfire.org> --- lfs/samba | 22 +- .../samba/CVE-2017-2619-race-condition-fix.patch | 1150 ++++++++++++++++++++ .../CVE-2017-2619-regression-bug-12721-fix.patch | 179 +++ src/patches/samba/CVE-2017-2619-tests.patch | 296 +++++ src/patches/samba/samba-3.6.25-CVE-2017-7494.patch | 14 + .../samba/samba-3.6.25-security-2015-12-16.patch | 255 +++++ 6 files changed, 1909 insertions(+), 7 deletions(-) create mode 100644 src/patches/samba/CVE-2017-2619-race-condition-fix.patch create mode 100644 src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch create mode 100644 src/patches/samba/CVE-2017-2619-tests.patch create mode 100644 src/patches/samba/samba-3.6.25-CVE-2017-7494.patch create mode 100644 src/patches/samba/samba-3.6.25-security-2015-12-16.patch diff --git a/lfs/samba b/lfs/samba index 076152f48..445646464 100644 --- a/lfs/samba +++ b/lfs/samba @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2016 IPFire Team <info(a)ipfire.org> # +# Copyright (C) 2007-2017 IPFire Team <info(a)ipfire.org> # # # # 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 # @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = samba -PAK_VER = 64 +PAK_VER = 65 DEPS = "cups krb5" @@ -54,7 +54,7 @@ download :$(patsubst %,$(DIR_DL)/%,$(objects)) md5 : $(subst %,%_MD5,$(objects)) -dist: +dist: @$(PAK) ############################################################################### @@ -88,6 +88,17 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2016-2118-v3-6.patch cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2015-5370-v3-6.patch + # Apply Debian CVE patches + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017-2619-race-condition-fix.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017-2619-tests.patch + + # Fixes CVE-2015-5252 - Samba + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/samba-3.6.25-security-2015-12-16.patch + + # Fixes CVE-2017-7494 - Samba + cd $(DIR_APP) && patch -Np0 < $(DIR_SRC)/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch + cd $(DIR_APP)/source3 && ./autogen.sh cd $(DIR_APP)/source3 && ./configure \ --prefix=/usr \ @@ -102,10 +113,7 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) --with-libsmbclient \ --with-libsmbsharemodes \ --with-sendfile-support \ - --without-smbwrapper \ - --with-mmap \ --with-fhs \ - --with-vfs \ --with-winbind \ --disable-swat \ --enable-cups \ @@ -119,8 +127,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) #cd $(DIR_APP)/source3 && install -v -m755 nsswitch/libnss_winbind.so /lib #cd $(DIR_APP)/source3 && ln -v -sf libnss_winbind.so /lib/libnss_winbind.so.2 #cd $(DIR_APP)/source3 && ln -v -sf libnss_wins.so /lib/libnss_wins.so.2 + -mkdir -p /var/ipfire/samba cd $(DIR_APP)/source3 && install -v -m644 ../examples/smb.conf.default /var/ipfire/samba - -mkdir -p /var/ipfire/samba cp -vrf $(DIR_SRC)/config/samba/* /var/ipfire/samba/ chown nobody:nobody -R /var/ipfire/samba/ cp -vfp /var/ipfire/samba/default.global /var/ipfire/samba/global diff --git a/src/patches/samba/CVE-2017-2619-race-condition-fix.patch b/src/patches/samba/CVE-2017-2619-race-condition-fix.patch new file mode 100644 index 000000000..a96d6be3b --- /dev/null +++ b/src/patches/samba/CVE-2017-2619-race-condition-fix.patch @@ -0,0 +1,1150 @@ +Description: This patch is a consolidation of several patches described by the Git commit summaries below +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-2619 +bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +From ec1bca1d5315549e945c93cbf5e3abdb695de782 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 20 Mar 2017 11:32:19 -0700 +Subject: [PATCH 01/15] CVE-2017-2619: s3/smbd: re-open directory after + dptr_CloseDir() + +dptr_CloseDir() will close and invalidate the fsp's file descriptor, we +have to reopen it. + +Bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Ralph Bohme <slow(a)samba.org> +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/open.c | 2 +- + source3/smbd/proto.h | 2 ++ + source3/smbd/smb2_find.c | 17 +++++++++++++++++ + 3 files changed, 20 insertions(+), 1 deletion(-) + +From 2bb9a3d35f6a0cc43a30638594969c4860ffd5a5 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Tue, 28 Feb 2017 09:24:07 -0800 +Subject: [PATCH 02/15] s3: vfs: dirsort doesn't handle opendir of "." + correctly. + +Needs to store $cwd path for correct sorting. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12499 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/modules/vfs_dirsort.c | 4 ++++ + 1 file changed, 4 insertions(+) + +From 327d09ba641046f68daa5b2bb98f09530294cb0d Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 13 Mar 2017 13:44:42 -0700 +Subject: [PATCH 03/15] s3: VFS: vfs_streams_xattr.c: Make streams_xattr_open() + store the same path as streams_xattr_recheck(). + +If the open is changing directories, fsp->fsp_name->base_name +will be the full path from the share root, whilst +smb_fname will be relative to the $cwd. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12546 + +Back-ported from a24ba3e4083200ec9885363efc5769f43183fb6b + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/modules/vfs_streams_xattr.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +From 27871d3bfb0857ad3306aabdce6f9b55e32fff3d Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 13 Mar 2017 13:54:04 -0700 +Subject: [PATCH 04/15] vfs_streams_xattr: use fsp, not base_fsp + +The base_fsp's fd is always -1 as it's closed after being openend in +create_file_unixpath(). + +Additionally in streams_xattr_open force using of SMB_VFS_FSETXATTR() by +sticking the just created fd into the fsp (and removing it afterwards). + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12591 + +Back-ported from 021189e32ba507832b5e821e5cda8a2889225955. + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/modules/vfs_streams_xattr.c | 205 +++++++++++++++++------------------- + 1 file changed, 99 insertions(+), 106 deletions(-) + +From a419b277c5994459c956ebdd324679e728ebae10 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 19 Dec 2016 11:55:56 -0800 +Subject: [PATCH 05/15] s3: smbd: Create wrapper function for OpenDir in + preparation for making robust. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/dir.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +From e47e3c40b5fc8f52fe70c3e1edf5489ac8b4badf Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 19 Dec 2016 16:25:26 -0800 +Subject: [PATCH 06/15] s3: smbd: Opendir_internal() early return if + SMB_VFS_OPENDIR failed. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/dir.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +From 45e41b709b6c2e67acb99f29aa05b61b53091e57 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 19 Dec 2016 16:35:00 -0800 +Subject: [PATCH 07/15] s3: smbd: Create and use open_dir_safely(). Use from + OpenDir(). + +Hardens OpenDir against TOC/TOU races. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/dir.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 59 insertions(+), 7 deletions(-) + +From 720abcec65b04fdac1052a14898180c8cc816464 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 19 Dec 2016 12:13:20 -0800 +Subject: [PATCH 08/15] s3: smbd: OpenDir_fsp() use early returns. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/dir.c | 34 +++++++++++++++++++++------------- + 1 file changed, 21 insertions(+), 13 deletions(-) + +From 5070f319bbb7dda87766621a83691910414d06a1 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 19 Dec 2016 12:15:59 -0800 +Subject: [PATCH 09/15] s3: smbd: OpenDir_fsp() - Fix memory leak on error. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/dir.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +From 65d37759f8b4979bc0c0833e0a5eecd277dfa604 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 19 Dec 2016 12:32:07 -0800 +Subject: [PATCH 10/15] s3: smbd: Move the reference counting and destructor + setup to just before retuning success. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/dir.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +From 5a821d791aba90643ddf7a3c29dad4f6621ef185 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 19 Dec 2016 12:35:32 -0800 +Subject: [PATCH 11/15] s3: smbd: Correctly fallback to open_dir_safely if + FDOPENDIR not supported on system. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/dir.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +From 597aa3b99a2790133a4839260607b0a8df41c8e3 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Thu, 15 Dec 2016 12:52:13 -0800 +Subject: [PATCH 12/15] s3: smbd: Remove O_NOFOLLOW guards. We insist on + O_NOFOLLOW existing. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/open.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +From 563af2ffec05a2c0b54897e2d28ac7e1adb66e0f Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Thu, 15 Dec 2016 12:56:08 -0800 +Subject: [PATCH 13/15] s3: smbd: Move special handling of symlink errno's into + a utility function. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/open.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +From b34a67cd3a996804ba7bf90e86cf9e22edf60eb3 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Thu, 15 Dec 2016 13:04:46 -0800 +Subject: [PATCH 14/15] s3: smbd: Add the core functions to prevent symlink + open races. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/open.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 242 insertions(+) + +From 5920309d2f62dd24fc50530c92dd68077f96a6d2 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Thu, 15 Dec 2016 13:06:31 -0800 +Subject: [PATCH 15/15] s3: smbd: Use the new non_widelink_open() function. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +--- + source3/smbd/open.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + + +--- samba-3.6.6.orig/source3/smbd/open.c ++++ samba-3.6.6/source3/smbd/open.c +@@ -187,10 +187,277 @@ + } + + /**************************************************************************** ++ Handle differing symlink errno's ++****************************************************************************/ ++ ++static int link_errno_convert(int err) ++{ ++#if defined(ENOTSUP) && defined(OSF1) ++ /* handle special Tru64 errno */ ++ if (err == ENOTSUP) { ++ err = ELOOP; ++ } ++#endif /* ENOTSUP */ ++#ifdef EFTYPE ++ /* fix broken NetBSD errno */ ++ if (err == EFTYPE) { ++ err = ELOOP; ++ } ++#endif /* EFTYPE */ ++ /* fix broken FreeBSD errno */ ++ if (err == EMLINK) { ++ err = ELOOP; ++ } ++ return err; ++} ++ ++static int non_widelink_open(struct connection_struct *conn, ++ const char *conn_rootdir, ++ files_struct *fsp, ++ struct smb_filename *smb_fname, ++ int flags, ++ mode_t mode, ++ unsigned int link_depth); ++ ++/**************************************************************************** ++ Follow a symlink in userspace. ++****************************************************************************/ ++ ++static int process_symlink_open(struct connection_struct *conn, ++ const char *conn_rootdir, ++ files_struct *fsp, ++ struct smb_filename *smb_fname, ++ int flags, ++ mode_t mode, ++ unsigned int link_depth) ++{ ++ int fd = -1; ++ char *link_target = NULL; ++ int link_len = -1; ++ char *oldwd = NULL; ++ size_t rootdir_len = 0; ++ char *resolved_name = NULL; ++ bool matched = false; ++ int saved_errno = 0; ++ ++ /* ++ * Ensure we don't get stuck in a symlink loop. ++ */ ++ link_depth++; ++ if (link_depth >= 20) { ++ errno = ELOOP; ++ goto out; ++ } ++ ++ /* Allocate space for the link target. */ ++ link_target = talloc_array(talloc_tos(), char, PATH_MAX); ++ if (link_target == NULL) { ++ errno = ENOMEM; ++ goto out; ++ } ++ ++ /* Read the link target. */ ++ link_len = SMB_VFS_READLINK(conn, ++ smb_fname->base_name, ++ link_target, ++ PATH_MAX - 1); ++ if (link_len == -1) { ++ goto out; ++ } ++ ++ /* Ensure it's at least null terminated. */ ++ link_target[link_len] = '\0'; ++ ++ /* Convert to an absolute path. */ ++ resolved_name = SMB_VFS_REALPATH(conn, link_target); ++ if (resolved_name == NULL) { ++ goto out; ++ } ++ ++ /* ++ * We know conn_rootdir starts with '/' and ++ * does not end in '/'. FIXME ! Should we ++ * smb_assert this ? ++ */ ++ rootdir_len = strlen(conn_rootdir); ++ ++ matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0); ++ if (!matched) { ++ errno = EACCES; ++ goto out; ++ } ++ ++ /* ++ * Turn into a path relative to the share root. ++ */ ++ if (resolved_name[rootdir_len] == '\0') { ++ /* Link to the root of the share. */ ++ smb_fname->base_name = talloc_strdup(talloc_tos(), "."); ++ if (smb_fname->base_name == NULL) { ++ errno = ENOMEM; ++ goto out; ++ } ++ } else if (resolved_name[rootdir_len] == '/') { ++ smb_fname->base_name = &resolved_name[rootdir_len+1]; ++ } else { ++ errno = EACCES; ++ goto out; ++ } ++ ++ oldwd = vfs_GetWd(talloc_tos(), conn); ++ if (oldwd == NULL) { ++ goto out; ++ } ++ ++ /* Ensure we operate from the root of the share. */ ++ if (vfs_ChDir(conn, conn_rootdir) == -1) { ++ goto out; ++ } ++ ++ /* And do it all again.. */ ++ fd = non_widelink_open(conn, ++ conn_rootdir, ++ fsp, ++ smb_fname, ++ flags, ++ mode, ++ link_depth); ++ if (fd == -1) { ++ saved_errno = errno; ++ } ++ ++ out: ++ ++ SAFE_FREE(resolved_name); ++ TALLOC_FREE(link_target); ++ if (oldwd != NULL) { ++ int ret = vfs_ChDir(conn, oldwd); ++ if (ret == -1) { ++ smb_panic("unable to get back to old directory\n"); ++ } ++ TALLOC_FREE(oldwd); ++ } ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } ++ return fd; ++} ++ ++/**************************************************************************** ++ Non-widelink open. ++****************************************************************************/ ++ ++static int non_widelink_open(struct connection_struct *conn, ++ const char *conn_rootdir, ++ files_struct *fsp, ++ struct smb_filename *smb_fname, ++ int flags, ++ mode_t mode, ++ unsigned int link_depth) ++{ ++ NTSTATUS status; ++ int fd = -1; ++ struct smb_filename *smb_fname_rel = NULL; ++ int saved_errno = 0; ++ char *oldwd = NULL; ++ char *parent_dir = NULL; ++ const char *final_component = NULL; ++ ++ if (!parent_dirname(talloc_tos(), ++ smb_fname->base_name, ++ &parent_dir, ++ &final_component)) { ++ goto out; ++ } ++ ++ oldwd = vfs_GetWd(talloc_tos(), conn); ++ if (oldwd == NULL) { ++ goto out; ++ } ++ ++ /* Pin parent directory in place. */ ++ if (vfs_ChDir(conn, parent_dir) == -1) { ++ goto out; ++ } ++ ++ /* Ensure the relative path is below the share. */ ++ status = check_reduced_name(conn, final_component); ++ if (!NT_STATUS_IS_OK(status)) { ++ saved_errno = map_errno_from_nt_status(status); ++ goto out; ++ } ++ ++ status = create_synthetic_smb_fname(talloc_tos(), ++ final_component, ++ smb_fname->stream_name, ++ &smb_fname->st, ++ &smb_fname_rel); ++ if (!NT_STATUS_IS_OK(status)) { ++ saved_errno = map_errno_from_nt_status(status); ++ goto out; ++ } ++ ++ flags |= O_NOFOLLOW; ++ ++ { ++ struct smb_filename *tmp_name = fsp->fsp_name; ++ fsp->fsp_name = smb_fname_rel; ++ fd = SMB_VFS_OPEN(conn, smb_fname_rel, fsp, flags, mode); ++ fsp->fsp_name = tmp_name; ++ } ++ ++ if (fd == -1) { ++ saved_errno = link_errno_convert(errno); ++ if (saved_errno == ELOOP) { ++ if (fsp->posix_open) { ++ /* Never follow symlinks on posix open. */ ++ goto out; ++ } ++ if (!lp_symlinks(SNUM(conn))) { ++ /* Explicitly no symlinks. */ ++ goto out; ++ } ++ /* ++ * We have a symlink. Follow in userspace ++ * to ensure it's under the share definition. ++ */ ++ fd = process_symlink_open(conn, ++ conn_rootdir, ++ fsp, ++ smb_fname_rel, ++ flags, ++ mode, ++ link_depth); ++ if (fd == -1) { ++ saved_errno = ++ link_errno_convert(errno); ++ } ++ } ++ } ++ ++ out: ++ ++ TALLOC_FREE(parent_dir); ++ TALLOC_FREE(smb_fname_rel); ++ ++ if (oldwd != NULL) { ++ int ret = vfs_ChDir(conn, oldwd); ++ if (ret == -1) { ++ smb_panic("unable to get back to old directory\n"); ++ } ++ TALLOC_FREE(oldwd); ++ } ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } ++ return fd; ++} ++ ++/**************************************************************************** + fd support routines - attempt to do a dos_open. + ****************************************************************************/ + +-static NTSTATUS fd_open(struct connection_struct *conn, ++NTSTATUS fd_open(struct connection_struct *conn, + files_struct *fsp, + int flags, + mode_t mode) +@@ -198,8 +465,7 @@ + struct smb_filename *smb_fname = fsp->fsp_name; + NTSTATUS status = NT_STATUS_OK; + +-#ifdef O_NOFOLLOW +- /* ++ /* + * Never follow symlinks on a POSIX client. The + * client should be doing this. + */ +@@ -207,12 +473,33 @@ + if (fsp->posix_open || !lp_symlinks(SNUM(conn))) { + flags |= O_NOFOLLOW; + } +-#endif + +- fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); ++ /* Ensure path is below share definition. */ ++ if (!lp_widelinks(SNUM(conn))) { ++ const char *conn_rootdir = SMB_VFS_CONNECTPATH(conn, ++ smb_fname->base_name); ++ if (conn_rootdir == NULL) { ++ return NT_STATUS_NO_MEMORY; ++ } ++ /* ++ * Only follow symlinks within a share ++ * definition. ++ */ ++ fsp->fh->fd = non_widelink_open(conn, ++ conn_rootdir, ++ fsp, ++ smb_fname, ++ flags, ++ mode, ++ 0); ++ } else { ++ fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); ++ } ++ + if (fsp->fh->fd == -1) { +- status = map_nt_error_from_unix(errno); +- if (errno == EMFILE) { ++ int posix_errno = link_errno_convert(errno); ++ status = map_nt_error_from_unix(posix_errno); ++ if (posix_errno == EMFILE) { + static time_t last_warned = 0L; + + if (time((time_t *) NULL) > last_warned) { +--- samba-3.6.6.orig/source3/smbd/proto.h ++++ samba-3.6.6/source3/smbd/proto.h +@@ -592,6 +592,8 @@ + const struct security_token *token, + uint32_t access_desired, + uint32_t *access_granted); ++NTSTATUS fd_open(struct connection_struct *conn, files_struct *fsp, ++ int flags, mode_t mode); + NTSTATUS fd_close(files_struct *fsp); + void change_file_owner_to_parent(connection_struct *conn, + const char *inherit_from_dir, +--- samba-3.6.6.orig/source3/smbd/smb2_find.c ++++ samba-3.6.6/source3/smbd/smb2_find.c +@@ -24,6 +24,7 @@ + #include "../libcli/smb/smb_common.h" + #include "trans2.h" + #include "../lib/util/tevent_ntstatus.h" ++#include "system/filesys.h" + + static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, +@@ -300,7 +301,23 @@ + } + + if (in_flags & SMB2_CONTINUE_FLAG_REOPEN) { ++ int flags; ++ + dptr_CloseDir(fsp); ++ ++ /* ++ * dptr_CloseDir() will close and invalidate the fsp's file ++ * descriptor, we have to reopen it. ++ */ ++ ++ flags = O_RDONLY; ++#ifdef O_DIRECTORY ++ flags |= O_DIRECTORY; ++#endif ++ status = fd_open(conn, fsp, flags, 0); ++ if (tevent_req_nterror(req, status)) { ++ return tevent_req_post(req, ev); ++ } + } + + if (fsp->dptr == NULL) { +--- samba-3.6.6.orig/source3/modules/vfs_dirsort.c ++++ samba-3.6.6/source3/modules/vfs_dirsort.c +@@ -141,6 +141,10 @@ + return NULL; + } + ++ if (ISDOT(data->smb_fname->base_name)) { ++ data->smb_fname->base_name = vfs_GetWd(data, handle->conn); ++ } ++ + /* Open the underlying directory and count the number of entries */ + data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, + attr); +--- samba-3.6.6.orig/source3/modules/vfs_streams_xattr.c ++++ samba-3.6.6/source3/modules/vfs_streams_xattr.c +@@ -229,7 +229,7 @@ + return -1; + } + +- sbuf->st_ex_size = get_xattr_size(handle->conn, fsp->base_fsp, ++ sbuf->st_ex_size = get_xattr_size(handle->conn, fsp, + io->base, io->xattr_name); + if (sbuf->st_ex_size == -1) { + return -1; +@@ -364,6 +364,7 @@ + char *xattr_name = NULL; + int baseflags; + int hostfd = -1; ++ int ret; + + DEBUG(10, ("streams_xattr_open called for %s\n", + smb_fname_str_dbg(smb_fname))); +@@ -375,133 +376,125 @@ + /* If the default stream is requested, just open the base file. */ + if (is_ntfs_default_stream_smb_fname(smb_fname)) { + char *tmp_stream_name; +- int ret; + + tmp_stream_name = smb_fname->stream_name; + smb_fname->stream_name = NULL; + + ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode); + +- smb_fname->stream_name = tmp_stream_name; +- +- return ret; +- } ++ smb_fname->stream_name = tmp_stream_name; + +- status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name, +- &xattr_name); +- if (!NT_STATUS_IS_OK(status)) { +- errno = map_errno_from_nt_status(status); +- goto fail; +- } ++ return ret; ++ } + +- /* Create an smb_filename with stream_name == NULL. */ +- status = create_synthetic_smb_fname(talloc_tos(), +- smb_fname->base_name, +- NULL, NULL, +- &smb_fname_base); +- if (!NT_STATUS_IS_OK(status)) { +- errno = map_errno_from_nt_status(status); +- goto fail; +- } ++ status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name, ++ &xattr_name); ++ if (!NT_STATUS_IS_OK(status)) { ++ errno = map_errno_from_nt_status(status); ++ goto fail; ++ } + +- /* +- * We use baseflags to turn off nasty side-effects when opening the +- * underlying file. +- */ +- baseflags = flags; +- baseflags &= ~O_TRUNC; +- baseflags &= ~O_EXCL; +- baseflags &= ~O_CREAT; +- +- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp, +- baseflags, mode); +- +- TALLOC_FREE(smb_fname_base); +- +- /* It is legit to open a stream on a directory, but the base +- * fd has to be read-only. +- */ +- if ((hostfd == -1) && (errno == EISDIR)) { +- baseflags &= ~O_ACCMODE; +- baseflags |= O_RDONLY; +- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, baseflags, +- mode); +- } ++ /* Create an smb_filename with stream_name == NULL. */ ++ status = create_synthetic_smb_fname(talloc_tos(), ++ smb_fname->base_name, ++ NULL, NULL, ++ &smb_fname_base); ++ if (!NT_STATUS_IS_OK(status)) { ++ errno = map_errno_from_nt_status(status); ++ goto fail; ++ } + +- if (hostfd == -1) { +- goto fail; +- } ++ /* ++ * We use baseflags to turn off nasty side-effects when opening the ++ * underlying file. ++ */ ++ baseflags = flags; ++ baseflags &= ~O_TRUNC; ++ baseflags &= ~O_EXCL; ++ baseflags &= ~O_CREAT; + +- status = get_ea_value(talloc_tos(), handle->conn, NULL, +- smb_fname->base_name, xattr_name, &ea); ++ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp, ++ baseflags, mode); + +- DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status))); ++ TALLOC_FREE(smb_fname_base); + +- if (!NT_STATUS_IS_OK(status) +- && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { +- /* +- * The base file is not there. This is an error even if we got +- * O_CREAT, the higher levels should have created the base +- * file for us. ++ /* It is legit to open a stream on a directory, but the base ++ * fd has to be read-only. + */ +- DEBUG(10, ("streams_xattr_open: base file %s not around, " +- "returning ENOENT\n", smb_fname->base_name)); +- errno = ENOENT; +- goto fail; +- } ++ if ((hostfd == -1) && (errno == EISDIR)) { ++ baseflags &= ~O_ACCMODE; ++ baseflags |= O_RDONLY; ++ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, baseflags, ++ mode); ++ } + +- if (!NT_STATUS_IS_OK(status)) { +- /* +- * The attribute does not exist +- */ ++ if (hostfd == -1) { ++ goto fail; ++ } ++ ++ status = get_ea_value(talloc_tos(), handle->conn, NULL, ++ smb_fname->base_name, xattr_name, &ea); + +- if (flags & O_CREAT) { ++ DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status))); ++ ++ if (!NT_STATUS_IS_OK(status) ++ && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + /* +- * Darn, xattrs need at least 1 byte ++ * The base file is not there. This is an error even if we got ++ * O_CREAT, the higher levels should have created the base ++ * file for us. + */ +- char null = '\0'; ++ DEBUG(10, ("streams_xattr_open: base file %s not around, " ++ "returning ENOENT\n", smb_fname->base_name)); ++ errno = ENOENT; ++ goto fail; ++ } + +- DEBUG(10, ("creating attribute %s on file %s\n", +- xattr_name, smb_fname->base_name)); ++ if (!NT_STATUS_IS_OK(status)) { ++ /* ++ * The attribute does not exist ++ */ + ++ if (flags & O_CREAT) { ++ /* ++ * Darn, xattrs need at least 1 byte ++ */ ++ char null = '\0'; ++ ++ DEBUG(10, ("creating attribute %s on file %s\n", ++ xattr_name, smb_fname->base_name)); ++ ++ fsp->fh->fd = hostfd; ++ ret = SMB_VFS_FSETXATTR(fsp, xattr_name, ++ &null, sizeof(null), ++ flags & O_EXCL ? XATTR_CREATE : 0); ++ fsp->fh->fd = -1; ++ if (ret != 0) { ++ goto fail; ++ } ++ } ++ } ++ ++ if (flags & O_TRUNC) { ++ char null = '\0'; + if (fsp->base_fsp->fh->fd != -1) { +- if (SMB_VFS_FSETXATTR( +- fsp->base_fsp, xattr_name, +- &null, sizeof(null), +- flags & O_EXCL ? XATTR_CREATE : 0) == -1) { ++ if (SMB_VFS_FSETXATTR( ++ fsp->base_fsp, xattr_name, ++ &null, sizeof(null), ++ flags & O_EXCL ? XATTR_CREATE : 0) == -1) { + goto fail; + } + } else { +- if (SMB_VFS_SETXATTR( +- handle->conn, smb_fname->base_name, +- xattr_name, &null, sizeof(null), +- flags & O_EXCL ? XATTR_CREATE : 0) == -1) { ++ if (SMB_VFS_SETXATTR( ++ handle->conn, smb_fname->base_name, ++ xattr_name, &null, sizeof(null), ++ flags & O_EXCL ? XATTR_CREATE : 0) == -1) { + goto fail; + } + } + } +- } +- +- if (flags & O_TRUNC) { +- char null = '\0'; +- if (fsp->base_fsp->fh->fd != -1) { +- if (SMB_VFS_FSETXATTR( +- fsp->base_fsp, xattr_name, +- &null, sizeof(null), +- flags & O_EXCL ? XATTR_CREATE : 0) == -1) { +- goto fail; +- } +- } else { +- if (SMB_VFS_SETXATTR( +- handle->conn, smb_fname->base_name, +- xattr_name, &null, sizeof(null), +- flags & O_EXCL ? XATTR_CREATE : 0) == -1) { +- goto fail; +- } +- } +- } + +- sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp, ++ sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp, + struct stream_io, + NULL); + if (sio == NULL) { +@@ -511,8 +504,15 @@ + + sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), + xattr_name); ++ /* ++ * sio->base needs to be a copy of fsp->fsp_name->base_name, ++ * making it identical to streams_xattr_recheck(). If the ++ * open is changing directories, fsp->fsp_name->base_name ++ * will be the full path from the share root, whilst ++ * smb_fname will be relative to the $cwd. ++ */ + sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), +- smb_fname->base_name); ++ fsp->fsp_name->base_name); + sio->fsp_name_ptr = fsp->fsp_name; + sio->handle = handle; + sio->fsp = fsp; +@@ -861,7 +861,7 @@ + return -1; + } + +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, + sio->base, sio->xattr_name, &ea); + if (!NT_STATUS_IS_OK(status)) { + return -1; +@@ -885,13 +885,13 @@ + + memcpy(ea.value.data + offset, data, n); + +- if (fsp->base_fsp->fh->fd != -1) { +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, ++ if (fsp->fh->fd != -1) { ++ ret = SMB_VFS_FSETXATTR(fsp, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } else { + ret = SMB_VFS_SETXATTR(fsp->conn, +- fsp->base_fsp->fsp_name->base_name, ++ fsp->fsp_name->base_name, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } +@@ -925,7 +925,7 @@ + return -1; + } + +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, + sio->base, sio->xattr_name, &ea); + if (!NT_STATUS_IS_OK(status)) { + return -1; +@@ -970,7 +970,7 @@ + return -1; + } + +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, + sio->base, sio->xattr_name, &ea); + if (!NT_STATUS_IS_OK(status)) { + return -1; +@@ -995,13 +995,13 @@ + ea.value.length = offset + 1; + ea.value.data[offset] = 0; + +- if (fsp->base_fsp->fh->fd != -1) { +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, ++ if (fsp->fh->fd != -1) { ++ ret = SMB_VFS_FSETXATTR(fsp, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } else { + ret = SMB_VFS_SETXATTR(fsp->conn, +- fsp->base_fsp->fsp_name->base_name, ++ fsp->fsp_name->base_name, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } +--- samba-3.6.6.orig/source3/smbd/dir.c ++++ samba-3.6.6/source3/smbd/dir.c +@@ -1358,7 +1358,8 @@ + Open a directory. + ********************************************************************/ + +-struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, ++static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, ++ connection_struct *conn, + const char *name, + const char *mask, + uint32 attr) +@@ -1370,27 +1371,21 @@ + return NULL; + } + +- dirp->conn = conn; +- dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); +- +- dirp->dir_path = talloc_strdup(dirp, name); +- if (!dirp->dir_path) { +- errno = ENOMEM; ++ dirp->dir = SMB_VFS_OPENDIR(conn, name, mask, attr); ++ if (!dirp->dir) { ++ DEBUG(5,("OpenDir: Can't open %s. %s\n", name, ++ strerror(errno) )); + goto fail; + } + ++ dirp->conn = conn; ++ dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); ++ + if (sconn && !sconn->using_smb2) { + sconn->searches.dirhandles_open++; + } + talloc_set_destructor(dirp, smb_Dir_destructor); + +- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); +- if (!dirp->dir) { +- DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, +- strerror(errno) )); +- goto fail; +- } +- + return dirp; + + fail: +@@ -1398,6 +1393,76 @@ + return NULL; + } + ++/**************************************************************************** ++ Open a directory handle by pathname, ensuring it's under the share path. ++****************************************************************************/ ++ ++static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx, ++ connection_struct *conn, ++ const char *name, ++ const char *wcard, ++ uint32_t attr) ++{ ++ struct smb_Dir *dir_hnd = NULL; ++ char *saved_dir = vfs_GetWd(ctx, conn); ++ NTSTATUS status; ++ ++ if (saved_dir == NULL) { ++ return NULL; ++ } ++ ++ if (vfs_ChDir(conn, name) == -1) { ++ goto out; ++ } ++ ++ /* ++ * Now the directory is pinned, use ++ * REALPATH to ensure we can access it. ++ */ ++ status = check_name(conn, "."); ++ if (!NT_STATUS_IS_OK(status)) { ++ goto out; ++ } ++ ++ dir_hnd = OpenDir_internal(ctx, ++ conn, ++ ".", ++ wcard, ++ attr); ++ ++ if (dir_hnd == NULL) { ++ goto out; ++ } ++ ++ /* ++ * OpenDir_internal only gets "." as the dir name. ++ * Store the real dir name here. ++ */ ++ ++ dir_hnd->dir_path = talloc_strdup(dir_hnd, name); ++ if (!dir_hnd->dir_path) { ++ errno = ENOMEM; ++ } ++ ++ out: ++ ++ vfs_ChDir(conn, saved_dir); ++ TALLOC_FREE(saved_dir); ++ return dir_hnd; ++} ++ ++struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, ++ const char *name, ++ const char *mask, ++ uint32_t attr) ++{ ++ return open_dir_safely(mem_ctx, ++ conn, ++ name, ++ mask, ++ attr); ++} ++ + /******************************************************************* + Open a directory from an fsp. + ********************************************************************/ +@@ -1411,7 +1476,17 @@ + struct smbd_server_connection *sconn = conn->sconn; + + if (!dirp) { +- return NULL; ++ goto fail; ++ } ++ ++ if (!fsp->is_directory) { ++ errno = EBADF; ++ goto fail; ++ } ++ ++ if (fsp->fh->fd == -1) { ++ errno = EBADF; ++ goto fail; + } + + dirp->conn = conn; +@@ -1423,36 +1498,33 @@ + goto fail; + } + +- if (sconn && !sconn->using_smb2) { +- sconn->searches.dirhandles_open++; +- } +- talloc_set_destructor(dirp, smb_Dir_destructor); +- +- if (fsp->is_directory && fsp->fh->fd != -1) { +- dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); +- if (dirp->dir != NULL) { +- dirp->fsp = fsp; +- } else { +- DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " +- "NULL (%s)\n", +- dirp->dir_path, +- strerror(errno))); +- if (errno != ENOSYS) { +- return NULL; +- } ++ dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); ++ if (dirp->dir != NULL) { ++ dirp->fsp = fsp; ++ } else { ++ DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " ++ "NULL (%s)\n", ++ dirp->dir_path, ++ strerror(errno))); ++ if (errno != ENOSYS) { ++ goto fail; + } + } + + if (dirp->dir == NULL) { +- /* FDOPENDIR didn't work. Use OPENDIR instead. */ +- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); ++ /* FDOPENDIR is not supported. Use OPENDIR instead. */ ++ TALLOC_FREE(dirp); ++ return open_dir_safely(mem_ctx, ++ conn, ++ fsp->fsp_name->base_name, ++ mask, ++ attr); + } + +- if (!dirp->dir) { +- DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", dirp->dir_path, +- strerror(errno) )); +- goto fail; ++ if (sconn && !sconn->using_smb2) { ++ sconn->searches.dirhandles_open++; + } ++ talloc_set_destructor(dirp, smb_Dir_destructor); + + return dirp; + diff --git a/src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch b/src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch new file mode 100644 index 000000000..cefdd86ea --- /dev/null +++ b/src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch @@ -0,0 +1,179 @@ +bug: https://bugzilla.samba.org/show_bug.cgi?id=12721 +Description: This patch is a consolidation of several patches described by the Git commit summaries below + +From 5d4ef6ff0970c93fed49e51a01e63cb67d49d087 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 27 Mar 2017 10:46:47 -0700 +Subject: [PATCH 1/3] s3: smbd: Fix incorrect logic exposed by fix for the + security bug 12496 (CVE-2017-2619). + +In a UNIX filesystem, the names "." and ".." by definition can *never* +be symlinks - they are already reserved names. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +Reviewed-by: Uri Simchoni <uri(a)samba.org> +(cherry picked from commit ae17bebd250bdde5614b2ac17e53512f19fe9b68) +--- + source3/smbd/vfs.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +From 71500662d1098d17657b0148a0aa06cd69482c7d Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 27 Mar 2017 17:04:58 -0700 +Subject: [PATCH 2/3] s3: smbd: Fix "follow symlink = no" regression part 2. + +Add an extra paramter to cwd_name to check_reduced_name(). + +If cwd_name == NULL then fname is a client given path relative +to the root path of the share. + +If cwd_name != NULL then fname is a client given path relative +to cwd_name. cwd_name is relative to the root path of the share. + +Not yet used, logic added in the next commit. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +Reviewed-by: Ralph Boehme <slow(a)samba.org> +(cherry picked from commit 83e30cb48859b412b76572b6a3ba84d8fde167af) +--- + source3/smbd/filename.c | 2 +- + source3/smbd/open.c | 2 +- + source3/smbd/proto.h | 4 +++- + source3/smbd/vfs.c | 10 +++++++++- + 4 files changed, 14 insertions(+), 4 deletions(-) + +From e3fd46264b82ffc22424ee7364b3fd2c0fc14a7e Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 27 Mar 2017 17:09:38 -0700 +Subject: [PATCH 3/3] s3: smbd: Fix "follow symlink = no" regression part 2. + +Use the cwd_name parameter to reconstruct the original +client name for symlink testing. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +Reviewed-by: Ralph Boehme <slow(a)samba.org> +(cherry picked from commit e182a4d39e86c9694e255efdf6ee2ea3ccb9af4a) +--- + source3/smbd/vfs.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- samba-3.6.6.orig/source3/smbd/vfs.c ++++ samba-3.6.6/source3/smbd/vfs.c +@@ -894,11 +894,20 @@ + /******************************************************************* + Reduce a file name, removing .. elements and checking that + it is below dir in the heirachy. This uses realpath. ++ ++ If cwd_name == NULL then fname is a client given path relative ++ to the root path of the share. ++ ++ If cwd_name != NULL then fname is a client given path relative ++ to cwd_name. cwd_name is relative to the root path of the share. + ********************************************************************/ + +-NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) ++NTSTATUS check_reduced_name(connection_struct *conn, ++ const char *cwd_name, ++ const char *fname) + { + char *resolved_name = NULL; ++ char *new_fname = NULL; + bool allow_symlinks = true; + bool allow_widelinks = false; + +@@ -1026,8 +1035,11 @@ + /* fname can't have changed in resolved_path. */ + const char *p = &resolved_name[rootdir_len]; + +- /* *p can be '\0' if fname was "." */ +- if (*p == '\0' && ISDOT(fname)) { ++ /* ++ * UNIX filesystem semantics, names consisting ++ * only of "." or ".." CANNOT be symlinks. ++ */ ++ if (ISDOT(fname) || ISDOTDOT(fname)) { + goto out; + } + +@@ -1041,11 +1053,32 @@ + } + + p++; ++ ++ /* ++ * If cwd_name is present and not ".", ++ * then fname is relative to that, not ++ * the root of the share. Make sure the ++ * path we check is the one the client ++ * sent (cwd_name+fname). ++ */ ++ if (cwd_name != NULL && !ISDOT(cwd_name)) { ++ new_fname = talloc_asprintf(talloc_tos(), ++ "%s/%s", ++ cwd_name, ++ fname); ++ if (new_fname == NULL) { ++ SAFE_FREE(resolved_name); ++ return NT_STATUS_NO_MEMORY; ++ } ++ fname = new_fname; ++ } ++ + if (strcmp(fname, p)!=0) { + DEBUG(2, ("check_reduced_name: Bad access " + "attempt: %s is a symlink\n", + fname)); + SAFE_FREE(resolved_name); ++ TALLOC_FREE(new_fname); + return NT_STATUS_ACCESS_DENIED; + } + } +@@ -1056,6 +1089,7 @@ + DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname, + resolved_name)); + SAFE_FREE(resolved_name); ++ TALLOC_FREE(new_fname); + return NT_STATUS_OK; + } + +--- samba-3.6.6.orig/source3/smbd/filename.c ++++ samba-3.6.6/source3/smbd/filename.c +@@ -1009,7 +1009,7 @@ + } + + if (!lp_widelinks(SNUM(conn)) || !lp_symlinks(SNUM(conn))) { +- status = check_reduced_name(conn,name); ++ status = check_reduced_name(conn, NULL, name); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(5,("check_name: name %s failed with %s\n",name, + nt_errstr(status))); +--- samba-3.6.6.orig/source3/smbd/open.c ++++ samba-3.6.6/source3/smbd/open.c +@@ -381,7 +381,7 @@ + } + + /* Ensure the relative path is below the share. */ +- status = check_reduced_name(conn, final_component); ++ status = check_reduced_name(conn, parent_dir, final_component); + if (!NT_STATUS_IS_OK(status)) { + saved_errno = map_errno_from_nt_status(status); + goto out; +--- samba-3.6.6.orig/source3/smbd/proto.h ++++ samba-3.6.6/source3/smbd/proto.h +@@ -1179,7 +1179,9 @@ + SMB_STRUCT_STAT *sbuf, char **talloced); + int vfs_ChDir(connection_struct *conn, const char *path); + char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn); +-NTSTATUS check_reduced_name(connection_struct *conn, const char *fname); ++NTSTATUS check_reduced_name(connection_struct *conn, ++ const char *cwd_name, ++ const char *fname); + int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf); + int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, diff --git a/src/patches/samba/CVE-2017-2619-tests.patch b/src/patches/samba/CVE-2017-2619-tests.patch new file mode 100644 index 000000000..41c84610e --- /dev/null +++ b/src/patches/samba/CVE-2017-2619-tests.patch @@ -0,0 +1,296 @@ +Description: Patches to unit tests associated with CVE-2017-2619 regression +origin: https://attachments.samba.org/attachment.cgi?id=13130 + +From 2c6de8584779e413f1e6ff9c933f9281693bfbc0 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 27 Mar 2017 11:48:25 -0700 +Subject: [PATCH 2/6] s3: Test for CVE-2017-2619 regression with "follow + symlinks = no". + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +Reviewed-by: Uri Simchoni <uri(a)samba.org> + +Back-ported from commit 782172a9bef0040981d20e49519b13dd744df6a0 +--- + selftest/target/Samba3.pm | 7 +++ + source3/script/tests/test_smbclient_s3.sh | 73 +++++++++++++++++++++++++++++++ + 2 files changed, 80 insertions(+) + +diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm +index 01a1c470af0..7765b9efbb2 100644 +--- a/selftest/target/Samba3.pm ++++ b/selftest/target/Samba3.pm +@@ -481,6 +481,9 @@ sub provision($$$$$$) + my $msdfs_deeppath="$msdfs_shrdir/deeppath"; + push(@dirs,$msdfs_deeppath); + ++ my $nosymlinks_shrdir="$shrdir/nosymlinks"; ++ push(@dirs,$nosymlinks_shrdir); ++ + # this gets autocreated by winbindd + my $wbsockdir="$prefix_abs/winbindd"; + my $wbsockprivdir="$lockdir/winbindd_privileged"; +@@ -695,6 +698,10 @@ sub provision($$$$$$) + copy = print1 + [print\$] + copy = tmp ++[nosymlinks] ++ copy = tmp ++ path = $nosymlinks_shrdir ++ follow symlinks = no + "; + close(CONF); + +diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh +index 772802f77b1..57ef87e4949 100755 +--- a/source3/script/tests/test_smbclient_s3.sh ++++ b/source3/script/tests/test_smbclient_s3.sh +@@ -401,6 +401,75 @@ done + + LOGDIR=$(mktemp -d ${PREFIX}/${LOGDIR_PREFIX}_XXXXXX) + ++# Test follow symlinks can't access symlinks ++test_nosymlinks() ++{ ++# Setup test dirs. ++ slink_name="$LOCAL_PATH/nosymlinks/source" ++ slink_target="$LOCAL_PATH/nosymlinks/target" ++ mkdir_target="$LOCAL_PATH/nosymlinks/a" ++ ++ rm -f $slink_target ++ rm -f $slink_name ++ rm -rf $mkdir_target ++ ++ touch $slink_target ++ ln -s $slink_target $slink_name ++ ++# Getting a file through a symlink name should fail. ++ tmpfile=$PREFIX/smbclient_interactive_prompt_commands ++ cat > $tmpfile <<EOF ++get source ++quit ++EOF ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' ++ eval echo "$cmd" ++ out=`eval $cmd` ++ ret=$? ++ rm -f $tmpfile ++ ++ if [ $ret != 0 ] ; then ++ echo "$out" ++ echo "failed accessing nosymlinks with error $ret" ++ false ++ return ++ fi ++ ++ echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' ++ ret=$? ++ if [ $ret != 0 ] ; then ++ echo "$out" ++ echo "failed - should get NT_STATUS_ACCESS_DENIED getting \\nosymlinks\\source" ++ false ++ fi ++ ++# But we should be able to create and delete directories. ++ cat > $tmpfile <<EOF ++mkdir a ++mkdir a\\b ++quit ++EOF ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' ++ eval echo "$cmd" ++ out=`eval $cmd` ++ ret=$? ++ rm -f $tmpfile ++ ++ if [ $ret != 0 ] ; then ++ echo "$out" ++ echo "failed accessing nosymlinks with error $ret" ++ false ++ return ++ fi ++ ++ echo "$out" | grep 'NT_STATUS' ++ ret=$? ++ if [ $ret == 0 ] ; then ++ echo "$out" ++ echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b on \\nosymlinks" ++ false ++ fi ++} + + testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p 139 || failed=`expr $failed + 1` + testit "smbclient -L $SERVER -I $SERVER_IP" $SMBCLIENT -L $SERVER -I $SERVER_IP -N -p 139 -c quit || failed=`expr $failed + 1` +@@ -445,6 +514,10 @@ testit "ccache access works for smbclient" \ + test_ccache_access || \ + failed=`expr $failed + 1` + ++testit "follow symlinks = no" \ ++ test_nosymlinks || \ ++ failed=`expr $failed + 1` ++ + testit "rm -rf $LOGDIR" \ + rm -rf $LOGDIR || \ + failed=`expr $failed + 1` +-- +2.12.0 + + +From 17865cf188f42850f18f46514643a5b3a43e5707 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 27 Mar 2017 22:07:50 -0700 +Subject: [PATCH 3/6] s3: Fixup test for CVE-2017-2619 regression with "follow + symlinks = no" + +Use correct bash operators (not string operators). +Add missing "return". + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +Reviewed-by: Ralph Boehme <slow(a)samba.org> +(cherry picked from commit 037297a1c50e90a0092e3b94f472623f41ccc015) +--- + source3/script/tests/test_smbclient_s3.sh | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh +index 57ef87e4949..bd5714fca6e 100755 +--- a/source3/script/tests/test_smbclient_s3.sh ++++ b/source3/script/tests/test_smbclient_s3.sh +@@ -428,7 +428,7 @@ EOF + ret=$? + rm -f $tmpfile + +- if [ $ret != 0 ] ; then ++ if [ $ret -ne 0 ] ; then + echo "$out" + echo "failed accessing nosymlinks with error $ret" + false +@@ -437,10 +437,11 @@ EOF + + echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' + ret=$? +- if [ $ret != 0 ] ; then ++ if [ $ret -ne 0 ] ; then + echo "$out" + echo "failed - should get NT_STATUS_ACCESS_DENIED getting \\nosymlinks\\source" + false ++ return + fi + + # But we should be able to create and delete directories. +@@ -455,7 +456,7 @@ EOF + ret=$? + rm -f $tmpfile + +- if [ $ret != 0 ] ; then ++ if [ $ret -ne 0 ] ; then + echo "$out" + echo "failed accessing nosymlinks with error $ret" + false +@@ -464,7 +465,7 @@ EOF + + echo "$out" | grep 'NT_STATUS' + ret=$? +- if [ $ret == 0 ] ; then ++ if [ $ret -eq 0 ] ; then + echo "$out" + echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b on \\nosymlinks" + false +-- +2.12.0 + + +From 9b573af39f3d4995464e30771fa06e0709b5e57b Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Mon, 27 Mar 2017 22:10:29 -0700 +Subject: [PATCH 6/6] s3: Test for CVE-2017-2619 regression with "follow + symlinks = no" - part 2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add tests for regular access. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +Reviewed-by: Ralph Boehme <slow(a)samba.org> + +Autobuild-User(master): Ralph Böhme <slow(a)samba.org> +Autobuild-Date(master): Tue Mar 28 17:05:27 CEST 2017 on sn-devel-144 + +(cherry picked from commit 4e734fcd1bf82c08aa303ce44e9735acccffcf06) +--- + source3/script/tests/test_smbclient_s3.sh | 37 +++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh +index bd5714fca6e..885766f6c16 100755 +--- a/source3/script/tests/test_smbclient_s3.sh ++++ b/source3/script/tests/test_smbclient_s3.sh +@@ -408,14 +408,22 @@ test_nosymlinks() + slink_name="$LOCAL_PATH/nosymlinks/source" + slink_target="$LOCAL_PATH/nosymlinks/target" + mkdir_target="$LOCAL_PATH/nosymlinks/a" ++ dir1="$LOCAL_PATH/nosymlinks/foo" ++ dir2="$LOCAL_PATH/nosymlinks/foo/bar" ++ get_target="$LOCAL_PATH/nosymlinks/foo/bar/testfile" + + rm -f $slink_target + rm -f $slink_name + rm -rf $mkdir_target ++ rm -rf $dir1 + + touch $slink_target + ln -s $slink_target $slink_name + ++ mkdir $dir1 ++ mkdir $dir2 ++ touch $get_target ++ + # Getting a file through a symlink name should fail. + tmpfile=$PREFIX/smbclient_interactive_prompt_commands + cat > $tmpfile <<EOF +@@ -470,6 +478,35 @@ EOF + echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b on \\nosymlinks" + false + fi ++ ++# Ensure regular file/directory access also works. ++ cat > $tmpfile <<EOF ++cd foo\\bar ++ls ++get testfile - ++quit ++EOF ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' ++ eval echo "$cmd" ++ out=`eval $cmd` ++ ret=$? ++ rm -f $tmpfile ++ ++ if [ $ret -ne 0 ] ; then ++ echo "$out" ++ echo "failed accessing nosymlinks with error $ret" ++ false ++ return ++ fi ++ ++ echo "$out" | grep 'NT_STATUS' ++ ret=$? ++ if [ $ret -eq 0 ] ; then ++ echo "$out" ++ echo "failed - NT_STATUS_XXXX doing cd foo\\bar; get testfile on \\nosymlinks" ++ false ++ return ++ fi + } + + testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p 139 || failed=`expr $failed + 1` +-- +2.12.0 + diff --git a/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch b/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch new file mode 100644 index 000000000..54bb1841b --- /dev/null +++ b/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch @@ -0,0 +1,14 @@ +--- source3/rpc_server/srv_pipe.c Sun Feb 22 16:11:32 2015 ++++ source3/rpc_server/srv_pipe.c Fri May 26 17:28:40 2017 +@@ -465,6 +465,11 @@ + const char *pipename = cli_filename; + NTSTATUS status; + ++ if (strchr(pipename, '/')) { ++ DEBUG(1, ("Refusing open on pipe %s\n", pipename)); ++ return false; ++ } ++ + if (strnequal(pipename, "\\PIPE\\", 6)) { + pipename += 5; + } diff --git a/src/patches/samba/samba-3.6.25-security-2015-12-16.patch b/src/patches/samba/samba-3.6.25-security-2015-12-16.patch new file mode 100644 index 000000000..df1057fea --- /dev/null +++ b/src/patches/samba/samba-3.6.25-security-2015-12-16.patch @@ -0,0 +1,255 @@ +From 2e94b6ec10f1d15e24867bab3063bb85f173406a Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Thu, 9 Jul 2015 10:58:11 -0700 +Subject: [PATCH] CVE-2015-5252: s3: smbd: Fix symlink verification (file + access outside the share). + +Ensure matching component ends in '/' or '\0'. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11395 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +Reviewed-by: Volker Lendecke <vl(a)samba.org> +--- + source3/smbd/vfs.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c +index 6c56964..bd93b7f 100644 +--- a/source3/smbd/vfs.c ++++ b/source3/smbd/vfs.c +@@ -982,6 +982,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) + if (!allow_widelinks || !allow_symlinks) { + const char *conn_rootdir; + size_t rootdir_len; ++ bool matched; + + conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname); + if (conn_rootdir == NULL) { +@@ -992,8 +993,10 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) + } + + rootdir_len = strlen(conn_rootdir); +- if (strncmp(conn_rootdir, resolved_name, +- rootdir_len) != 0) { ++ matched = (strncmp(conn_rootdir, resolved_name, ++ rootdir_len) == 0); ++ if (!matched || (resolved_name[rootdir_len] != '/' && ++ resolved_name[rootdir_len] != '\0')) { + DEBUG(2, ("check_reduced_name: Bad access " + "attempt: %s is a symlink outside the " + "share path\n", fname)); +-- +2.5.0 + +From 25139116756cc285a3a5534834cc276ef1b7baaa Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <metze(a)samba.org> +Date: Wed, 30 Sep 2015 21:17:02 +0200 +Subject: [PATCH 1/2] CVE-2015-5296: s3:libsmb: force signing when requiring + encryption in do_connect() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536 + +Signed-off-by: Stefan Metzmacher <metze(a)samba.org> +Reviewed-by: Jeremy Allison <jra(a)samba.org> +--- + source3/libsmb/clidfs.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c +index 23e1471..f153b6b 100644 +--- a/source3/libsmb/clidfs.c ++++ b/source3/libsmb/clidfs.c +@@ -98,6 +98,11 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, + const char *username; + const char *password; + NTSTATUS status; ++ int signing_state = get_cmdline_auth_info_signing_state(auth_info); ++ ++ if (force_encrypt) { ++ signing_state = Required; ++ } + + /* make a copy so we don't modify the global string 'service' */ + servicename = talloc_strdup(ctx,share); +@@ -132,7 +137,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, + zero_sockaddr(&ss); + + /* have to open a new connection */ +- c = cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)); ++ c = cli_initialise_ex(signing_state); + if (c == NULL) { + d_printf("Connection to %s failed\n", server_n); + return NULL; +-- +2.5.0 + + +From 060adb0abdeda51b8b622c6020b5dea0c8dde1cf Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <metze(a)samba.org> +Date: Wed, 30 Sep 2015 21:17:02 +0200 +Subject: [PATCH 2/2] CVE-2015-5296: s3:libsmb: force signing when requiring + encryption in SMBC_server_internal() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536 + +Signed-off-by: Stefan Metzmacher <metze(a)samba.org> +Reviewed-by: Jeremy Allison <jra(a)samba.org> +--- + source3/libsmb/libsmb_server.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c +index 45be660..167f2c9 100644 +--- a/source3/libsmb/libsmb_server.c ++++ b/source3/libsmb/libsmb_server.c +@@ -258,6 +258,7 @@ SMBC_server_internal(TALLOC_CTX *ctx, + const char *username_used; + NTSTATUS status; + char *newserver, *newshare; ++ int signing_state = Undefined; + + zero_sockaddr(&ss); + ZERO_STRUCT(c); +@@ -404,8 +405,12 @@ again: + + zero_sockaddr(&ss); + ++ if (context->internal->smb_encryption_level != SMBC_ENCRYPTLEVEL_NONE) { ++ signing_state = Required; ++ } ++ + /* have to open a new connection */ +- if ((c = cli_initialise()) == NULL) { ++ if ((c = cli_initialise_ex(signing_state)) == NULL) { + errno = ENOMEM; + return NULL; + } +@@ -750,6 +755,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, + ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$", + pp_workgroup, pp_username, pp_password); + if (!ipc_srv) { ++ int signing_state = Undefined; + + /* We didn't find a cached connection. Get the password */ + if (!*pp_password || (*pp_password)[0] == '\0') { +@@ -771,6 +777,9 @@ SMBC_attr_server(TALLOC_CTX *ctx, + if (smbc_getOptionUseCCache(context)) { + flags |= CLI_FULL_CONNECTION_USE_CCACHE; + } ++ if (context->internal->smb_encryption_level != SMBC_ENCRYPTLEVEL_NONE) { ++ signing_state = Required; ++ } + + zero_sockaddr(&ss); + nt_status = cli_full_connection(&ipc_cli, +@@ -780,7 +789,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, + *pp_workgroup, + *pp_password, + flags, +- Undefined); ++ signing_state); + if (! NT_STATUS_IS_OK(nt_status)) { + DEBUG(1,("cli_full_connection failed! (%s)\n", + nt_errstr(nt_status))); +-- +2.5.0 + +From 8e49de7754f7171a58a1f94dee0f1138dbee3c60 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <jra(a)samba.org> +Date: Fri, 23 Oct 2015 14:54:31 -0700 +Subject: [PATCH] CVE-2015-5299: s3-shadow-copy2: fix missing access check on + snapdir + +Fix originally from <partha(a)exablox.com> + +https://bugzilla.samba.org/show_bug.cgi?id=11529 + +Signed-off-by: Jeremy Allison <jra(a)samba.org> +Reviewed-by: David Disseldorp <ddiss(a)samba.org> +--- + source3/modules/vfs_shadow_copy2.c | 47 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 47 insertions(+) + +diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c +index fedfb53..16c1ed7 100644 +--- a/source3/modules/vfs_shadow_copy2.c ++++ b/source3/modules/vfs_shadow_copy2.c +@@ -21,6 +21,8 @@ + + #include "includes.h" + #include "smbd/smbd.h" ++#include "smbd/globals.h" ++#include "../libcli/security/security.h" + #include "system/filesys.h" + #include "ntioctl.h" + +@@ -764,6 +766,43 @@ static int shadow_copy2_mkdir(vfs_handle_struct *handle, const char *fname, mod + SHADOW2_NEXT(MKDIR, (handle, name, mode), int, -1); + } + ++static bool check_access_snapdir(struct vfs_handle_struct *handle, ++ const char *path) ++{ ++ struct smb_filename smb_fname; ++ int ret; ++ NTSTATUS status; ++ uint32_t access_granted = 0; ++ ++ ZERO_STRUCT(smb_fname); ++ smb_fname.base_name = talloc_asprintf(talloc_tos(), ++ "%s", ++ path); ++ if (smb_fname.base_name == NULL) { ++ return false; ++ } ++ ++ ret = SMB_VFS_NEXT_STAT(handle, &smb_fname); ++ if (ret != 0 || !S_ISDIR(smb_fname.st.st_ex_mode)) { ++ TALLOC_FREE(smb_fname.base_name); ++ return false; ++ } ++ ++ status = smbd_check_open_rights(handle->conn, ++ &smb_fname, ++ SEC_DIR_LIST, ++ &access_granted); ++ if (!NT_STATUS_IS_OK(status)) { ++ DEBUG(0,("user does not have list permission " ++ "on snapdir %s\n", ++ smb_fname.base_name)); ++ TALLOC_FREE(smb_fname.base_name); ++ return false; ++ } ++ TALLOC_FREE(smb_fname.base_name); ++ return true; ++} ++ + static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname) + { + SHADOW2_NEXT(RMDIR, (handle, name), int, -1); +@@ -877,6 +916,7 @@ static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, + SMB_STRUCT_DIRENT *d; + TALLOC_CTX *tmp_ctx = talloc_new(handle->data); + char *snapshot; ++ bool ret; + + snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle); + if (snapdir == NULL) { +@@ -886,6 +926,13 @@ static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, + talloc_free(tmp_ctx); + return -1; + } ++ ret = check_access_snapdir(handle, snapdir); ++ if (!ret) { ++ DEBUG(0,("access denied on listing snapdir %s\n", snapdir)); ++ errno = EACCES; ++ talloc_free(tmp_ctx); ++ return -1; ++ } + + p = SMB_VFS_NEXT_OPENDIR(handle, snapdir, NULL, 0); + +-- +2.5.0 + -- 2.13.0 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Security updates for samba 3.6.25 2017-05-28 9:22 [PATCH] Security updates for samba 3.6.25 Matthias Fischer @ 2017-05-29 16:57 ` Michael Tremer 2017-05-29 18:30 ` Matthias Fischer 0 siblings, 1 reply; 4+ messages in thread From: Michael Tremer @ 2017-05-29 16:57 UTC (permalink / raw) To: development [-- Attachment #1: Type: text/plain, Size: 70796 bytes --] Hi, thank you for working on this. Yes, Arne submitted a patch that at least fixes the security vulnerability. However, could you split this patch into two with the two remaining changes so that we can merge those? Best, -Michael On Sun, 2017-05-28 at 11:22 +0200, Matthias Fischer wrote: > Based on: > > https://anonscm.debian.org/cgit/pkg-samba/samba.git/commit/?h=wheezy&id=762a3a > fd8eb45526e44cd0b2ae8a5b1a058ec647 > > https://www.samba.org/samba/history/security.html > > https://www.samba.org/samba/samba/ftp/patches/security/ > > Fixes current CVE-2017-7494 and some more... > > Removed three 'unrecognized' configure-options. > > Some 'lfs'-tuning was made, too. > > I altered 'PAK_VER' from "64" to "65" - if not necessary, please change back. > > Best, > Matthias > > Signed-off-by: Matthias Fischer <matthias.fischer(a)ipfire.org> > --- > lfs/samba | 22 +- > .../samba/CVE-2017-2619-race-condition-fix.patch | 1150 > ++++++++++++++++++++ > .../CVE-2017-2619-regression-bug-12721-fix.patch | 179 +++ > src/patches/samba/CVE-2017-2619-tests.patch | 296 +++++ > src/patches/samba/samba-3.6.25-CVE-2017-7494.patch | 14 + > .../samba/samba-3.6.25-security-2015-12-16.patch | 255 +++++ > 6 files changed, 1909 insertions(+), 7 deletions(-) > create mode 100644 src/patches/samba/CVE-2017-2619-race-condition-fix.patch > create mode 100644 src/patches/samba/CVE-2017-2619-regression-bug-12721- > fix.patch > create mode 100644 src/patches/samba/CVE-2017-2619-tests.patch > create mode 100644 src/patches/samba/samba-3.6.25-CVE-2017-7494.patch > create mode 100644 src/patches/samba/samba-3.6.25-security-2015-12-16.patch > > diff --git a/lfs/samba b/lfs/samba > index 076152f48..445646464 100644 > --- a/lfs/samba > +++ b/lfs/samba > @@ -1,7 +1,7 @@ > ############################################################################# > ## > # > # > # IPFire.org - A linux based > firewall # > -# Copyright (C) 2007-2016 IPFire Team <info(a)ipfire.org> > # > +# Copyright (C) 2007-2017 IPFire Team <info(a)ipfire.org> > # > # > # > # 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 # > @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) > DIR_APP = $(DIR_SRC)/$(THISAPP) > TARGET = $(DIR_INFO)/$(THISAPP) > PROG = samba > -PAK_VER = 64 > +PAK_VER = 65 > > DEPS = "cups krb5" > > @@ -54,7 +54,7 @@ download :$(patsubst %,$(DIR_DL)/%,$(objects)) > > md5 : $(subst %,%_MD5,$(objects)) > > -dist: > +dist: > @$(PAK) > > ############################################################################# > ## > @@ -88,6 +88,17 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) > cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2016- > 2118-v3-6.patch > cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2015- > 5370-v3-6.patch > > + # Apply Debian CVE patches > + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017- > 2619-race-condition-fix.patch > + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017- > 2619-regression-bug-12721-fix.patch > + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017- > 2619-tests.patch > + > + # Fixes CVE-2015-5252 - Samba > + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/samba- > 3.6.25-security-2015-12-16.patch > + > + # Fixes CVE-2017-7494 - Samba > + cd $(DIR_APP) && patch -Np0 < $(DIR_SRC)/src/patches/samba/samba- > 3.6.25-CVE-2017-7494.patch > + > cd $(DIR_APP)/source3 && ./autogen.sh > cd $(DIR_APP)/source3 && ./configure \ > --prefix=/usr \ > @@ -102,10 +113,7 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) > --with-libsmbclient \ > --with-libsmbsharemodes \ > --with-sendfile-support \ > - --without-smbwrapper \ > - --with-mmap \ > --with-fhs \ > - --with-vfs \ > --with-winbind \ > --disable-swat \ > --enable-cups \ > @@ -119,8 +127,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) > #cd $(DIR_APP)/source3 && install -v -m755 nsswitch/libnss_winbind.so > /lib > #cd $(DIR_APP)/source3 && ln -v -sf libnss_winbind.so > /lib/libnss_winbind.so.2 > #cd $(DIR_APP)/source3 && ln -v -sf libnss_wins.so > /lib/libnss_wins.so.2 > + -mkdir -p /var/ipfire/samba > cd $(DIR_APP)/source3 && install -v -m644 > ../examples/smb.conf.default /var/ipfire/samba > - -mkdir -p /var/ipfire/samba > cp -vrf $(DIR_SRC)/config/samba/* /var/ipfire/samba/ > chown nobody:nobody -R /var/ipfire/samba/ > cp -vfp /var/ipfire/samba/default.global /var/ipfire/samba/global > diff --git a/src/patches/samba/CVE-2017-2619-race-condition-fix.patch > b/src/patches/samba/CVE-2017-2619-race-condition-fix.patch > new file mode 100644 > index 000000000..a96d6be3b > --- /dev/null > +++ b/src/patches/samba/CVE-2017-2619-race-condition-fix.patch > @@ -0,0 +1,1150 @@ > +Description: This patch is a consolidation of several patches described by > the Git commit summaries below > +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-261 > 9 > +bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +From ec1bca1d5315549e945c93cbf5e3abdb695de782 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 20 Mar 2017 11:32:19 -0700 > +Subject: [PATCH 01/15] CVE-2017-2619: s3/smbd: re-open directory after > + dptr_CloseDir() > + > +dptr_CloseDir() will close and invalidate the fsp's file descriptor, we > +have to reopen it. > + > +Bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Ralph Bohme <slow(a)samba.org> > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/open.c | 2 +- > + source3/smbd/proto.h | 2 ++ > + source3/smbd/smb2_find.c | 17 +++++++++++++++++ > + 3 files changed, 20 insertions(+), 1 deletion(-) > + > +From 2bb9a3d35f6a0cc43a30638594969c4860ffd5a5 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Tue, 28 Feb 2017 09:24:07 -0800 > +Subject: [PATCH 02/15] s3: vfs: dirsort doesn't handle opendir of "." > + correctly. > + > +Needs to store $cwd path for correct sorting. > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12499 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/modules/vfs_dirsort.c | 4 ++++ > + 1 file changed, 4 insertions(+) > + > +From 327d09ba641046f68daa5b2bb98f09530294cb0d Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 13 Mar 2017 13:44:42 -0700 > +Subject: [PATCH 03/15] s3: VFS: vfs_streams_xattr.c: Make > streams_xattr_open() > + store the same path as streams_xattr_recheck(). > + > +If the open is changing directories, fsp->fsp_name->base_name > +will be the full path from the share root, whilst > +smb_fname will be relative to the $cwd. > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12546 > + > +Back-ported from a24ba3e4083200ec9885363efc5769f43183fb6b > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/modules/vfs_streams_xattr.c | 9 ++++++++- > + 1 file changed, 8 insertions(+), 1 deletion(-) > + > +From 27871d3bfb0857ad3306aabdce6f9b55e32fff3d Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 13 Mar 2017 13:54:04 -0700 > +Subject: [PATCH 04/15] vfs_streams_xattr: use fsp, not base_fsp > + > +The base_fsp's fd is always -1 as it's closed after being openend in > +create_file_unixpath(). > + > +Additionally in streams_xattr_open force using of SMB_VFS_FSETXATTR() by > +sticking the just created fd into the fsp (and removing it afterwards). > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12591 > + > +Back-ported from 021189e32ba507832b5e821e5cda8a2889225955. > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/modules/vfs_streams_xattr.c | 205 +++++++++++++++++----------------- > -- > + 1 file changed, 99 insertions(+), 106 deletions(-) > + > +From a419b277c5994459c956ebdd324679e728ebae10 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 19 Dec 2016 11:55:56 -0800 > +Subject: [PATCH 05/15] s3: smbd: Create wrapper function for OpenDir in > + preparation for making robust. > + > +CVE-2017-2619 > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/dir.c | 15 ++++++++++++++- > + 1 file changed, 14 insertions(+), 1 deletion(-) > + > +From e47e3c40b5fc8f52fe70c3e1edf5489ac8b4badf Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 19 Dec 2016 16:25:26 -0800 > +Subject: [PATCH 06/15] s3: smbd: Opendir_internal() early return if > + SMB_VFS_OPENDIR failed. > + > +CVE-2017-2619 > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/dir.c | 14 +++++++------- > + 1 file changed, 7 insertions(+), 7 deletions(-) > + > +From 45e41b709b6c2e67acb99f29aa05b61b53091e57 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 19 Dec 2016 16:35:00 -0800 > +Subject: [PATCH 07/15] s3: smbd: Create and use open_dir_safely(). Use from > + OpenDir(). > + > +Hardens OpenDir against TOC/TOU races. > + > +CVE-2017-2619 > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/dir.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++-- > ---- > + 1 file changed, 59 insertions(+), 7 deletions(-) > + > +From 720abcec65b04fdac1052a14898180c8cc816464 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 19 Dec 2016 12:13:20 -0800 > +Subject: [PATCH 08/15] s3: smbd: OpenDir_fsp() use early returns. > + > +CVE-2017-2619 > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/dir.c | 34 +++++++++++++++++++++------------- > + 1 file changed, 21 insertions(+), 13 deletions(-) > + > +From 5070f319bbb7dda87766621a83691910414d06a1 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 19 Dec 2016 12:15:59 -0800 > +Subject: [PATCH 09/15] s3: smbd: OpenDir_fsp() - Fix memory leak on error. > + > +CVE-2017-2619 > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/dir.c | 2 +- > + 1 file changed, 1 insertion(+), 1 deletion(-) > + > +From 65d37759f8b4979bc0c0833e0a5eecd277dfa604 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 19 Dec 2016 12:32:07 -0800 > +Subject: [PATCH 10/15] s3: smbd: Move the reference counting and destructor > + setup to just before retuning success. > + > +CVE-2017-2619 > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/dir.c | 10 +++++----- > + 1 file changed, 5 insertions(+), 5 deletions(-) > + > +From 5a821d791aba90643ddf7a3c29dad4f6621ef185 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 19 Dec 2016 12:35:32 -0800 > +Subject: [PATCH 11/15] s3: smbd: Correctly fallback to open_dir_safely if > + FDOPENDIR not supported on system. > + > +CVE-2017-2619 > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/dir.c | 15 +++++++-------- > + 1 file changed, 7 insertions(+), 8 deletions(-) > + > +From 597aa3b99a2790133a4839260607b0a8df41c8e3 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Thu, 15 Dec 2016 12:52:13 -0800 > +Subject: [PATCH 12/15] s3: smbd: Remove O_NOFOLLOW guards. We insist on > + O_NOFOLLOW existing. > + > +CVE-2017-2619 > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/open.c | 4 +--- > + 1 file changed, 1 insertion(+), 3 deletions(-) > + > +From 563af2ffec05a2c0b54897e2d28ac7e1adb66e0f Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Thu, 15 Dec 2016 12:56:08 -0800 > +Subject: [PATCH 13/15] s3: smbd: Move special handling of symlink errno's > into > + a utility function. > + > +CVE-2017-2619 > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/open.c | 30 ++++++++++++++++++++++++++++-- > + 1 file changed, 28 insertions(+), 2 deletions(-) > + > +From b34a67cd3a996804ba7bf90e86cf9e22edf60eb3 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Thu, 15 Dec 2016 13:04:46 -0800 > +Subject: [PATCH 14/15] s3: smbd: Add the core functions to prevent symlink > + open races. > + > +CVE-2017-2619 > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/open.c | 242 > ++++++++++++++++++++++++++++++++++++++++++++++++++++ > + 1 file changed, 242 insertions(+) > + > +From 5920309d2f62dd24fc50530c92dd68077f96a6d2 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Thu, 15 Dec 2016 13:06:31 -0800 > +Subject: [PATCH 15/15] s3: smbd: Use the new non_widelink_open() function. > + > +CVE-2017-2619 > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/smbd/open.c | 23 ++++++++++++++++++++++- > + 1 file changed, 22 insertions(+), 1 deletion(-) > + > + > +--- samba-3.6.6.orig/source3/smbd/open.c > ++++ samba-3.6.6/source3/smbd/open.c > +@@ -187,10 +187,277 @@ > + } > + > + > /**************************************************************************** > ++ Handle differing symlink errno's > ++**************************************************************************** > / > ++ > ++static int link_errno_convert(int err) > ++{ > ++#if defined(ENOTSUP) && defined(OSF1) > ++ /* handle special Tru64 errno */ > ++ if (err == ENOTSUP) { > ++ err = ELOOP; > ++ } > ++#endif /* ENOTSUP */ > ++#ifdef EFTYPE > ++ /* fix broken NetBSD errno */ > ++ if (err == EFTYPE) { > ++ err = ELOOP; > ++ } > ++#endif /* EFTYPE */ > ++ /* fix broken FreeBSD errno */ > ++ if (err == EMLINK) { > ++ err = ELOOP; > ++ } > ++ return err; > ++} > ++ > ++static int non_widelink_open(struct connection_struct *conn, > ++ const char *conn_rootdir, > ++ files_struct *fsp, > ++ struct smb_filename *smb_fname, > ++ int flags, > ++ mode_t mode, > ++ unsigned int link_depth); > ++ > ++/*************************************************************************** > * > ++ Follow a symlink in userspace. > ++**************************************************************************** > / > ++ > ++static int process_symlink_open(struct connection_struct *conn, > ++ const char *conn_rootdir, > ++ files_struct *fsp, > ++ struct smb_filename *smb_fname, > ++ int flags, > ++ mode_t mode, > ++ unsigned int link_depth) > ++{ > ++ int fd = -1; > ++ char *link_target = NULL; > ++ int link_len = -1; > ++ char *oldwd = NULL; > ++ size_t rootdir_len = 0; > ++ char *resolved_name = NULL; > ++ bool matched = false; > ++ int saved_errno = 0; > ++ > ++ /* > ++ * Ensure we don't get stuck in a symlink loop. > ++ */ > ++ link_depth++; > ++ if (link_depth >= 20) { > ++ errno = ELOOP; > ++ goto out; > ++ } > ++ > ++ /* Allocate space for the link target. */ > ++ link_target = talloc_array(talloc_tos(), char, PATH_MAX); > ++ if (link_target == NULL) { > ++ errno = ENOMEM; > ++ goto out; > ++ } > ++ > ++ /* Read the link target. */ > ++ link_len = SMB_VFS_READLINK(conn, > ++ smb_fname->base_name, > ++ link_target, > ++ PATH_MAX - 1); > ++ if (link_len == -1) { > ++ goto out; > ++ } > ++ > ++ /* Ensure it's at least null terminated. */ > ++ link_target[link_len] = '\0'; > ++ > ++ /* Convert to an absolute path. */ > ++ resolved_name = SMB_VFS_REALPATH(conn, link_target); > ++ if (resolved_name == NULL) { > ++ goto out; > ++ } > ++ > ++ /* > ++ * We know conn_rootdir starts with '/' and > ++ * does not end in '/'. FIXME ! Should we > ++ * smb_assert this ? > ++ */ > ++ rootdir_len = strlen(conn_rootdir); > ++ > ++ matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0); > ++ if (!matched) { > ++ errno = EACCES; > ++ goto out; > ++ } > ++ > ++ /* > ++ * Turn into a path relative to the share root. > ++ */ > ++ if (resolved_name[rootdir_len] == '\0') { > ++ /* Link to the root of the share. */ > ++ smb_fname->base_name = talloc_strdup(talloc_tos(), "."); > ++ if (smb_fname->base_name == NULL) { > ++ errno = ENOMEM; > ++ goto out; > ++ } > ++ } else if (resolved_name[rootdir_len] == '/') { > ++ smb_fname->base_name = &resolved_name[rootdir_len+1]; > ++ } else { > ++ errno = EACCES; > ++ goto out; > ++ } > ++ > ++ oldwd = vfs_GetWd(talloc_tos(), conn); > ++ if (oldwd == NULL) { > ++ goto out; > ++ } > ++ > ++ /* Ensure we operate from the root of the share. */ > ++ if (vfs_ChDir(conn, conn_rootdir) == -1) { > ++ goto out; > ++ } > ++ > ++ /* And do it all again.. */ > ++ fd = non_widelink_open(conn, > ++ conn_rootdir, > ++ fsp, > ++ smb_fname, > ++ flags, > ++ mode, > ++ link_depth); > ++ if (fd == -1) { > ++ saved_errno = errno; > ++ } > ++ > ++ out: > ++ > ++ SAFE_FREE(resolved_name); > ++ TALLOC_FREE(link_target); > ++ if (oldwd != NULL) { > ++ int ret = vfs_ChDir(conn, oldwd); > ++ if (ret == -1) { > ++ smb_panic("unable to get back to old directory\n"); > ++ } > ++ TALLOC_FREE(oldwd); > ++ } > ++ if (saved_errno != 0) { > ++ errno = saved_errno; > ++ } > ++ return fd; > ++} > ++ > ++/*************************************************************************** > * > ++ Non-widelink open. > ++**************************************************************************** > / > ++ > ++static int non_widelink_open(struct connection_struct *conn, > ++ const char *conn_rootdir, > ++ files_struct *fsp, > ++ struct smb_filename *smb_fname, > ++ int flags, > ++ mode_t mode, > ++ unsigned int link_depth) > ++{ > ++ NTSTATUS status; > ++ int fd = -1; > ++ struct smb_filename *smb_fname_rel = NULL; > ++ int saved_errno = 0; > ++ char *oldwd = NULL; > ++ char *parent_dir = NULL; > ++ const char *final_component = NULL; > ++ > ++ if (!parent_dirname(talloc_tos(), > ++ smb_fname->base_name, > ++ &parent_dir, > ++ &final_component)) { > ++ goto out; > ++ } > ++ > ++ oldwd = vfs_GetWd(talloc_tos(), conn); > ++ if (oldwd == NULL) { > ++ goto out; > ++ } > ++ > ++ /* Pin parent directory in place. */ > ++ if (vfs_ChDir(conn, parent_dir) == -1) { > ++ goto out; > ++ } > ++ > ++ /* Ensure the relative path is below the share. */ > ++ status = check_reduced_name(conn, final_component); > ++ if (!NT_STATUS_IS_OK(status)) { > ++ saved_errno = map_errno_from_nt_status(status); > ++ goto out; > ++ } > ++ > ++ status = create_synthetic_smb_fname(talloc_tos(), > ++ final_component, > ++ smb_fname->stream_name, > ++ &smb_fname->st, > ++ &smb_fname_rel); > ++ if (!NT_STATUS_IS_OK(status)) { > ++ saved_errno = map_errno_from_nt_status(status); > ++ goto out; > ++ } > ++ > ++ flags |= O_NOFOLLOW; > ++ > ++ { > ++ struct smb_filename *tmp_name = fsp->fsp_name; > ++ fsp->fsp_name = smb_fname_rel; > ++ fd = SMB_VFS_OPEN(conn, smb_fname_rel, fsp, flags, mode); > ++ fsp->fsp_name = tmp_name; > ++ } > ++ > ++ if (fd == -1) { > ++ saved_errno = link_errno_convert(errno); > ++ if (saved_errno == ELOOP) { > ++ if (fsp->posix_open) { > ++ /* Never follow symlinks on posix open. */ > ++ goto out; > ++ } > ++ if (!lp_symlinks(SNUM(conn))) { > ++ /* Explicitly no symlinks. */ > ++ goto out; > ++ } > ++ /* > ++ * We have a symlink. Follow in userspace > ++ * to ensure it's under the share definition. > ++ */ > ++ fd = process_symlink_open(conn, > ++ conn_rootdir, > ++ fsp, > ++ smb_fname_rel, > ++ flags, > ++ mode, > ++ link_depth); > ++ if (fd == -1) { > ++ saved_errno = > ++ link_errno_convert(errno); > ++ } > ++ } > ++ } > ++ > ++ out: > ++ > ++ TALLOC_FREE(parent_dir); > ++ TALLOC_FREE(smb_fname_rel); > ++ > ++ if (oldwd != NULL) { > ++ int ret = vfs_ChDir(conn, oldwd); > ++ if (ret == -1) { > ++ smb_panic("unable to get back to old directory\n"); > ++ } > ++ TALLOC_FREE(oldwd); > ++ } > ++ if (saved_errno != 0) { > ++ errno = saved_errno; > ++ } > ++ return fd; > ++} > ++ > ++/*************************************************************************** > * > + fd support routines - attempt to do a dos_open. > + > ****************************************************************************/ > + > +-static NTSTATUS fd_open(struct connection_struct *conn, > ++NTSTATUS fd_open(struct connection_struct *conn, > + files_struct *fsp, > + int flags, > + mode_t mode) > +@@ -198,8 +465,7 @@ > + struct smb_filename *smb_fname = fsp->fsp_name; > + NTSTATUS status = NT_STATUS_OK; > + > +-#ifdef O_NOFOLLOW > +- /* > ++ /* > + * Never follow symlinks on a POSIX client. The > + * client should be doing this. > + */ > +@@ -207,12 +473,33 @@ > + if (fsp->posix_open || !lp_symlinks(SNUM(conn))) { > + flags |= O_NOFOLLOW; > + } > +-#endif > + > +- fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); > ++ /* Ensure path is below share definition. */ > ++ if (!lp_widelinks(SNUM(conn))) { > ++ const char *conn_rootdir = SMB_VFS_CONNECTPATH(conn, > ++ smb_fname->base_name); > ++ if (conn_rootdir == NULL) { > ++ return NT_STATUS_NO_MEMORY; > ++ } > ++ /* > ++ * Only follow symlinks within a share > ++ * definition. > ++ */ > ++ fsp->fh->fd = non_widelink_open(conn, > ++ conn_rootdir, > ++ fsp, > ++ smb_fname, > ++ flags, > ++ mode, > ++ 0); > ++ } else { > ++ fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, > mode); > ++ } > ++ > + if (fsp->fh->fd == -1) { > +- status = map_nt_error_from_unix(errno); > +- if (errno == EMFILE) { > ++ int posix_errno = link_errno_convert(errno); > ++ status = map_nt_error_from_unix(posix_errno); > ++ if (posix_errno == EMFILE) { > + static time_t last_warned = 0L; > + > + if (time((time_t *) NULL) > last_warned) { > +--- samba-3.6.6.orig/source3/smbd/proto.h > ++++ samba-3.6.6/source3/smbd/proto.h > +@@ -592,6 +592,8 @@ > + const struct security_token *token, > + uint32_t access_desired, > + uint32_t *access_granted); > ++NTSTATUS fd_open(struct connection_struct *conn, files_struct *fsp, > ++ int flags, mode_t mode); > + NTSTATUS fd_close(files_struct *fsp); > + void change_file_owner_to_parent(connection_struct *conn, > + const char *inherit_from_dir, > +--- samba-3.6.6.orig/source3/smbd/smb2_find.c > ++++ samba-3.6.6/source3/smbd/smb2_find.c > +@@ -24,6 +24,7 @@ > + #include "../libcli/smb/smb_common.h" > + #include "trans2.h" > + #include "../lib/util/tevent_ntstatus.h" > ++#include "system/filesys.h" > + > + static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx, > + struct tevent_context *ev, > +@@ -300,7 +301,23 @@ > + } > + > + if (in_flags & SMB2_CONTINUE_FLAG_REOPEN) { > ++ int flags; > ++ > + dptr_CloseDir(fsp); > ++ > ++ /* > ++ * dptr_CloseDir() will close and invalidate the fsp's file > ++ * descriptor, we have to reopen it. > ++ */ > ++ > ++ flags = O_RDONLY; > ++#ifdef O_DIRECTORY > ++ flags |= O_DIRECTORY; > ++#endif > ++ status = fd_open(conn, fsp, flags, 0); > ++ if (tevent_req_nterror(req, status)) { > ++ return tevent_req_post(req, ev); > ++ } > + } > + > + if (fsp->dptr == NULL) { > +--- samba-3.6.6.orig/source3/modules/vfs_dirsort.c > ++++ samba-3.6.6/source3/modules/vfs_dirsort.c > +@@ -141,6 +141,10 @@ > + return NULL; > + } > + > ++ if (ISDOT(data->smb_fname->base_name)) { > ++ data->smb_fname->base_name = vfs_GetWd(data, handle->conn); > ++ } > ++ > + /* Open the underlying directory and count the number of entries */ > + data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, > + attr); > +--- samba-3.6.6.orig/source3/modules/vfs_streams_xattr.c > ++++ samba-3.6.6/source3/modules/vfs_streams_xattr.c > +@@ -229,7 +229,7 @@ > + return -1; > + } > + > +- sbuf->st_ex_size = get_xattr_size(handle->conn, fsp->base_fsp, > ++ sbuf->st_ex_size = get_xattr_size(handle->conn, fsp, > + io->base, io->xattr_name); > + if (sbuf->st_ex_size == -1) { > + return -1; > +@@ -364,6 +364,7 @@ > + char *xattr_name = NULL; > + int baseflags; > + int hostfd = -1; > ++ int ret; > + > + DEBUG(10, ("streams_xattr_open called for %s\n", > + smb_fname_str_dbg(smb_fname))); > +@@ -375,133 +376,125 @@ > + /* If the default stream is requested, just open the base file. */ > + if (is_ntfs_default_stream_smb_fname(smb_fname)) { > + char *tmp_stream_name; > +- int ret; > + > + tmp_stream_name = smb_fname->stream_name; > + smb_fname->stream_name = NULL; > + > + ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, > mode); > + > +- smb_fname->stream_name = tmp_stream_name; > +- > +- return ret; > +- } > ++ smb_fname->stream_name = tmp_stream_name; > + > +- status = streams_xattr_get_name(talloc_tos(), smb_fname- > >stream_name, > +- &xattr_name); > +- if (!NT_STATUS_IS_OK(status)) { > +- errno = map_errno_from_nt_status(status); > +- goto fail; > +- } > ++ return ret; > ++ } > + > +- /* Create an smb_filename with stream_name == NULL. */ > +- status = create_synthetic_smb_fname(talloc_tos(), > +- smb_fname->base_name, > +- NULL, NULL, > +- &smb_fname_base); > +- if (!NT_STATUS_IS_OK(status)) { > +- errno = map_errno_from_nt_status(status); > +- goto fail; > +- } > ++ status = streams_xattr_get_name(talloc_tos(), smb_fname- > >stream_name, > ++ &xattr_name); > ++ if (!NT_STATUS_IS_OK(status)) { > ++ errno = map_errno_from_nt_status(status); > ++ goto fail; > ++ } > + > +- /* > +- * We use baseflags to turn off nasty side-effects when opening the > +- * underlying file. > +- */ > +- baseflags = flags; > +- baseflags &= ~O_TRUNC; > +- baseflags &= ~O_EXCL; > +- baseflags &= ~O_CREAT; > +- > +- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp, > +- baseflags, mode); > +- > +- TALLOC_FREE(smb_fname_base); > +- > +- /* It is legit to open a stream on a directory, but the base > +- * fd has to be read-only. > +- */ > +- if ((hostfd == -1) && (errno == EISDIR)) { > +- baseflags &= ~O_ACCMODE; > +- baseflags |= O_RDONLY; > +- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, > baseflags, > +- mode); > +- } > ++ /* Create an smb_filename with stream_name == NULL. */ > ++ status = create_synthetic_smb_fname(talloc_tos(), > ++ smb_fname->base_name, > ++ NULL, NULL, > ++ &smb_fname_base); > ++ if (!NT_STATUS_IS_OK(status)) { > ++ errno = map_errno_from_nt_status(status); > ++ goto fail; > ++ } > + > +- if (hostfd == -1) { > +- goto fail; > +- } > ++ /* > ++ * We use baseflags to turn off nasty side-effects when > opening the > ++ * underlying file. > ++ */ > ++ baseflags = flags; > ++ baseflags &= ~O_TRUNC; > ++ baseflags &= ~O_EXCL; > ++ baseflags &= ~O_CREAT; > + > +- status = get_ea_value(talloc_tos(), handle->conn, NULL, > +- smb_fname->base_name, xattr_name, &ea); > ++ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp, > ++ baseflags, mode); > + > +- DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status))); > ++ TALLOC_FREE(smb_fname_base); > + > +- if (!NT_STATUS_IS_OK(status) > +- && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { > +- /* > +- * The base file is not there. This is an error even if we > got > +- * O_CREAT, the higher levels should have created the base > +- * file for us. > ++ /* It is legit to open a stream on a directory, but the base > ++ * fd has to be read-only. > + */ > +- DEBUG(10, ("streams_xattr_open: base file %s not around, " > +- "returning ENOENT\n", smb_fname->base_name)); > +- errno = ENOENT; > +- goto fail; > +- } > ++ if ((hostfd == -1) && (errno == EISDIR)) { > ++ baseflags &= ~O_ACCMODE; > ++ baseflags |= O_RDONLY; > ++ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, > baseflags, > ++ mode); > ++ } > + > +- if (!NT_STATUS_IS_OK(status)) { > +- /* > +- * The attribute does not exist > +- */ > ++ if (hostfd == -1) { > ++ goto fail; > ++ } > ++ > ++ status = get_ea_value(talloc_tos(), handle->conn, NULL, > ++ smb_fname->base_name, xattr_name, > &ea); > + > +- if (flags & O_CREAT) { > ++ DEBUG(10, ("get_ea_value returned %s\n", > nt_errstr(status))); > ++ > ++ if (!NT_STATUS_IS_OK(status) > ++ && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { > + /* > +- * Darn, xattrs need at least 1 byte > ++ * The base file is not there. This is an error even > if we got > ++ * O_CREAT, the higher levels should have created > the base > ++ * file for us. > + */ > +- char null = '\0'; > ++ DEBUG(10, ("streams_xattr_open: base file %s not > around, " > ++ "returning ENOENT\n", smb_fname- > >base_name)); > ++ errno = ENOENT; > ++ goto fail; > ++ } > + > +- DEBUG(10, ("creating attribute %s on file %s\n", > +- xattr_name, smb_fname->base_name)); > ++ if (!NT_STATUS_IS_OK(status)) { > ++ /* > ++ * The attribute does not exist > ++ */ > + > ++ if (flags & O_CREAT) { > ++ /* > ++ * Darn, xattrs need at least 1 byte > ++ */ > ++ char null = '\0'; > ++ > ++ DEBUG(10, ("creating attribute %s on file > %s\n", > ++ xattr_name, smb_fname- > >base_name)); > ++ > ++ fsp->fh->fd = hostfd; > ++ ret = SMB_VFS_FSETXATTR(fsp, xattr_name, > ++ &null, sizeof(null), > ++ flags & O_EXCL ? > XATTR_CREATE : 0); > ++ fsp->fh->fd = -1; > ++ if (ret != 0) { > ++ goto fail; > ++ } > ++ } > ++ } > ++ > ++ if (flags & O_TRUNC) { > ++ char null = '\0'; > + if (fsp->base_fsp->fh->fd != -1) { > +- if (SMB_VFS_FSETXATTR( > +- fsp->base_fsp, xattr_name, > +- &null, sizeof(null), > +- flags & O_EXCL ? XATTR_CREATE : 0) > == -1) { > ++ if (SMB_VFS_FSETXATTR( > ++ fsp->base_fsp, xattr_name, > ++ &null, sizeof(null), > ++ flags & O_EXCL ? > XATTR_CREATE : 0) == -1) { > + goto fail; > + } > + } else { > +- if (SMB_VFS_SETXATTR( > +- handle->conn, smb_fname->base_name, > +- xattr_name, &null, sizeof(null), > +- flags & O_EXCL ? XATTR_CREATE : 0) > == -1) { > ++ if (SMB_VFS_SETXATTR( > ++ handle->conn, smb_fname- > >base_name, > ++ xattr_name, &null, > sizeof(null), > ++ flags & O_EXCL ? > XATTR_CREATE : 0) == -1) { > + goto fail; > + } > + } > + } > +- } > +- > +- if (flags & O_TRUNC) { > +- char null = '\0'; > +- if (fsp->base_fsp->fh->fd != -1) { > +- if (SMB_VFS_FSETXATTR( > +- fsp->base_fsp, xattr_name, > +- &null, sizeof(null), > +- flags & O_EXCL ? XATTR_CREATE : 0) > == -1) { > +- goto fail; > +- } > +- } else { > +- if (SMB_VFS_SETXATTR( > +- handle->conn, smb_fname->base_name, > +- xattr_name, &null, sizeof(null), > +- flags & O_EXCL ? XATTR_CREATE : 0) > == -1) { > +- goto fail; > +- } > +- } > +- } > + > +- sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp, > ++ sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp, > + struct stream_io, > + NULL); > + if (sio == NULL) { > +@@ -511,8 +504,15 @@ > + > + sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, > fsp), > + xattr_name); > ++ /* > ++ * sio->base needs to be a copy of fsp->fsp_name->base_name, > ++ * making it identical to streams_xattr_recheck(). If the > ++ * open is changing directories, fsp->fsp_name->base_name > ++ * will be the full path from the share root, whilst > ++ * smb_fname will be relative to the $cwd. > ++ */ > + sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), > +- smb_fname->base_name); > ++ fsp->fsp_name->base_name); > + sio->fsp_name_ptr = fsp->fsp_name; > + sio->handle = handle; > + sio->fsp = fsp; > +@@ -861,7 +861,7 @@ > + return -1; > + } > + > +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, > ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, > + sio->base, sio->xattr_name, &ea); > + if (!NT_STATUS_IS_OK(status)) { > + return -1; > +@@ -885,13 +885,13 @@ > + > + memcpy(ea.value.data + offset, data, n); > + > +- if (fsp->base_fsp->fh->fd != -1) { > +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, > ++ if (fsp->fh->fd != -1) { > ++ ret = SMB_VFS_FSETXATTR(fsp, > + sio->xattr_name, > + ea.value.data, ea.value.length, 0); > + } else { > + ret = SMB_VFS_SETXATTR(fsp->conn, > +- fsp->base_fsp->fsp_name->base_name, > ++ fsp->fsp_name->base_name, > + sio->xattr_name, > + ea.value.data, ea.value.length, 0); > + } > +@@ -925,7 +925,7 @@ > + return -1; > + } > + > +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, > ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, > + sio->base, sio->xattr_name, &ea); > + if (!NT_STATUS_IS_OK(status)) { > + return -1; > +@@ -970,7 +970,7 @@ > + return -1; > + } > + > +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, > ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, > + sio->base, sio->xattr_name, &ea); > + if (!NT_STATUS_IS_OK(status)) { > + return -1; > +@@ -995,13 +995,13 @@ > + ea.value.length = offset + 1; > + ea.value.data[offset] = 0; > + > +- if (fsp->base_fsp->fh->fd != -1) { > +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, > ++ if (fsp->fh->fd != -1) { > ++ ret = SMB_VFS_FSETXATTR(fsp, > + sio->xattr_name, > + ea.value.data, ea.value.length, 0); > + } else { > + ret = SMB_VFS_SETXATTR(fsp->conn, > +- fsp->base_fsp->fsp_name->base_name, > ++ fsp->fsp_name->base_name, > + sio->xattr_name, > + ea.value.data, ea.value.length, 0); > + } > +--- samba-3.6.6.orig/source3/smbd/dir.c > ++++ samba-3.6.6/source3/smbd/dir.c > +@@ -1358,7 +1358,8 @@ > + Open a directory. > + ********************************************************************/ > + > +-struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, > ++static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, > ++ connection_struct *conn, > + const char *name, > + const char *mask, > + uint32 attr) > +@@ -1370,27 +1371,21 @@ > + return NULL; > + } > + > +- dirp->conn = conn; > +- dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); > +- > +- dirp->dir_path = talloc_strdup(dirp, name); > +- if (!dirp->dir_path) { > +- errno = ENOMEM; > ++ dirp->dir = SMB_VFS_OPENDIR(conn, name, mask, attr); > ++ if (!dirp->dir) { > ++ DEBUG(5,("OpenDir: Can't open %s. %s\n", name, > ++ strerror(errno) )); > + goto fail; > + } > + > ++ dirp->conn = conn; > ++ dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); > ++ > + if (sconn && !sconn->using_smb2) { > + sconn->searches.dirhandles_open++; > + } > + talloc_set_destructor(dirp, smb_Dir_destructor); > + > +- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); > +- if (!dirp->dir) { > +- DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, > +- strerror(errno) )); > +- goto fail; > +- } > +- > + return dirp; > + > + fail: > +@@ -1398,6 +1393,76 @@ > + return NULL; > + } > + > ++/*************************************************************************** > * > ++ Open a directory handle by pathname, ensuring it's under the share path. > ++**************************************************************************** > / > ++ > ++static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx, > ++ connection_struct *conn, > ++ const char *name, > ++ const char *wcard, > ++ uint32_t attr) > ++{ > ++ struct smb_Dir *dir_hnd = NULL; > ++ char *saved_dir = vfs_GetWd(ctx, conn); > ++ NTSTATUS status; > ++ > ++ if (saved_dir == NULL) { > ++ return NULL; > ++ } > ++ > ++ if (vfs_ChDir(conn, name) == -1) { > ++ goto out; > ++ } > ++ > ++ /* > ++ * Now the directory is pinned, use > ++ * REALPATH to ensure we can access it. > ++ */ > ++ status = check_name(conn, "."); > ++ if (!NT_STATUS_IS_OK(status)) { > ++ goto out; > ++ } > ++ > ++ dir_hnd = OpenDir_internal(ctx, > ++ conn, > ++ ".", > ++ wcard, > ++ attr); > ++ > ++ if (dir_hnd == NULL) { > ++ goto out; > ++ } > ++ > ++ /* > ++ * OpenDir_internal only gets "." as the dir name. > ++ * Store the real dir name here. > ++ */ > ++ > ++ dir_hnd->dir_path = talloc_strdup(dir_hnd, name); > ++ if (!dir_hnd->dir_path) { > ++ errno = ENOMEM; > ++ } > ++ > ++ out: > ++ > ++ vfs_ChDir(conn, saved_dir); > ++ TALLOC_FREE(saved_dir); > ++ return dir_hnd; > ++} > ++ > ++struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, > ++ const char *name, > ++ const char *mask, > ++ uint32_t attr) > ++{ > ++ return open_dir_safely(mem_ctx, > ++ conn, > ++ name, > ++ mask, > ++ attr); > ++} > ++ > + /******************************************************************* > + Open a directory from an fsp. > + ********************************************************************/ > +@@ -1411,7 +1476,17 @@ > + struct smbd_server_connection *sconn = conn->sconn; > + > + if (!dirp) { > +- return NULL; > ++ goto fail; > ++ } > ++ > ++ if (!fsp->is_directory) { > ++ errno = EBADF; > ++ goto fail; > ++ } > ++ > ++ if (fsp->fh->fd == -1) { > ++ errno = EBADF; > ++ goto fail; > + } > + > + dirp->conn = conn; > +@@ -1423,36 +1498,33 @@ > + goto fail; > + } > + > +- if (sconn && !sconn->using_smb2) { > +- sconn->searches.dirhandles_open++; > +- } > +- talloc_set_destructor(dirp, smb_Dir_destructor); > +- > +- if (fsp->is_directory && fsp->fh->fd != -1) { > +- dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); > +- if (dirp->dir != NULL) { > +- dirp->fsp = fsp; > +- } else { > +- DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s > returned " > +- "NULL (%s)\n", > +- dirp->dir_path, > +- strerror(errno))); > +- if (errno != ENOSYS) { > +- return NULL; > +- } > ++ dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); > ++ if (dirp->dir != NULL) { > ++ dirp->fsp = fsp; > ++ } else { > ++ DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " > ++ "NULL (%s)\n", > ++ dirp->dir_path, > ++ strerror(errno))); > ++ if (errno != ENOSYS) { > ++ goto fail; > + } > + } > + > + if (dirp->dir == NULL) { > +- /* FDOPENDIR didn't work. Use OPENDIR instead. */ > +- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, > attr); > ++ /* FDOPENDIR is not supported. Use OPENDIR instead. */ > ++ TALLOC_FREE(dirp); > ++ return open_dir_safely(mem_ctx, > ++ conn, > ++ fsp->fsp_name->base_name, > ++ mask, > ++ attr); > + } > + > +- if (!dirp->dir) { > +- DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", dirp->dir_path, > +- strerror(errno) )); > +- goto fail; > ++ if (sconn && !sconn->using_smb2) { > ++ sconn->searches.dirhandles_open++; > + } > ++ talloc_set_destructor(dirp, smb_Dir_destructor); > + > + return dirp; > + > diff --git a/src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch > b/src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch > new file mode 100644 > index 000000000..cefdd86ea > --- /dev/null > +++ b/src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch > @@ -0,0 +1,179 @@ > +bug: https://bugzilla.samba.org/show_bug.cgi?id=12721 > +Description: This patch is a consolidation of several patches described by > the Git commit summaries below > + > +From 5d4ef6ff0970c93fed49e51a01e63cb67d49d087 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 27 Mar 2017 10:46:47 -0700 > +Subject: [PATCH 1/3] s3: smbd: Fix incorrect logic exposed by fix for the > + security bug 12496 (CVE-2017-2619). > + > +In a UNIX filesystem, the names "." and ".." by definition can *never* > +be symlinks - they are already reserved names. > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +Reviewed-by: Uri Simchoni <uri(a)samba.org> > +(cherry picked from commit ae17bebd250bdde5614b2ac17e53512f19fe9b68) > +--- > + source3/smbd/vfs.c | 7 +++++-- > + 1 file changed, 5 insertions(+), 2 deletions(-) > + > +From 71500662d1098d17657b0148a0aa06cd69482c7d Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 27 Mar 2017 17:04:58 -0700 > +Subject: [PATCH 2/3] s3: smbd: Fix "follow symlink = no" regression part 2. > + > +Add an extra paramter to cwd_name to check_reduced_name(). > + > +If cwd_name == NULL then fname is a client given path relative > +to the root path of the share. > + > +If cwd_name != NULL then fname is a client given path relative > +to cwd_name. cwd_name is relative to the root path of the share. > + > +Not yet used, logic added in the next commit. > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +Reviewed-by: Ralph Boehme <slow(a)samba.org> > +(cherry picked from commit 83e30cb48859b412b76572b6a3ba84d8fde167af) > +--- > + source3/smbd/filename.c | 2 +- > + source3/smbd/open.c | 2 +- > + source3/smbd/proto.h | 4 +++- > + source3/smbd/vfs.c | 10 +++++++++- > + 4 files changed, 14 insertions(+), 4 deletions(-) > + > +From e3fd46264b82ffc22424ee7364b3fd2c0fc14a7e Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 27 Mar 2017 17:09:38 -0700 > +Subject: [PATCH 3/3] s3: smbd: Fix "follow symlink = no" regression part 2. > + > +Use the cwd_name parameter to reconstruct the original > +client name for symlink testing. > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +Reviewed-by: Ralph Boehme <slow(a)samba.org> > +(cherry picked from commit e182a4d39e86c9694e255efdf6ee2ea3ccb9af4a) > +--- > + source3/smbd/vfs.c | 23 +++++++++++++++++++++++ > + 1 file changed, 23 insertions(+) > + > +--- samba-3.6.6.orig/source3/smbd/vfs.c > ++++ samba-3.6.6/source3/smbd/vfs.c > +@@ -894,11 +894,20 @@ > + /******************************************************************* > + Reduce a file name, removing .. elements and checking that > + it is below dir in the heirachy. This uses realpath. > ++ > ++ If cwd_name == NULL then fname is a client given path relative > ++ to the root path of the share. > ++ > ++ If cwd_name != NULL then fname is a client given path relative > ++ to cwd_name. cwd_name is relative to the root path of the share. > + ********************************************************************/ > + > +-NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) > ++NTSTATUS check_reduced_name(connection_struct *conn, > ++ const char *cwd_name, > ++ const char *fname) > + { > + char *resolved_name = NULL; > ++ char *new_fname = NULL; > + bool allow_symlinks = true; > + bool allow_widelinks = false; > + > +@@ -1026,8 +1035,11 @@ > + /* fname can't have changed in resolved_path. */ > + const char *p = &resolved_name[rootdir_len]; > + > +- /* *p can be '\0' if fname was "." */ > +- if (*p == '\0' && ISDOT(fname)) { > ++ /* > ++ * UNIX filesystem semantics, names consisting > ++ * only of "." or ".." CANNOT be symlinks. > ++ */ > ++ if (ISDOT(fname) || ISDOTDOT(fname)) { > + goto out; > + } > + > +@@ -1041,11 +1053,32 @@ > + } > + > + p++; > ++ > ++ /* > ++ * If cwd_name is present and not ".", > ++ * then fname is relative to that, not > ++ * the root of the share. Make sure the > ++ * path we check is the one the client > ++ * sent (cwd_name+fname). > ++ */ > ++ if (cwd_name != NULL && !ISDOT(cwd_name)) { > ++ new_fname = talloc_asprintf(talloc_tos(), > ++ "%s/%s", > ++ cwd_name, > ++ fname); > ++ if (new_fname == NULL) { > ++ SAFE_FREE(resolved_name); > ++ return NT_STATUS_NO_MEMORY; > ++ } > ++ fname = new_fname; > ++ } > ++ > + if (strcmp(fname, p)!=0) { > + DEBUG(2, ("check_reduced_name: Bad access " > + "attempt: %s is a symlink\n", > + fname)); > + SAFE_FREE(resolved_name); > ++ TALLOC_FREE(new_fname); > + return NT_STATUS_ACCESS_DENIED; > + } > + } > +@@ -1056,6 +1089,7 @@ > + DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname, > + resolved_name)); > + SAFE_FREE(resolved_name); > ++ TALLOC_FREE(new_fname); > + return NT_STATUS_OK; > + } > + > +--- samba-3.6.6.orig/source3/smbd/filename.c > ++++ samba-3.6.6/source3/smbd/filename.c > +@@ -1009,7 +1009,7 @@ > + } > + > + if (!lp_widelinks(SNUM(conn)) || !lp_symlinks(SNUM(conn))) { > +- status = check_reduced_name(conn,name); > ++ status = check_reduced_name(conn, NULL, name); > + if (!NT_STATUS_IS_OK(status)) { > + DEBUG(5,("check_name: name %s failed with > %s\n",name, > + nt_errstr(status))); > +--- samba-3.6.6.orig/source3/smbd/open.c > ++++ samba-3.6.6/source3/smbd/open.c > +@@ -381,7 +381,7 @@ > + } > + > + /* Ensure the relative path is below the share. */ > +- status = check_reduced_name(conn, final_component); > ++ status = check_reduced_name(conn, parent_dir, final_component); > + if (!NT_STATUS_IS_OK(status)) { > + saved_errno = map_errno_from_nt_status(status); > + goto out; > +--- samba-3.6.6.orig/source3/smbd/proto.h > ++++ samba-3.6.6/source3/smbd/proto.h > +@@ -1179,7 +1179,9 @@ > + SMB_STRUCT_STAT *sbuf, char **talloced); > + int vfs_ChDir(connection_struct *conn, const char *path); > + char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn); > +-NTSTATUS check_reduced_name(connection_struct *conn, const char *fname); > ++NTSTATUS check_reduced_name(connection_struct *conn, > ++ const char *cwd_name, > ++ const char *fname); > + int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, > + SMB_STRUCT_STAT *psbuf); > + int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, > diff --git a/src/patches/samba/CVE-2017-2619-tests.patch > b/src/patches/samba/CVE-2017-2619-tests.patch > new file mode 100644 > index 000000000..41c84610e > --- /dev/null > +++ b/src/patches/samba/CVE-2017-2619-tests.patch > @@ -0,0 +1,296 @@ > +Description: Patches to unit tests associated with CVE-2017-2619 regression > +origin: https://attachments.samba.org/attachment.cgi?id=13130 > + > +From 2c6de8584779e413f1e6ff9c933f9281693bfbc0 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 27 Mar 2017 11:48:25 -0700 > +Subject: [PATCH 2/6] s3: Test for CVE-2017-2619 regression with "follow > + symlinks = no". > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +Reviewed-by: Uri Simchoni <uri(a)samba.org> > + > +Back-ported from commit 782172a9bef0040981d20e49519b13dd744df6a0 > +--- > + selftest/target/Samba3.pm | 7 +++ > + source3/script/tests/test_smbclient_s3.sh | 73 > +++++++++++++++++++++++++++++++ > + 2 files changed, 80 insertions(+) > + > +diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm > +index 01a1c470af0..7765b9efbb2 100644 > +--- a/selftest/target/Samba3.pm > ++++ b/selftest/target/Samba3.pm > +@@ -481,6 +481,9 @@ sub provision($$$$$$) > + my $msdfs_deeppath="$msdfs_shrdir/deeppath"; > + push(@dirs,$msdfs_deeppath); > + > ++ my $nosymlinks_shrdir="$shrdir/nosymlinks"; > ++ push(@dirs,$nosymlinks_shrdir); > ++ > + # this gets autocreated by winbindd > + my $wbsockdir="$prefix_abs/winbindd"; > + my $wbsockprivdir="$lockdir/winbindd_privileged"; > +@@ -695,6 +698,10 @@ sub provision($$$$$$) > + copy = print1 > + [print\$] > + copy = tmp > ++[nosymlinks] > ++ copy = tmp > ++ path = $nosymlinks_shrdir > ++ follow symlinks = no > + "; > + close(CONF); > + > +diff --git a/source3/script/tests/test_smbclient_s3.sh > b/source3/script/tests/test_smbclient_s3.sh > +index 772802f77b1..57ef87e4949 100755 > +--- a/source3/script/tests/test_smbclient_s3.sh > ++++ b/source3/script/tests/test_smbclient_s3.sh > +@@ -401,6 +401,75 @@ done > + > + LOGDIR=$(mktemp -d ${PREFIX}/${LOGDIR_PREFIX}_XXXXXX) > + > ++# Test follow symlinks can't access symlinks > ++test_nosymlinks() > ++{ > ++# Setup test dirs. > ++ slink_name="$LOCAL_PATH/nosymlinks/source" > ++ slink_target="$LOCAL_PATH/nosymlinks/target" > ++ mkdir_target="$LOCAL_PATH/nosymlinks/a" > ++ > ++ rm -f $slink_target > ++ rm -f $slink_name > ++ rm -rf $mkdir_target > ++ > ++ touch $slink_target > ++ ln -s $slink_target $slink_name > ++ > ++# Getting a file through a symlink name should fail. > ++ tmpfile=$PREFIX/smbclient_interactive_prompt_commands > ++ cat > $tmpfile <<EOF > ++get source > ++quit > ++EOF > ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD > //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' > ++ eval echo "$cmd" > ++ out=`eval $cmd` > ++ ret=$? > ++ rm -f $tmpfile > ++ > ++ if [ $ret != 0 ] ; then > ++ echo "$out" > ++ echo "failed accessing nosymlinks with error $ret" > ++ false > ++ return > ++ fi > ++ > ++ echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' > ++ ret=$? > ++ if [ $ret != 0 ] ; then > ++ echo "$out" > ++ echo "failed - should get NT_STATUS_ACCESS_DENIED getting > \\nosymlinks\\source" > ++ false > ++ fi > ++ > ++# But we should be able to create and delete directories. > ++ cat > $tmpfile <<EOF > ++mkdir a > ++mkdir a\\b > ++quit > ++EOF > ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD > //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' > ++ eval echo "$cmd" > ++ out=`eval $cmd` > ++ ret=$? > ++ rm -f $tmpfile > ++ > ++ if [ $ret != 0 ] ; then > ++ echo "$out" > ++ echo "failed accessing nosymlinks with error $ret" > ++ false > ++ return > ++ fi > ++ > ++ echo "$out" | grep 'NT_STATUS' > ++ ret=$? > ++ if [ $ret == 0 ] ; then > ++ echo "$out" > ++ echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b on > \\nosymlinks" > ++ false > ++ fi > ++} > + > + testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p 139 || > failed=`expr $failed + 1` > + testit "smbclient -L $SERVER -I $SERVER_IP" $SMBCLIENT -L $SERVER -I > $SERVER_IP -N -p 139 -c quit || failed=`expr $failed + 1` > +@@ -445,6 +514,10 @@ testit "ccache access works for smbclient" \ > + test_ccache_access || \ > + failed=`expr $failed + 1` > + > ++testit "follow symlinks = no" \ > ++ test_nosymlinks || \ > ++ failed=`expr $failed + 1` > ++ > + testit "rm -rf $LOGDIR" \ > + rm -rf $LOGDIR || \ > + failed=`expr $failed + 1` > +-- > +2.12.0 > + > + > +From 17865cf188f42850f18f46514643a5b3a43e5707 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 27 Mar 2017 22:07:50 -0700 > +Subject: [PATCH 3/6] s3: Fixup test for CVE-2017-2619 regression with "follow > + symlinks = no" > + > +Use correct bash operators (not string operators). > +Add missing "return". > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +Reviewed-by: Ralph Boehme <slow(a)samba.org> > +(cherry picked from commit 037297a1c50e90a0092e3b94f472623f41ccc015) > +--- > + source3/script/tests/test_smbclient_s3.sh | 9 +++++---- > + 1 file changed, 5 insertions(+), 4 deletions(-) > + > +diff --git a/source3/script/tests/test_smbclient_s3.sh > b/source3/script/tests/test_smbclient_s3.sh > +index 57ef87e4949..bd5714fca6e 100755 > +--- a/source3/script/tests/test_smbclient_s3.sh > ++++ b/source3/script/tests/test_smbclient_s3.sh > +@@ -428,7 +428,7 @@ EOF > + ret=$? > + rm -f $tmpfile > + > +- if [ $ret != 0 ] ; then > ++ if [ $ret -ne 0 ] ; then > + echo "$out" > + echo "failed accessing nosymlinks with error $ret" > + false > +@@ -437,10 +437,11 @@ EOF > + > + echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' > + ret=$? > +- if [ $ret != 0 ] ; then > ++ if [ $ret -ne 0 ] ; then > + echo "$out" > + echo "failed - should get NT_STATUS_ACCESS_DENIED getting > \\nosymlinks\\source" > + false > ++ return > + fi > + > + # But we should be able to create and delete directories. > +@@ -455,7 +456,7 @@ EOF > + ret=$? > + rm -f $tmpfile > + > +- if [ $ret != 0 ] ; then > ++ if [ $ret -ne 0 ] ; then > + echo "$out" > + echo "failed accessing nosymlinks with error $ret" > + false > +@@ -464,7 +465,7 @@ EOF > + > + echo "$out" | grep 'NT_STATUS' > + ret=$? > +- if [ $ret == 0 ] ; then > ++ if [ $ret -eq 0 ] ; then > + echo "$out" > + echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b on > \\nosymlinks" > + false > +-- > +2.12.0 > + > + > +From 9b573af39f3d4995464e30771fa06e0709b5e57b Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Mon, 27 Mar 2017 22:10:29 -0700 > +Subject: [PATCH 6/6] s3: Test for CVE-2017-2619 regression with "follow > + symlinks = no" - part 2 > +MIME-Version: 1.0 > +Content-Type: text/plain; charset=UTF-8 > +Content-Transfer-Encoding: 8bit > + > +Add tests for regular access. > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +Reviewed-by: Ralph Boehme <slow(a)samba.org> > + > +Autobuild-User(master): Ralph Böhme <slow(a)samba.org> > +Autobuild-Date(master): Tue Mar 28 17:05:27 CEST 2017 on sn-devel-144 > + > +(cherry picked from commit 4e734fcd1bf82c08aa303ce44e9735acccffcf06) > +--- > + source3/script/tests/test_smbclient_s3.sh | 37 > +++++++++++++++++++++++++++++++ > + 1 file changed, 37 insertions(+) > + > +diff --git a/source3/script/tests/test_smbclient_s3.sh > b/source3/script/tests/test_smbclient_s3.sh > +index bd5714fca6e..885766f6c16 100755 > +--- a/source3/script/tests/test_smbclient_s3.sh > ++++ b/source3/script/tests/test_smbclient_s3.sh > +@@ -408,14 +408,22 @@ test_nosymlinks() > + slink_name="$LOCAL_PATH/nosymlinks/source" > + slink_target="$LOCAL_PATH/nosymlinks/target" > + mkdir_target="$LOCAL_PATH/nosymlinks/a" > ++ dir1="$LOCAL_PATH/nosymlinks/foo" > ++ dir2="$LOCAL_PATH/nosymlinks/foo/bar" > ++ get_target="$LOCAL_PATH/nosymlinks/foo/bar/testfile" > + > + rm -f $slink_target > + rm -f $slink_name > + rm -rf $mkdir_target > ++ rm -rf $dir1 > + > + touch $slink_target > + ln -s $slink_target $slink_name > + > ++ mkdir $dir1 > ++ mkdir $dir2 > ++ touch $get_target > ++ > + # Getting a file through a symlink name should fail. > + tmpfile=$PREFIX/smbclient_interactive_prompt_commands > + cat > $tmpfile <<EOF > +@@ -470,6 +478,35 @@ EOF > + echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b on > \\nosymlinks" > + false > + fi > ++ > ++# Ensure regular file/directory access also works. > ++ cat > $tmpfile <<EOF > ++cd foo\\bar > ++ls > ++get testfile - > ++quit > ++EOF > ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD > //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' > ++ eval echo "$cmd" > ++ out=`eval $cmd` > ++ ret=$? > ++ rm -f $tmpfile > ++ > ++ if [ $ret -ne 0 ] ; then > ++ echo "$out" > ++ echo "failed accessing nosymlinks with error $ret" > ++ false > ++ return > ++ fi > ++ > ++ echo "$out" | grep 'NT_STATUS' > ++ ret=$? > ++ if [ $ret -eq 0 ] ; then > ++ echo "$out" > ++ echo "failed - NT_STATUS_XXXX doing cd foo\\bar; get testfile on > \\nosymlinks" > ++ false > ++ return > ++ fi > + } > + > + testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p 139 || > failed=`expr $failed + 1` > +-- > +2.12.0 > + > diff --git a/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch > b/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch > new file mode 100644 > index 000000000..54bb1841b > --- /dev/null > +++ b/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch > @@ -0,0 +1,14 @@ > +--- source3/rpc_server/srv_pipe.c Sun Feb 22 16:11:32 2015 > ++++ source3/rpc_server/srv_pipe.c Fri May 26 17:28:40 2017 > +@@ -465,6 +465,11 @@ > + const char *pipename = cli_filename; > + NTSTATUS status; > + > ++ if (strchr(pipename, '/')) { > ++ DEBUG(1, ("Refusing open on pipe %s\n", pipename)); > ++ return false; > ++ } > ++ > + if (strnequal(pipename, "\\PIPE\\", 6)) { > + pipename += 5; > + } > diff --git a/src/patches/samba/samba-3.6.25-security-2015-12-16.patch > b/src/patches/samba/samba-3.6.25-security-2015-12-16.patch > new file mode 100644 > index 000000000..df1057fea > --- /dev/null > +++ b/src/patches/samba/samba-3.6.25-security-2015-12-16.patch > @@ -0,0 +1,255 @@ > +From 2e94b6ec10f1d15e24867bab3063bb85f173406a Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Thu, 9 Jul 2015 10:58:11 -0700 > +Subject: [PATCH] CVE-2015-5252: s3: smbd: Fix symlink verification (file > + access outside the share). > + > +Ensure matching component ends in '/' or '\0'. > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11395 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +Reviewed-by: Volker Lendecke <vl(a)samba.org> > +--- > + source3/smbd/vfs.c | 7 +++++-- > + 1 file changed, 5 insertions(+), 2 deletions(-) > + > +diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c > +index 6c56964..bd93b7f 100644 > +--- a/source3/smbd/vfs.c > ++++ b/source3/smbd/vfs.c > +@@ -982,6 +982,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, > const char *fname) > + if (!allow_widelinks || !allow_symlinks) { > + const char *conn_rootdir; > + size_t rootdir_len; > ++ bool matched; > + > + conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname); > + if (conn_rootdir == NULL) { > +@@ -992,8 +993,10 @@ NTSTATUS check_reduced_name(connection_struct *conn, > const char *fname) > + } > + > + rootdir_len = strlen(conn_rootdir); > +- if (strncmp(conn_rootdir, resolved_name, > +- rootdir_len) != 0) { > ++ matched = (strncmp(conn_rootdir, resolved_name, > ++ rootdir_len) == 0); > ++ if (!matched || (resolved_name[rootdir_len] != '/' && > ++ resolved_name[rootdir_len] != '\0')) { > + DEBUG(2, ("check_reduced_name: Bad access " > + "attempt: %s is a symlink outside the " > + "share path\n", fname)); > +-- > +2.5.0 > + > +From 25139116756cc285a3a5534834cc276ef1b7baaa Mon Sep 17 00:00:00 2001 > +From: Stefan Metzmacher <metze(a)samba.org> > +Date: Wed, 30 Sep 2015 21:17:02 +0200 > +Subject: [PATCH 1/2] CVE-2015-5296: s3:libsmb: force signing when requiring > + encryption in do_connect() > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536 > + > +Signed-off-by: Stefan Metzmacher <metze(a)samba.org> > +Reviewed-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/libsmb/clidfs.c | 7 ++++++- > + 1 file changed, 6 insertions(+), 1 deletion(-) > + > +diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c > +index 23e1471..f153b6b 100644 > +--- a/source3/libsmb/clidfs.c > ++++ b/source3/libsmb/clidfs.c > +@@ -98,6 +98,11 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, > + const char *username; > + const char *password; > + NTSTATUS status; > ++ int signing_state = get_cmdline_auth_info_signing_state(auth_info); > ++ > ++ if (force_encrypt) { > ++ signing_state = Required; > ++ } > + > + /* make a copy so we don't modify the global string 'service' */ > + servicename = talloc_strdup(ctx,share); > +@@ -132,7 +137,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, > + zero_sockaddr(&ss); > + > + /* have to open a new connection */ > +- c = > cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)); > ++ c = cli_initialise_ex(signing_state); > + if (c == NULL) { > + d_printf("Connection to %s failed\n", server_n); > + return NULL; > +-- > +2.5.0 > + > + > +From 060adb0abdeda51b8b622c6020b5dea0c8dde1cf Mon Sep 17 00:00:00 2001 > +From: Stefan Metzmacher <metze(a)samba.org> > +Date: Wed, 30 Sep 2015 21:17:02 +0200 > +Subject: [PATCH 2/2] CVE-2015-5296: s3:libsmb: force signing when requiring > + encryption in SMBC_server_internal() > + > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536 > + > +Signed-off-by: Stefan Metzmacher <metze(a)samba.org> > +Reviewed-by: Jeremy Allison <jra(a)samba.org> > +--- > + source3/libsmb/libsmb_server.c | 13 +++++++++++-- > + 1 file changed, 11 insertions(+), 2 deletions(-) > + > +diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c > +index 45be660..167f2c9 100644 > +--- a/source3/libsmb/libsmb_server.c > ++++ b/source3/libsmb/libsmb_server.c > +@@ -258,6 +258,7 @@ SMBC_server_internal(TALLOC_CTX *ctx, > + const char *username_used; > + NTSTATUS status; > + char *newserver, *newshare; > ++ int signing_state = Undefined; > + > + zero_sockaddr(&ss); > + ZERO_STRUCT(c); > +@@ -404,8 +405,12 @@ again: > + > + zero_sockaddr(&ss); > + > ++ if (context->internal->smb_encryption_level != > SMBC_ENCRYPTLEVEL_NONE) { > ++ signing_state = Required; > ++ } > ++ > + /* have to open a new connection */ > +- if ((c = cli_initialise()) == NULL) { > ++ if ((c = cli_initialise_ex(signing_state)) == NULL) { > + errno = ENOMEM; > + return NULL; > + } > +@@ -750,6 +755,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, > + ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$", > + pp_workgroup, pp_username, pp_password); > + if (!ipc_srv) { > ++ int signing_state = Undefined; > + > + /* We didn't find a cached connection. Get the password */ > + if (!*pp_password || (*pp_password)[0] == '\0') { > +@@ -771,6 +777,9 @@ SMBC_attr_server(TALLOC_CTX *ctx, > + if (smbc_getOptionUseCCache(context)) { > + flags |= CLI_FULL_CONNECTION_USE_CCACHE; > + } > ++ if (context->internal->smb_encryption_level != > SMBC_ENCRYPTLEVEL_NONE) { > ++ signing_state = Required; > ++ } > + > + zero_sockaddr(&ss); > + nt_status = cli_full_connection(&ipc_cli, > +@@ -780,7 +789,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, > + *pp_workgroup, > + *pp_password, > + flags, > +- Undefined); > ++ signing_state); > + if (! NT_STATUS_IS_OK(nt_status)) { > + DEBUG(1,("cli_full_connection failed! (%s)\n", > + nt_errstr(nt_status))); > +-- > +2.5.0 > + > +From 8e49de7754f7171a58a1f94dee0f1138dbee3c60 Mon Sep 17 00:00:00 2001 > +From: Jeremy Allison <jra(a)samba.org> > +Date: Fri, 23 Oct 2015 14:54:31 -0700 > +Subject: [PATCH] CVE-2015-5299: s3-shadow-copy2: fix missing access check on > + snapdir > + > +Fix originally from <partha(a)exablox.com> > + > +https://bugzilla.samba.org/show_bug.cgi?id=11529 > + > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > +Reviewed-by: David Disseldorp <ddiss(a)samba.org> > +--- > + source3/modules/vfs_shadow_copy2.c | 47 > ++++++++++++++++++++++++++++++++++++++ > + 1 file changed, 47 insertions(+) > + > +diff --git a/source3/modules/vfs_shadow_copy2.c > b/source3/modules/vfs_shadow_copy2.c > +index fedfb53..16c1ed7 100644 > +--- a/source3/modules/vfs_shadow_copy2.c > ++++ b/source3/modules/vfs_shadow_copy2.c > +@@ -21,6 +21,8 @@ > + > + #include "includes.h" > + #include "smbd/smbd.h" > ++#include "smbd/globals.h" > ++#include "../libcli/security/security.h" > + #include "system/filesys.h" > + #include "ntioctl.h" > + > +@@ -764,6 +766,43 @@ static int shadow_copy2_mkdir(vfs_handle_struct > *handle, const char *fname, mod > + SHADOW2_NEXT(MKDIR, (handle, name, mode), int, -1); > + } > + > ++static bool check_access_snapdir(struct vfs_handle_struct *handle, > ++ const char *path) > ++{ > ++ struct smb_filename smb_fname; > ++ int ret; > ++ NTSTATUS status; > ++ uint32_t access_granted = 0; > ++ > ++ ZERO_STRUCT(smb_fname); > ++ smb_fname.base_name = talloc_asprintf(talloc_tos(), > ++ "%s", > ++ path); > ++ if (smb_fname.base_name == NULL) { > ++ return false; > ++ } > ++ > ++ ret = SMB_VFS_NEXT_STAT(handle, &smb_fname); > ++ if (ret != 0 || !S_ISDIR(smb_fname.st.st_ex_mode)) { > ++ TALLOC_FREE(smb_fname.base_name); > ++ return false; > ++ } > ++ > ++ status = smbd_check_open_rights(handle->conn, > ++ &smb_fname, > ++ SEC_DIR_LIST, > ++ &access_granted); > ++ if (!NT_STATUS_IS_OK(status)) { > ++ DEBUG(0,("user does not have list permission " > ++ "on snapdir %s\n", > ++ smb_fname.base_name)); > ++ TALLOC_FREE(smb_fname.base_name); > ++ return false; > ++ } > ++ TALLOC_FREE(smb_fname.base_name); > ++ return true; > ++} > ++ > + static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname) > + { > + SHADOW2_NEXT(RMDIR, (handle, name), int, -1); > +@@ -877,6 +916,7 @@ static int > shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, > + SMB_STRUCT_DIRENT *d; > + TALLOC_CTX *tmp_ctx = talloc_new(handle->data); > + char *snapshot; > ++ bool ret; > + > + snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle); > + if (snapdir == NULL) { > +@@ -886,6 +926,13 @@ static int > shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, > + talloc_free(tmp_ctx); > + return -1; > + } > ++ ret = check_access_snapdir(handle, snapdir); > ++ if (!ret) { > ++ DEBUG(0,("access denied on listing snapdir %s\n", snapdir)); > ++ errno = EACCES; > ++ talloc_free(tmp_ctx); > ++ return -1; > ++ } > + > + p = SMB_VFS_NEXT_OPENDIR(handle, snapdir, NULL, 0); > + > +-- > +2.5.0 > + [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Security updates for samba 3.6.25 2017-05-29 16:57 ` Michael Tremer @ 2017-05-29 18:30 ` Matthias Fischer 2017-05-29 21:07 ` Michael Tremer 0 siblings, 1 reply; 4+ messages in thread From: Matthias Fischer @ 2017-05-29 18:30 UTC (permalink / raw) To: development [-- Attachment #1: Type: text/plain, Size: 70917 bytes --] On 29.05.2017 18:57, Michael Tremer wrote: > Hi, Hi, > thank you for working on this. No problem - had fun... ;-) > Yes, Arne submitted a patch that at least fixes the security vulnerability. > > However, could you split this patch into two with the two remaining changes so > that we can merge those? Done. I pushed the - hopefully last - remaining patches. Best, Matthias > Best, > -Michael > > On Sun, 2017-05-28 at 11:22 +0200, Matthias Fischer wrote: >> Based on: >> >> https://anonscm.debian.org/cgit/pkg-samba/samba.git/commit/?h=wheezy&id=762a3a >> fd8eb45526e44cd0b2ae8a5b1a058ec647 >> >> https://www.samba.org/samba/history/security.html >> >> https://www.samba.org/samba/samba/ftp/patches/security/ >> >> Fixes current CVE-2017-7494 and some more... >> >> Removed three 'unrecognized' configure-options. >> >> Some 'lfs'-tuning was made, too. >> >> I altered 'PAK_VER' from "64" to "65" - if not necessary, please change back. >> >> Best, >> Matthias >> >> Signed-off-by: Matthias Fischer <matthias.fischer(a)ipfire.org> >> --- >> lfs/samba | 22 +- >> .../samba/CVE-2017-2619-race-condition-fix.patch | 1150 >> ++++++++++++++++++++ >> .../CVE-2017-2619-regression-bug-12721-fix.patch | 179 +++ >> src/patches/samba/CVE-2017-2619-tests.patch | 296 +++++ >> src/patches/samba/samba-3.6.25-CVE-2017-7494.patch | 14 + >> .../samba/samba-3.6.25-security-2015-12-16.patch | 255 +++++ >> 6 files changed, 1909 insertions(+), 7 deletions(-) >> create mode 100644 src/patches/samba/CVE-2017-2619-race-condition-fix.patch >> create mode 100644 src/patches/samba/CVE-2017-2619-regression-bug-12721- >> fix.patch >> create mode 100644 src/patches/samba/CVE-2017-2619-tests.patch >> create mode 100644 src/patches/samba/samba-3.6.25-CVE-2017-7494.patch >> create mode 100644 src/patches/samba/samba-3.6.25-security-2015-12-16.patch >> >> diff --git a/lfs/samba b/lfs/samba >> index 076152f48..445646464 100644 >> --- a/lfs/samba >> +++ b/lfs/samba >> @@ -1,7 +1,7 @@ >> ############################################################################# >> ## >> # >> # >> # IPFire.org - A linux based >> firewall # >> -# Copyright (C) 2007-2016 IPFire Team <info(a)ipfire.org> >> # >> +# Copyright (C) 2007-2017 IPFire Team <info(a)ipfire.org> >> # >> # >> # >> # 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 # >> @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) >> DIR_APP = $(DIR_SRC)/$(THISAPP) >> TARGET = $(DIR_INFO)/$(THISAPP) >> PROG = samba >> -PAK_VER = 64 >> +PAK_VER = 65 >> >> DEPS = "cups krb5" >> >> @@ -54,7 +54,7 @@ download :$(patsubst %,$(DIR_DL)/%,$(objects)) >> >> md5 : $(subst %,%_MD5,$(objects)) >> >> -dist: >> +dist: >> @$(PAK) >> >> ############################################################################# >> ## >> @@ -88,6 +88,17 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) >> cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2016- >> 2118-v3-6.patch >> cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2015- >> 5370-v3-6.patch >> >> + # Apply Debian CVE patches >> + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017- >> 2619-race-condition-fix.patch >> + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017- >> 2619-regression-bug-12721-fix.patch >> + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017- >> 2619-tests.patch >> + >> + # Fixes CVE-2015-5252 - Samba >> + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/samba- >> 3.6.25-security-2015-12-16.patch >> + >> + # Fixes CVE-2017-7494 - Samba >> + cd $(DIR_APP) && patch -Np0 < $(DIR_SRC)/src/patches/samba/samba- >> 3.6.25-CVE-2017-7494.patch >> + >> cd $(DIR_APP)/source3 && ./autogen.sh >> cd $(DIR_APP)/source3 && ./configure \ >> --prefix=/usr \ >> @@ -102,10 +113,7 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) >> --with-libsmbclient \ >> --with-libsmbsharemodes \ >> --with-sendfile-support \ >> - --without-smbwrapper \ >> - --with-mmap \ >> --with-fhs \ >> - --with-vfs \ >> --with-winbind \ >> --disable-swat \ >> --enable-cups \ >> @@ -119,8 +127,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) >> #cd $(DIR_APP)/source3 && install -v -m755 nsswitch/libnss_winbind.so >> /lib >> #cd $(DIR_APP)/source3 && ln -v -sf libnss_winbind.so >> /lib/libnss_winbind.so.2 >> #cd $(DIR_APP)/source3 && ln -v -sf libnss_wins.so >> /lib/libnss_wins.so.2 >> + -mkdir -p /var/ipfire/samba >> cd $(DIR_APP)/source3 && install -v -m644 >> ../examples/smb.conf.default /var/ipfire/samba >> - -mkdir -p /var/ipfire/samba >> cp -vrf $(DIR_SRC)/config/samba/* /var/ipfire/samba/ >> chown nobody:nobody -R /var/ipfire/samba/ >> cp -vfp /var/ipfire/samba/default.global /var/ipfire/samba/global >> diff --git a/src/patches/samba/CVE-2017-2619-race-condition-fix.patch >> b/src/patches/samba/CVE-2017-2619-race-condition-fix.patch >> new file mode 100644 >> index 000000000..a96d6be3b >> --- /dev/null >> +++ b/src/patches/samba/CVE-2017-2619-race-condition-fix.patch >> @@ -0,0 +1,1150 @@ >> +Description: This patch is a consolidation of several patches described by >> the Git commit summaries below >> +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-261 >> 9 >> +bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +From ec1bca1d5315549e945c93cbf5e3abdb695de782 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 20 Mar 2017 11:32:19 -0700 >> +Subject: [PATCH 01/15] CVE-2017-2619: s3/smbd: re-open directory after >> + dptr_CloseDir() >> + >> +dptr_CloseDir() will close and invalidate the fsp's file descriptor, we >> +have to reopen it. >> + >> +Bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Ralph Bohme <slow(a)samba.org> >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/open.c | 2 +- >> + source3/smbd/proto.h | 2 ++ >> + source3/smbd/smb2_find.c | 17 +++++++++++++++++ >> + 3 files changed, 20 insertions(+), 1 deletion(-) >> + >> +From 2bb9a3d35f6a0cc43a30638594969c4860ffd5a5 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Tue, 28 Feb 2017 09:24:07 -0800 >> +Subject: [PATCH 02/15] s3: vfs: dirsort doesn't handle opendir of "." >> + correctly. >> + >> +Needs to store $cwd path for correct sorting. >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12499 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/modules/vfs_dirsort.c | 4 ++++ >> + 1 file changed, 4 insertions(+) >> + >> +From 327d09ba641046f68daa5b2bb98f09530294cb0d Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 13 Mar 2017 13:44:42 -0700 >> +Subject: [PATCH 03/15] s3: VFS: vfs_streams_xattr.c: Make >> streams_xattr_open() >> + store the same path as streams_xattr_recheck(). >> + >> +If the open is changing directories, fsp->fsp_name->base_name >> +will be the full path from the share root, whilst >> +smb_fname will be relative to the $cwd. >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12546 >> + >> +Back-ported from a24ba3e4083200ec9885363efc5769f43183fb6b >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/modules/vfs_streams_xattr.c | 9 ++++++++- >> + 1 file changed, 8 insertions(+), 1 deletion(-) >> + >> +From 27871d3bfb0857ad3306aabdce6f9b55e32fff3d Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 13 Mar 2017 13:54:04 -0700 >> +Subject: [PATCH 04/15] vfs_streams_xattr: use fsp, not base_fsp >> + >> +The base_fsp's fd is always -1 as it's closed after being openend in >> +create_file_unixpath(). >> + >> +Additionally in streams_xattr_open force using of SMB_VFS_FSETXATTR() by >> +sticking the just created fd into the fsp (and removing it afterwards). >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12591 >> + >> +Back-ported from 021189e32ba507832b5e821e5cda8a2889225955. >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/modules/vfs_streams_xattr.c | 205 +++++++++++++++++----------------- >> -- >> + 1 file changed, 99 insertions(+), 106 deletions(-) >> + >> +From a419b277c5994459c956ebdd324679e728ebae10 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 19 Dec 2016 11:55:56 -0800 >> +Subject: [PATCH 05/15] s3: smbd: Create wrapper function for OpenDir in >> + preparation for making robust. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/dir.c | 15 ++++++++++++++- >> + 1 file changed, 14 insertions(+), 1 deletion(-) >> + >> +From e47e3c40b5fc8f52fe70c3e1edf5489ac8b4badf Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 19 Dec 2016 16:25:26 -0800 >> +Subject: [PATCH 06/15] s3: smbd: Opendir_internal() early return if >> + SMB_VFS_OPENDIR failed. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/dir.c | 14 +++++++------- >> + 1 file changed, 7 insertions(+), 7 deletions(-) >> + >> +From 45e41b709b6c2e67acb99f29aa05b61b53091e57 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 19 Dec 2016 16:35:00 -0800 >> +Subject: [PATCH 07/15] s3: smbd: Create and use open_dir_safely(). Use from >> + OpenDir(). >> + >> +Hardens OpenDir against TOC/TOU races. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/dir.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++-- >> ---- >> + 1 file changed, 59 insertions(+), 7 deletions(-) >> + >> +From 720abcec65b04fdac1052a14898180c8cc816464 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 19 Dec 2016 12:13:20 -0800 >> +Subject: [PATCH 08/15] s3: smbd: OpenDir_fsp() use early returns. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/dir.c | 34 +++++++++++++++++++++------------- >> + 1 file changed, 21 insertions(+), 13 deletions(-) >> + >> +From 5070f319bbb7dda87766621a83691910414d06a1 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 19 Dec 2016 12:15:59 -0800 >> +Subject: [PATCH 09/15] s3: smbd: OpenDir_fsp() - Fix memory leak on error. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/dir.c | 2 +- >> + 1 file changed, 1 insertion(+), 1 deletion(-) >> + >> +From 65d37759f8b4979bc0c0833e0a5eecd277dfa604 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 19 Dec 2016 12:32:07 -0800 >> +Subject: [PATCH 10/15] s3: smbd: Move the reference counting and destructor >> + setup to just before retuning success. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/dir.c | 10 +++++----- >> + 1 file changed, 5 insertions(+), 5 deletions(-) >> + >> +From 5a821d791aba90643ddf7a3c29dad4f6621ef185 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 19 Dec 2016 12:35:32 -0800 >> +Subject: [PATCH 11/15] s3: smbd: Correctly fallback to open_dir_safely if >> + FDOPENDIR not supported on system. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/dir.c | 15 +++++++-------- >> + 1 file changed, 7 insertions(+), 8 deletions(-) >> + >> +From 597aa3b99a2790133a4839260607b0a8df41c8e3 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Thu, 15 Dec 2016 12:52:13 -0800 >> +Subject: [PATCH 12/15] s3: smbd: Remove O_NOFOLLOW guards. We insist on >> + O_NOFOLLOW existing. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/open.c | 4 +--- >> + 1 file changed, 1 insertion(+), 3 deletions(-) >> + >> +From 563af2ffec05a2c0b54897e2d28ac7e1adb66e0f Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Thu, 15 Dec 2016 12:56:08 -0800 >> +Subject: [PATCH 13/15] s3: smbd: Move special handling of symlink errno's >> into >> + a utility function. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/open.c | 30 ++++++++++++++++++++++++++++-- >> + 1 file changed, 28 insertions(+), 2 deletions(-) >> + >> +From b34a67cd3a996804ba7bf90e86cf9e22edf60eb3 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Thu, 15 Dec 2016 13:04:46 -0800 >> +Subject: [PATCH 14/15] s3: smbd: Add the core functions to prevent symlink >> + open races. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/open.c | 242 >> ++++++++++++++++++++++++++++++++++++++++++++++++++++ >> + 1 file changed, 242 insertions(+) >> + >> +From 5920309d2f62dd24fc50530c92dd68077f96a6d2 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Thu, 15 Dec 2016 13:06:31 -0800 >> +Subject: [PATCH 15/15] s3: smbd: Use the new non_widelink_open() function. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/smbd/open.c | 23 ++++++++++++++++++++++- >> + 1 file changed, 22 insertions(+), 1 deletion(-) >> + >> + >> +--- samba-3.6.6.orig/source3/smbd/open.c >> ++++ samba-3.6.6/source3/smbd/open.c >> +@@ -187,10 +187,277 @@ >> + } >> + >> + >> /**************************************************************************** >> ++ Handle differing symlink errno's >> ++**************************************************************************** >> / >> ++ >> ++static int link_errno_convert(int err) >> ++{ >> ++#if defined(ENOTSUP) && defined(OSF1) >> ++ /* handle special Tru64 errno */ >> ++ if (err == ENOTSUP) { >> ++ err = ELOOP; >> ++ } >> ++#endif /* ENOTSUP */ >> ++#ifdef EFTYPE >> ++ /* fix broken NetBSD errno */ >> ++ if (err == EFTYPE) { >> ++ err = ELOOP; >> ++ } >> ++#endif /* EFTYPE */ >> ++ /* fix broken FreeBSD errno */ >> ++ if (err == EMLINK) { >> ++ err = ELOOP; >> ++ } >> ++ return err; >> ++} >> ++ >> ++static int non_widelink_open(struct connection_struct *conn, >> ++ const char *conn_rootdir, >> ++ files_struct *fsp, >> ++ struct smb_filename *smb_fname, >> ++ int flags, >> ++ mode_t mode, >> ++ unsigned int link_depth); >> ++ >> ++/*************************************************************************** >> * >> ++ Follow a symlink in userspace. >> ++**************************************************************************** >> / >> ++ >> ++static int process_symlink_open(struct connection_struct *conn, >> ++ const char *conn_rootdir, >> ++ files_struct *fsp, >> ++ struct smb_filename *smb_fname, >> ++ int flags, >> ++ mode_t mode, >> ++ unsigned int link_depth) >> ++{ >> ++ int fd = -1; >> ++ char *link_target = NULL; >> ++ int link_len = -1; >> ++ char *oldwd = NULL; >> ++ size_t rootdir_len = 0; >> ++ char *resolved_name = NULL; >> ++ bool matched = false; >> ++ int saved_errno = 0; >> ++ >> ++ /* >> ++ * Ensure we don't get stuck in a symlink loop. >> ++ */ >> ++ link_depth++; >> ++ if (link_depth >= 20) { >> ++ errno = ELOOP; >> ++ goto out; >> ++ } >> ++ >> ++ /* Allocate space for the link target. */ >> ++ link_target = talloc_array(talloc_tos(), char, PATH_MAX); >> ++ if (link_target == NULL) { >> ++ errno = ENOMEM; >> ++ goto out; >> ++ } >> ++ >> ++ /* Read the link target. */ >> ++ link_len = SMB_VFS_READLINK(conn, >> ++ smb_fname->base_name, >> ++ link_target, >> ++ PATH_MAX - 1); >> ++ if (link_len == -1) { >> ++ goto out; >> ++ } >> ++ >> ++ /* Ensure it's at least null terminated. */ >> ++ link_target[link_len] = '\0'; >> ++ >> ++ /* Convert to an absolute path. */ >> ++ resolved_name = SMB_VFS_REALPATH(conn, link_target); >> ++ if (resolved_name == NULL) { >> ++ goto out; >> ++ } >> ++ >> ++ /* >> ++ * We know conn_rootdir starts with '/' and >> ++ * does not end in '/'. FIXME ! Should we >> ++ * smb_assert this ? >> ++ */ >> ++ rootdir_len = strlen(conn_rootdir); >> ++ >> ++ matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0); >> ++ if (!matched) { >> ++ errno = EACCES; >> ++ goto out; >> ++ } >> ++ >> ++ /* >> ++ * Turn into a path relative to the share root. >> ++ */ >> ++ if (resolved_name[rootdir_len] == '\0') { >> ++ /* Link to the root of the share. */ >> ++ smb_fname->base_name = talloc_strdup(talloc_tos(), "."); >> ++ if (smb_fname->base_name == NULL) { >> ++ errno = ENOMEM; >> ++ goto out; >> ++ } >> ++ } else if (resolved_name[rootdir_len] == '/') { >> ++ smb_fname->base_name = &resolved_name[rootdir_len+1]; >> ++ } else { >> ++ errno = EACCES; >> ++ goto out; >> ++ } >> ++ >> ++ oldwd = vfs_GetWd(talloc_tos(), conn); >> ++ if (oldwd == NULL) { >> ++ goto out; >> ++ } >> ++ >> ++ /* Ensure we operate from the root of the share. */ >> ++ if (vfs_ChDir(conn, conn_rootdir) == -1) { >> ++ goto out; >> ++ } >> ++ >> ++ /* And do it all again.. */ >> ++ fd = non_widelink_open(conn, >> ++ conn_rootdir, >> ++ fsp, >> ++ smb_fname, >> ++ flags, >> ++ mode, >> ++ link_depth); >> ++ if (fd == -1) { >> ++ saved_errno = errno; >> ++ } >> ++ >> ++ out: >> ++ >> ++ SAFE_FREE(resolved_name); >> ++ TALLOC_FREE(link_target); >> ++ if (oldwd != NULL) { >> ++ int ret = vfs_ChDir(conn, oldwd); >> ++ if (ret == -1) { >> ++ smb_panic("unable to get back to old directory\n"); >> ++ } >> ++ TALLOC_FREE(oldwd); >> ++ } >> ++ if (saved_errno != 0) { >> ++ errno = saved_errno; >> ++ } >> ++ return fd; >> ++} >> ++ >> ++/*************************************************************************** >> * >> ++ Non-widelink open. >> ++**************************************************************************** >> / >> ++ >> ++static int non_widelink_open(struct connection_struct *conn, >> ++ const char *conn_rootdir, >> ++ files_struct *fsp, >> ++ struct smb_filename *smb_fname, >> ++ int flags, >> ++ mode_t mode, >> ++ unsigned int link_depth) >> ++{ >> ++ NTSTATUS status; >> ++ int fd = -1; >> ++ struct smb_filename *smb_fname_rel = NULL; >> ++ int saved_errno = 0; >> ++ char *oldwd = NULL; >> ++ char *parent_dir = NULL; >> ++ const char *final_component = NULL; >> ++ >> ++ if (!parent_dirname(talloc_tos(), >> ++ smb_fname->base_name, >> ++ &parent_dir, >> ++ &final_component)) { >> ++ goto out; >> ++ } >> ++ >> ++ oldwd = vfs_GetWd(talloc_tos(), conn); >> ++ if (oldwd == NULL) { >> ++ goto out; >> ++ } >> ++ >> ++ /* Pin parent directory in place. */ >> ++ if (vfs_ChDir(conn, parent_dir) == -1) { >> ++ goto out; >> ++ } >> ++ >> ++ /* Ensure the relative path is below the share. */ >> ++ status = check_reduced_name(conn, final_component); >> ++ if (!NT_STATUS_IS_OK(status)) { >> ++ saved_errno = map_errno_from_nt_status(status); >> ++ goto out; >> ++ } >> ++ >> ++ status = create_synthetic_smb_fname(talloc_tos(), >> ++ final_component, >> ++ smb_fname->stream_name, >> ++ &smb_fname->st, >> ++ &smb_fname_rel); >> ++ if (!NT_STATUS_IS_OK(status)) { >> ++ saved_errno = map_errno_from_nt_status(status); >> ++ goto out; >> ++ } >> ++ >> ++ flags |= O_NOFOLLOW; >> ++ >> ++ { >> ++ struct smb_filename *tmp_name = fsp->fsp_name; >> ++ fsp->fsp_name = smb_fname_rel; >> ++ fd = SMB_VFS_OPEN(conn, smb_fname_rel, fsp, flags, mode); >> ++ fsp->fsp_name = tmp_name; >> ++ } >> ++ >> ++ if (fd == -1) { >> ++ saved_errno = link_errno_convert(errno); >> ++ if (saved_errno == ELOOP) { >> ++ if (fsp->posix_open) { >> ++ /* Never follow symlinks on posix open. */ >> ++ goto out; >> ++ } >> ++ if (!lp_symlinks(SNUM(conn))) { >> ++ /* Explicitly no symlinks. */ >> ++ goto out; >> ++ } >> ++ /* >> ++ * We have a symlink. Follow in userspace >> ++ * to ensure it's under the share definition. >> ++ */ >> ++ fd = process_symlink_open(conn, >> ++ conn_rootdir, >> ++ fsp, >> ++ smb_fname_rel, >> ++ flags, >> ++ mode, >> ++ link_depth); >> ++ if (fd == -1) { >> ++ saved_errno = >> ++ link_errno_convert(errno); >> ++ } >> ++ } >> ++ } >> ++ >> ++ out: >> ++ >> ++ TALLOC_FREE(parent_dir); >> ++ TALLOC_FREE(smb_fname_rel); >> ++ >> ++ if (oldwd != NULL) { >> ++ int ret = vfs_ChDir(conn, oldwd); >> ++ if (ret == -1) { >> ++ smb_panic("unable to get back to old directory\n"); >> ++ } >> ++ TALLOC_FREE(oldwd); >> ++ } >> ++ if (saved_errno != 0) { >> ++ errno = saved_errno; >> ++ } >> ++ return fd; >> ++} >> ++ >> ++/*************************************************************************** >> * >> + fd support routines - attempt to do a dos_open. >> + >> ****************************************************************************/ >> + >> +-static NTSTATUS fd_open(struct connection_struct *conn, >> ++NTSTATUS fd_open(struct connection_struct *conn, >> + files_struct *fsp, >> + int flags, >> + mode_t mode) >> +@@ -198,8 +465,7 @@ >> + struct smb_filename *smb_fname = fsp->fsp_name; >> + NTSTATUS status = NT_STATUS_OK; >> + >> +-#ifdef O_NOFOLLOW >> +- /* >> ++ /* >> + * Never follow symlinks on a POSIX client. The >> + * client should be doing this. >> + */ >> +@@ -207,12 +473,33 @@ >> + if (fsp->posix_open || !lp_symlinks(SNUM(conn))) { >> + flags |= O_NOFOLLOW; >> + } >> +-#endif >> + >> +- fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); >> ++ /* Ensure path is below share definition. */ >> ++ if (!lp_widelinks(SNUM(conn))) { >> ++ const char *conn_rootdir = SMB_VFS_CONNECTPATH(conn, >> ++ smb_fname->base_name); >> ++ if (conn_rootdir == NULL) { >> ++ return NT_STATUS_NO_MEMORY; >> ++ } >> ++ /* >> ++ * Only follow symlinks within a share >> ++ * definition. >> ++ */ >> ++ fsp->fh->fd = non_widelink_open(conn, >> ++ conn_rootdir, >> ++ fsp, >> ++ smb_fname, >> ++ flags, >> ++ mode, >> ++ 0); >> ++ } else { >> ++ fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, >> mode); >> ++ } >> ++ >> + if (fsp->fh->fd == -1) { >> +- status = map_nt_error_from_unix(errno); >> +- if (errno == EMFILE) { >> ++ int posix_errno = link_errno_convert(errno); >> ++ status = map_nt_error_from_unix(posix_errno); >> ++ if (posix_errno == EMFILE) { >> + static time_t last_warned = 0L; >> + >> + if (time((time_t *) NULL) > last_warned) { >> +--- samba-3.6.6.orig/source3/smbd/proto.h >> ++++ samba-3.6.6/source3/smbd/proto.h >> +@@ -592,6 +592,8 @@ >> + const struct security_token *token, >> + uint32_t access_desired, >> + uint32_t *access_granted); >> ++NTSTATUS fd_open(struct connection_struct *conn, files_struct *fsp, >> ++ int flags, mode_t mode); >> + NTSTATUS fd_close(files_struct *fsp); >> + void change_file_owner_to_parent(connection_struct *conn, >> + const char *inherit_from_dir, >> +--- samba-3.6.6.orig/source3/smbd/smb2_find.c >> ++++ samba-3.6.6/source3/smbd/smb2_find.c >> +@@ -24,6 +24,7 @@ >> + #include "../libcli/smb/smb_common.h" >> + #include "trans2.h" >> + #include "../lib/util/tevent_ntstatus.h" >> ++#include "system/filesys.h" >> + >> + static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx, >> + struct tevent_context *ev, >> +@@ -300,7 +301,23 @@ >> + } >> + >> + if (in_flags & SMB2_CONTINUE_FLAG_REOPEN) { >> ++ int flags; >> ++ >> + dptr_CloseDir(fsp); >> ++ >> ++ /* >> ++ * dptr_CloseDir() will close and invalidate the fsp's file >> ++ * descriptor, we have to reopen it. >> ++ */ >> ++ >> ++ flags = O_RDONLY; >> ++#ifdef O_DIRECTORY >> ++ flags |= O_DIRECTORY; >> ++#endif >> ++ status = fd_open(conn, fsp, flags, 0); >> ++ if (tevent_req_nterror(req, status)) { >> ++ return tevent_req_post(req, ev); >> ++ } >> + } >> + >> + if (fsp->dptr == NULL) { >> +--- samba-3.6.6.orig/source3/modules/vfs_dirsort.c >> ++++ samba-3.6.6/source3/modules/vfs_dirsort.c >> +@@ -141,6 +141,10 @@ >> + return NULL; >> + } >> + >> ++ if (ISDOT(data->smb_fname->base_name)) { >> ++ data->smb_fname->base_name = vfs_GetWd(data, handle->conn); >> ++ } >> ++ >> + /* Open the underlying directory and count the number of entries */ >> + data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, >> + attr); >> +--- samba-3.6.6.orig/source3/modules/vfs_streams_xattr.c >> ++++ samba-3.6.6/source3/modules/vfs_streams_xattr.c >> +@@ -229,7 +229,7 @@ >> + return -1; >> + } >> + >> +- sbuf->st_ex_size = get_xattr_size(handle->conn, fsp->base_fsp, >> ++ sbuf->st_ex_size = get_xattr_size(handle->conn, fsp, >> + io->base, io->xattr_name); >> + if (sbuf->st_ex_size == -1) { >> + return -1; >> +@@ -364,6 +364,7 @@ >> + char *xattr_name = NULL; >> + int baseflags; >> + int hostfd = -1; >> ++ int ret; >> + >> + DEBUG(10, ("streams_xattr_open called for %s\n", >> + smb_fname_str_dbg(smb_fname))); >> +@@ -375,133 +376,125 @@ >> + /* If the default stream is requested, just open the base file. */ >> + if (is_ntfs_default_stream_smb_fname(smb_fname)) { >> + char *tmp_stream_name; >> +- int ret; >> + >> + tmp_stream_name = smb_fname->stream_name; >> + smb_fname->stream_name = NULL; >> + >> + ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, >> mode); >> + >> +- smb_fname->stream_name = tmp_stream_name; >> +- >> +- return ret; >> +- } >> ++ smb_fname->stream_name = tmp_stream_name; >> + >> +- status = streams_xattr_get_name(talloc_tos(), smb_fname- >> >stream_name, >> +- &xattr_name); >> +- if (!NT_STATUS_IS_OK(status)) { >> +- errno = map_errno_from_nt_status(status); >> +- goto fail; >> +- } >> ++ return ret; >> ++ } >> + >> +- /* Create an smb_filename with stream_name == NULL. */ >> +- status = create_synthetic_smb_fname(talloc_tos(), >> +- smb_fname->base_name, >> +- NULL, NULL, >> +- &smb_fname_base); >> +- if (!NT_STATUS_IS_OK(status)) { >> +- errno = map_errno_from_nt_status(status); >> +- goto fail; >> +- } >> ++ status = streams_xattr_get_name(talloc_tos(), smb_fname- >> >stream_name, >> ++ &xattr_name); >> ++ if (!NT_STATUS_IS_OK(status)) { >> ++ errno = map_errno_from_nt_status(status); >> ++ goto fail; >> ++ } >> + >> +- /* >> +- * We use baseflags to turn off nasty side-effects when opening the >> +- * underlying file. >> +- */ >> +- baseflags = flags; >> +- baseflags &= ~O_TRUNC; >> +- baseflags &= ~O_EXCL; >> +- baseflags &= ~O_CREAT; >> +- >> +- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp, >> +- baseflags, mode); >> +- >> +- TALLOC_FREE(smb_fname_base); >> +- >> +- /* It is legit to open a stream on a directory, but the base >> +- * fd has to be read-only. >> +- */ >> +- if ((hostfd == -1) && (errno == EISDIR)) { >> +- baseflags &= ~O_ACCMODE; >> +- baseflags |= O_RDONLY; >> +- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, >> baseflags, >> +- mode); >> +- } >> ++ /* Create an smb_filename with stream_name == NULL. */ >> ++ status = create_synthetic_smb_fname(talloc_tos(), >> ++ smb_fname->base_name, >> ++ NULL, NULL, >> ++ &smb_fname_base); >> ++ if (!NT_STATUS_IS_OK(status)) { >> ++ errno = map_errno_from_nt_status(status); >> ++ goto fail; >> ++ } >> + >> +- if (hostfd == -1) { >> +- goto fail; >> +- } >> ++ /* >> ++ * We use baseflags to turn off nasty side-effects when >> opening the >> ++ * underlying file. >> ++ */ >> ++ baseflags = flags; >> ++ baseflags &= ~O_TRUNC; >> ++ baseflags &= ~O_EXCL; >> ++ baseflags &= ~O_CREAT; >> + >> +- status = get_ea_value(talloc_tos(), handle->conn, NULL, >> +- smb_fname->base_name, xattr_name, &ea); >> ++ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp, >> ++ baseflags, mode); >> + >> +- DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status))); >> ++ TALLOC_FREE(smb_fname_base); >> + >> +- if (!NT_STATUS_IS_OK(status) >> +- && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { >> +- /* >> +- * The base file is not there. This is an error even if we >> got >> +- * O_CREAT, the higher levels should have created the base >> +- * file for us. >> ++ /* It is legit to open a stream on a directory, but the base >> ++ * fd has to be read-only. >> + */ >> +- DEBUG(10, ("streams_xattr_open: base file %s not around, " >> +- "returning ENOENT\n", smb_fname->base_name)); >> +- errno = ENOENT; >> +- goto fail; >> +- } >> ++ if ((hostfd == -1) && (errno == EISDIR)) { >> ++ baseflags &= ~O_ACCMODE; >> ++ baseflags |= O_RDONLY; >> ++ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, >> baseflags, >> ++ mode); >> ++ } >> + >> +- if (!NT_STATUS_IS_OK(status)) { >> +- /* >> +- * The attribute does not exist >> +- */ >> ++ if (hostfd == -1) { >> ++ goto fail; >> ++ } >> ++ >> ++ status = get_ea_value(talloc_tos(), handle->conn, NULL, >> ++ smb_fname->base_name, xattr_name, >> &ea); >> + >> +- if (flags & O_CREAT) { >> ++ DEBUG(10, ("get_ea_value returned %s\n", >> nt_errstr(status))); >> ++ >> ++ if (!NT_STATUS_IS_OK(status) >> ++ && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { >> + /* >> +- * Darn, xattrs need at least 1 byte >> ++ * The base file is not there. This is an error even >> if we got >> ++ * O_CREAT, the higher levels should have created >> the base >> ++ * file for us. >> + */ >> +- char null = '\0'; >> ++ DEBUG(10, ("streams_xattr_open: base file %s not >> around, " >> ++ "returning ENOENT\n", smb_fname- >> >base_name)); >> ++ errno = ENOENT; >> ++ goto fail; >> ++ } >> + >> +- DEBUG(10, ("creating attribute %s on file %s\n", >> +- xattr_name, smb_fname->base_name)); >> ++ if (!NT_STATUS_IS_OK(status)) { >> ++ /* >> ++ * The attribute does not exist >> ++ */ >> + >> ++ if (flags & O_CREAT) { >> ++ /* >> ++ * Darn, xattrs need at least 1 byte >> ++ */ >> ++ char null = '\0'; >> ++ >> ++ DEBUG(10, ("creating attribute %s on file >> %s\n", >> ++ xattr_name, smb_fname- >> >base_name)); >> ++ >> ++ fsp->fh->fd = hostfd; >> ++ ret = SMB_VFS_FSETXATTR(fsp, xattr_name, >> ++ &null, sizeof(null), >> ++ flags & O_EXCL ? >> XATTR_CREATE : 0); >> ++ fsp->fh->fd = -1; >> ++ if (ret != 0) { >> ++ goto fail; >> ++ } >> ++ } >> ++ } >> ++ >> ++ if (flags & O_TRUNC) { >> ++ char null = '\0'; >> + if (fsp->base_fsp->fh->fd != -1) { >> +- if (SMB_VFS_FSETXATTR( >> +- fsp->base_fsp, xattr_name, >> +- &null, sizeof(null), >> +- flags & O_EXCL ? XATTR_CREATE : 0) >> == -1) { >> ++ if (SMB_VFS_FSETXATTR( >> ++ fsp->base_fsp, xattr_name, >> ++ &null, sizeof(null), >> ++ flags & O_EXCL ? >> XATTR_CREATE : 0) == -1) { >> + goto fail; >> + } >> + } else { >> +- if (SMB_VFS_SETXATTR( >> +- handle->conn, smb_fname->base_name, >> +- xattr_name, &null, sizeof(null), >> +- flags & O_EXCL ? XATTR_CREATE : 0) >> == -1) { >> ++ if (SMB_VFS_SETXATTR( >> ++ handle->conn, smb_fname- >> >base_name, >> ++ xattr_name, &null, >> sizeof(null), >> ++ flags & O_EXCL ? >> XATTR_CREATE : 0) == -1) { >> + goto fail; >> + } >> + } >> + } >> +- } >> +- >> +- if (flags & O_TRUNC) { >> +- char null = '\0'; >> +- if (fsp->base_fsp->fh->fd != -1) { >> +- if (SMB_VFS_FSETXATTR( >> +- fsp->base_fsp, xattr_name, >> +- &null, sizeof(null), >> +- flags & O_EXCL ? XATTR_CREATE : 0) >> == -1) { >> +- goto fail; >> +- } >> +- } else { >> +- if (SMB_VFS_SETXATTR( >> +- handle->conn, smb_fname->base_name, >> +- xattr_name, &null, sizeof(null), >> +- flags & O_EXCL ? XATTR_CREATE : 0) >> == -1) { >> +- goto fail; >> +- } >> +- } >> +- } >> + >> +- sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp, >> ++ sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp, >> + struct stream_io, >> + NULL); >> + if (sio == NULL) { >> +@@ -511,8 +504,15 @@ >> + >> + sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, >> fsp), >> + xattr_name); >> ++ /* >> ++ * sio->base needs to be a copy of fsp->fsp_name->base_name, >> ++ * making it identical to streams_xattr_recheck(). If the >> ++ * open is changing directories, fsp->fsp_name->base_name >> ++ * will be the full path from the share root, whilst >> ++ * smb_fname will be relative to the $cwd. >> ++ */ >> + sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), >> +- smb_fname->base_name); >> ++ fsp->fsp_name->base_name); >> + sio->fsp_name_ptr = fsp->fsp_name; >> + sio->handle = handle; >> + sio->fsp = fsp; >> +@@ -861,7 +861,7 @@ >> + return -1; >> + } >> + >> +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, >> ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, >> + sio->base, sio->xattr_name, &ea); >> + if (!NT_STATUS_IS_OK(status)) { >> + return -1; >> +@@ -885,13 +885,13 @@ >> + >> + memcpy(ea.value.data + offset, data, n); >> + >> +- if (fsp->base_fsp->fh->fd != -1) { >> +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, >> ++ if (fsp->fh->fd != -1) { >> ++ ret = SMB_VFS_FSETXATTR(fsp, >> + sio->xattr_name, >> + ea.value.data, ea.value.length, 0); >> + } else { >> + ret = SMB_VFS_SETXATTR(fsp->conn, >> +- fsp->base_fsp->fsp_name->base_name, >> ++ fsp->fsp_name->base_name, >> + sio->xattr_name, >> + ea.value.data, ea.value.length, 0); >> + } >> +@@ -925,7 +925,7 @@ >> + return -1; >> + } >> + >> +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, >> ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, >> + sio->base, sio->xattr_name, &ea); >> + if (!NT_STATUS_IS_OK(status)) { >> + return -1; >> +@@ -970,7 +970,7 @@ >> + return -1; >> + } >> + >> +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, >> ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, >> + sio->base, sio->xattr_name, &ea); >> + if (!NT_STATUS_IS_OK(status)) { >> + return -1; >> +@@ -995,13 +995,13 @@ >> + ea.value.length = offset + 1; >> + ea.value.data[offset] = 0; >> + >> +- if (fsp->base_fsp->fh->fd != -1) { >> +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, >> ++ if (fsp->fh->fd != -1) { >> ++ ret = SMB_VFS_FSETXATTR(fsp, >> + sio->xattr_name, >> + ea.value.data, ea.value.length, 0); >> + } else { >> + ret = SMB_VFS_SETXATTR(fsp->conn, >> +- fsp->base_fsp->fsp_name->base_name, >> ++ fsp->fsp_name->base_name, >> + sio->xattr_name, >> + ea.value.data, ea.value.length, 0); >> + } >> +--- samba-3.6.6.orig/source3/smbd/dir.c >> ++++ samba-3.6.6/source3/smbd/dir.c >> +@@ -1358,7 +1358,8 @@ >> + Open a directory. >> + ********************************************************************/ >> + >> +-struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, >> ++static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, >> ++ connection_struct *conn, >> + const char *name, >> + const char *mask, >> + uint32 attr) >> +@@ -1370,27 +1371,21 @@ >> + return NULL; >> + } >> + >> +- dirp->conn = conn; >> +- dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); >> +- >> +- dirp->dir_path = talloc_strdup(dirp, name); >> +- if (!dirp->dir_path) { >> +- errno = ENOMEM; >> ++ dirp->dir = SMB_VFS_OPENDIR(conn, name, mask, attr); >> ++ if (!dirp->dir) { >> ++ DEBUG(5,("OpenDir: Can't open %s. %s\n", name, >> ++ strerror(errno) )); >> + goto fail; >> + } >> + >> ++ dirp->conn = conn; >> ++ dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); >> ++ >> + if (sconn && !sconn->using_smb2) { >> + sconn->searches.dirhandles_open++; >> + } >> + talloc_set_destructor(dirp, smb_Dir_destructor); >> + >> +- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); >> +- if (!dirp->dir) { >> +- DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, >> +- strerror(errno) )); >> +- goto fail; >> +- } >> +- >> + return dirp; >> + >> + fail: >> +@@ -1398,6 +1393,76 @@ >> + return NULL; >> + } >> + >> ++/*************************************************************************** >> * >> ++ Open a directory handle by pathname, ensuring it's under the share path. >> ++**************************************************************************** >> / >> ++ >> ++static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx, >> ++ connection_struct *conn, >> ++ const char *name, >> ++ const char *wcard, >> ++ uint32_t attr) >> ++{ >> ++ struct smb_Dir *dir_hnd = NULL; >> ++ char *saved_dir = vfs_GetWd(ctx, conn); >> ++ NTSTATUS status; >> ++ >> ++ if (saved_dir == NULL) { >> ++ return NULL; >> ++ } >> ++ >> ++ if (vfs_ChDir(conn, name) == -1) { >> ++ goto out; >> ++ } >> ++ >> ++ /* >> ++ * Now the directory is pinned, use >> ++ * REALPATH to ensure we can access it. >> ++ */ >> ++ status = check_name(conn, "."); >> ++ if (!NT_STATUS_IS_OK(status)) { >> ++ goto out; >> ++ } >> ++ >> ++ dir_hnd = OpenDir_internal(ctx, >> ++ conn, >> ++ ".", >> ++ wcard, >> ++ attr); >> ++ >> ++ if (dir_hnd == NULL) { >> ++ goto out; >> ++ } >> ++ >> ++ /* >> ++ * OpenDir_internal only gets "." as the dir name. >> ++ * Store the real dir name here. >> ++ */ >> ++ >> ++ dir_hnd->dir_path = talloc_strdup(dir_hnd, name); >> ++ if (!dir_hnd->dir_path) { >> ++ errno = ENOMEM; >> ++ } >> ++ >> ++ out: >> ++ >> ++ vfs_ChDir(conn, saved_dir); >> ++ TALLOC_FREE(saved_dir); >> ++ return dir_hnd; >> ++} >> ++ >> ++struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, >> ++ const char *name, >> ++ const char *mask, >> ++ uint32_t attr) >> ++{ >> ++ return open_dir_safely(mem_ctx, >> ++ conn, >> ++ name, >> ++ mask, >> ++ attr); >> ++} >> ++ >> + /******************************************************************* >> + Open a directory from an fsp. >> + ********************************************************************/ >> +@@ -1411,7 +1476,17 @@ >> + struct smbd_server_connection *sconn = conn->sconn; >> + >> + if (!dirp) { >> +- return NULL; >> ++ goto fail; >> ++ } >> ++ >> ++ if (!fsp->is_directory) { >> ++ errno = EBADF; >> ++ goto fail; >> ++ } >> ++ >> ++ if (fsp->fh->fd == -1) { >> ++ errno = EBADF; >> ++ goto fail; >> + } >> + >> + dirp->conn = conn; >> +@@ -1423,36 +1498,33 @@ >> + goto fail; >> + } >> + >> +- if (sconn && !sconn->using_smb2) { >> +- sconn->searches.dirhandles_open++; >> +- } >> +- talloc_set_destructor(dirp, smb_Dir_destructor); >> +- >> +- if (fsp->is_directory && fsp->fh->fd != -1) { >> +- dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); >> +- if (dirp->dir != NULL) { >> +- dirp->fsp = fsp; >> +- } else { >> +- DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s >> returned " >> +- "NULL (%s)\n", >> +- dirp->dir_path, >> +- strerror(errno))); >> +- if (errno != ENOSYS) { >> +- return NULL; >> +- } >> ++ dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); >> ++ if (dirp->dir != NULL) { >> ++ dirp->fsp = fsp; >> ++ } else { >> ++ DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " >> ++ "NULL (%s)\n", >> ++ dirp->dir_path, >> ++ strerror(errno))); >> ++ if (errno != ENOSYS) { >> ++ goto fail; >> + } >> + } >> + >> + if (dirp->dir == NULL) { >> +- /* FDOPENDIR didn't work. Use OPENDIR instead. */ >> +- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, >> attr); >> ++ /* FDOPENDIR is not supported. Use OPENDIR instead. */ >> ++ TALLOC_FREE(dirp); >> ++ return open_dir_safely(mem_ctx, >> ++ conn, >> ++ fsp->fsp_name->base_name, >> ++ mask, >> ++ attr); >> + } >> + >> +- if (!dirp->dir) { >> +- DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", dirp->dir_path, >> +- strerror(errno) )); >> +- goto fail; >> ++ if (sconn && !sconn->using_smb2) { >> ++ sconn->searches.dirhandles_open++; >> + } >> ++ talloc_set_destructor(dirp, smb_Dir_destructor); >> + >> + return dirp; >> + >> diff --git a/src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch >> b/src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch >> new file mode 100644 >> index 000000000..cefdd86ea >> --- /dev/null >> +++ b/src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch >> @@ -0,0 +1,179 @@ >> +bug: https://bugzilla.samba.org/show_bug.cgi?id=12721 >> +Description: This patch is a consolidation of several patches described by >> the Git commit summaries below >> + >> +From 5d4ef6ff0970c93fed49e51a01e63cb67d49d087 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 27 Mar 2017 10:46:47 -0700 >> +Subject: [PATCH 1/3] s3: smbd: Fix incorrect logic exposed by fix for the >> + security bug 12496 (CVE-2017-2619). >> + >> +In a UNIX filesystem, the names "." and ".." by definition can *never* >> +be symlinks - they are already reserved names. >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +Reviewed-by: Uri Simchoni <uri(a)samba.org> >> +(cherry picked from commit ae17bebd250bdde5614b2ac17e53512f19fe9b68) >> +--- >> + source3/smbd/vfs.c | 7 +++++-- >> + 1 file changed, 5 insertions(+), 2 deletions(-) >> + >> +From 71500662d1098d17657b0148a0aa06cd69482c7d Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 27 Mar 2017 17:04:58 -0700 >> +Subject: [PATCH 2/3] s3: smbd: Fix "follow symlink = no" regression part 2. >> + >> +Add an extra paramter to cwd_name to check_reduced_name(). >> + >> +If cwd_name == NULL then fname is a client given path relative >> +to the root path of the share. >> + >> +If cwd_name != NULL then fname is a client given path relative >> +to cwd_name. cwd_name is relative to the root path of the share. >> + >> +Not yet used, logic added in the next commit. >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +Reviewed-by: Ralph Boehme <slow(a)samba.org> >> +(cherry picked from commit 83e30cb48859b412b76572b6a3ba84d8fde167af) >> +--- >> + source3/smbd/filename.c | 2 +- >> + source3/smbd/open.c | 2 +- >> + source3/smbd/proto.h | 4 +++- >> + source3/smbd/vfs.c | 10 +++++++++- >> + 4 files changed, 14 insertions(+), 4 deletions(-) >> + >> +From e3fd46264b82ffc22424ee7364b3fd2c0fc14a7e Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 27 Mar 2017 17:09:38 -0700 >> +Subject: [PATCH 3/3] s3: smbd: Fix "follow symlink = no" regression part 2. >> + >> +Use the cwd_name parameter to reconstruct the original >> +client name for symlink testing. >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +Reviewed-by: Ralph Boehme <slow(a)samba.org> >> +(cherry picked from commit e182a4d39e86c9694e255efdf6ee2ea3ccb9af4a) >> +--- >> + source3/smbd/vfs.c | 23 +++++++++++++++++++++++ >> + 1 file changed, 23 insertions(+) >> + >> +--- samba-3.6.6.orig/source3/smbd/vfs.c >> ++++ samba-3.6.6/source3/smbd/vfs.c >> +@@ -894,11 +894,20 @@ >> + /******************************************************************* >> + Reduce a file name, removing .. elements and checking that >> + it is below dir in the heirachy. This uses realpath. >> ++ >> ++ If cwd_name == NULL then fname is a client given path relative >> ++ to the root path of the share. >> ++ >> ++ If cwd_name != NULL then fname is a client given path relative >> ++ to cwd_name. cwd_name is relative to the root path of the share. >> + ********************************************************************/ >> + >> +-NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) >> ++NTSTATUS check_reduced_name(connection_struct *conn, >> ++ const char *cwd_name, >> ++ const char *fname) >> + { >> + char *resolved_name = NULL; >> ++ char *new_fname = NULL; >> + bool allow_symlinks = true; >> + bool allow_widelinks = false; >> + >> +@@ -1026,8 +1035,11 @@ >> + /* fname can't have changed in resolved_path. */ >> + const char *p = &resolved_name[rootdir_len]; >> + >> +- /* *p can be '\0' if fname was "." */ >> +- if (*p == '\0' && ISDOT(fname)) { >> ++ /* >> ++ * UNIX filesystem semantics, names consisting >> ++ * only of "." or ".." CANNOT be symlinks. >> ++ */ >> ++ if (ISDOT(fname) || ISDOTDOT(fname)) { >> + goto out; >> + } >> + >> +@@ -1041,11 +1053,32 @@ >> + } >> + >> + p++; >> ++ >> ++ /* >> ++ * If cwd_name is present and not ".", >> ++ * then fname is relative to that, not >> ++ * the root of the share. Make sure the >> ++ * path we check is the one the client >> ++ * sent (cwd_name+fname). >> ++ */ >> ++ if (cwd_name != NULL && !ISDOT(cwd_name)) { >> ++ new_fname = talloc_asprintf(talloc_tos(), >> ++ "%s/%s", >> ++ cwd_name, >> ++ fname); >> ++ if (new_fname == NULL) { >> ++ SAFE_FREE(resolved_name); >> ++ return NT_STATUS_NO_MEMORY; >> ++ } >> ++ fname = new_fname; >> ++ } >> ++ >> + if (strcmp(fname, p)!=0) { >> + DEBUG(2, ("check_reduced_name: Bad access " >> + "attempt: %s is a symlink\n", >> + fname)); >> + SAFE_FREE(resolved_name); >> ++ TALLOC_FREE(new_fname); >> + return NT_STATUS_ACCESS_DENIED; >> + } >> + } >> +@@ -1056,6 +1089,7 @@ >> + DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname, >> + resolved_name)); >> + SAFE_FREE(resolved_name); >> ++ TALLOC_FREE(new_fname); >> + return NT_STATUS_OK; >> + } >> + >> +--- samba-3.6.6.orig/source3/smbd/filename.c >> ++++ samba-3.6.6/source3/smbd/filename.c >> +@@ -1009,7 +1009,7 @@ >> + } >> + >> + if (!lp_widelinks(SNUM(conn)) || !lp_symlinks(SNUM(conn))) { >> +- status = check_reduced_name(conn,name); >> ++ status = check_reduced_name(conn, NULL, name); >> + if (!NT_STATUS_IS_OK(status)) { >> + DEBUG(5,("check_name: name %s failed with >> %s\n",name, >> + nt_errstr(status))); >> +--- samba-3.6.6.orig/source3/smbd/open.c >> ++++ samba-3.6.6/source3/smbd/open.c >> +@@ -381,7 +381,7 @@ >> + } >> + >> + /* Ensure the relative path is below the share. */ >> +- status = check_reduced_name(conn, final_component); >> ++ status = check_reduced_name(conn, parent_dir, final_component); >> + if (!NT_STATUS_IS_OK(status)) { >> + saved_errno = map_errno_from_nt_status(status); >> + goto out; >> +--- samba-3.6.6.orig/source3/smbd/proto.h >> ++++ samba-3.6.6/source3/smbd/proto.h >> +@@ -1179,7 +1179,9 @@ >> + SMB_STRUCT_STAT *sbuf, char **talloced); >> + int vfs_ChDir(connection_struct *conn, const char *path); >> + char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn); >> +-NTSTATUS check_reduced_name(connection_struct *conn, const char *fname); >> ++NTSTATUS check_reduced_name(connection_struct *conn, >> ++ const char *cwd_name, >> ++ const char *fname); >> + int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, >> + SMB_STRUCT_STAT *psbuf); >> + int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, >> diff --git a/src/patches/samba/CVE-2017-2619-tests.patch >> b/src/patches/samba/CVE-2017-2619-tests.patch >> new file mode 100644 >> index 000000000..41c84610e >> --- /dev/null >> +++ b/src/patches/samba/CVE-2017-2619-tests.patch >> @@ -0,0 +1,296 @@ >> +Description: Patches to unit tests associated with CVE-2017-2619 regression >> +origin: https://attachments.samba.org/attachment.cgi?id=13130 >> + >> +From 2c6de8584779e413f1e6ff9c933f9281693bfbc0 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 27 Mar 2017 11:48:25 -0700 >> +Subject: [PATCH 2/6] s3: Test for CVE-2017-2619 regression with "follow >> + symlinks = no". >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +Reviewed-by: Uri Simchoni <uri(a)samba.org> >> + >> +Back-ported from commit 782172a9bef0040981d20e49519b13dd744df6a0 >> +--- >> + selftest/target/Samba3.pm | 7 +++ >> + source3/script/tests/test_smbclient_s3.sh | 73 >> +++++++++++++++++++++++++++++++ >> + 2 files changed, 80 insertions(+) >> + >> +diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >> +index 01a1c470af0..7765b9efbb2 100644 >> +--- a/selftest/target/Samba3.pm >> ++++ b/selftest/target/Samba3.pm >> +@@ -481,6 +481,9 @@ sub provision($$$$$$) >> + my $msdfs_deeppath="$msdfs_shrdir/deeppath"; >> + push(@dirs,$msdfs_deeppath); >> + >> ++ my $nosymlinks_shrdir="$shrdir/nosymlinks"; >> ++ push(@dirs,$nosymlinks_shrdir); >> ++ >> + # this gets autocreated by winbindd >> + my $wbsockdir="$prefix_abs/winbindd"; >> + my $wbsockprivdir="$lockdir/winbindd_privileged"; >> +@@ -695,6 +698,10 @@ sub provision($$$$$$) >> + copy = print1 >> + [print\$] >> + copy = tmp >> ++[nosymlinks] >> ++ copy = tmp >> ++ path = $nosymlinks_shrdir >> ++ follow symlinks = no >> + "; >> + close(CONF); >> + >> +diff --git a/source3/script/tests/test_smbclient_s3.sh >> b/source3/script/tests/test_smbclient_s3.sh >> +index 772802f77b1..57ef87e4949 100755 >> +--- a/source3/script/tests/test_smbclient_s3.sh >> ++++ b/source3/script/tests/test_smbclient_s3.sh >> +@@ -401,6 +401,75 @@ done >> + >> + LOGDIR=$(mktemp -d ${PREFIX}/${LOGDIR_PREFIX}_XXXXXX) >> + >> ++# Test follow symlinks can't access symlinks >> ++test_nosymlinks() >> ++{ >> ++# Setup test dirs. >> ++ slink_name="$LOCAL_PATH/nosymlinks/source" >> ++ slink_target="$LOCAL_PATH/nosymlinks/target" >> ++ mkdir_target="$LOCAL_PATH/nosymlinks/a" >> ++ >> ++ rm -f $slink_target >> ++ rm -f $slink_name >> ++ rm -rf $mkdir_target >> ++ >> ++ touch $slink_target >> ++ ln -s $slink_target $slink_name >> ++ >> ++# Getting a file through a symlink name should fail. >> ++ tmpfile=$PREFIX/smbclient_interactive_prompt_commands >> ++ cat > $tmpfile <<EOF >> ++get source >> ++quit >> ++EOF >> ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD >> //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' >> ++ eval echo "$cmd" >> ++ out=`eval $cmd` >> ++ ret=$? >> ++ rm -f $tmpfile >> ++ >> ++ if [ $ret != 0 ] ; then >> ++ echo "$out" >> ++ echo "failed accessing nosymlinks with error $ret" >> ++ false >> ++ return >> ++ fi >> ++ >> ++ echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' >> ++ ret=$? >> ++ if [ $ret != 0 ] ; then >> ++ echo "$out" >> ++ echo "failed - should get NT_STATUS_ACCESS_DENIED getting >> \\nosymlinks\\source" >> ++ false >> ++ fi >> ++ >> ++# But we should be able to create and delete directories. >> ++ cat > $tmpfile <<EOF >> ++mkdir a >> ++mkdir a\\b >> ++quit >> ++EOF >> ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD >> //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' >> ++ eval echo "$cmd" >> ++ out=`eval $cmd` >> ++ ret=$? >> ++ rm -f $tmpfile >> ++ >> ++ if [ $ret != 0 ] ; then >> ++ echo "$out" >> ++ echo "failed accessing nosymlinks with error $ret" >> ++ false >> ++ return >> ++ fi >> ++ >> ++ echo "$out" | grep 'NT_STATUS' >> ++ ret=$? >> ++ if [ $ret == 0 ] ; then >> ++ echo "$out" >> ++ echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b on >> \\nosymlinks" >> ++ false >> ++ fi >> ++} >> + >> + testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p 139 || >> failed=`expr $failed + 1` >> + testit "smbclient -L $SERVER -I $SERVER_IP" $SMBCLIENT -L $SERVER -I >> $SERVER_IP -N -p 139 -c quit || failed=`expr $failed + 1` >> +@@ -445,6 +514,10 @@ testit "ccache access works for smbclient" \ >> + test_ccache_access || \ >> + failed=`expr $failed + 1` >> + >> ++testit "follow symlinks = no" \ >> ++ test_nosymlinks || \ >> ++ failed=`expr $failed + 1` >> ++ >> + testit "rm -rf $LOGDIR" \ >> + rm -rf $LOGDIR || \ >> + failed=`expr $failed + 1` >> +-- >> +2.12.0 >> + >> + >> +From 17865cf188f42850f18f46514643a5b3a43e5707 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 27 Mar 2017 22:07:50 -0700 >> +Subject: [PATCH 3/6] s3: Fixup test for CVE-2017-2619 regression with "follow >> + symlinks = no" >> + >> +Use correct bash operators (not string operators). >> +Add missing "return". >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +Reviewed-by: Ralph Boehme <slow(a)samba.org> >> +(cherry picked from commit 037297a1c50e90a0092e3b94f472623f41ccc015) >> +--- >> + source3/script/tests/test_smbclient_s3.sh | 9 +++++---- >> + 1 file changed, 5 insertions(+), 4 deletions(-) >> + >> +diff --git a/source3/script/tests/test_smbclient_s3.sh >> b/source3/script/tests/test_smbclient_s3.sh >> +index 57ef87e4949..bd5714fca6e 100755 >> +--- a/source3/script/tests/test_smbclient_s3.sh >> ++++ b/source3/script/tests/test_smbclient_s3.sh >> +@@ -428,7 +428,7 @@ EOF >> + ret=$? >> + rm -f $tmpfile >> + >> +- if [ $ret != 0 ] ; then >> ++ if [ $ret -ne 0 ] ; then >> + echo "$out" >> + echo "failed accessing nosymlinks with error $ret" >> + false >> +@@ -437,10 +437,11 @@ EOF >> + >> + echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' >> + ret=$? >> +- if [ $ret != 0 ] ; then >> ++ if [ $ret -ne 0 ] ; then >> + echo "$out" >> + echo "failed - should get NT_STATUS_ACCESS_DENIED getting >> \\nosymlinks\\source" >> + false >> ++ return >> + fi >> + >> + # But we should be able to create and delete directories. >> +@@ -455,7 +456,7 @@ EOF >> + ret=$? >> + rm -f $tmpfile >> + >> +- if [ $ret != 0 ] ; then >> ++ if [ $ret -ne 0 ] ; then >> + echo "$out" >> + echo "failed accessing nosymlinks with error $ret" >> + false >> +@@ -464,7 +465,7 @@ EOF >> + >> + echo "$out" | grep 'NT_STATUS' >> + ret=$? >> +- if [ $ret == 0 ] ; then >> ++ if [ $ret -eq 0 ] ; then >> + echo "$out" >> + echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b on >> \\nosymlinks" >> + false >> +-- >> +2.12.0 >> + >> + >> +From 9b573af39f3d4995464e30771fa06e0709b5e57b Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Mon, 27 Mar 2017 22:10:29 -0700 >> +Subject: [PATCH 6/6] s3: Test for CVE-2017-2619 regression with "follow >> + symlinks = no" - part 2 >> +MIME-Version: 1.0 >> +Content-Type: text/plain; charset=UTF-8 >> +Content-Transfer-Encoding: 8bit >> + >> +Add tests for regular access. >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +Reviewed-by: Ralph Boehme <slow(a)samba.org> >> + >> +Autobuild-User(master): Ralph Böhme <slow(a)samba.org> >> +Autobuild-Date(master): Tue Mar 28 17:05:27 CEST 2017 on sn-devel-144 >> + >> +(cherry picked from commit 4e734fcd1bf82c08aa303ce44e9735acccffcf06) >> +--- >> + source3/script/tests/test_smbclient_s3.sh | 37 >> +++++++++++++++++++++++++++++++ >> + 1 file changed, 37 insertions(+) >> + >> +diff --git a/source3/script/tests/test_smbclient_s3.sh >> b/source3/script/tests/test_smbclient_s3.sh >> +index bd5714fca6e..885766f6c16 100755 >> +--- a/source3/script/tests/test_smbclient_s3.sh >> ++++ b/source3/script/tests/test_smbclient_s3.sh >> +@@ -408,14 +408,22 @@ test_nosymlinks() >> + slink_name="$LOCAL_PATH/nosymlinks/source" >> + slink_target="$LOCAL_PATH/nosymlinks/target" >> + mkdir_target="$LOCAL_PATH/nosymlinks/a" >> ++ dir1="$LOCAL_PATH/nosymlinks/foo" >> ++ dir2="$LOCAL_PATH/nosymlinks/foo/bar" >> ++ get_target="$LOCAL_PATH/nosymlinks/foo/bar/testfile" >> + >> + rm -f $slink_target >> + rm -f $slink_name >> + rm -rf $mkdir_target >> ++ rm -rf $dir1 >> + >> + touch $slink_target >> + ln -s $slink_target $slink_name >> + >> ++ mkdir $dir1 >> ++ mkdir $dir2 >> ++ touch $get_target >> ++ >> + # Getting a file through a symlink name should fail. >> + tmpfile=$PREFIX/smbclient_interactive_prompt_commands >> + cat > $tmpfile <<EOF >> +@@ -470,6 +478,35 @@ EOF >> + echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b on >> \\nosymlinks" >> + false >> + fi >> ++ >> ++# Ensure regular file/directory access also works. >> ++ cat > $tmpfile <<EOF >> ++cd foo\\bar >> ++ls >> ++get testfile - >> ++quit >> ++EOF >> ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD >> //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' >> ++ eval echo "$cmd" >> ++ out=`eval $cmd` >> ++ ret=$? >> ++ rm -f $tmpfile >> ++ >> ++ if [ $ret -ne 0 ] ; then >> ++ echo "$out" >> ++ echo "failed accessing nosymlinks with error $ret" >> ++ false >> ++ return >> ++ fi >> ++ >> ++ echo "$out" | grep 'NT_STATUS' >> ++ ret=$? >> ++ if [ $ret -eq 0 ] ; then >> ++ echo "$out" >> ++ echo "failed - NT_STATUS_XXXX doing cd foo\\bar; get testfile on >> \\nosymlinks" >> ++ false >> ++ return >> ++ fi >> + } >> + >> + testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p 139 || >> failed=`expr $failed + 1` >> +-- >> +2.12.0 >> + >> diff --git a/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch >> b/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch >> new file mode 100644 >> index 000000000..54bb1841b >> --- /dev/null >> +++ b/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch >> @@ -0,0 +1,14 @@ >> +--- source3/rpc_server/srv_pipe.c Sun Feb 22 16:11:32 2015 >> ++++ source3/rpc_server/srv_pipe.c Fri May 26 17:28:40 2017 >> +@@ -465,6 +465,11 @@ >> + const char *pipename = cli_filename; >> + NTSTATUS status; >> + >> ++ if (strchr(pipename, '/')) { >> ++ DEBUG(1, ("Refusing open on pipe %s\n", pipename)); >> ++ return false; >> ++ } >> ++ >> + if (strnequal(pipename, "\\PIPE\\", 6)) { >> + pipename += 5; >> + } >> diff --git a/src/patches/samba/samba-3.6.25-security-2015-12-16.patch >> b/src/patches/samba/samba-3.6.25-security-2015-12-16.patch >> new file mode 100644 >> index 000000000..df1057fea >> --- /dev/null >> +++ b/src/patches/samba/samba-3.6.25-security-2015-12-16.patch >> @@ -0,0 +1,255 @@ >> +From 2e94b6ec10f1d15e24867bab3063bb85f173406a Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Thu, 9 Jul 2015 10:58:11 -0700 >> +Subject: [PATCH] CVE-2015-5252: s3: smbd: Fix symlink verification (file >> + access outside the share). >> + >> +Ensure matching component ends in '/' or '\0'. >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11395 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +Reviewed-by: Volker Lendecke <vl(a)samba.org> >> +--- >> + source3/smbd/vfs.c | 7 +++++-- >> + 1 file changed, 5 insertions(+), 2 deletions(-) >> + >> +diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c >> +index 6c56964..bd93b7f 100644 >> +--- a/source3/smbd/vfs.c >> ++++ b/source3/smbd/vfs.c >> +@@ -982,6 +982,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, >> const char *fname) >> + if (!allow_widelinks || !allow_symlinks) { >> + const char *conn_rootdir; >> + size_t rootdir_len; >> ++ bool matched; >> + >> + conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname); >> + if (conn_rootdir == NULL) { >> +@@ -992,8 +993,10 @@ NTSTATUS check_reduced_name(connection_struct *conn, >> const char *fname) >> + } >> + >> + rootdir_len = strlen(conn_rootdir); >> +- if (strncmp(conn_rootdir, resolved_name, >> +- rootdir_len) != 0) { >> ++ matched = (strncmp(conn_rootdir, resolved_name, >> ++ rootdir_len) == 0); >> ++ if (!matched || (resolved_name[rootdir_len] != '/' && >> ++ resolved_name[rootdir_len] != '\0')) { >> + DEBUG(2, ("check_reduced_name: Bad access " >> + "attempt: %s is a symlink outside the " >> + "share path\n", fname)); >> +-- >> +2.5.0 >> + >> +From 25139116756cc285a3a5534834cc276ef1b7baaa Mon Sep 17 00:00:00 2001 >> +From: Stefan Metzmacher <metze(a)samba.org> >> +Date: Wed, 30 Sep 2015 21:17:02 +0200 >> +Subject: [PATCH 1/2] CVE-2015-5296: s3:libsmb: force signing when requiring >> + encryption in do_connect() >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536 >> + >> +Signed-off-by: Stefan Metzmacher <metze(a)samba.org> >> +Reviewed-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/libsmb/clidfs.c | 7 ++++++- >> + 1 file changed, 6 insertions(+), 1 deletion(-) >> + >> +diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c >> +index 23e1471..f153b6b 100644 >> +--- a/source3/libsmb/clidfs.c >> ++++ b/source3/libsmb/clidfs.c >> +@@ -98,6 +98,11 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, >> + const char *username; >> + const char *password; >> + NTSTATUS status; >> ++ int signing_state = get_cmdline_auth_info_signing_state(auth_info); >> ++ >> ++ if (force_encrypt) { >> ++ signing_state = Required; >> ++ } >> + >> + /* make a copy so we don't modify the global string 'service' */ >> + servicename = talloc_strdup(ctx,share); >> +@@ -132,7 +137,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, >> + zero_sockaddr(&ss); >> + >> + /* have to open a new connection */ >> +- c = >> cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)); >> ++ c = cli_initialise_ex(signing_state); >> + if (c == NULL) { >> + d_printf("Connection to %s failed\n", server_n); >> + return NULL; >> +-- >> +2.5.0 >> + >> + >> +From 060adb0abdeda51b8b622c6020b5dea0c8dde1cf Mon Sep 17 00:00:00 2001 >> +From: Stefan Metzmacher <metze(a)samba.org> >> +Date: Wed, 30 Sep 2015 21:17:02 +0200 >> +Subject: [PATCH 2/2] CVE-2015-5296: s3:libsmb: force signing when requiring >> + encryption in SMBC_server_internal() >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536 >> + >> +Signed-off-by: Stefan Metzmacher <metze(a)samba.org> >> +Reviewed-by: Jeremy Allison <jra(a)samba.org> >> +--- >> + source3/libsmb/libsmb_server.c | 13 +++++++++++-- >> + 1 file changed, 11 insertions(+), 2 deletions(-) >> + >> +diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c >> +index 45be660..167f2c9 100644 >> +--- a/source3/libsmb/libsmb_server.c >> ++++ b/source3/libsmb/libsmb_server.c >> +@@ -258,6 +258,7 @@ SMBC_server_internal(TALLOC_CTX *ctx, >> + const char *username_used; >> + NTSTATUS status; >> + char *newserver, *newshare; >> ++ int signing_state = Undefined; >> + >> + zero_sockaddr(&ss); >> + ZERO_STRUCT(c); >> +@@ -404,8 +405,12 @@ again: >> + >> + zero_sockaddr(&ss); >> + >> ++ if (context->internal->smb_encryption_level != >> SMBC_ENCRYPTLEVEL_NONE) { >> ++ signing_state = Required; >> ++ } >> ++ >> + /* have to open a new connection */ >> +- if ((c = cli_initialise()) == NULL) { >> ++ if ((c = cli_initialise_ex(signing_state)) == NULL) { >> + errno = ENOMEM; >> + return NULL; >> + } >> +@@ -750,6 +755,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, >> + ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$", >> + pp_workgroup, pp_username, pp_password); >> + if (!ipc_srv) { >> ++ int signing_state = Undefined; >> + >> + /* We didn't find a cached connection. Get the password */ >> + if (!*pp_password || (*pp_password)[0] == '\0') { >> +@@ -771,6 +777,9 @@ SMBC_attr_server(TALLOC_CTX *ctx, >> + if (smbc_getOptionUseCCache(context)) { >> + flags |= CLI_FULL_CONNECTION_USE_CCACHE; >> + } >> ++ if (context->internal->smb_encryption_level != >> SMBC_ENCRYPTLEVEL_NONE) { >> ++ signing_state = Required; >> ++ } >> + >> + zero_sockaddr(&ss); >> + nt_status = cli_full_connection(&ipc_cli, >> +@@ -780,7 +789,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, >> + *pp_workgroup, >> + *pp_password, >> + flags, >> +- Undefined); >> ++ signing_state); >> + if (! NT_STATUS_IS_OK(nt_status)) { >> + DEBUG(1,("cli_full_connection failed! (%s)\n", >> + nt_errstr(nt_status))); >> +-- >> +2.5.0 >> + >> +From 8e49de7754f7171a58a1f94dee0f1138dbee3c60 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison <jra(a)samba.org> >> +Date: Fri, 23 Oct 2015 14:54:31 -0700 >> +Subject: [PATCH] CVE-2015-5299: s3-shadow-copy2: fix missing access check on >> + snapdir >> + >> +Fix originally from <partha(a)exablox.com> >> + >> +https://bugzilla.samba.org/show_bug.cgi?id=11529 >> + >> +Signed-off-by: Jeremy Allison <jra(a)samba.org> >> +Reviewed-by: David Disseldorp <ddiss(a)samba.org> >> +--- >> + source3/modules/vfs_shadow_copy2.c | 47 >> ++++++++++++++++++++++++++++++++++++++ >> + 1 file changed, 47 insertions(+) >> + >> +diff --git a/source3/modules/vfs_shadow_copy2.c >> b/source3/modules/vfs_shadow_copy2.c >> +index fedfb53..16c1ed7 100644 >> +--- a/source3/modules/vfs_shadow_copy2.c >> ++++ b/source3/modules/vfs_shadow_copy2.c >> +@@ -21,6 +21,8 @@ >> + >> + #include "includes.h" >> + #include "smbd/smbd.h" >> ++#include "smbd/globals.h" >> ++#include "../libcli/security/security.h" >> + #include "system/filesys.h" >> + #include "ntioctl.h" >> + >> +@@ -764,6 +766,43 @@ static int shadow_copy2_mkdir(vfs_handle_struct >> *handle, const char *fname, mod >> + SHADOW2_NEXT(MKDIR, (handle, name, mode), int, -1); >> + } >> + >> ++static bool check_access_snapdir(struct vfs_handle_struct *handle, >> ++ const char *path) >> ++{ >> ++ struct smb_filename smb_fname; >> ++ int ret; >> ++ NTSTATUS status; >> ++ uint32_t access_granted = 0; >> ++ >> ++ ZERO_STRUCT(smb_fname); >> ++ smb_fname.base_name = talloc_asprintf(talloc_tos(), >> ++ "%s", >> ++ path); >> ++ if (smb_fname.base_name == NULL) { >> ++ return false; >> ++ } >> ++ >> ++ ret = SMB_VFS_NEXT_STAT(handle, &smb_fname); >> ++ if (ret != 0 || !S_ISDIR(smb_fname.st.st_ex_mode)) { >> ++ TALLOC_FREE(smb_fname.base_name); >> ++ return false; >> ++ } >> ++ >> ++ status = smbd_check_open_rights(handle->conn, >> ++ &smb_fname, >> ++ SEC_DIR_LIST, >> ++ &access_granted); >> ++ if (!NT_STATUS_IS_OK(status)) { >> ++ DEBUG(0,("user does not have list permission " >> ++ "on snapdir %s\n", >> ++ smb_fname.base_name)); >> ++ TALLOC_FREE(smb_fname.base_name); >> ++ return false; >> ++ } >> ++ TALLOC_FREE(smb_fname.base_name); >> ++ return true; >> ++} >> ++ >> + static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname) >> + { >> + SHADOW2_NEXT(RMDIR, (handle, name), int, -1); >> +@@ -877,6 +916,7 @@ static int >> shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, >> + SMB_STRUCT_DIRENT *d; >> + TALLOC_CTX *tmp_ctx = talloc_new(handle->data); >> + char *snapshot; >> ++ bool ret; >> + >> + snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle); >> + if (snapdir == NULL) { >> +@@ -886,6 +926,13 @@ static int >> shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, >> + talloc_free(tmp_ctx); >> + return -1; >> + } >> ++ ret = check_access_snapdir(handle, snapdir); >> ++ if (!ret) { >> ++ DEBUG(0,("access denied on listing snapdir %s\n", snapdir)); >> ++ errno = EACCES; >> ++ talloc_free(tmp_ctx); >> ++ return -1; >> ++ } >> + >> + p = SMB_VFS_NEXT_OPENDIR(handle, snapdir, NULL, 0); >> + >> +-- >> +2.5.0 >> + > ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Security updates for samba 3.6.25 2017-05-29 18:30 ` Matthias Fischer @ 2017-05-29 21:07 ` Michael Tremer 0 siblings, 0 replies; 4+ messages in thread From: Michael Tremer @ 2017-05-29 21:07 UTC (permalink / raw) To: development [-- Attachment #1: Type: text/plain, Size: 81820 bytes --] Perfect! Thank you! -Michael On Mon, 2017-05-29 at 20:30 +0200, Matthias Fischer wrote: > On 29.05.2017 18:57, Michael Tremer wrote: > > Hi, > > Hi, > > > thank you for working on this. > > No problem - had fun... ;-) > > > Yes, Arne submitted a patch that at least fixes the security > > vulnerability. > > > > However, could you split this patch into two with the two remaining > > changes so > > that we can merge those? > > Done. I pushed the - hopefully last - remaining patches. > > Best, > Matthias > > > Best, > > -Michael > > > > On Sun, 2017-05-28 at 11:22 +0200, Matthias Fischer wrote: > > > Based on: > > > > > > https://anonscm.debian.org/cgit/pkg-samba/samba.git/commit/?h=whe > > > ezy&id=762a3a > > > fd8eb45526e44cd0b2ae8a5b1a058ec647 > > > > > > https://www.samba.org/samba/history/security.html > > > > > > https://www.samba.org/samba/samba/ftp/patches/security/ > > > > > > Fixes current CVE-2017-7494 and some more... > > > > > > Removed three 'unrecognized' configure-options. > > > > > > Some 'lfs'-tuning was made, too. > > > > > > I altered 'PAK_VER' from "64" to "65" - if not necessary, please > > > change back. > > > > > > Best, > > > Matthias > > > > > > Signed-off-by: Matthias Fischer <matthias.fischer(a)ipfire.org> > > > --- > > > lfs/samba | 22 +- > > > .../samba/CVE-2017-2619-race-condition-fix.patch | 1150 > > > ++++++++++++++++++++ > > > .../CVE-2017-2619-regression-bug-12721-fix.patch | 179 +++ > > > src/patches/samba/CVE-2017-2619-tests.patch | 296 +++++ > > > src/patches/samba/samba-3.6.25-CVE-2017-7494.patch | 14 + > > > .../samba/samba-3.6.25-security-2015-12-16.patch | 255 +++++ > > > 6 files changed, 1909 insertions(+), 7 deletions(-) > > > create mode 100644 src/patches/samba/CVE-2017-2619-race- > > > condition-fix.patch > > > create mode 100644 src/patches/samba/CVE-2017-2619-regression- > > > bug-12721- > > > fix.patch > > > create mode 100644 src/patches/samba/CVE-2017-2619-tests.patch > > > create mode 100644 src/patches/samba/samba-3.6.25-CVE-2017- > > > 7494.patch > > > create mode 100644 src/patches/samba/samba-3.6.25-security-2015- > > > 12-16.patch > > > > > > diff --git a/lfs/samba b/lfs/samba > > > index 076152f48..445646464 100644 > > > --- a/lfs/samba > > > +++ b/lfs/samba > > > @@ -1,7 +1,7 @@ > > > ################################################################ > > > ############# > > > ## > > > # > > > > > > # > > > # IPFire.org - A linux based > > > firewall # > > > -# Copyright (C) 2007-2016 IPFire Team <info(a)ipfire.org> > > > > > > # > > > +# Copyright (C) 2007-2017 IPFire Team <info(a)ipfire.org> > > > > > > # > > > # > > > > > > # > > > # 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 # > > > @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) > > > DIR_APP = $(DIR_SRC)/$(THISAPP) > > > TARGET = $(DIR_INFO)/$(THISAPP) > > > PROG = samba > > > -PAK_VER = 64 > > > +PAK_VER = 65 > > > > > > DEPS = "cups krb5" > > > > > > @@ -54,7 +54,7 @@ download :$(patsubst %,$(DIR_DL)/%,$(objects)) > > > > > > md5 : $(subst %,%_MD5,$(objects)) > > > > > > -dist: > > > +dist: > > > @$(PAK) > > > > > > ################################################################ > > > ############# > > > ## > > > @@ -88,6 +88,17 @@ $(TARGET) : $(patsubst > > > %,$(DIR_DL)/%,$(objects)) > > > cd $(DIR_APP) && patch -Np1 < > > > $(DIR_SRC)/src/patches/samba/CVE-2016- > > > 2118-v3-6.patch > > > cd $(DIR_APP) && patch -Np1 < > > > $(DIR_SRC)/src/patches/samba/CVE-2015- > > > 5370-v3-6.patch > > > > > > + # Apply Debian CVE patches > > > + cd $(DIR_APP) && patch -Np1 < > > > $(DIR_SRC)/src/patches/samba/CVE-2017- > > > 2619-race-condition-fix.patch > > > + cd $(DIR_APP) && patch -Np1 < > > > $(DIR_SRC)/src/patches/samba/CVE-2017- > > > 2619-regression-bug-12721-fix.patch > > > + cd $(DIR_APP) && patch -Np1 < > > > $(DIR_SRC)/src/patches/samba/CVE-2017- > > > 2619-tests.patch > > > + > > > + # Fixes CVE-2015-5252 - Samba > > > + cd $(DIR_APP) && patch -Np1 < > > > $(DIR_SRC)/src/patches/samba/samba- > > > 3.6.25-security-2015-12-16.patch > > > + > > > + # Fixes CVE-2017-7494 - Samba > > > + cd $(DIR_APP) && patch -Np0 < > > > $(DIR_SRC)/src/patches/samba/samba- > > > 3.6.25-CVE-2017-7494.patch > > > + > > > cd $(DIR_APP)/source3 && ./autogen.sh > > > cd $(DIR_APP)/source3 && ./configure \ > > > --prefix=/usr \ > > > @@ -102,10 +113,7 @@ $(TARGET) : $(patsubst > > > %,$(DIR_DL)/%,$(objects)) > > > --with-libsmbclient \ > > > --with-libsmbsharemodes \ > > > --with-sendfile-support \ > > > - --without-smbwrapper \ > > > - --with-mmap \ > > > --with-fhs \ > > > - --with-vfs \ > > > --with-winbind \ > > > --disable-swat \ > > > --enable-cups \ > > > @@ -119,8 +127,8 @@ $(TARGET) : $(patsubst > > > %,$(DIR_DL)/%,$(objects)) > > > #cd $(DIR_APP)/source3 && install -v -m755 > > > nsswitch/libnss_winbind.so > > > /lib > > > #cd $(DIR_APP)/source3 && ln -v -sf libnss_winbind.so > > > /lib/libnss_winbind.so.2 > > > #cd $(DIR_APP)/source3 && ln -v -sf libnss_wins.so > > > /lib/libnss_wins.so.2 > > > + -mkdir -p /var/ipfire/samba > > > cd $(DIR_APP)/source3 && install -v -m644 > > > ../examples/smb.conf.default /var/ipfire/samba > > > - -mkdir -p /var/ipfire/samba > > > cp -vrf $(DIR_SRC)/config/samba/* /var/ipfire/samba/ > > > chown nobody:nobody -R /var/ipfire/samba/ > > > cp -vfp /var/ipfire/samba/default.global > > > /var/ipfire/samba/global > > > diff --git a/src/patches/samba/CVE-2017-2619-race-condition- > > > fix.patch > > > b/src/patches/samba/CVE-2017-2619-race-condition-fix.patch > > > new file mode 100644 > > > index 000000000..a96d6be3b > > > --- /dev/null > > > +++ b/src/patches/samba/CVE-2017-2619-race-condition-fix.patch > > > @@ -0,0 +1,1150 @@ > > > +Description: This patch is a consolidation of several patches > > > described by > > > the Git commit summaries below > > > +Bug-Debian-Security: https://security-tracker.debian.org/tracker > > > /CVE-2017-261 > > > 9 > > > +bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +From ec1bca1d5315549e945c93cbf5e3abdb695de782 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 20 Mar 2017 11:32:19 -0700 > > > +Subject: [PATCH 01/15] CVE-2017-2619: s3/smbd: re-open directory > > > after > > > + dptr_CloseDir() > > > + > > > +dptr_CloseDir() will close and invalidate the fsp's file > > > descriptor, we > > > +have to reopen it. > > > + > > > +Bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Ralph Bohme <slow(a)samba.org> > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/open.c | 2 +- > > > + source3/smbd/proto.h | 2 ++ > > > + source3/smbd/smb2_find.c | 17 +++++++++++++++++ > > > + 3 files changed, 20 insertions(+), 1 deletion(-) > > > + > > > +From 2bb9a3d35f6a0cc43a30638594969c4860ffd5a5 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Tue, 28 Feb 2017 09:24:07 -0800 > > > +Subject: [PATCH 02/15] s3: vfs: dirsort doesn't handle opendir > > > of "." > > > + correctly. > > > + > > > +Needs to store $cwd path for correct sorting. > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12499 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/modules/vfs_dirsort.c | 4 ++++ > > > + 1 file changed, 4 insertions(+) > > > + > > > +From 327d09ba641046f68daa5b2bb98f09530294cb0d Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 13 Mar 2017 13:44:42 -0700 > > > +Subject: [PATCH 03/15] s3: VFS: vfs_streams_xattr.c: Make > > > streams_xattr_open() > > > + store the same path as streams_xattr_recheck(). > > > + > > > +If the open is changing directories, fsp->fsp_name->base_name > > > +will be the full path from the share root, whilst > > > +smb_fname will be relative to the $cwd. > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12546 > > > + > > > +Back-ported from a24ba3e4083200ec9885363efc5769f43183fb6b > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/modules/vfs_streams_xattr.c | 9 ++++++++- > > > + 1 file changed, 8 insertions(+), 1 deletion(-) > > > + > > > +From 27871d3bfb0857ad3306aabdce6f9b55e32fff3d Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 13 Mar 2017 13:54:04 -0700 > > > +Subject: [PATCH 04/15] vfs_streams_xattr: use fsp, not base_fsp > > > + > > > +The base_fsp's fd is always -1 as it's closed after being > > > openend in > > > +create_file_unixpath(). > > > + > > > +Additionally in streams_xattr_open force using of > > > SMB_VFS_FSETXATTR() by > > > +sticking the just created fd into the fsp (and removing it > > > afterwards). > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12591 > > > + > > > +Back-ported from 021189e32ba507832b5e821e5cda8a2889225955. > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/modules/vfs_streams_xattr.c | 205 +++++++++++++++++-- > > > --------------- > > > -- > > > + 1 file changed, 99 insertions(+), 106 deletions(-) > > > + > > > +From a419b277c5994459c956ebdd324679e728ebae10 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 19 Dec 2016 11:55:56 -0800 > > > +Subject: [PATCH 05/15] s3: smbd: Create wrapper function for > > > OpenDir in > > > + preparation for making robust. > > > + > > > +CVE-2017-2619 > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/dir.c | 15 ++++++++++++++- > > > + 1 file changed, 14 insertions(+), 1 deletion(-) > > > + > > > +From e47e3c40b5fc8f52fe70c3e1edf5489ac8b4badf Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 19 Dec 2016 16:25:26 -0800 > > > +Subject: [PATCH 06/15] s3: smbd: Opendir_internal() early return > > > if > > > + SMB_VFS_OPENDIR failed. > > > + > > > +CVE-2017-2619 > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/dir.c | 14 +++++++------- > > > + 1 file changed, 7 insertions(+), 7 deletions(-) > > > + > > > +From 45e41b709b6c2e67acb99f29aa05b61b53091e57 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 19 Dec 2016 16:35:00 -0800 > > > +Subject: [PATCH 07/15] s3: smbd: Create and use > > > open_dir_safely(). Use from > > > + OpenDir(). > > > + > > > +Hardens OpenDir against TOC/TOU races. > > > + > > > +CVE-2017-2619 > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/dir.c | 66 > > > ++++++++++++++++++++++++++++++++++++++++++++++++-- > > > ---- > > > + 1 file changed, 59 insertions(+), 7 deletions(-) > > > + > > > +From 720abcec65b04fdac1052a14898180c8cc816464 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 19 Dec 2016 12:13:20 -0800 > > > +Subject: [PATCH 08/15] s3: smbd: OpenDir_fsp() use early > > > returns. > > > + > > > +CVE-2017-2619 > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/dir.c | 34 +++++++++++++++++++++------------- > > > + 1 file changed, 21 insertions(+), 13 deletions(-) > > > + > > > +From 5070f319bbb7dda87766621a83691910414d06a1 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 19 Dec 2016 12:15:59 -0800 > > > +Subject: [PATCH 09/15] s3: smbd: OpenDir_fsp() - Fix memory leak > > > on error. > > > + > > > +CVE-2017-2619 > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/dir.c | 2 +- > > > + 1 file changed, 1 insertion(+), 1 deletion(-) > > > + > > > +From 65d37759f8b4979bc0c0833e0a5eecd277dfa604 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 19 Dec 2016 12:32:07 -0800 > > > +Subject: [PATCH 10/15] s3: smbd: Move the reference counting and > > > destructor > > > + setup to just before retuning success. > > > + > > > +CVE-2017-2619 > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/dir.c | 10 +++++----- > > > + 1 file changed, 5 insertions(+), 5 deletions(-) > > > + > > > +From 5a821d791aba90643ddf7a3c29dad4f6621ef185 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 19 Dec 2016 12:35:32 -0800 > > > +Subject: [PATCH 11/15] s3: smbd: Correctly fallback to > > > open_dir_safely if > > > + FDOPENDIR not supported on system. > > > + > > > +CVE-2017-2619 > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/dir.c | 15 +++++++-------- > > > + 1 file changed, 7 insertions(+), 8 deletions(-) > > > + > > > +From 597aa3b99a2790133a4839260607b0a8df41c8e3 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Thu, 15 Dec 2016 12:52:13 -0800 > > > +Subject: [PATCH 12/15] s3: smbd: Remove O_NOFOLLOW guards. We > > > insist on > > > + O_NOFOLLOW existing. > > > + > > > +CVE-2017-2619 > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/open.c | 4 +--- > > > + 1 file changed, 1 insertion(+), 3 deletions(-) > > > + > > > +From 563af2ffec05a2c0b54897e2d28ac7e1adb66e0f Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Thu, 15 Dec 2016 12:56:08 -0800 > > > +Subject: [PATCH 13/15] s3: smbd: Move special handling of > > > symlink errno's > > > into > > > + a utility function. > > > + > > > +CVE-2017-2619 > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/open.c | 30 ++++++++++++++++++++++++++++-- > > > + 1 file changed, 28 insertions(+), 2 deletions(-) > > > + > > > +From b34a67cd3a996804ba7bf90e86cf9e22edf60eb3 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Thu, 15 Dec 2016 13:04:46 -0800 > > > +Subject: [PATCH 14/15] s3: smbd: Add the core functions to > > > prevent symlink > > > + open races. > > > + > > > +CVE-2017-2619 > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/open.c | 242 > > > ++++++++++++++++++++++++++++++++++++++++++++++++++++ > > > + 1 file changed, 242 insertions(+) > > > + > > > +From 5920309d2f62dd24fc50530c92dd68077f96a6d2 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Thu, 15 Dec 2016 13:06:31 -0800 > > > +Subject: [PATCH 15/15] s3: smbd: Use the new non_widelink_open() > > > function. > > > + > > > +CVE-2017-2619 > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/smbd/open.c | 23 ++++++++++++++++++++++- > > > + 1 file changed, 22 insertions(+), 1 deletion(-) > > > + > > > + > > > +--- samba-3.6.6.orig/source3/smbd/open.c > > > ++++ samba-3.6.6/source3/smbd/open.c > > > +@@ -187,10 +187,277 @@ > > > + } > > > + > > > + > > > /**************************************************************** > > > ************ > > > ++ Handle differing symlink errno's > > > ++*************************************************************** > > > ************* > > > / > > > ++ > > > ++static int link_errno_convert(int err) > > > ++{ > > > ++#if defined(ENOTSUP) && defined(OSF1) > > > ++ /* handle special Tru64 errno */ > > > ++ if (err == ENOTSUP) { > > > ++ err = ELOOP; > > > ++ } > > > ++#endif /* ENOTSUP */ > > > ++#ifdef EFTYPE > > > ++ /* fix broken NetBSD errno */ > > > ++ if (err == EFTYPE) { > > > ++ err = ELOOP; > > > ++ } > > > ++#endif /* EFTYPE */ > > > ++ /* fix broken FreeBSD errno */ > > > ++ if (err == EMLINK) { > > > ++ err = ELOOP; > > > ++ } > > > ++ return err; > > > ++} > > > ++ > > > ++static int non_widelink_open(struct connection_struct *conn, > > > ++ const char *conn_rootdir, > > > ++ files_struct *fsp, > > > ++ struct smb_filename *smb_fname, > > > ++ int flags, > > > ++ mode_t mode, > > > ++ unsigned int link_depth); > > > ++ > > > ++/************************************************************** > > > ************* > > > * > > > ++ Follow a symlink in userspace. > > > ++*************************************************************** > > > ************* > > > / > > > ++ > > > ++static int process_symlink_open(struct connection_struct *conn, > > > ++ const char *conn_rootdir, > > > ++ files_struct *fsp, > > > ++ struct smb_filename *smb_fname, > > > ++ int flags, > > > ++ mode_t mode, > > > ++ unsigned int link_depth) > > > ++{ > > > ++ int fd = -1; > > > ++ char *link_target = NULL; > > > ++ int link_len = -1; > > > ++ char *oldwd = NULL; > > > ++ size_t rootdir_len = 0; > > > ++ char *resolved_name = NULL; > > > ++ bool matched = false; > > > ++ int saved_errno = 0; > > > ++ > > > ++ /* > > > ++ * Ensure we don't get stuck in a symlink loop. > > > ++ */ > > > ++ link_depth++; > > > ++ if (link_depth >= 20) { > > > ++ errno = ELOOP; > > > ++ goto out; > > > ++ } > > > ++ > > > ++ /* Allocate space for the link target. */ > > > ++ link_target = talloc_array(talloc_tos(), char, > > > PATH_MAX); > > > ++ if (link_target == NULL) { > > > ++ errno = ENOMEM; > > > ++ goto out; > > > ++ } > > > ++ > > > ++ /* Read the link target. */ > > > ++ link_len = SMB_VFS_READLINK(conn, > > > ++ smb_fname->base_name, > > > ++ link_target, > > > ++ PATH_MAX - 1); > > > ++ if (link_len == -1) { > > > ++ goto out; > > > ++ } > > > ++ > > > ++ /* Ensure it's at least null terminated. */ > > > ++ link_target[link_len] = '\0'; > > > ++ > > > ++ /* Convert to an absolute path. */ > > > ++ resolved_name = SMB_VFS_REALPATH(conn, link_target); > > > ++ if (resolved_name == NULL) { > > > ++ goto out; > > > ++ } > > > ++ > > > ++ /* > > > ++ * We know conn_rootdir starts with '/' and > > > ++ * does not end in '/'. FIXME ! Should we > > > ++ * smb_assert this ? > > > ++ */ > > > ++ rootdir_len = strlen(conn_rootdir); > > > ++ > > > ++ matched = (strncmp(conn_rootdir, resolved_name, > > > rootdir_len) == 0); > > > ++ if (!matched) { > > > ++ errno = EACCES; > > > ++ goto out; > > > ++ } > > > ++ > > > ++ /* > > > ++ * Turn into a path relative to the share root. > > > ++ */ > > > ++ if (resolved_name[rootdir_len] == '\0') { > > > ++ /* Link to the root of the share. */ > > > ++ smb_fname->base_name = > > > talloc_strdup(talloc_tos(), "."); > > > ++ if (smb_fname->base_name == NULL) { > > > ++ errno = ENOMEM; > > > ++ goto out; > > > ++ } > > > ++ } else if (resolved_name[rootdir_len] == '/') { > > > ++ smb_fname->base_name = > > > &resolved_name[rootdir_len+1]; > > > ++ } else { > > > ++ errno = EACCES; > > > ++ goto out; > > > ++ } > > > ++ > > > ++ oldwd = vfs_GetWd(talloc_tos(), conn); > > > ++ if (oldwd == NULL) { > > > ++ goto out; > > > ++ } > > > ++ > > > ++ /* Ensure we operate from the root of the share. */ > > > ++ if (vfs_ChDir(conn, conn_rootdir) == -1) { > > > ++ goto out; > > > ++ } > > > ++ > > > ++ /* And do it all again.. */ > > > ++ fd = non_widelink_open(conn, > > > ++ conn_rootdir, > > > ++ fsp, > > > ++ smb_fname, > > > ++ flags, > > > ++ mode, > > > ++ link_depth); > > > ++ if (fd == -1) { > > > ++ saved_errno = errno; > > > ++ } > > > ++ > > > ++ out: > > > ++ > > > ++ SAFE_FREE(resolved_name); > > > ++ TALLOC_FREE(link_target); > > > ++ if (oldwd != NULL) { > > > ++ int ret = vfs_ChDir(conn, oldwd); > > > ++ if (ret == -1) { > > > ++ smb_panic("unable to get back to old > > > directory\n"); > > > ++ } > > > ++ TALLOC_FREE(oldwd); > > > ++ } > > > ++ if (saved_errno != 0) { > > > ++ errno = saved_errno; > > > ++ } > > > ++ return fd; > > > ++} > > > ++ > > > ++/************************************************************** > > > ************* > > > * > > > ++ Non-widelink open. > > > ++*************************************************************** > > > ************* > > > / > > > ++ > > > ++static int non_widelink_open(struct connection_struct *conn, > > > ++ const char *conn_rootdir, > > > ++ files_struct *fsp, > > > ++ struct smb_filename *smb_fname, > > > ++ int flags, > > > ++ mode_t mode, > > > ++ unsigned int link_depth) > > > ++{ > > > ++ NTSTATUS status; > > > ++ int fd = -1; > > > ++ struct smb_filename *smb_fname_rel = NULL; > > > ++ int saved_errno = 0; > > > ++ char *oldwd = NULL; > > > ++ char *parent_dir = NULL; > > > ++ const char *final_component = NULL; > > > ++ > > > ++ if (!parent_dirname(talloc_tos(), > > > ++ smb_fname->base_name, > > > ++ &parent_dir, > > > ++ &final_component)) { > > > ++ goto out; > > > ++ } > > > ++ > > > ++ oldwd = vfs_GetWd(talloc_tos(), conn); > > > ++ if (oldwd == NULL) { > > > ++ goto out; > > > ++ } > > > ++ > > > ++ /* Pin parent directory in place. */ > > > ++ if (vfs_ChDir(conn, parent_dir) == -1) { > > > ++ goto out; > > > ++ } > > > ++ > > > ++ /* Ensure the relative path is below the share. */ > > > ++ status = check_reduced_name(conn, final_component); > > > ++ if (!NT_STATUS_IS_OK(status)) { > > > ++ saved_errno = map_errno_from_nt_status(status); > > > ++ goto out; > > > ++ } > > > ++ > > > ++ status = create_synthetic_smb_fname(talloc_tos(), > > > ++ final_component, > > > ++ smb_fname->stream_name, > > > ++ &smb_fname->st, > > > ++ &smb_fname_rel); > > > ++ if (!NT_STATUS_IS_OK(status)) { > > > ++ saved_errno = map_errno_from_nt_status(status); > > > ++ goto out; > > > ++ } > > > ++ > > > ++ flags |= O_NOFOLLOW; > > > ++ > > > ++ { > > > ++ struct smb_filename *tmp_name = fsp->fsp_name; > > > ++ fsp->fsp_name = smb_fname_rel; > > > ++ fd = SMB_VFS_OPEN(conn, smb_fname_rel, fsp, > > > flags, mode); > > > ++ fsp->fsp_name = tmp_name; > > > ++ } > > > ++ > > > ++ if (fd == -1) { > > > ++ saved_errno = link_errno_convert(errno); > > > ++ if (saved_errno == ELOOP) { > > > ++ if (fsp->posix_open) { > > > ++ /* Never follow symlinks on > > > posix open. */ > > > ++ goto out; > > > ++ } > > > ++ if (!lp_symlinks(SNUM(conn))) { > > > ++ /* Explicitly no symlinks. */ > > > ++ goto out; > > > ++ } > > > ++ /* > > > ++ * We have a symlink. Follow in > > > userspace > > > ++ * to ensure it's under the share > > > definition. > > > ++ */ > > > ++ fd = process_symlink_open(conn, > > > ++ conn_rootdir, > > > ++ fsp, > > > ++ smb_fname_rel, > > > ++ flags, > > > ++ mode, > > > ++ link_depth); > > > ++ if (fd == -1) { > > > ++ saved_errno = > > > ++ link_errno_convert(errn > > > o); > > > ++ } > > > ++ } > > > ++ } > > > ++ > > > ++ out: > > > ++ > > > ++ TALLOC_FREE(parent_dir); > > > ++ TALLOC_FREE(smb_fname_rel); > > > ++ > > > ++ if (oldwd != NULL) { > > > ++ int ret = vfs_ChDir(conn, oldwd); > > > ++ if (ret == -1) { > > > ++ smb_panic("unable to get back to old > > > directory\n"); > > > ++ } > > > ++ TALLOC_FREE(oldwd); > > > ++ } > > > ++ if (saved_errno != 0) { > > > ++ errno = saved_errno; > > > ++ } > > > ++ return fd; > > > ++} > > > ++ > > > ++/************************************************************** > > > ************* > > > * > > > + fd support routines - attempt to do a dos_open. > > > + > > > ***************************************************************** > > > ***********/ > > > + > > > +-static NTSTATUS fd_open(struct connection_struct *conn, > > > ++NTSTATUS fd_open(struct connection_struct *conn, > > > + files_struct *fsp, > > > + int flags, > > > + mode_t mode) > > > +@@ -198,8 +465,7 @@ > > > + struct smb_filename *smb_fname = fsp->fsp_name; > > > + NTSTATUS status = NT_STATUS_OK; > > > + > > > +-#ifdef O_NOFOLLOW > > > +- /* > > > ++ /* > > > + * Never follow symlinks on a POSIX client. The > > > + * client should be doing this. > > > + */ > > > +@@ -207,12 +473,33 @@ > > > + if (fsp->posix_open || !lp_symlinks(SNUM(conn))) { > > > + flags |= O_NOFOLLOW; > > > + } > > > +-#endif > > > + > > > +- fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, > > > mode); > > > ++ /* Ensure path is below share definition. */ > > > ++ if (!lp_widelinks(SNUM(conn))) { > > > ++ const char *conn_rootdir = > > > SMB_VFS_CONNECTPATH(conn, > > > ++ smb_fname- > > > >base_name); > > > ++ if (conn_rootdir == NULL) { > > > ++ return NT_STATUS_NO_MEMORY; > > > ++ } > > > ++ /* > > > ++ * Only follow symlinks within a share > > > ++ * definition. > > > ++ */ > > > ++ fsp->fh->fd = non_widelink_open(conn, > > > ++ conn_rootdir, > > > ++ fsp, > > > ++ smb_fname, > > > ++ flags, > > > ++ mode, > > > ++ 0); > > > ++ } else { > > > ++ fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, > > > fsp, flags, > > > mode); > > > ++ } > > > ++ > > > + if (fsp->fh->fd == -1) { > > > +- status = map_nt_error_from_unix(errno); > > > +- if (errno == EMFILE) { > > > ++ int posix_errno = link_errno_convert(errno); > > > ++ status = map_nt_error_from_unix(posix_errno); > > > ++ if (posix_errno == EMFILE) { > > > + static time_t last_warned = 0L; > > > + > > > + if (time((time_t *) NULL) > > > > last_warned) { > > > +--- samba-3.6.6.orig/source3/smbd/proto.h > > > ++++ samba-3.6.6/source3/smbd/proto.h > > > +@@ -592,6 +592,8 @@ > > > + const struct security_token > > > *token, > > > + uint32_t access_desired, > > > + uint32_t *access_granted); > > > ++NTSTATUS fd_open(struct connection_struct *conn, files_struct > > > *fsp, > > > ++ int flags, mode_t mode); > > > + NTSTATUS fd_close(files_struct *fsp); > > > + void change_file_owner_to_parent(connection_struct *conn, > > > + const char *inherit_from_dir, > > > +--- samba-3.6.6.orig/source3/smbd/smb2_find.c > > > ++++ samba-3.6.6/source3/smbd/smb2_find.c > > > +@@ -24,6 +24,7 @@ > > > + #include "../libcli/smb/smb_common.h" > > > + #include "trans2.h" > > > + #include "../lib/util/tevent_ntstatus.h" > > > ++#include "system/filesys.h" > > > + > > > + static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX > > > *mem_ctx, > > > + struct > > > tevent_context *ev, > > > +@@ -300,7 +301,23 @@ > > > + } > > > + > > > + if (in_flags & SMB2_CONTINUE_FLAG_REOPEN) { > > > ++ int flags; > > > ++ > > > + dptr_CloseDir(fsp); > > > ++ > > > ++ /* > > > ++ * dptr_CloseDir() will close and invalidate > > > the fsp's file > > > ++ * descriptor, we have to reopen it. > > > ++ */ > > > ++ > > > ++ flags = O_RDONLY; > > > ++#ifdef O_DIRECTORY > > > ++ flags |= O_DIRECTORY; > > > ++#endif > > > ++ status = fd_open(conn, fsp, flags, 0); > > > ++ if (tevent_req_nterror(req, status)) { > > > ++ return tevent_req_post(req, ev); > > > ++ } > > > + } > > > + > > > + if (fsp->dptr == NULL) { > > > +--- samba-3.6.6.orig/source3/modules/vfs_dirsort.c > > > ++++ samba-3.6.6/source3/modules/vfs_dirsort.c > > > +@@ -141,6 +141,10 @@ > > > + return NULL; > > > + } > > > + > > > ++ if (ISDOT(data->smb_fname->base_name)) { > > > ++ data->smb_fname->base_name = vfs_GetWd(data, > > > handle->conn); > > > ++ } > > > ++ > > > + /* Open the underlying directory and count the number > > > of entries */ > > > + data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, > > > fname, mask, > > > + attr); > > > +--- samba-3.6.6.orig/source3/modules/vfs_streams_xattr.c > > > ++++ samba-3.6.6/source3/modules/vfs_streams_xattr.c > > > +@@ -229,7 +229,7 @@ > > > + return -1; > > > + } > > > + > > > +- sbuf->st_ex_size = get_xattr_size(handle->conn, fsp- > > > >base_fsp, > > > ++ sbuf->st_ex_size = get_xattr_size(handle->conn, fsp, > > > + io->base, io- > > > >xattr_name); > > > + if (sbuf->st_ex_size == -1) { > > > + return -1; > > > +@@ -364,6 +364,7 @@ > > > + char *xattr_name = NULL; > > > + int baseflags; > > > + int hostfd = -1; > > > ++ int ret; > > > + > > > + DEBUG(10, ("streams_xattr_open called for %s\n", > > > + smb_fname_str_dbg(smb_fname))); > > > +@@ -375,133 +376,125 @@ > > > + /* If the default stream is requested, just open the > > > base file. */ > > > + if (is_ntfs_default_stream_smb_fname(smb_fname)) { > > > + char *tmp_stream_name; > > > +- int ret; > > > + > > > + tmp_stream_name = smb_fname->stream_name; > > > + smb_fname->stream_name = NULL; > > > + > > > + ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, > > > flags, > > > mode); > > > + > > > +- smb_fname->stream_name = tmp_stream_name; > > > +- > > > +- return ret; > > > +- } > > > ++ smb_fname->stream_name = > > > tmp_stream_name; > > > + > > > +- status = streams_xattr_get_name(talloc_tos(), > > > smb_fname- > > > > stream_name, > > > > > > +- &xattr_name); > > > +- if (!NT_STATUS_IS_OK(status)) { > > > +- errno = map_errno_from_nt_status(status); > > > +- goto fail; > > > +- } > > > ++ return ret; > > > ++ } > > > + > > > +- /* Create an smb_filename with stream_name == NULL. */ > > > +- status = create_synthetic_smb_fname(talloc_tos(), > > > +- smb_fname- > > > >base_name, > > > +- NULL, NULL, > > > +- &smb_fname_base); > > > +- if (!NT_STATUS_IS_OK(status)) { > > > +- errno = map_errno_from_nt_status(status); > > > +- goto fail; > > > +- } > > > ++ status = streams_xattr_get_name(talloc_tos(), > > > smb_fname- > > > > stream_name, > > > > > > ++ &xattr_name); > > > ++ if (!NT_STATUS_IS_OK(status)) { > > > ++ errno = > > > map_errno_from_nt_status(status); > > > ++ goto fail; > > > ++ } > > > + > > > +- /* > > > +- * We use baseflags to turn off nasty side-effects when > > > opening the > > > +- * underlying file. > > > +- */ > > > +- baseflags = flags; > > > +- baseflags &= ~O_TRUNC; > > > +- baseflags &= ~O_EXCL; > > > +- baseflags &= ~O_CREAT; > > > +- > > > +- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, > > > fsp, > > > +- baseflags, mode); > > > +- > > > +- TALLOC_FREE(smb_fname_base); > > > +- > > > +- /* It is legit to open a stream on a directory, but the > > > base > > > +- * fd has to be read-only. > > > +- */ > > > +- if ((hostfd == -1) && (errno == EISDIR)) { > > > +- baseflags &= ~O_ACCMODE; > > > +- baseflags |= O_RDONLY; > > > +- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, > > > fsp, > > > baseflags, > > > +- mode); > > > +- } > > > ++ /* Create an smb_filename with stream_name == > > > NULL. */ > > > ++ status = > > > create_synthetic_smb_fname(talloc_tos(), > > > ++ smb_fname- > > > >base_name, > > > ++ NULL, NULL, > > > ++ &smb_fname_ > > > base); > > > ++ if (!NT_STATUS_IS_OK(status)) { > > > ++ errno = > > > map_errno_from_nt_status(status); > > > ++ goto fail; > > > ++ } > > > + > > > +- if (hostfd == -1) { > > > +- goto fail; > > > +- } > > > ++ /* > > > ++ * We use baseflags to turn off nasty side- > > > effects when > > > opening the > > > ++ * underlying file. > > > ++ */ > > > ++ baseflags = flags; > > > ++ baseflags &= ~O_TRUNC; > > > ++ baseflags &= ~O_EXCL; > > > ++ baseflags &= ~O_CREAT; > > > + > > > +- status = get_ea_value(talloc_tos(), handle->conn, NULL, > > > +- smb_fname->base_name, xattr_name, > > > &ea); > > > ++ hostfd = SMB_VFS_OPEN(handle->conn, > > > smb_fname_base, fsp, > > > ++ baseflags, mode); > > > + > > > +- DEBUG(10, ("get_ea_value returned %s\n", > > > nt_errstr(status))); > > > ++ TALLOC_FREE(smb_fname_base); > > > + > > > +- if (!NT_STATUS_IS_OK(status) > > > +- && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { > > > +- /* > > > +- * The base file is not there. This is an error > > > even if we > > > got > > > +- * O_CREAT, the higher levels should have > > > created the base > > > +- * file for us. > > > ++ /* It is legit to open a stream on a directory, > > > but the base > > > ++ * fd has to be read-only. > > > + */ > > > +- DEBUG(10, ("streams_xattr_open: base file %s > > > not around, " > > > +- "returning ENOENT\n", smb_fname- > > > >base_name)); > > > +- errno = ENOENT; > > > +- goto fail; > > > +- } > > > ++ if ((hostfd == -1) && (errno == EISDIR)) { > > > ++ baseflags &= ~O_ACCMODE; > > > ++ baseflags |= O_RDONLY; > > > ++ hostfd = SMB_VFS_OPEN(handle->conn, > > > smb_fname, fsp, > > > baseflags, > > > ++ mode); > > > ++ } > > > + > > > +- if (!NT_STATUS_IS_OK(status)) { > > > +- /* > > > +- * The attribute does not exist > > > +- */ > > > ++ if (hostfd == -1) { > > > ++ goto fail; > > > ++ } > > > ++ > > > ++ status = get_ea_value(talloc_tos(), handle- > > > >conn, NULL, > > > ++ smb_fname->base_name, > > > xattr_name, > > > &ea); > > > + > > > +- if (flags & O_CREAT) { > > > ++ DEBUG(10, ("get_ea_value returned %s\n", > > > nt_errstr(status))); > > > ++ > > > ++ if (!NT_STATUS_IS_OK(status) > > > ++ && !NT_STATUS_EQUAL(status, > > > NT_STATUS_NOT_FOUND)) { > > > + /* > > > +- * Darn, xattrs need at least 1 byte > > > ++ * The base file is not there. This is > > > an error even > > > if we got > > > ++ * O_CREAT, the higher levels should > > > have created > > > the base > > > ++ * file for us. > > > + */ > > > +- char null = '\0'; > > > ++ DEBUG(10, ("streams_xattr_open: base > > > file %s not > > > around, " > > > ++ "returning ENOENT\n", > > > smb_fname- > > > > base_name)); > > > > > > ++ errno = ENOENT; > > > ++ goto fail; > > > ++ } > > > + > > > +- DEBUG(10, ("creating attribute %s on > > > file %s\n", > > > +- xattr_name, smb_fname- > > > >base_name)); > > > ++ if (!NT_STATUS_IS_OK(status)) { > > > ++ /* > > > ++ * The attribute does not exist > > > ++ */ > > > + > > > ++ if (flags & O_CREAT) { > > > ++ /* > > > ++ * Darn, xattrs need at least 1 > > > byte > > > ++ */ > > > ++ char null = '\0'; > > > ++ > > > ++ DEBUG(10, ("creating attribute > > > %s on file > > > %s\n", > > > ++ xattr_name, > > > smb_fname- > > > > base_name)); > > > > > > ++ > > > ++ fsp->fh->fd = hostfd; > > > ++ ret = SMB_VFS_FSETXATTR(fsp, > > > xattr_name, > > > ++ &null, > > > sizeof(null), > > > ++ flags & O_EXCL > > > ? > > > XATTR_CREATE : 0); > > > ++ fsp->fh->fd = -1; > > > ++ if (ret != 0) { > > > ++ goto fail; > > > ++ } > > > ++ } > > > ++ } > > > ++ > > > ++ if (flags & O_TRUNC) { > > > ++ char null = '\0'; > > > + if (fsp->base_fsp->fh->fd != -1) { > > > +- if (SMB_VFS_FSETXATTR( > > > +- fsp->base_fsp, > > > xattr_name, > > > +- &null, sizeof(null), > > > +- flags & O_EXCL ? > > > XATTR_CREATE : 0) > > > == -1) { > > > ++ if (SMB_VFS_FSETXATTR( > > > ++ fsp->base_fsp, > > > xattr_name, > > > ++ &null, > > > sizeof(null), > > > ++ flags & O_EXCL > > > ? > > > XATTR_CREATE : 0) == -1) { > > > + goto fail; > > > + } > > > + } else { > > > +- if (SMB_VFS_SETXATTR( > > > +- handle->conn, > > > smb_fname->base_name, > > > +- xattr_name, &null, > > > sizeof(null), > > > +- flags & O_EXCL ? > > > XATTR_CREATE : 0) > > > == -1) { > > > ++ if (SMB_VFS_SETXATTR( > > > ++ handle->conn, > > > smb_fname- > > > > base_name, > > > > > > ++ xattr_name, > > > &null, > > > sizeof(null), > > > ++ flags & O_EXCL > > > ? > > > XATTR_CREATE : 0) == -1) { > > > + goto fail; > > > + } > > > + } > > > + } > > > +- } > > > +- > > > +- if (flags & O_TRUNC) { > > > +- char null = '\0'; > > > +- if (fsp->base_fsp->fh->fd != -1) { > > > +- if (SMB_VFS_FSETXATTR( > > > +- fsp->base_fsp, > > > xattr_name, > > > +- &null, sizeof(null), > > > +- flags & O_EXCL ? > > > XATTR_CREATE : 0) > > > == -1) { > > > +- goto fail; > > > +- } > > > +- } else { > > > +- if (SMB_VFS_SETXATTR( > > > +- handle->conn, > > > smb_fname->base_name, > > > +- xattr_name, &null, > > > sizeof(null), > > > +- flags & O_EXCL ? > > > XATTR_CREATE : 0) > > > == -1) { > > > +- goto fail; > > > +- } > > > +- } > > > +- } > > > + > > > +- sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, > > > fsp, > > > ++ sio = (struct stream_io > > > *)VFS_ADD_FSP_EXTENSION(handle, fsp, > > > + struct > > > stream_io, > > > + NULL); > > > + if (sio == NULL) { > > > +@@ -511,8 +504,15 @@ > > > + > > > + sio->xattr_name = > > > talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, > > > fsp), > > > + xattr_name); > > > ++ /* > > > ++ * sio->base needs to be a copy of fsp->fsp_name- > > > >base_name, > > > ++ * making it identical to streams_xattr_recheck(). If > > > the > > > ++ * open is changing directories, fsp->fsp_name- > > > >base_name > > > ++ * will be the full path from the share root, whilst > > > ++ * smb_fname will be relative to the $cwd. > > > ++ */ > > > + sio->base = > > > talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), > > > +- smb_fname->base_name); > > > ++ fsp->fsp_name->base_name); > > > + sio->fsp_name_ptr = fsp->fsp_name; > > > + sio->handle = handle; > > > + sio->fsp = fsp; > > > +@@ -861,7 +861,7 @@ > > > + return -1; > > > + } > > > + > > > +- status = get_ea_value(talloc_tos(), handle->conn, fsp- > > > >base_fsp, > > > ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, > > > + sio->base, sio->xattr_name, &ea); > > > + if (!NT_STATUS_IS_OK(status)) { > > > + return -1; > > > +@@ -885,13 +885,13 @@ > > > + > > > + memcpy(ea.value.data + offset, data, n); > > > + > > > +- if (fsp->base_fsp->fh->fd != -1) { > > > +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, > > > ++ if (fsp->fh->fd != -1) { > > > ++ ret = SMB_VFS_FSETXATTR(fsp, > > > + sio->xattr_name, > > > + ea.value.data, ea.value.length, > > > 0); > > > + } else { > > > + ret = SMB_VFS_SETXATTR(fsp->conn, > > > +- fsp->base_fsp->fsp_name- > > > >base_name, > > > ++ fsp->fsp_name- > > > >base_name, > > > + sio->xattr_name, > > > + ea.value.data, ea.value.length, > > > 0); > > > + } > > > +@@ -925,7 +925,7 @@ > > > + return -1; > > > + } > > > + > > > +- status = get_ea_value(talloc_tos(), handle->conn, fsp- > > > >base_fsp, > > > ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, > > > + sio->base, sio->xattr_name, &ea); > > > + if (!NT_STATUS_IS_OK(status)) { > > > + return -1; > > > +@@ -970,7 +970,7 @@ > > > + return -1; > > > + } > > > + > > > +- status = get_ea_value(talloc_tos(), handle->conn, fsp- > > > >base_fsp, > > > ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, > > > + sio->base, sio->xattr_name, &ea); > > > + if (!NT_STATUS_IS_OK(status)) { > > > + return -1; > > > +@@ -995,13 +995,13 @@ > > > + ea.value.length = offset + 1; > > > + ea.value.data[offset] = 0; > > > + > > > +- if (fsp->base_fsp->fh->fd != -1) { > > > +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, > > > ++ if (fsp->fh->fd != -1) { > > > ++ ret = SMB_VFS_FSETXATTR(fsp, > > > + sio->xattr_name, > > > + ea.value.data, ea.value.length, > > > 0); > > > + } else { > > > + ret = SMB_VFS_SETXATTR(fsp->conn, > > > +- fsp->base_fsp->fsp_name- > > > >base_name, > > > ++ fsp->fsp_name->base_name, > > > + sio->xattr_name, > > > + ea.value.data, ea.value.length, > > > 0); > > > + } > > > +--- samba-3.6.6.orig/source3/smbd/dir.c > > > ++++ samba-3.6.6/source3/smbd/dir.c > > > +@@ -1358,7 +1358,8 @@ > > > + Open a directory. > > > + > > > ***************************************************************** > > > ***/ > > > + > > > +-struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct > > > *conn, > > > ++static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, > > > ++ connection_struct *conn, > > > + const char *name, > > > + const char *mask, > > > + uint32 attr) > > > +@@ -1370,27 +1371,21 @@ > > > + return NULL; > > > + } > > > + > > > +- dirp->conn = conn; > > > +- dirp->name_cache_size = > > > lp_directory_name_cache_size(SNUM(conn)); > > > +- > > > +- dirp->dir_path = talloc_strdup(dirp, name); > > > +- if (!dirp->dir_path) { > > > +- errno = ENOMEM; > > > ++ dirp->dir = SMB_VFS_OPENDIR(conn, name, mask, attr); > > > ++ if (!dirp->dir) { > > > ++ DEBUG(5,("OpenDir: Can't open %s. %s\n", name, > > > ++ strerror(errno) )); > > > + goto fail; > > > + } > > > + > > > ++ dirp->conn = conn; > > > ++ dirp->name_cache_size = > > > lp_directory_name_cache_size(SNUM(conn)); > > > ++ > > > + if (sconn && !sconn->using_smb2) { > > > + sconn->searches.dirhandles_open++; > > > + } > > > + talloc_set_destructor(dirp, smb_Dir_destructor); > > > + > > > +- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, > > > attr); > > > +- if (!dirp->dir) { > > > +- DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp- > > > >dir_path, > > > +- strerror(errno) )); > > > +- goto fail; > > > +- } > > > +- > > > + return dirp; > > > + > > > + fail: > > > +@@ -1398,6 +1393,76 @@ > > > + return NULL; > > > + } > > > + > > > ++/************************************************************** > > > ************* > > > * > > > ++ Open a directory handle by pathname, ensuring it's under the > > > share path. > > > ++*************************************************************** > > > ************* > > > / > > > ++ > > > ++static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx, > > > ++ connection_struct > > > *conn, > > > ++ const char *name, > > > ++ const char *wcard, > > > ++ uint32_t attr) > > > ++{ > > > ++ struct smb_Dir *dir_hnd = NULL; > > > ++ char *saved_dir = vfs_GetWd(ctx, conn); > > > ++ NTSTATUS status; > > > ++ > > > ++ if (saved_dir == NULL) { > > > ++ return NULL; > > > ++ } > > > ++ > > > ++ if (vfs_ChDir(conn, name) == -1) { > > > ++ goto out; > > > ++ } > > > ++ > > > ++ /* > > > ++ * Now the directory is pinned, use > > > ++ * REALPATH to ensure we can access it. > > > ++ */ > > > ++ status = check_name(conn, "."); > > > ++ if (!NT_STATUS_IS_OK(status)) { > > > ++ goto out; > > > ++ } > > > ++ > > > ++ dir_hnd = OpenDir_internal(ctx, > > > ++ conn, > > > ++ ".", > > > ++ wcard, > > > ++ attr); > > > ++ > > > ++ if (dir_hnd == NULL) { > > > ++ goto out; > > > ++ } > > > ++ > > > ++ /* > > > ++ * OpenDir_internal only gets "." as the dir name. > > > ++ * Store the real dir name here. > > > ++ */ > > > ++ > > > ++ dir_hnd->dir_path = talloc_strdup(dir_hnd, name); > > > ++ if (!dir_hnd->dir_path) { > > > ++ errno = ENOMEM; > > > ++ } > > > ++ > > > ++ out: > > > ++ > > > ++ vfs_ChDir(conn, saved_dir); > > > ++ TALLOC_FREE(saved_dir); > > > ++ return dir_hnd; > > > ++} > > > ++ > > > ++struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct > > > *conn, > > > ++ const char *name, > > > ++ const char *mask, > > > ++ uint32_t attr) > > > ++{ > > > ++ return open_dir_safely(mem_ctx, > > > ++ conn, > > > ++ name, > > > ++ mask, > > > ++ attr); > > > ++} > > > ++ > > > + > > > /**************************************************************** > > > *** > > > + Open a directory from an fsp. > > > + > > > ***************************************************************** > > > ***/ > > > +@@ -1411,7 +1476,17 @@ > > > + struct smbd_server_connection *sconn = conn->sconn; > > > + > > > + if (!dirp) { > > > +- return NULL; > > > ++ goto fail; > > > ++ } > > > ++ > > > ++ if (!fsp->is_directory) { > > > ++ errno = EBADF; > > > ++ goto fail; > > > ++ } > > > ++ > > > ++ if (fsp->fh->fd == -1) { > > > ++ errno = EBADF; > > > ++ goto fail; > > > + } > > > + > > > + dirp->conn = conn; > > > +@@ -1423,36 +1498,33 @@ > > > + goto fail; > > > + } > > > + > > > +- if (sconn && !sconn->using_smb2) { > > > +- sconn->searches.dirhandles_open++; > > > +- } > > > +- talloc_set_destructor(dirp, smb_Dir_destructor); > > > +- > > > +- if (fsp->is_directory && fsp->fh->fd != -1) { > > > +- dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); > > > +- if (dirp->dir != NULL) { > > > +- dirp->fsp = fsp; > > > +- } else { > > > +- DEBUG(10,("OpenDir_fsp: > > > SMB_VFS_FDOPENDIR on %s > > > returned " > > > +- "NULL (%s)\n", > > > +- dirp->dir_path, > > > +- strerror(errno))); > > > +- if (errno != ENOSYS) { > > > +- return NULL; > > > +- } > > > ++ dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); > > > ++ if (dirp->dir != NULL) { > > > ++ dirp->fsp = fsp; > > > ++ } else { > > > ++ DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s > > > returned " > > > ++ "NULL (%s)\n", > > > ++ dirp->dir_path, > > > ++ strerror(errno))); > > > ++ if (errno != ENOSYS) { > > > ++ goto fail; > > > + } > > > + } > > > + > > > + if (dirp->dir == NULL) { > > > +- /* FDOPENDIR didn't work. Use OPENDIR instead. > > > */ > > > +- dirp->dir = SMB_VFS_OPENDIR(conn, dirp- > > > >dir_path, mask, > > > attr); > > > ++ /* FDOPENDIR is not supported. Use OPENDIR > > > instead. */ > > > ++ TALLOC_FREE(dirp); > > > ++ return open_dir_safely(mem_ctx, > > > ++ conn, > > > ++ fsp->fsp_name- > > > >base_name, > > > ++ mask, > > > ++ attr); > > > + } > > > + > > > +- if (!dirp->dir) { > > > +- DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", > > > dirp->dir_path, > > > +- strerror(errno) )); > > > +- goto fail; > > > ++ if (sconn && !sconn->using_smb2) { > > > ++ sconn->searches.dirhandles_open++; > > > + } > > > ++ talloc_set_destructor(dirp, smb_Dir_destructor); > > > + > > > + return dirp; > > > + > > > diff --git a/src/patches/samba/CVE-2017-2619-regression-bug- > > > 12721-fix.patch > > > b/src/patches/samba/CVE-2017-2619-regression-bug-12721-fix.patch > > > new file mode 100644 > > > index 000000000..cefdd86ea > > > --- /dev/null > > > +++ b/src/patches/samba/CVE-2017-2619-regression-bug-12721- > > > fix.patch > > > @@ -0,0 +1,179 @@ > > > +bug: https://bugzilla.samba.org/show_bug.cgi?id=12721 > > > +Description: This patch is a consolidation of several patches > > > described by > > > the Git commit summaries below > > > + > > > +From 5d4ef6ff0970c93fed49e51a01e63cb67d49d087 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 27 Mar 2017 10:46:47 -0700 > > > +Subject: [PATCH 1/3] s3: smbd: Fix incorrect logic exposed by > > > fix for the > > > + security bug 12496 (CVE-2017-2619). > > > + > > > +In a UNIX filesystem, the names "." and ".." by definition can > > > *never* > > > +be symlinks - they are already reserved names. > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +Reviewed-by: Uri Simchoni <uri(a)samba.org> > > > +(cherry picked from commit > > > ae17bebd250bdde5614b2ac17e53512f19fe9b68) > > > +--- > > > + source3/smbd/vfs.c | 7 +++++-- > > > + 1 file changed, 5 insertions(+), 2 deletions(-) > > > + > > > +From 71500662d1098d17657b0148a0aa06cd69482c7d Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 27 Mar 2017 17:04:58 -0700 > > > +Subject: [PATCH 2/3] s3: smbd: Fix "follow symlink = no" > > > regression part 2. > > > + > > > +Add an extra paramter to cwd_name to check_reduced_name(). > > > + > > > +If cwd_name == NULL then fname is a client given path relative > > > +to the root path of the share. > > > + > > > +If cwd_name != NULL then fname is a client given path relative > > > +to cwd_name. cwd_name is relative to the root path of the share. > > > + > > > +Not yet used, logic added in the next commit. > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +Reviewed-by: Ralph Boehme <slow(a)samba.org> > > > +(cherry picked from commit > > > 83e30cb48859b412b76572b6a3ba84d8fde167af) > > > +--- > > > + source3/smbd/filename.c | 2 +- > > > + source3/smbd/open.c | 2 +- > > > + source3/smbd/proto.h | 4 +++- > > > + source3/smbd/vfs.c | 10 +++++++++- > > > + 4 files changed, 14 insertions(+), 4 deletions(-) > > > + > > > +From e3fd46264b82ffc22424ee7364b3fd2c0fc14a7e Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 27 Mar 2017 17:09:38 -0700 > > > +Subject: [PATCH 3/3] s3: smbd: Fix "follow symlink = no" > > > regression part 2. > > > + > > > +Use the cwd_name parameter to reconstruct the original > > > +client name for symlink testing. > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +Reviewed-by: Ralph Boehme <slow(a)samba.org> > > > +(cherry picked from commit > > > e182a4d39e86c9694e255efdf6ee2ea3ccb9af4a) > > > +--- > > > + source3/smbd/vfs.c | 23 +++++++++++++++++++++++ > > > + 1 file changed, 23 insertions(+) > > > + > > > +--- samba-3.6.6.orig/source3/smbd/vfs.c > > > ++++ samba-3.6.6/source3/smbd/vfs.c > > > +@@ -894,11 +894,20 @@ > > > + > > > /**************************************************************** > > > *** > > > + Reduce a file name, removing .. elements and checking that > > > + it is below dir in the heirachy. This uses realpath. > > > ++ > > > ++ If cwd_name == NULL then fname is a client given path relative > > > ++ to the root path of the share. > > > ++ > > > ++ If cwd_name != NULL then fname is a client given path relative > > > ++ to cwd_name. cwd_name is relative to the root path of the > > > share. > > > + > > > ***************************************************************** > > > ***/ > > > + > > > +-NTSTATUS check_reduced_name(connection_struct *conn, const char > > > *fname) > > > ++NTSTATUS check_reduced_name(connection_struct *conn, > > > ++ const char *cwd_name, > > > ++ const char *fname) > > > + { > > > + char *resolved_name = NULL; > > > ++ char *new_fname = NULL; > > > + bool allow_symlinks = true; > > > + bool allow_widelinks = false; > > > + > > > +@@ -1026,8 +1035,11 @@ > > > + /* fname can't have changed in > > > resolved_path. */ > > > + const char *p = > > > &resolved_name[rootdir_len]; > > > + > > > +- /* *p can be '\0' if fname was "." */ > > > +- if (*p == '\0' && ISDOT(fname)) { > > > ++ /* > > > ++ * UNIX filesystem semantics, names > > > consisting > > > ++ * only of "." or ".." CANNOT be > > > symlinks. > > > ++ */ > > > ++ if (ISDOT(fname) || ISDOTDOT(fname)) { > > > + goto out; > > > + } > > > + > > > +@@ -1041,11 +1053,32 @@ > > > + } > > > + > > > + p++; > > > ++ > > > ++ /* > > > ++ * If cwd_name is present and not ".", > > > ++ * then fname is relative to that, not > > > ++ * the root of the share. Make sure the > > > ++ * path we check is the one the client > > > ++ * sent (cwd_name+fname). > > > ++ */ > > > ++ if (cwd_name != NULL && > > > !ISDOT(cwd_name)) { > > > ++ new_fname = > > > talloc_asprintf(talloc_tos(), > > > ++ "%s/%s" > > > , > > > ++ cwd_nam > > > e, > > > ++ fname); > > > ++ if (new_fname == NULL) { > > > ++ SAFE_FREE(resolved_name > > > ); > > > ++ return > > > NT_STATUS_NO_MEMORY; > > > ++ } > > > ++ fname = new_fname; > > > ++ } > > > ++ > > > + if (strcmp(fname, p)!=0) { > > > + DEBUG(2, ("check_reduced_name: > > > Bad access " > > > + "attempt: %s is a > > > symlink\n", > > > + fname)); > > > + SAFE_FREE(resolved_name); > > > ++ TALLOC_FREE(new_fname); > > > + return NT_STATUS_ACCESS_DENIED; > > > + } > > > + } > > > +@@ -1056,6 +1089,7 @@ > > > + DEBUG(3,("check_reduced_name: %s reduced to %s\n", > > > fname, > > > + resolved_name)); > > > + SAFE_FREE(resolved_name); > > > ++ TALLOC_FREE(new_fname); > > > + return NT_STATUS_OK; > > > + } > > > + > > > +--- samba-3.6.6.orig/source3/smbd/filename.c > > > ++++ samba-3.6.6/source3/smbd/filename.c > > > +@@ -1009,7 +1009,7 @@ > > > + } > > > + > > > + if (!lp_widelinks(SNUM(conn)) || > > > !lp_symlinks(SNUM(conn))) { > > > +- status = check_reduced_name(conn,name); > > > ++ status = check_reduced_name(conn, NULL, name); > > > + if (!NT_STATUS_IS_OK(status)) { > > > + DEBUG(5,("check_name: name %s failed > > > with > > > %s\n",name, > > > + nt_errstr(statu > > > s))); > > > +--- samba-3.6.6.orig/source3/smbd/open.c > > > ++++ samba-3.6.6/source3/smbd/open.c > > > +@@ -381,7 +381,7 @@ > > > + } > > > + > > > + /* Ensure the relative path is below the share. */ > > > +- status = check_reduced_name(conn, final_component); > > > ++ status = check_reduced_name(conn, parent_dir, > > > final_component); > > > + if (!NT_STATUS_IS_OK(status)) { > > > + saved_errno = map_errno_from_nt_status(status); > > > + goto out; > > > +--- samba-3.6.6.orig/source3/smbd/proto.h > > > ++++ samba-3.6.6/source3/smbd/proto.h > > > +@@ -1179,7 +1179,9 @@ > > > + SMB_STRUCT_STAT *sbuf, char > > > **talloced); > > > + int vfs_ChDir(connection_struct *conn, const char *path); > > > + char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn); > > > +-NTSTATUS check_reduced_name(connection_struct *conn, const char > > > *fname); > > > ++NTSTATUS check_reduced_name(connection_struct *conn, > > > ++ const char *cwd_name, > > > ++ const char *fname); > > > + int vfs_stat_smb_fname(struct connection_struct *conn, const > > > char *fname, > > > + SMB_STRUCT_STAT *psbuf); > > > + int vfs_lstat_smb_fname(struct connection_struct *conn, const > > > char *fname, > > > diff --git a/src/patches/samba/CVE-2017-2619-tests.patch > > > b/src/patches/samba/CVE-2017-2619-tests.patch > > > new file mode 100644 > > > index 000000000..41c84610e > > > --- /dev/null > > > +++ b/src/patches/samba/CVE-2017-2619-tests.patch > > > @@ -0,0 +1,296 @@ > > > +Description: Patches to unit tests associated with CVE-2017-2619 > > > regression > > > +origin: https://attachments.samba.org/attachment.cgi?id=13130 > > > + > > > +From 2c6de8584779e413f1e6ff9c933f9281693bfbc0 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 27 Mar 2017 11:48:25 -0700 > > > +Subject: [PATCH 2/6] s3: Test for CVE-2017-2619 regression with > > > "follow > > > + symlinks = no". > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +Reviewed-by: Uri Simchoni <uri(a)samba.org> > > > + > > > +Back-ported from commit 782172a9bef0040981d20e49519b13dd744df6a0 > > > +--- > > > + selftest/target/Samba3.pm | 7 +++ > > > + source3/script/tests/test_smbclient_s3.sh | 73 > > > +++++++++++++++++++++++++++++++ > > > + 2 files changed, 80 insertions(+) > > > + > > > +diff --git a/selftest/target/Samba3.pm > > > b/selftest/target/Samba3.pm > > > +index 01a1c470af0..7765b9efbb2 100644 > > > +--- a/selftest/target/Samba3.pm > > > ++++ b/selftest/target/Samba3.pm > > > +@@ -481,6 +481,9 @@ sub provision($$$$$$) > > > + my $msdfs_deeppath="$msdfs_shrdir/deeppath"; > > > + push(@dirs,$msdfs_deeppath); > > > + > > > ++ my $nosymlinks_shrdir="$shrdir/nosymlinks"; > > > ++ push(@dirs,$nosymlinks_shrdir); > > > ++ > > > + # this gets autocreated by winbindd > > > + my $wbsockdir="$prefix_abs/winbindd"; > > > + my $wbsockprivdir="$lockdir/winbindd_privileged"; > > > +@@ -695,6 +698,10 @@ sub provision($$$$$$) > > > + copy = print1 > > > + [print\$] > > > + copy = tmp > > > ++[nosymlinks] > > > ++ copy = tmp > > > ++ path = $nosymlinks_shrdir > > > ++ follow symlinks = no > > > + "; > > > + close(CONF); > > > + > > > +diff --git a/source3/script/tests/test_smbclient_s3.sh > > > b/source3/script/tests/test_smbclient_s3.sh > > > +index 772802f77b1..57ef87e4949 100755 > > > +--- a/source3/script/tests/test_smbclient_s3.sh > > > ++++ b/source3/script/tests/test_smbclient_s3.sh > > > +@@ -401,6 +401,75 @@ done > > > + > > > + LOGDIR=$(mktemp -d ${PREFIX}/${LOGDIR_PREFIX}_XXXXXX) > > > + > > > ++# Test follow symlinks can't access symlinks > > > ++test_nosymlinks() > > > ++{ > > > ++# Setup test dirs. > > > ++ slink_name="$LOCAL_PATH/nosymlinks/source" > > > ++ slink_target="$LOCAL_PATH/nosymlinks/target" > > > ++ mkdir_target="$LOCAL_PATH/nosymlinks/a" > > > ++ > > > ++ rm -f $slink_target > > > ++ rm -f $slink_name > > > ++ rm -rf $mkdir_target > > > ++ > > > ++ touch $slink_target > > > ++ ln -s $slink_target $slink_name > > > ++ > > > ++# Getting a file through a symlink name should fail. > > > ++ tmpfile=$PREFIX/smbclient_interactive_prompt_commands > > > ++ cat > $tmpfile <<EOF > > > ++get source > > > ++quit > > > ++EOF > > > ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" > > > -U$USERNAME%$PASSWORD > > > //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' > > > ++ eval echo "$cmd" > > > ++ out=`eval $cmd` > > > ++ ret=$? > > > ++ rm -f $tmpfile > > > ++ > > > ++ if [ $ret != 0 ] ; then > > > ++ echo "$out" > > > ++ echo "failed accessing nosymlinks with error $ret" > > > ++ false > > > ++ return > > > ++ fi > > > ++ > > > ++ echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' > > > ++ ret=$? > > > ++ if [ $ret != 0 ] ; then > > > ++ echo "$out" > > > ++ echo "failed - should get NT_STATUS_ACCESS_DENIED > > > getting > > > \\nosymlinks\\source" > > > ++ false > > > ++ fi > > > ++ > > > ++# But we should be able to create and delete directories. > > > ++ cat > $tmpfile <<EOF > > > ++mkdir a > > > ++mkdir a\\b > > > ++quit > > > ++EOF > > > ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" > > > -U$USERNAME%$PASSWORD > > > //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' > > > ++ eval echo "$cmd" > > > ++ out=`eval $cmd` > > > ++ ret=$? > > > ++ rm -f $tmpfile > > > ++ > > > ++ if [ $ret != 0 ] ; then > > > ++ echo "$out" > > > ++ echo "failed accessing nosymlinks with error $ret" > > > ++ false > > > ++ return > > > ++ fi > > > ++ > > > ++ echo "$out" | grep 'NT_STATUS' > > > ++ ret=$? > > > ++ if [ $ret == 0 ] ; then > > > ++ echo "$out" > > > ++ echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b > > > on > > > \\nosymlinks" > > > ++ false > > > ++ fi > > > ++} > > > + > > > + testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p > > > 139 || > > > failed=`expr $failed + 1` > > > + testit "smbclient -L $SERVER -I $SERVER_IP" $SMBCLIENT -L > > > $SERVER -I > > > $SERVER_IP -N -p 139 -c quit || failed=`expr $failed + 1` > > > +@@ -445,6 +514,10 @@ testit "ccache access works for smbclient" > > > \ > > > + test_ccache_access || \ > > > + failed=`expr $failed + 1` > > > + > > > ++testit "follow symlinks = no" \ > > > ++ test_nosymlinks || \ > > > ++ failed=`expr $failed + 1` > > > ++ > > > + testit "rm -rf $LOGDIR" \ > > > + rm -rf $LOGDIR || \ > > > + failed=`expr $failed + 1` > > > +-- > > > +2.12.0 > > > + > > > + > > > +From 17865cf188f42850f18f46514643a5b3a43e5707 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 27 Mar 2017 22:07:50 -0700 > > > +Subject: [PATCH 3/6] s3: Fixup test for CVE-2017-2619 regression > > > with "follow > > > + symlinks = no" > > > + > > > +Use correct bash operators (not string operators). > > > +Add missing "return". > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +Reviewed-by: Ralph Boehme <slow(a)samba.org> > > > +(cherry picked from commit > > > 037297a1c50e90a0092e3b94f472623f41ccc015) > > > +--- > > > + source3/script/tests/test_smbclient_s3.sh | 9 +++++---- > > > + 1 file changed, 5 insertions(+), 4 deletions(-) > > > + > > > +diff --git a/source3/script/tests/test_smbclient_s3.sh > > > b/source3/script/tests/test_smbclient_s3.sh > > > +index 57ef87e4949..bd5714fca6e 100755 > > > +--- a/source3/script/tests/test_smbclient_s3.sh > > > ++++ b/source3/script/tests/test_smbclient_s3.sh > > > +@@ -428,7 +428,7 @@ EOF > > > + ret=$? > > > + rm -f $tmpfile > > > + > > > +- if [ $ret != 0 ] ; then > > > ++ if [ $ret -ne 0 ] ; then > > > + echo "$out" > > > + echo "failed accessing nosymlinks with error $ret" > > > + false > > > +@@ -437,10 +437,11 @@ EOF > > > + > > > + echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' > > > + ret=$? > > > +- if [ $ret != 0 ] ; then > > > ++ if [ $ret -ne 0 ] ; then > > > + echo "$out" > > > + echo "failed - should get NT_STATUS_ACCESS_DENIED > > > getting > > > \\nosymlinks\\source" > > > + false > > > ++ return > > > + fi > > > + > > > + # But we should be able to create and delete directories. > > > +@@ -455,7 +456,7 @@ EOF > > > + ret=$? > > > + rm -f $tmpfile > > > + > > > +- if [ $ret != 0 ] ; then > > > ++ if [ $ret -ne 0 ] ; then > > > + echo "$out" > > > + echo "failed accessing nosymlinks with error $ret" > > > + false > > > +@@ -464,7 +465,7 @@ EOF > > > + > > > + echo "$out" | grep 'NT_STATUS' > > > + ret=$? > > > +- if [ $ret == 0 ] ; then > > > ++ if [ $ret -eq 0 ] ; then > > > + echo "$out" > > > + echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b > > > on > > > \\nosymlinks" > > > + false > > > +-- > > > +2.12.0 > > > + > > > + > > > +From 9b573af39f3d4995464e30771fa06e0709b5e57b Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Mon, 27 Mar 2017 22:10:29 -0700 > > > +Subject: [PATCH 6/6] s3: Test for CVE-2017-2619 regression with > > > "follow > > > + symlinks = no" - part 2 > > > +MIME-Version: 1.0 > > > +Content-Type: text/plain; charset=UTF-8 > > > +Content-Transfer-Encoding: 8bit > > > + > > > +Add tests for regular access. > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +Reviewed-by: Ralph Boehme <slow(a)samba.org> > > > + > > > +Autobuild-User(master): Ralph Böhme <slow(a)samba.org> > > > +Autobuild-Date(master): Tue Mar 28 17:05:27 CEST 2017 on sn- > > > devel-144 > > > + > > > +(cherry picked from commit > > > 4e734fcd1bf82c08aa303ce44e9735acccffcf06) > > > +--- > > > + source3/script/tests/test_smbclient_s3.sh | 37 > > > +++++++++++++++++++++++++++++++ > > > + 1 file changed, 37 insertions(+) > > > + > > > +diff --git a/source3/script/tests/test_smbclient_s3.sh > > > b/source3/script/tests/test_smbclient_s3.sh > > > +index bd5714fca6e..885766f6c16 100755 > > > +--- a/source3/script/tests/test_smbclient_s3.sh > > > ++++ b/source3/script/tests/test_smbclient_s3.sh > > > +@@ -408,14 +408,22 @@ test_nosymlinks() > > > + slink_name="$LOCAL_PATH/nosymlinks/source" > > > + slink_target="$LOCAL_PATH/nosymlinks/target" > > > + mkdir_target="$LOCAL_PATH/nosymlinks/a" > > > ++ dir1="$LOCAL_PATH/nosymlinks/foo" > > > ++ dir2="$LOCAL_PATH/nosymlinks/foo/bar" > > > ++ get_target="$LOCAL_PATH/nosymlinks/foo/bar/testfile" > > > + > > > + rm -f $slink_target > > > + rm -f $slink_name > > > + rm -rf $mkdir_target > > > ++ rm -rf $dir1 > > > + > > > + touch $slink_target > > > + ln -s $slink_target $slink_name > > > + > > > ++ mkdir $dir1 > > > ++ mkdir $dir2 > > > ++ touch $get_target > > > ++ > > > + # Getting a file through a symlink name should fail. > > > + tmpfile=$PREFIX/smbclient_interactive_prompt_commands > > > + cat > $tmpfile <<EOF > > > +@@ -470,6 +478,35 @@ EOF > > > + echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b > > > on > > > \\nosymlinks" > > > + false > > > + fi > > > ++ > > > ++# Ensure regular file/directory access also works. > > > ++ cat > $tmpfile <<EOF > > > ++cd foo\\bar > > > ++ls > > > ++get testfile - > > > ++quit > > > ++EOF > > > ++ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" > > > -U$USERNAME%$PASSWORD > > > //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' > > > ++ eval echo "$cmd" > > > ++ out=`eval $cmd` > > > ++ ret=$? > > > ++ rm -f $tmpfile > > > ++ > > > ++ if [ $ret -ne 0 ] ; then > > > ++ echo "$out" > > > ++ echo "failed accessing nosymlinks with error $ret" > > > ++ false > > > ++ return > > > ++ fi > > > ++ > > > ++ echo "$out" | grep 'NT_STATUS' > > > ++ ret=$? > > > ++ if [ $ret -eq 0 ] ; then > > > ++ echo "$out" > > > ++ echo "failed - NT_STATUS_XXXX doing cd foo\\bar; get > > > testfile on > > > \\nosymlinks" > > > ++ false > > > ++ return > > > ++ fi > > > + } > > > + > > > + testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p > > > 139 || > > > failed=`expr $failed + 1` > > > +-- > > > +2.12.0 > > > + > > > diff --git a/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch > > > b/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch > > > new file mode 100644 > > > index 000000000..54bb1841b > > > --- /dev/null > > > +++ b/src/patches/samba/samba-3.6.25-CVE-2017-7494.patch > > > @@ -0,0 +1,14 @@ > > > +--- source3/rpc_server/srv_pipe.c Sun Feb 22 16:11:32 > > > 2015 > > > ++++ source3/rpc_server/srv_pipe.c Fri May 26 17:28:40 > > > 2017 > > > +@@ -465,6 +465,11 @@ > > > + const char *pipename = cli_filename; > > > + NTSTATUS status; > > > + > > > ++ if (strchr(pipename, '/')) { > > > ++ DEBUG(1, ("Refusing open on pipe %s\n", > > > pipename)); > > > ++ return false; > > > ++ } > > > ++ > > > + if (strnequal(pipename, "\\PIPE\\", 6)) { > > > + pipename += 5; > > > + } > > > diff --git a/src/patches/samba/samba-3.6.25-security-2015-12- > > > 16.patch > > > b/src/patches/samba/samba-3.6.25-security-2015-12-16.patch > > > new file mode 100644 > > > index 000000000..df1057fea > > > --- /dev/null > > > +++ b/src/patches/samba/samba-3.6.25-security-2015-12-16.patch > > > @@ -0,0 +1,255 @@ > > > +From 2e94b6ec10f1d15e24867bab3063bb85f173406a Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Thu, 9 Jul 2015 10:58:11 -0700 > > > +Subject: [PATCH] CVE-2015-5252: s3: smbd: Fix symlink > > > verification (file > > > + access outside the share). > > > + > > > +Ensure matching component ends in '/' or '\0'. > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11395 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +Reviewed-by: Volker Lendecke <vl(a)samba.org> > > > +--- > > > + source3/smbd/vfs.c | 7 +++++-- > > > + 1 file changed, 5 insertions(+), 2 deletions(-) > > > + > > > +diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c > > > +index 6c56964..bd93b7f 100644 > > > +--- a/source3/smbd/vfs.c > > > ++++ b/source3/smbd/vfs.c > > > +@@ -982,6 +982,7 @@ NTSTATUS > > > check_reduced_name(connection_struct *conn, > > > const char *fname) > > > + if (!allow_widelinks || !allow_symlinks) { > > > + const char *conn_rootdir; > > > + size_t rootdir_len; > > > ++ bool matched; > > > + > > > + conn_rootdir = SMB_VFS_CONNECTPATH(conn, > > > fname); > > > + if (conn_rootdir == NULL) { > > > +@@ -992,8 +993,10 @@ NTSTATUS > > > check_reduced_name(connection_struct *conn, > > > const char *fname) > > > + } > > > + > > > + rootdir_len = strlen(conn_rootdir); > > > +- if (strncmp(conn_rootdir, resolved_name, > > > +- rootdir_len) != 0) { > > > ++ matched = (strncmp(conn_rootdir, resolved_name, > > > ++ rootdir_len) == 0); > > > ++ if (!matched || (resolved_name[rootdir_len] != > > > '/' && > > > ++ resolved_name[rootdir_len] != > > > '\0')) { > > > + DEBUG(2, ("check_reduced_name: Bad > > > access " > > > + "attempt: %s is a symlink > > > outside the " > > > + "share path\n", fname)); > > > +-- > > > +2.5.0 > > > + > > > +From 25139116756cc285a3a5534834cc276ef1b7baaa Mon Sep 17 > > > 00:00:00 2001 > > > +From: Stefan Metzmacher <metze(a)samba.org> > > > +Date: Wed, 30 Sep 2015 21:17:02 +0200 > > > +Subject: [PATCH 1/2] CVE-2015-5296: s3:libsmb: force signing > > > when requiring > > > + encryption in do_connect() > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536 > > > + > > > +Signed-off-by: Stefan Metzmacher <metze(a)samba.org> > > > +Reviewed-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/libsmb/clidfs.c | 7 ++++++- > > > + 1 file changed, 6 insertions(+), 1 deletion(-) > > > + > > > +diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c > > > +index 23e1471..f153b6b 100644 > > > +--- a/source3/libsmb/clidfs.c > > > ++++ b/source3/libsmb/clidfs.c > > > +@@ -98,6 +98,11 @@ static struct cli_state > > > *do_connect(TALLOC_CTX *ctx, > > > + const char *username; > > > + const char *password; > > > + NTSTATUS status; > > > ++ int signing_state = > > > get_cmdline_auth_info_signing_state(auth_info); > > > ++ > > > ++ if (force_encrypt) { > > > ++ signing_state = Required; > > > ++ } > > > + > > > + /* make a copy so we don't modify the global string > > > 'service' */ > > > + servicename = talloc_strdup(ctx,share); > > > +@@ -132,7 +137,7 @@ static struct cli_state > > > *do_connect(TALLOC_CTX *ctx, > > > + zero_sockaddr(&ss); > > > + > > > + /* have to open a new connection */ > > > +- c = > > > cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)) > > > ; > > > ++ c = cli_initialise_ex(signing_state); > > > + if (c == NULL) { > > > + d_printf("Connection to %s failed\n", > > > server_n); > > > + return NULL; > > > +-- > > > +2.5.0 > > > + > > > + > > > +From 060adb0abdeda51b8b622c6020b5dea0c8dde1cf Mon Sep 17 > > > 00:00:00 2001 > > > +From: Stefan Metzmacher <metze(a)samba.org> > > > +Date: Wed, 30 Sep 2015 21:17:02 +0200 > > > +Subject: [PATCH 2/2] CVE-2015-5296: s3:libsmb: force signing > > > when requiring > > > + encryption in SMBC_server_internal() > > > + > > > +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536 > > > + > > > +Signed-off-by: Stefan Metzmacher <metze(a)samba.org> > > > +Reviewed-by: Jeremy Allison <jra(a)samba.org> > > > +--- > > > + source3/libsmb/libsmb_server.c | 13 +++++++++++-- > > > + 1 file changed, 11 insertions(+), 2 deletions(-) > > > + > > > +diff --git a/source3/libsmb/libsmb_server.c > > > b/source3/libsmb/libsmb_server.c > > > +index 45be660..167f2c9 100644 > > > +--- a/source3/libsmb/libsmb_server.c > > > ++++ b/source3/libsmb/libsmb_server.c > > > +@@ -258,6 +258,7 @@ SMBC_server_internal(TALLOC_CTX *ctx, > > > + const char *username_used; > > > + NTSTATUS status; > > > + char *newserver, *newshare; > > > ++ int signing_state = Undefined; > > > + > > > + zero_sockaddr(&ss); > > > + ZERO_STRUCT(c); > > > +@@ -404,8 +405,12 @@ again: > > > + > > > + zero_sockaddr(&ss); > > > + > > > ++ if (context->internal->smb_encryption_level != > > > SMBC_ENCRYPTLEVEL_NONE) { > > > ++ signing_state = Required; > > > ++ } > > > ++ > > > + /* have to open a new connection */ > > > +- if ((c = cli_initialise()) == NULL) { > > > ++ if ((c = cli_initialise_ex(signing_state)) == NULL) { > > > + errno = ENOMEM; > > > + return NULL; > > > + } > > > +@@ -750,6 +755,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, > > > + ipc_srv = SMBC_find_server(ctx, context, server, > > > "*IPC$", > > > + pp_workgroup, pp_username, > > > pp_password); > > > + if (!ipc_srv) { > > > ++ int signing_state = Undefined; > > > + > > > + /* We didn't find a cached connection. Get the > > > password */ > > > + if (!*pp_password || (*pp_password)[0] == '\0') > > > { > > > +@@ -771,6 +777,9 @@ SMBC_attr_server(TALLOC_CTX *ctx, > > > + if (smbc_getOptionUseCCache(context)) { > > > + flags |= > > > CLI_FULL_CONNECTION_USE_CCACHE; > > > + } > > > ++ if (context->internal->smb_encryption_level != > > > SMBC_ENCRYPTLEVEL_NONE) { > > > ++ signing_state = Required; > > > ++ } > > > + > > > + zero_sockaddr(&ss); > > > + nt_status = cli_full_connection(&ipc_cli, > > > +@@ -780,7 +789,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, > > > + *pp_workgroup, > > > + *pp_password, > > > + flags, > > > +- Undefined); > > > ++ signing_state); > > > + if (! NT_STATUS_IS_OK(nt_status)) { > > > + DEBUG(1,("cli_full_connection failed! > > > (%s)\n", > > > + nt_errstr(nt_status))); > > > +-- > > > +2.5.0 > > > + > > > +From 8e49de7754f7171a58a1f94dee0f1138dbee3c60 Mon Sep 17 > > > 00:00:00 2001 > > > +From: Jeremy Allison <jra(a)samba.org> > > > +Date: Fri, 23 Oct 2015 14:54:31 -0700 > > > +Subject: [PATCH] CVE-2015-5299: s3-shadow-copy2: fix missing > > > access check on > > > + snapdir > > > + > > > +Fix originally from <partha(a)exablox.com> > > > + > > > +https://bugzilla.samba.org/show_bug.cgi?id=11529 > > > + > > > +Signed-off-by: Jeremy Allison <jra(a)samba.org> > > > +Reviewed-by: David Disseldorp <ddiss(a)samba.org> > > > +--- > > > + source3/modules/vfs_shadow_copy2.c | 47 > > > ++++++++++++++++++++++++++++++++++++++ > > > + 1 file changed, 47 insertions(+) > > > + > > > +diff --git a/source3/modules/vfs_shadow_copy2.c > > > b/source3/modules/vfs_shadow_copy2.c > > > +index fedfb53..16c1ed7 100644 > > > +--- a/source3/modules/vfs_shadow_copy2.c > > > ++++ b/source3/modules/vfs_shadow_copy2.c > > > +@@ -21,6 +21,8 @@ > > > + > > > + #include "includes.h" > > > + #include "smbd/smbd.h" > > > ++#include "smbd/globals.h" > > > ++#include "../libcli/security/security.h" > > > + #include "system/filesys.h" > > > + #include "ntioctl.h" > > > + > > > +@@ -764,6 +766,43 @@ static int > > > shadow_copy2_mkdir(vfs_handle_struct > > > *handle, const char *fname, mod > > > + SHADOW2_NEXT(MKDIR, (handle, name, mode), int, -1); > > > + } > > > + > > > ++static bool check_access_snapdir(struct vfs_handle_struct > > > *handle, > > > ++ const char *path) > > > ++{ > > > ++ struct smb_filename smb_fname; > > > ++ int ret; > > > ++ NTSTATUS status; > > > ++ uint32_t access_granted = 0; > > > ++ > > > ++ ZERO_STRUCT(smb_fname); > > > ++ smb_fname.base_name = talloc_asprintf(talloc_tos(), > > > ++ "%s", > > > ++ path); > > > ++ if (smb_fname.base_name == NULL) { > > > ++ return false; > > > ++ } > > > ++ > > > ++ ret = SMB_VFS_NEXT_STAT(handle, &smb_fname); > > > ++ if (ret != 0 || !S_ISDIR(smb_fname.st.st_ex_mode)) { > > > ++ TALLOC_FREE(smb_fname.base_name); > > > ++ return false; > > > ++ } > > > ++ > > > ++ status = smbd_check_open_rights(handle->conn, > > > ++ &smb_fname, > > > ++ SEC_DIR_LIST, > > > ++ &access_granted); > > > ++ if (!NT_STATUS_IS_OK(status)) { > > > ++ DEBUG(0,("user does not have list permission " > > > ++ "on snapdir %s\n", > > > ++ smb_fname.base_name)); > > > ++ TALLOC_FREE(smb_fname.base_name); > > > ++ return false; > > > ++ } > > > ++ TALLOC_FREE(smb_fname.base_name); > > > ++ return true; > > > ++} > > > ++ > > > + static int shadow_copy2_rmdir(vfs_handle_struct *handle, const > > > char *fname) > > > + { > > > + SHADOW2_NEXT(RMDIR, (handle, name), int, -1); > > > +@@ -877,6 +916,7 @@ static int > > > shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, > > > + SMB_STRUCT_DIRENT *d; > > > + TALLOC_CTX *tmp_ctx = talloc_new(handle->data); > > > + char *snapshot; > > > ++ bool ret; > > > + > > > + snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle); > > > + if (snapdir == NULL) { > > > +@@ -886,6 +926,13 @@ static int > > > shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, > > > + talloc_free(tmp_ctx); > > > + return -1; > > > + } > > > ++ ret = check_access_snapdir(handle, snapdir); > > > ++ if (!ret) { > > > ++ DEBUG(0,("access denied on listing snapdir > > > %s\n", snapdir)); > > > ++ errno = EACCES; > > > ++ talloc_free(tmp_ctx); > > > ++ return -1; > > > ++ } > > > + > > > + p = SMB_VFS_NEXT_OPENDIR(handle, snapdir, NULL, 0); > > > + > > > +-- > > > +2.5.0 > > > + > > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-05-29 21:07 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-05-28 9:22 [PATCH] Security updates for samba 3.6.25 Matthias Fischer 2017-05-29 16:57 ` Michael Tremer 2017-05-29 18:30 ` Matthias Fischer 2017-05-29 21:07 ` Michael Tremer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox