From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matthias Fischer To: development@lists.ipfire.org Subject: Re: [PATCH] Security updates for samba 3.6.25 Date: Mon, 29 May 2017 20:30:04 +0200 Message-ID: <289db684-d6f7-c9b1-898e-be1cb688e25b@ipfire.org> In-Reply-To: <1496077040.2151.55.camel@ipfire.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0445421404879118193==" List-Id: --===============0445421404879118193== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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. >=20 > 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 >=20 > On Sun, 2017-05-28 at 11:22 +0200, Matthias Fischer wrote: >> Based on: >>=20 >> https://anonscm.debian.org/cgit/pkg-samba/samba.git/commit/?h=3Dwheezy&id= =3D762a3a >> fd8eb45526e44cd0b2ae8a5b1a058ec647 >>=20 >> https://www.samba.org/samba/history/security.html >>=20 >> https://www.samba.org/samba/samba/ftp/patches/security/ >>=20 >> Fixes current CVE-2017-7494 and some more... >>=20 >> Removed three 'unrecognized' configure-options. >>=20 >> Some 'lfs'-tuning was made, too. >>=20 >> I altered 'PAK_VER' from "64" to "65" - if not necessary, please change ba= ck. >>=20 >> Best, >> Matthias >>=20 >> Signed-off-by: Matthias Fischer >> --- >> 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.pat= ch >> 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.pat= ch >>=20 >> diff --git a/lfs/samba b/lfs/samba >> index 076152f48..445646464 100644 >> --- a/lfs/samba >> +++ b/lfs/samba >> @@ -1,7 +1,7 @@ >> #########################################################################= #### >> ## >> # = =20 >> # >> # IPFire.org - A linux based >> firewall # >> -# Copyright (C) 2007-2016 IPFire Team = =20 >> # >> +# Copyright (C) 2007-2017 IPFire Team = =20 >> # >> # = =20 >> # >> # 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 =3D $(URL_IPFIRE) >> DIR_APP =3D $(DIR_SRC)/$(THISAPP) >> TARGET =3D $(DIR_INFO)/$(THISAPP) >> PROG =3D samba >> -PAK_VER =3D 64 >> +PAK_VER =3D 65 >> =20 >> DEPS =3D "cups krb5" >> =20 >> @@ -54,7 +54,7 @@ download :$(patsubst %,$(DIR_DL)/%,$(objects)) >> =20 >> md5 : $(subst %,%_MD5,$(objects)) >> =20 >> -dist:=20 >> +dist: >> @$(PAK) >> =20 >> #########################################################################= #### >> ## >> @@ -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 >> =20 >> + # 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=3D/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=09 >> 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=3D12496 >> + >> +From ec1bca1d5315549e945c93cbf5e3abdb695de782 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +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=3D12496 >> + >> +Signed-off-by: Ralph Bohme >> +Signed-off-by: Jeremy Allison >> +--- >> + 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 >> +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=3D12499 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + source3/modules/vfs_dirsort.c | 4 ++++ >> + 1 file changed, 4 insertions(+) >> + >> +From 327d09ba641046f68daa5b2bb98f09530294cb0d Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +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=3D12546 >> + >> +Back-ported from a24ba3e4083200ec9885363efc5769f43183fb6b >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + 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 >> +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=3D12591 >> + >> +Back-ported from 021189e32ba507832b5e821e5cda8a2889225955. >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + 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 >> +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=3D12496 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + source3/smbd/dir.c | 15 ++++++++++++++- >> + 1 file changed, 14 insertions(+), 1 deletion(-) >> + >> +From e47e3c40b5fc8f52fe70c3e1edf5489ac8b4badf Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +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=3D12496 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + source3/smbd/dir.c | 14 +++++++------- >> + 1 file changed, 7 insertions(+), 7 deletions(-) >> + >> +From 45e41b709b6c2e67acb99f29aa05b61b53091e57 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +Date: Mon, 19 Dec 2016 16:35:00 -0800 >> +Subject: [PATCH 07/15] s3: smbd: Create and use open_dir_safely(). Use fr= om >> + OpenDir(). >> + >> +Hardens OpenDir against TOC/TOU races. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=3D12496 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + source3/smbd/dir.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++= -- >> ---- >> + 1 file changed, 59 insertions(+), 7 deletions(-) >> + >> +From 720abcec65b04fdac1052a14898180c8cc816464 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +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=3D12496 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + source3/smbd/dir.c | 34 +++++++++++++++++++++------------- >> + 1 file changed, 21 insertions(+), 13 deletions(-) >> + >> +From 5070f319bbb7dda87766621a83691910414d06a1 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +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=3D12496 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + source3/smbd/dir.c | 2 +- >> + 1 file changed, 1 insertion(+), 1 deletion(-) >> + >> +From 65d37759f8b4979bc0c0833e0a5eecd277dfa604 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +Date: Mon, 19 Dec 2016 12:32:07 -0800 >> +Subject: [PATCH 10/15] s3: smbd: Move the reference counting and destruct= or >> + setup to just before retuning success. >> + >> +CVE-2017-2619 >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=3D12496 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + source3/smbd/dir.c | 10 +++++----- >> + 1 file changed, 5 insertions(+), 5 deletions(-) >> + >> +From 5a821d791aba90643ddf7a3c29dad4f6621ef185 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +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=3D12496 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + source3/smbd/dir.c | 15 +++++++-------- >> + 1 file changed, 7 insertions(+), 8 deletions(-) >> + >> +From 597aa3b99a2790133a4839260607b0a8df41c8e3 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +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=3D12496 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + source3/smbd/open.c | 4 +--- >> + 1 file changed, 1 insertion(+), 3 deletions(-) >> + >> +From 563af2ffec05a2c0b54897e2d28ac7e1adb66e0f Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +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=3D12496 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + source3/smbd/open.c | 30 ++++++++++++++++++++++++++++-- >> + 1 file changed, 28 insertions(+), 2 deletions(-) >> + >> +From b34a67cd3a996804ba7bf90e86cf9e22edf60eb3 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +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=3D12496 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + source3/smbd/open.c | 242 >> ++++++++++++++++++++++++++++++++++++++++++++++++++++ >> + 1 file changed, 242 insertions(+) >> + >> +From 5920309d2f62dd24fc50530c92dd68077f96a6d2 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +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=3D12496 >> + >> +Signed-off-by: Jeremy Allison >> +--- >> + 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 @@ >> + } >> +=20 >> + >> /*************************************************************************= *** >> ++ Handle differing symlink errno's >> ++************************************************************************= **** >> / >> ++ >> ++static int link_errno_convert(int err) >> ++{ >> ++#if defined(ENOTSUP) && defined(OSF1) >> ++ /* handle special Tru64 errno */ >> ++ if (err =3D=3D ENOTSUP) { >> ++ err =3D ELOOP; >> ++ } >> ++#endif /* ENOTSUP */ >> ++#ifdef EFTYPE >> ++ /* fix broken NetBSD errno */ >> ++ if (err =3D=3D EFTYPE) { >> ++ err =3D ELOOP; >> ++ } >> ++#endif /* EFTYPE */ >> ++ /* fix broken FreeBSD errno */ >> ++ if (err =3D=3D EMLINK) { >> ++ err =3D 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 =3D -1; >> ++ char *link_target =3D NULL; >> ++ int link_len =3D -1; >> ++ char *oldwd =3D NULL; >> ++ size_t rootdir_len =3D 0; >> ++ char *resolved_name =3D NULL; >> ++ bool matched =3D false; >> ++ int saved_errno =3D 0; >> ++ >> ++ /* >> ++ * Ensure we don't get stuck in a symlink loop. >> ++ */ >> ++ link_depth++; >> ++ if (link_depth >=3D 20) { >> ++ errno =3D ELOOP; >> ++ goto out; >> ++ } >> ++ >> ++ /* Allocate space for the link target. */ >> ++ link_target =3D talloc_array(talloc_tos(), char, PATH_MAX); >> ++ if (link_target =3D=3D NULL) { >> ++ errno =3D ENOMEM; >> ++ goto out; >> ++ } >> ++ >> ++ /* Read the link target. */ >> ++ link_len =3D SMB_VFS_READLINK(conn, >> ++ smb_fname->base_name, >> ++ link_target, >> ++ PATH_MAX - 1); >> ++ if (link_len =3D=3D -1) { >> ++ goto out; >> ++ } >> ++ >> ++ /* Ensure it's at least null terminated. */ >> ++ link_target[link_len] =3D '\0'; >> ++ >> ++ /* Convert to an absolute path. */ >> ++ resolved_name =3D SMB_VFS_REALPATH(conn, link_target); >> ++ if (resolved_name =3D=3D NULL) { >> ++ goto out; >> ++ } >> ++ >> ++ /* >> ++ * We know conn_rootdir starts with '/' and >> ++ * does not end in '/'. FIXME ! Should we >> ++ * smb_assert this ? >> ++ */ >> ++ rootdir_len =3D strlen(conn_rootdir); >> ++ >> ++ matched =3D (strncmp(conn_rootdir, resolved_name, rootdir_len) =3D=3D 0= ); >> ++ if (!matched) { >> ++ errno =3D EACCES; >> ++ goto out; >> ++ } >> ++ >> ++ /* >> ++ * Turn into a path relative to the share root. >> ++ */ >> ++ if (resolved_name[rootdir_len] =3D=3D '\0') { >> ++ /* Link to the root of the share. */ >> ++ smb_fname->base_name =3D talloc_strdup(talloc_tos(), "."); >> ++ if (smb_fname->base_name =3D=3D NULL) { >> ++ errno =3D ENOMEM; >> ++ goto out; >> ++ } >> ++ } else if (resolved_name[rootdir_len] =3D=3D '/') { >> ++ smb_fname->base_name =3D &resolved_name[rootdir_len+1]; >> ++ } else { >> ++ errno =3D EACCES; >> ++ goto out; >> ++ } >> ++ >> ++ oldwd =3D vfs_GetWd(talloc_tos(), conn); >> ++ if (oldwd =3D=3D NULL) { >> ++ goto out; >> ++ } >> ++ >> ++ /* Ensure we operate from the root of the share. */ >> ++ if (vfs_ChDir(conn, conn_rootdir) =3D=3D -1) { >> ++ goto out; >> ++ } >> ++ >> ++ /* And do it all again.. */ >> ++ fd =3D non_widelink_open(conn, >> ++ conn_rootdir, >> ++ fsp, >> ++ smb_fname, >> ++ flags, >> ++ mode, >> ++ link_depth); >> ++ if (fd =3D=3D -1) { >> ++ saved_errno =3D errno; >> ++ } >> ++ >> ++ out: >> ++ >> ++ SAFE_FREE(resolved_name); >> ++ TALLOC_FREE(link_target); >> ++ if (oldwd !=3D NULL) { >> ++ int ret =3D vfs_ChDir(conn, oldwd); >> ++ if (ret =3D=3D -1) { >> ++ smb_panic("unable to get back to old directory\n"); >> ++ } >> ++ TALLOC_FREE(oldwd); >> ++ } >> ++ if (saved_errno !=3D 0) { >> ++ errno =3D 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 =3D -1; >> ++ struct smb_filename *smb_fname_rel =3D NULL; >> ++ int saved_errno =3D 0; >> ++ char *oldwd =3D NULL; >> ++ char *parent_dir =3D NULL; >> ++ const char *final_component =3D NULL; >> ++ >> ++ if (!parent_dirname(talloc_tos(), >> ++ smb_fname->base_name, >> ++ &parent_dir, >> ++ &final_component)) { >> ++ goto out; >> ++ } >> ++ >> ++ oldwd =3D vfs_GetWd(talloc_tos(), conn); >> ++ if (oldwd =3D=3D NULL) { >> ++ goto out; >> ++ } >> ++ >> ++ /* Pin parent directory in place. */ >> ++ if (vfs_ChDir(conn, parent_dir) =3D=3D -1) { >> ++ goto out; >> ++ } >> ++ >> ++ /* Ensure the relative path is below the share. */ >> ++ status =3D check_reduced_name(conn, final_component); >> ++ if (!NT_STATUS_IS_OK(status)) { >> ++ saved_errno =3D map_errno_from_nt_status(status); >> ++ goto out; >> ++ } >> ++ >> ++ status =3D 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 =3D map_errno_from_nt_status(status); >> ++ goto out; >> ++ } >> ++ >> ++ flags |=3D O_NOFOLLOW; >> ++ >> ++ { >> ++ struct smb_filename *tmp_name =3D fsp->fsp_name; >> ++ fsp->fsp_name =3D smb_fname_rel; >> ++ fd =3D SMB_VFS_OPEN(conn, smb_fname_rel, fsp, flags, mode); >> ++ fsp->fsp_name =3D tmp_name; >> ++ } >> ++ >> ++ if (fd =3D=3D -1) { >> ++ saved_errno =3D link_errno_convert(errno); >> ++ if (saved_errno =3D=3D 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 =3D process_symlink_open(conn, >> ++ conn_rootdir, >> ++ fsp, >> ++ smb_fname_rel, >> ++ flags, >> ++ mode, >> ++ link_depth); >> ++ if (fd =3D=3D -1) { >> ++ saved_errno =3D >> ++ link_errno_convert(errno); >> ++ } >> ++ } >> ++ } >> ++ >> ++ out: >> ++ >> ++ TALLOC_FREE(parent_dir); >> ++ TALLOC_FREE(smb_fname_rel); >> ++ >> ++ if (oldwd !=3D NULL) { >> ++ int ret =3D vfs_ChDir(conn, oldwd); >> ++ if (ret =3D=3D -1) { >> ++ smb_panic("unable to get back to old directory\n"); >> ++ } >> ++ TALLOC_FREE(oldwd); >> ++ } >> ++ if (saved_errno !=3D 0) { >> ++ errno =3D saved_errno; >> ++ } >> ++ return fd; >> ++} >> ++ >> ++/***********************************************************************= **** >> * >> + fd support routines - attempt to do a dos_open. >> + >> **************************************************************************= **/ >> +=20 >> +-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 =3D fsp->fsp_name; >> + NTSTATUS status =3D NT_STATUS_OK; >> +=20 >> +-#ifdef O_NOFOLLOW >> +- /*=20 >> ++ /* >> + * 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 |=3D O_NOFOLLOW; >> + } >> +-#endif >> +=20 >> +- fsp->fh->fd =3D SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); >> ++ /* Ensure path is below share definition. */ >> ++ if (!lp_widelinks(SNUM(conn))) { >> ++ const char *conn_rootdir =3D SMB_VFS_CONNECTPATH(conn, >> ++ smb_fname->base_name); >> ++ if (conn_rootdir =3D=3D NULL) { >> ++ return NT_STATUS_NO_MEMORY; >> ++ } >> ++ /* >> ++ * Only follow symlinks within a share >> ++ * definition. >> ++ */ >> ++ fsp->fh->fd =3D non_widelink_open(conn, >> ++ conn_rootdir, >> ++ fsp, >> ++ smb_fname, >> ++ flags, >> ++ mode, >> ++ 0); >> ++ } else { >> ++ fsp->fh->fd =3D SMB_VFS_OPEN(conn, smb_fname, fsp, flags, >> mode); >> ++ } >> ++ >> + if (fsp->fh->fd =3D=3D -1) { >> +- status =3D map_nt_error_from_unix(errno); >> +- if (errno =3D=3D EMFILE) { >> ++ int posix_errno =3D link_errno_convert(errno); >> ++ status =3D map_nt_error_from_unix(posix_errno); >> ++ if (posix_errno =3D=3D EMFILE) { >> + static time_t last_warned =3D 0L; >> +=20 >> + 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" >> +=20 >> + static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx, >> + struct tevent_context *ev, >> +@@ -300,7 +301,23 @@ >> + } >> +=20 >> + 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 =3D O_RDONLY; >> ++#ifdef O_DIRECTORY >> ++ flags |=3D O_DIRECTORY; >> ++#endif >> ++ status =3D fd_open(conn, fsp, flags, 0); >> ++ if (tevent_req_nterror(req, status)) { >> ++ return tevent_req_post(req, ev); >> ++ } >> + } >> +=20 >> + if (fsp->dptr =3D=3D 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; >> + } >> +=20 >> ++ if (ISDOT(data->smb_fname->base_name)) { >> ++ data->smb_fname->base_name =3D vfs_GetWd(data, handle->conn); >> ++ } >> ++ >> + /* Open the underlying directory and count the number of entries */ >> + data->source_directory =3D 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; >> + } >> +=20 >> +- sbuf->st_ex_size =3D get_xattr_size(handle->conn, fsp->base_fsp, >> ++ sbuf->st_ex_size =3D get_xattr_size(handle->conn, fsp, >> + io->base, io->xattr_name); >> + if (sbuf->st_ex_size =3D=3D -1) { >> + return -1; >> +@@ -364,6 +364,7 @@ >> + char *xattr_name =3D NULL; >> + int baseflags; >> + int hostfd =3D -1; >> ++ int ret; >> +=20 >> + 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; >> +=20 >> + tmp_stream_name =3D smb_fname->stream_name; >> + smb_fname->stream_name =3D NULL; >> +=20 >> + ret =3D SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, >> mode); >> +=20 >> +- smb_fname->stream_name =3D tmp_stream_name; >> +- >> +- return ret; >> +- } >> ++ smb_fname->stream_name =3D tmp_stream_name; >> +=20 >> +- status =3D streams_xattr_get_name(talloc_tos(), smb_fname- >> >stream_name, >> +- &xattr_name); >> +- if (!NT_STATUS_IS_OK(status)) { >> +- errno =3D map_errno_from_nt_status(status); >> +- goto fail; >> +- } >> ++ return ret; >> ++ } >> +=20 >> +- /* Create an smb_filename with stream_name =3D=3D NULL. */ >> +- status =3D create_synthetic_smb_fname(talloc_tos(), >> +- smb_fname->base_name, >> +- NULL, NULL, >> +- &smb_fname_base); >> +- if (!NT_STATUS_IS_OK(status)) { >> +- errno =3D map_errno_from_nt_status(status); >> +- goto fail; >> +- } >> ++ status =3D streams_xattr_get_name(talloc_tos(), smb_fname- >> >stream_name, >> ++ &xattr_name); >> ++ if (!NT_STATUS_IS_OK(status)) { >> ++ errno =3D map_errno_from_nt_status(status); >> ++ goto fail; >> ++ } >> +=20 >> +- /* >> +- * We use baseflags to turn off nasty side-effects when opening the >> +- * underlying file. >> +- */ >> +- baseflags =3D flags; >> +- baseflags &=3D ~O_TRUNC; >> +- baseflags &=3D ~O_EXCL; >> +- baseflags &=3D ~O_CREAT; >> +- >> +- hostfd =3D 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 =3D=3D -1) && (errno =3D=3D EISDIR)) { >> +- baseflags &=3D ~O_ACCMODE; >> +- baseflags |=3D O_RDONLY; >> +- hostfd =3D SMB_VFS_OPEN(handle->conn, smb_fname, fsp, >> baseflags, >> +- mode); >> +- } >> ++ /* Create an smb_filename with stream_name =3D=3D NULL. */ >> ++ status =3D create_synthetic_smb_fname(talloc_tos(), >> ++ smb_fname->base_name, >> ++ NULL, NULL, >> ++ &smb_fname_base); >> ++ if (!NT_STATUS_IS_OK(status)) { >> ++ errno =3D map_errno_from_nt_status(status); >> ++ goto fail; >> ++ } >> +=20 >> +- if (hostfd =3D=3D -1) { >> +- goto fail; >> +- } >> ++ /* >> ++ * We use baseflags to turn off nasty side-effects when >> opening the >> ++ * underlying file. >> ++ */ >> ++ baseflags =3D flags; >> ++ baseflags &=3D ~O_TRUNC; >> ++ baseflags &=3D ~O_EXCL; >> ++ baseflags &=3D ~O_CREAT; >> +=20 >> +- status =3D get_ea_value(talloc_tos(), handle->conn, NULL, >> +- smb_fname->base_name, xattr_name, &ea); >> ++ hostfd =3D SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp, >> ++ baseflags, mode); >> +=20 >> +- DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status))); >> ++ TALLOC_FREE(smb_fname_base); >> +=20 >> +- 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 =3D ENOENT; >> +- goto fail; >> +- } >> ++ if ((hostfd =3D=3D -1) && (errno =3D=3D EISDIR)) { >> ++ baseflags &=3D ~O_ACCMODE; >> ++ baseflags |=3D O_RDONLY; >> ++ hostfd =3D SMB_VFS_OPEN(handle->conn, smb_fname, fsp, >> baseflags, >> ++ mode); >> ++ } >> +=20 >> +- if (!NT_STATUS_IS_OK(status)) { >> +- /* >> +- * The attribute does not exist >> +- */ >> ++ if (hostfd =3D=3D -1) { >> ++ goto fail; >> ++ } >> ++ >> ++ status =3D get_ea_value(talloc_tos(), handle->conn, NULL, >> ++ smb_fname->base_name, xattr_name, >> &ea); >> +=20 >> +- 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 =3D '\0'; >> ++ DEBUG(10, ("streams_xattr_open: base file %s not >> around, " >> ++ "returning ENOENT\n", smb_fname- >> >base_name)); >> ++ errno =3D ENOENT; >> ++ goto fail; >> ++ } >> +=20 >> +- 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 >> ++ */ >> +=20 >> ++ if (flags & O_CREAT) { >> ++ /* >> ++ * Darn, xattrs need at least 1 byte >> ++ */ >> ++ char null =3D '\0'; >> ++ >> ++ DEBUG(10, ("creating attribute %s on file >> %s\n", >> ++ xattr_name, smb_fname- >> >base_name)); >> ++ >> ++ fsp->fh->fd =3D hostfd; >> ++ ret =3D SMB_VFS_FSETXATTR(fsp, xattr_name, >> ++ &null, sizeof(null), >> ++ flags & O_EXCL ? >> XATTR_CREATE : 0); >> ++ fsp->fh->fd =3D -1; >> ++ if (ret !=3D 0) { >> ++ goto fail; >> ++ } >> ++ } >> ++ } >> ++ >> ++ if (flags & O_TRUNC) { >> ++ char null =3D '\0'; >> + if (fsp->base_fsp->fh->fd !=3D -1) { >> +- if (SMB_VFS_FSETXATTR( >> +- fsp->base_fsp, xattr_name, >> +- &null, sizeof(null), >> +- flags & O_EXCL ? XATTR_CREATE : 0) >> =3D=3D -1) { >> ++ if (SMB_VFS_FSETXATTR( >> ++ fsp->base_fsp, xattr_name, >> ++ &null, sizeof(null), >> ++ flags & O_EXCL ? >> XATTR_CREATE : 0) =3D=3D -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) >> =3D=3D -1) { >> ++ if (SMB_VFS_SETXATTR( >> ++ handle->conn, smb_fname- >> >base_name, >> ++ xattr_name, &null, >> sizeof(null), >> ++ flags & O_EXCL ? >> XATTR_CREATE : 0) =3D=3D -1) { >> + goto fail; >> + } >> + } >> + } >> +- } >> +- >> +- if (flags & O_TRUNC) { >> +- char null =3D '\0'; >> +- if (fsp->base_fsp->fh->fd !=3D -1) { >> +- if (SMB_VFS_FSETXATTR( >> +- fsp->base_fsp, xattr_name, >> +- &null, sizeof(null), >> +- flags & O_EXCL ? XATTR_CREATE : 0) >> =3D=3D -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) >> =3D=3D -1) { >> +- goto fail; >> +- } >> +- } >> +- } >> +=20 >> +- sio =3D (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp, >> ++ sio =3D (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp, >> + struct stream_io, >> + NULL); >> + if (sio =3D=3D NULL) { >> +@@ -511,8 +504,15 @@ >> +=20 >> + sio->xattr_name =3D talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handl= e, >> 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 =3D talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp= ), >> +- smb_fname->base_name); >> ++ fsp->fsp_name->base_name); >> + sio->fsp_name_ptr =3D fsp->fsp_name; >> + sio->handle =3D handle; >> + sio->fsp =3D fsp; >> +@@ -861,7 +861,7 @@ >> + return -1; >> + } >> +=20 >> +- status =3D get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, >> ++ status =3D 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 @@ >> +=20 >> + memcpy(ea.value.data + offset, data, n); >> +=20 >> +- if (fsp->base_fsp->fh->fd !=3D -1) { >> +- ret =3D SMB_VFS_FSETXATTR(fsp->base_fsp, >> ++ if (fsp->fh->fd !=3D -1) { >> ++ ret =3D SMB_VFS_FSETXATTR(fsp, >> + sio->xattr_name, >> + ea.value.data, ea.value.length, 0); >> + } else { >> + ret =3D 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; >> + } >> +=20 >> +- status =3D get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, >> ++ status =3D 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; >> + } >> +=20 >> +- status =3D get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, >> ++ status =3D 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 =3D offset + 1; >> + ea.value.data[offset] =3D 0; >> +=20 >> +- if (fsp->base_fsp->fh->fd !=3D -1) { >> +- ret =3D SMB_VFS_FSETXATTR(fsp->base_fsp, >> ++ if (fsp->fh->fd !=3D -1) { >> ++ ret =3D SMB_VFS_FSETXATTR(fsp, >> + sio->xattr_name, >> + ea.value.data, ea.value.length, 0); >> + } else { >> + ret =3D 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. >> + ********************************************************************/ >> +=20 >> +-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; >> + } >> +=20 >> +- dirp->conn =3D conn; >> +- dirp->name_cache_size =3D lp_directory_name_cache_size(SNUM(conn)); >> +- >> +- dirp->dir_path =3D talloc_strdup(dirp, name); >> +- if (!dirp->dir_path) { >> +- errno =3D ENOMEM; >> ++ dirp->dir =3D SMB_VFS_OPENDIR(conn, name, mask, attr); >> ++ if (!dirp->dir) { >> ++ DEBUG(5,("OpenDir: Can't open %s. %s\n", name, >> ++ strerror(errno) )); >> + goto fail; >> + } >> +=20 >> ++ dirp->conn =3D conn; >> ++ dirp->name_cache_size =3D lp_directory_name_cache_size(SNUM(conn)); >> ++ >> + if (sconn && !sconn->using_smb2) { >> + sconn->searches.dirhandles_open++; >> + } >> + talloc_set_destructor(dirp, smb_Dir_destructor); >> +=20 >> +- dirp->dir =3D 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; >> +=20 >> + fail: >> +@@ -1398,6 +1393,76 @@ >> + return NULL; >> + } >> +=20 >> ++/***********************************************************************= **** >> * >> ++ 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 =3D NULL; >> ++ char *saved_dir =3D vfs_GetWd(ctx, conn); >> ++ NTSTATUS status; >> ++ >> ++ if (saved_dir =3D=3D NULL) { >> ++ return NULL; >> ++ } >> ++ >> ++ if (vfs_ChDir(conn, name) =3D=3D -1) { >> ++ goto out; >> ++ } >> ++ >> ++ /* >> ++ * Now the directory is pinned, use >> ++ * REALPATH to ensure we can access it. >> ++ */ >> ++ status =3D check_name(conn, "."); >> ++ if (!NT_STATUS_IS_OK(status)) { >> ++ goto out; >> ++ } >> ++ >> ++ dir_hnd =3D OpenDir_internal(ctx, >> ++ conn, >> ++ ".", >> ++ wcard, >> ++ attr); >> ++ >> ++ if (dir_hnd =3D=3D NULL) { >> ++ goto out; >> ++ } >> ++ >> ++ /* >> ++ * OpenDir_internal only gets "." as the dir name. >> ++ * Store the real dir name here. >> ++ */ >> ++ >> ++ dir_hnd->dir_path =3D talloc_strdup(dir_hnd, name); >> ++ if (!dir_hnd->dir_path) { >> ++ errno =3D 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 =3D conn->sconn; >> +=20 >> + if (!dirp) { >> +- return NULL; >> ++ goto fail; >> ++ } >> ++ >> ++ if (!fsp->is_directory) { >> ++ errno =3D EBADF; >> ++ goto fail; >> ++ } >> ++ >> ++ if (fsp->fh->fd =3D=3D -1) { >> ++ errno =3D EBADF; >> ++ goto fail; >> + } >> +=20 >> + dirp->conn =3D conn; >> +@@ -1423,36 +1498,33 @@ >> + goto fail; >> + } >> +=20 >> +- if (sconn && !sconn->using_smb2) { >> +- sconn->searches.dirhandles_open++; >> +- } >> +- talloc_set_destructor(dirp, smb_Dir_destructor); >> +- >> +- if (fsp->is_directory && fsp->fh->fd !=3D -1) { >> +- dirp->dir =3D SMB_VFS_FDOPENDIR(fsp, mask, attr); >> +- if (dirp->dir !=3D NULL) { >> +- dirp->fsp =3D fsp; >> +- } else { >> +- DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s >> returned " >> +- "NULL (%s)\n", >> +- dirp->dir_path, >> +- strerror(errno))); >> +- if (errno !=3D ENOSYS) { >> +- return NULL; >> +- } >> ++ dirp->dir =3D SMB_VFS_FDOPENDIR(fsp, mask, attr); >> ++ if (dirp->dir !=3D NULL) { >> ++ dirp->fsp =3D fsp; >> ++ } else { >> ++ DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " >> ++ "NULL (%s)\n", >> ++ dirp->dir_path, >> ++ strerror(errno))); >> ++ if (errno !=3D ENOSYS) { >> ++ goto fail; >> + } >> + } >> +=20 >> + if (dirp->dir =3D=3D NULL) { >> +- /* FDOPENDIR didn't work. Use OPENDIR instead. */ >> +- dirp->dir =3D 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); >> + } >> +=20 >> +- 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); >> +=20 >> + return dirp; >> +=20 >> 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=3D12721 >> +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 >> +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=3D12721 >> + >> +Signed-off-by: Jeremy Allison >> +Reviewed-by: Uri Simchoni >> +(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 >> +Date: Mon, 27 Mar 2017 17:04:58 -0700 >> +Subject: [PATCH 2/3] s3: smbd: Fix "follow symlink =3D no" regression par= t 2. >> + >> +Add an extra paramter to cwd_name to check_reduced_name(). >> + >> +If cwd_name =3D=3D NULL then fname is a client given path relative >> +to the root path of the share. >> + >> +If cwd_name !=3D 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=3D12721 >> + >> +Signed-off-by: Jeremy Allison >> +Reviewed-by: Ralph Boehme >> +(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 >> +Date: Mon, 27 Mar 2017 17:09:38 -0700 >> +Subject: [PATCH 3/3] s3: smbd: Fix "follow symlink =3D no" regression par= t 2. >> + >> +Use the cwd_name parameter to reconstruct the original >> +client name for symlink testing. >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=3D12721 >> + >> +Signed-off-by: Jeremy Allison >> +Reviewed-by: Ralph Boehme >> +(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 =3D=3D NULL then fname is a client given path relative >> ++ to the root path of the share. >> ++ >> ++ If cwd_name !=3D NULL then fname is a client given path relative >> ++ to cwd_name. cwd_name is relative to the root path of the share. >> + ********************************************************************/ >> +=20 >> +-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 =3D NULL; >> ++ char *new_fname =3D NULL; >> + bool allow_symlinks =3D true; >> + bool allow_widelinks =3D false; >> +=20 >> +@@ -1026,8 +1035,11 @@ >> + /* fname can't have changed in resolved_path. */ >> + const char *p =3D &resolved_name[rootdir_len]; >> +=20 >> +- /* *p can be '\0' if fname was "." */ >> +- if (*p =3D=3D '\0' && ISDOT(fname)) { >> ++ /* >> ++ * UNIX filesystem semantics, names consisting >> ++ * only of "." or ".." CANNOT be symlinks. >> ++ */ >> ++ if (ISDOT(fname) || ISDOTDOT(fname)) { >> + goto out; >> + } >> +=20 >> +@@ -1041,11 +1053,32 @@ >> + } >> +=20 >> + 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 !=3D NULL && !ISDOT(cwd_name)) { >> ++ new_fname =3D talloc_asprintf(talloc_tos(), >> ++ "%s/%s", >> ++ cwd_name, >> ++ fname); >> ++ if (new_fname =3D=3D NULL) { >> ++ SAFE_FREE(resolved_name); >> ++ return NT_STATUS_NO_MEMORY; >> ++ } >> ++ fname =3D new_fname; >> ++ } >> ++ >> + if (strcmp(fname, p)!=3D0) { >> + 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; >> + } >> +=20 >> +--- samba-3.6.6.orig/source3/smbd/filename.c >> ++++ samba-3.6.6/source3/smbd/filename.c >> +@@ -1009,7 +1009,7 @@ >> + } >> +=20 >> + if (!lp_widelinks(SNUM(conn)) || !lp_symlinks(SNUM(conn))) { >> +- status =3D check_reduced_name(conn,name); >> ++ status =3D 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 @@ >> + } >> +=20 >> + /* Ensure the relative path is below the share. */ >> +- status =3D check_reduced_name(conn, final_component); >> ++ status =3D check_reduced_name(conn, parent_dir, final_component); >> + if (!NT_STATUS_IS_OK(status)) { >> + saved_errno =3D 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 *fnam= e, >> 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 regressi= on >> +origin: https://attachments.samba.org/attachment.cgi?id=3D13130 >> + >> +From 2c6de8584779e413f1e6ff9c933f9281693bfbc0 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +Date: Mon, 27 Mar 2017 11:48:25 -0700 >> +Subject: [PATCH 2/6] s3: Test for CVE-2017-2619 regression with "follow >> + symlinks =3D no". >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=3D12721 >> + >> +Signed-off-by: Jeremy Allison >> +Reviewed-by: Uri Simchoni >> + >> +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=3D"$msdfs_shrdir/deeppath"; >> + push(@dirs,$msdfs_deeppath); >> +=20 >> ++ my $nosymlinks_shrdir=3D"$shrdir/nosymlinks"; >> ++ push(@dirs,$nosymlinks_shrdir); >> ++ >> + # this gets autocreated by winbindd >> + my $wbsockdir=3D"$prefix_abs/winbindd"; >> + my $wbsockprivdir=3D"$lockdir/winbindd_privileged"; >> +@@ -695,6 +698,10 @@ sub provision($$$$$$) >> + copy =3D print1 >> + [print\$] >> + copy =3D tmp >> ++[nosymlinks] >> ++ copy =3D tmp >> ++ path =3D $nosymlinks_shrdir >> ++ follow symlinks =3D no >> + "; >> + close(CONF); >> +=20 >> +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 >> +=20 >> + LOGDIR=3D$(mktemp -d ${PREFIX}/${LOGDIR_PREFIX}_XXXXXX) >> +=20 >> ++# Test follow symlinks can't access symlinks >> ++test_nosymlinks() >> ++{ >> ++# Setup test dirs. >> ++ slink_name=3D"$LOCAL_PATH/nosymlinks/source" >> ++ slink_target=3D"$LOCAL_PATH/nosymlinks/target" >> ++ mkdir_target=3D"$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=3D$PREFIX/smbclient_interactive_prompt_commands >> ++ cat > $tmpfile <> ++get source >> ++quit >> ++EOF >> ++ cmd=3D'CLI_FORCE_INTERACTIVE=3Dyes $SMBCLIENT "$@" -U$USERNAME%$PASS= WORD >> //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' >> ++ eval echo "$cmd" >> ++ out=3D`eval $cmd` >> ++ ret=3D$? >> ++ rm -f $tmpfile >> ++ >> ++ if [ $ret !=3D 0 ] ; then >> ++ echo "$out" >> ++ echo "failed accessing nosymlinks with error $ret" >> ++ false >> ++ return >> ++ fi >> ++ >> ++ echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' >> ++ ret=3D$? >> ++ if [ $ret !=3D 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 <> ++mkdir a >> ++mkdir a\\b >> ++quit >> ++EOF >> ++ cmd=3D'CLI_FORCE_INTERACTIVE=3Dyes $SMBCLIENT "$@" -U$USERNAME%$PASS= WORD >> //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' >> ++ eval echo "$cmd" >> ++ out=3D`eval $cmd` >> ++ ret=3D$? >> ++ rm -f $tmpfile >> ++ >> ++ if [ $ret !=3D 0 ] ; then >> ++ echo "$out" >> ++ echo "failed accessing nosymlinks with error $ret" >> ++ false >> ++ return >> ++ fi >> ++ >> ++ echo "$out" | grep 'NT_STATUS' >> ++ ret=3D$? >> ++ if [ $ret =3D=3D 0 ] ; then >> ++ echo "$out" >> ++ echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b on >> \\nosymlinks" >> ++ false >> ++ fi >> ++} >> +=20 >> + testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p 139 || >> failed=3D`expr $failed + 1` >> + testit "smbclient -L $SERVER -I $SERVER_IP" $SMBCLIENT -L $SERVER -I >> $SERVER_IP -N -p 139 -c quit || failed=3D`expr $failed + 1` >> +@@ -445,6 +514,10 @@ testit "ccache access works for smbclient" \ >> + test_ccache_access || \ >> + failed=3D`expr $failed + 1` >> +=20 >> ++testit "follow symlinks =3D no" \ >> ++ test_nosymlinks || \ >> ++ failed=3D`expr $failed + 1` >> ++ >> + testit "rm -rf $LOGDIR" \ >> + rm -rf $LOGDIR || \ >> + failed=3D`expr $failed + 1` >> +--=20 >> +2.12.0 >> + >> + >> +From 17865cf188f42850f18f46514643a5b3a43e5707 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +Date: Mon, 27 Mar 2017 22:07:50 -0700 >> +Subject: [PATCH 3/6] s3: Fixup test for CVE-2017-2619 regression with "fo= llow >> + symlinks =3D no" >> + >> +Use correct bash operators (not string operators). >> +Add missing "return". >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=3D12721 >> + >> +Signed-off-by: Jeremy Allison >> +Reviewed-by: Ralph Boehme >> +(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=3D$? >> + rm -f $tmpfile >> +=20 >> +- if [ $ret !=3D 0 ] ; then >> ++ if [ $ret -ne 0 ] ; then >> + echo "$out" >> + echo "failed accessing nosymlinks with error $ret" >> + false >> +@@ -437,10 +437,11 @@ EOF >> +=20 >> + echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' >> + ret=3D$? >> +- if [ $ret !=3D 0 ] ; then >> ++ if [ $ret -ne 0 ] ; then >> + echo "$out" >> + echo "failed - should get NT_STATUS_ACCESS_DENIED getting >> \\nosymlinks\\source" >> + false >> ++ return >> + fi >> +=20 >> + # But we should be able to create and delete directories. >> +@@ -455,7 +456,7 @@ EOF >> + ret=3D$? >> + rm -f $tmpfile >> +=20 >> +- if [ $ret !=3D 0 ] ; then >> ++ if [ $ret -ne 0 ] ; then >> + echo "$out" >> + echo "failed accessing nosymlinks with error $ret" >> + false >> +@@ -464,7 +465,7 @@ EOF >> +=20 >> + echo "$out" | grep 'NT_STATUS' >> + ret=3D$? >> +- if [ $ret =3D=3D 0 ] ; then >> ++ if [ $ret -eq 0 ] ; then >> + echo "$out" >> + echo "failed - NT_STATUS_XXXX doing mkdir a; mkdir a\\b on >> \\nosymlinks" >> + false >> +--=20 >> +2.12.0 >> + >> + >> +From 9b573af39f3d4995464e30771fa06e0709b5e57b Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +Date: Mon, 27 Mar 2017 22:10:29 -0700 >> +Subject: [PATCH 6/6] s3: Test for CVE-2017-2619 regression with "follow >> + symlinks =3D no" - part 2 >> +MIME-Version: 1.0 >> +Content-Type: text/plain; charset=3DUTF-8 >> +Content-Transfer-Encoding: 8bit >> + >> +Add tests for regular access. >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=3D12721 >> + >> +Signed-off-by: Jeremy Allison >> +Reviewed-by: Ralph Boehme >> + >> +Autobuild-User(master): Ralph B=C3=B6hme >> +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=3D"$LOCAL_PATH/nosymlinks/source" >> + slink_target=3D"$LOCAL_PATH/nosymlinks/target" >> + mkdir_target=3D"$LOCAL_PATH/nosymlinks/a" >> ++ dir1=3D"$LOCAL_PATH/nosymlinks/foo" >> ++ dir2=3D"$LOCAL_PATH/nosymlinks/foo/bar" >> ++ get_target=3D"$LOCAL_PATH/nosymlinks/foo/bar/testfile" >> +=20 >> + rm -f $slink_target >> + rm -f $slink_name >> + rm -rf $mkdir_target >> ++ rm -rf $dir1 >> +=20 >> + touch $slink_target >> + ln -s $slink_target $slink_name >> +=20 >> ++ mkdir $dir1 >> ++ mkdir $dir2 >> ++ touch $get_target >> ++ >> + # Getting a file through a symlink name should fail. >> + tmpfile=3D$PREFIX/smbclient_interactive_prompt_commands >> + cat > $tmpfile <> +@@ -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 <> ++cd foo\\bar >> ++ls >> ++get testfile - >> ++quit >> ++EOF >> ++ cmd=3D'CLI_FORCE_INTERACTIVE=3Dyes $SMBCLIENT "$@" -U$USERNAME%$PASS= WORD >> //$SERVER/nosymlinks -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' >> ++ eval echo "$cmd" >> ++ out=3D`eval $cmd` >> ++ ret=3D$? >> ++ 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=3D$? >> ++ if [ $ret -eq 0 ] ; then >> ++ echo "$out" >> ++ echo "failed - NT_STATUS_XXXX doing cd foo\\bar; get testfile on >> \\nosymlinks" >> ++ false >> ++ return >> ++ fi >> + } >> +=20 >> + testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p 139 || >> failed=3D`expr $failed + 1` >> +--=20 >> +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 =3D cli_filename; >> + NTSTATUS status; >> +=20 >> ++ if (strchr(pipename, '/')) { >> ++ DEBUG(1, ("Refusing open on pipe %s\n", pipename)); >> ++ return false; >> ++ } >> ++ >> + if (strnequal(pipename, "\\PIPE\\", 6)) { >> + pipename +=3D 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 >> +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=3D11395 >> + >> +Signed-off-by: Jeremy Allison >> +Reviewed-by: Volker Lendecke >> +--- >> + 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; >> +=20 >> + conn_rootdir =3D SMB_VFS_CONNECTPATH(conn, fname); >> + if (conn_rootdir =3D=3D NULL) { >> +@@ -992,8 +993,10 @@ NTSTATUS check_reduced_name(connection_struct *conn, >> const char *fname) >> + } >> +=20 >> + rootdir_len =3D strlen(conn_rootdir); >> +- if (strncmp(conn_rootdir, resolved_name, >> +- rootdir_len) !=3D 0) { >> ++ matched =3D (strncmp(conn_rootdir, resolved_name, >> ++ rootdir_len) =3D=3D 0); >> ++ if (!matched || (resolved_name[rootdir_len] !=3D '/' && >> ++ resolved_name[rootdir_len] !=3D '\0')) { >> + DEBUG(2, ("check_reduced_name: Bad access " >> + "attempt: %s is a symlink outside the " >> + "share path\n", fname)); >> +--=20 >> +2.5.0 >> + >> +From 25139116756cc285a3a5534834cc276ef1b7baaa Mon Sep 17 00:00:00 2001 >> +From: Stefan Metzmacher >> +Date: Wed, 30 Sep 2015 21:17:02 +0200 >> +Subject: [PATCH 1/2] CVE-2015-5296: s3:libsmb: force signing when requiri= ng >> + encryption in do_connect() >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=3D11536 >> + >> +Signed-off-by: Stefan Metzmacher >> +Reviewed-by: Jeremy Allison >> +--- >> + 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 =3D get_cmdline_auth_info_signing_state(auth_info); >> ++ >> ++ if (force_encrypt) { >> ++ signing_state =3D Required; >> ++ } >> +=20 >> + /* make a copy so we don't modify the global string 'service' */ >> + servicename =3D talloc_strdup(ctx,share); >> +@@ -132,7 +137,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, >> + zero_sockaddr(&ss); >> +=20 >> + /* have to open a new connection */ >> +- c =3D >> cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)); >> ++ c =3D cli_initialise_ex(signing_state); >> + if (c =3D=3D NULL) { >> + d_printf("Connection to %s failed\n", server_n); >> + return NULL; >> +--=20 >> +2.5.0 >> + >> + >> +From 060adb0abdeda51b8b622c6020b5dea0c8dde1cf Mon Sep 17 00:00:00 2001 >> +From: Stefan Metzmacher >> +Date: Wed, 30 Sep 2015 21:17:02 +0200 >> +Subject: [PATCH 2/2] CVE-2015-5296: s3:libsmb: force signing when requiri= ng >> + encryption in SMBC_server_internal() >> + >> +BUG: https://bugzilla.samba.org/show_bug.cgi?id=3D11536 >> + >> +Signed-off-by: Stefan Metzmacher >> +Reviewed-by: Jeremy Allison >> +--- >> + 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_serve= r.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 =3D Undefined; >> +=20 >> + zero_sockaddr(&ss); >> + ZERO_STRUCT(c); >> +@@ -404,8 +405,12 @@ again: >> +=20 >> + zero_sockaddr(&ss); >> +=20 >> ++ if (context->internal->smb_encryption_level !=3D >> SMBC_ENCRYPTLEVEL_NONE) { >> ++ signing_state =3D Required; >> ++ } >> ++ >> + /* have to open a new connection */ >> +- if ((c =3D cli_initialise()) =3D=3D NULL) { >> ++ if ((c =3D cli_initialise_ex(signing_state)) =3D=3D NULL) { >> + errno =3D ENOMEM; >> + return NULL; >> + } >> +@@ -750,6 +755,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, >> + ipc_srv =3D SMBC_find_server(ctx, context, server, "*IPC$", >> + pp_workgroup, pp_username, pp_passwor= d); >> + if (!ipc_srv) { >> ++ int signing_state =3D Undefined; >> +=20 >> + /* We didn't find a cached connection. Get the password= */ >> + if (!*pp_password || (*pp_password)[0] =3D=3D '\0') { >> +@@ -771,6 +777,9 @@ SMBC_attr_server(TALLOC_CTX *ctx, >> + if (smbc_getOptionUseCCache(context)) { >> + flags |=3D CLI_FULL_CONNECTION_USE_CCACHE; >> + } >> ++ if (context->internal->smb_encryption_level !=3D >> SMBC_ENCRYPTLEVEL_NONE) { >> ++ signing_state =3D Required; >> ++ } >> +=20 >> + zero_sockaddr(&ss); >> + nt_status =3D 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))); >> +--=20 >> +2.5.0 >> + >> +From 8e49de7754f7171a58a1f94dee0f1138dbee3c60 Mon Sep 17 00:00:00 2001 >> +From: Jeremy Allison >> +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 >> + >> +https://bugzilla.samba.org/show_bug.cgi?id=3D11529 >> + >> +Signed-off-by: Jeremy Allison >> +Reviewed-by: David Disseldorp >> +--- >> + 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 @@ >> +=20 >> + #include "includes.h" >> + #include "smbd/smbd.h" >> ++#include "smbd/globals.h" >> ++#include "../libcli/security/security.h" >> + #include "system/filesys.h" >> + #include "ntioctl.h" >> +=20 >> +@@ -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); >> + } >> +=20 >> ++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 =3D 0; >> ++ >> ++ ZERO_STRUCT(smb_fname); >> ++ smb_fname.base_name =3D talloc_asprintf(talloc_tos(), >> ++ "%s", >> ++ path); >> ++ if (smb_fname.base_name =3D=3D NULL) { >> ++ return false; >> ++ } >> ++ >> ++ ret =3D SMB_VFS_NEXT_STAT(handle, &smb_fname); >> ++ if (ret !=3D 0 || !S_ISDIR(smb_fname.st.st_ex_mode)) { >> ++ TALLOC_FREE(smb_fname.base_name); >> ++ return false; >> ++ } >> ++ >> ++ status =3D 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 *fn= ame) >> + { >> + 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 =3D talloc_new(handle->data); >> + char *snapshot; >> ++ bool ret; >> +=20 >> + snapdir =3D shadow_copy2_find_snapdir(tmp_ctx, handle); >> + if (snapdir =3D=3D NULL) { >> +@@ -886,6 +926,13 @@ static int >> shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, >> + talloc_free(tmp_ctx); >> + return -1; >> + } >> ++ ret =3D check_access_snapdir(handle, snapdir); >> ++ if (!ret) { >> ++ DEBUG(0,("access denied on listing snapdir %s\n", snapdir)); >> ++ errno =3D EACCES; >> ++ talloc_free(tmp_ctx); >> ++ return -1; >> ++ } >> +=20 >> + p =3D SMB_VFS_NEXT_OPENDIR(handle, snapdir, NULL, 0); >> +=20 >> +--=20 >> +2.5.0 >> + >=20 --===============0445421404879118193==--