From: Matthias Fischer <matthias.fischer@ipfire.org>
To: development@lists.ipfire.org
Subject: Re: [PATCH] Security updates for samba 3.6.25
Date: Mon, 29 May 2017 20:30:04 +0200 [thread overview]
Message-ID: <289db684-d6f7-c9b1-898e-be1cb688e25b@ipfire.org> (raw)
In-Reply-To: <1496077040.2151.55.camel@ipfire.org>
[-- 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
>> +
>
next prev parent reply other threads:[~2017-05-29 18:30 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-28 9:22 Matthias Fischer
2017-05-29 16:57 ` Michael Tremer
2017-05-29 18:30 ` Matthias Fischer [this message]
2017-05-29 21:07 ` Michael Tremer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=289db684-d6f7-c9b1-898e-be1cb688e25b@ipfire.org \
--to=matthias.fischer@ipfire.org \
--cc=development@lists.ipfire.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox