mbox

Security updates for samba 3.6.25

Message ID 20170528092213.8026-1-matthias.fischer@ipfire.org
State Superseded
Headers

Message

Matthias Fischer May 28, 2017, 7:22 p.m. UTC
  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@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
  

Comments

Michael Tremer May 30, 2017, 2:57 a.m. UTC | #1
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@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@ipfire.org>                    
>  #
> +# Copyright (C) 2007-2017  IPFire Team  <info@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@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@samba.org>
> +Signed-off-by: Jeremy Allison <jra@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@samba.org>
> +Reviewed-by: Uri Simchoni <uri@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@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@samba.org>
> +Reviewed-by: Ralph Boehme <slow@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@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@samba.org>
> +Reviewed-by: Ralph Boehme <slow@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@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@samba.org>
> +Reviewed-by: Uri Simchoni <uri@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@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@samba.org>
> +Reviewed-by: Ralph Boehme <slow@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@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@samba.org>
> +Reviewed-by: Ralph Boehme <slow@samba.org>
> +
> +Autobuild-User(master): Ralph Böhme <slow@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@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@samba.org>
> +Reviewed-by: Volker Lendecke <vl@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@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@samba.org>
> +Reviewed-by: Jeremy Allison <jra@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@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@samba.org>
> +Reviewed-by: Jeremy Allison <jra@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@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@exablox.com>
> +
> +https://bugzilla.samba.org/show_bug.cgi?id=11529
> +
> +Signed-off-by: Jeremy Allison <jra@samba.org>
> +Reviewed-by: David Disseldorp <ddiss@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
> +
  
Matthias Fischer May 30, 2017, 4:30 a.m. UTC | #2
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@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@ipfire.org>                    
>>  #
>> +# Copyright (C) 2007-2017  IPFire Team  <info@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@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@samba.org>
>> +Signed-off-by: Jeremy Allison <jra@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@samba.org>
>> +Reviewed-by: Uri Simchoni <uri@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@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@samba.org>
>> +Reviewed-by: Ralph Boehme <slow@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@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@samba.org>
>> +Reviewed-by: Ralph Boehme <slow@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@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@samba.org>
>> +Reviewed-by: Uri Simchoni <uri@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@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@samba.org>
>> +Reviewed-by: Ralph Boehme <slow@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@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@samba.org>
>> +Reviewed-by: Ralph Boehme <slow@samba.org>
>> +
>> +Autobuild-User(master): Ralph Böhme <slow@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@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@samba.org>
>> +Reviewed-by: Volker Lendecke <vl@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@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@samba.org>
>> +Reviewed-by: Jeremy Allison <jra@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@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@samba.org>
>> +Reviewed-by: Jeremy Allison <jra@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@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@exablox.com>
>> +
>> +https://bugzilla.samba.org/show_bug.cgi?id=11529
>> +
>> +Signed-off-by: Jeremy Allison <jra@samba.org>
>> +Reviewed-by: David Disseldorp <ddiss@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
>> +
>
  
Michael Tremer May 30, 2017, 7:07 a.m. UTC | #3
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@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@ipfire.org>       
> > >              
> > >  #
> > > +# Copyright (C) 2007-2017  IPFire Team  <info@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@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@samba.org>
> > > +Signed-off-by: Jeremy Allison <jra@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@samba.org>
> > > +Reviewed-by: Uri Simchoni <uri@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@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@samba.org>
> > > +Reviewed-by: Ralph Boehme <slow@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@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@samba.org>
> > > +Reviewed-by: Ralph Boehme <slow@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@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@samba.org>
> > > +Reviewed-by: Uri Simchoni <uri@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@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@samba.org>
> > > +Reviewed-by: Ralph Boehme <slow@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@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@samba.org>
> > > +Reviewed-by: Ralph Boehme <slow@samba.org>
> > > +
> > > +Autobuild-User(master): Ralph Böhme <slow@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@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@samba.org>
> > > +Reviewed-by: Volker Lendecke <vl@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@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@samba.org>
> > > +Reviewed-by: Jeremy Allison <jra@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@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@samba.org>
> > > +Reviewed-by: Jeremy Allison <jra@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@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@exablox.com>
> > > +
> > > +https://bugzilla.samba.org/show_bug.cgi?id=11529
> > > +
> > > +Signed-off-by: Jeremy Allison <jra@samba.org>
> > > +Reviewed-by: David Disseldorp <ddiss@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
> > > +
> 
>