[Pkg-samba-maint] [samba] 03/03: Imported Debian patch 2:3.6.6-6+deb7u12
Roberto C. Sanchez
roberto at moszumanska.debian.org
Sat May 20 20:32:00 UTC 2017
This is an automated email from the git hooks/post-receive script.
roberto pushed a commit to branch wheezy
in repository samba.
commit 762a3afd8eb45526e44cd0b2ae8a5b1a058ec647
Author: Roberto C. Sanchez <roberto at debian.org>
Date: Fri Mar 31 17:58:52 2017 -0400
Imported Debian patch 2:3.6.6-6+deb7u12
---
debian/changelog | 48 +
debian/patches/CVE-2017-2619-prerequisites.patch | 270 +++++
.../patches/CVE-2017-2619-race-condition-fix.patch | 1150 ++++++++++++++++++++
.../CVE-2017-2619-regression-bug-12721-fix.patch | 179 +++
debian/patches/CVE-2017-2619-tests.patch | 296 +++++
debian/patches/series | 4 +
6 files changed, 1947 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index b9b8b2e..db54c6b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,51 @@
+samba (2:3.6.6-6+deb7u12) wheezy-security; urgency=high
+
+ * Non-maintainer upload by the LTS Team.
+ - CVE-2017-2619: symlink race permits opening files outside share directory
+ * Cherry-pick the following upstream changes required for CVE-2017-2619:
+ - s3: smbd: Maintain a back-pointer to the fsp in struct smb_Dir.
+ - s3: vfs: Change vfs_dirsort.c from MALLOC -> TALLOC.
+ - s3: vfs: Protect against early error in SMB_VFS_NEXT_READDIR.
+ - s3: vfs: Use an index i rather than re-using a state variable.
+ - s3: vfs: Protect open_and_sort_dir() from the directory changing size.
+ - s3: vfs: Clean error paths in opendir and fd_opendir.
+ - s3: vfs: Check SMB_VFS_NEXT_OPENDIR return in dirsort_opendir().
+ - s3: vfs: Convert mtime from a time_t to a struct timespec.
+ - s3: vfs: Remove the use of dirfd inside the vfs_dirsort.c.
+ * CVE-2017-2619 requires the following changes:
+ - s3: smbd: re-open directory after dptr_CloseDir()
+ - s3: vfs: dirsort doesn't handle opendir of "." correctly.
+ - s3: VFS: vfs_streams_xattr.c: Make streams_xattr_open() store the same
+ path as streams_xattr_recheck().
+ - vfs_streams_xattr: use fsp, not base_fsp
+ - s3: smbd: Create wrapper function for OpenDir in preparation for making
+ robust.
+ - s3: smbd: Opendir_internal() early return if SMB_VFS_OPENDIR failed.
+ - s3: smbd: Create and use open_dir_safely(). Use from OpenDir().
+ - s3: smbd: OpenDir_fsp() use early returns.
+ - s3: smbd: OpenDir_fsp() - Fix memory leak on error.
+ - s3: smbd: Move the reference counting and destructor setup to just before
+ retuning success.
+ - s3: smbd: Correctly fallback to open_dir_safely if FDOPENDIR not supported
+ on system.
+ - s3: smbd: Remove O_NOFOLLOW guards. We insist on O_NOFOLLOW existing.
+ - s3: smbd: Move special handling of symlink errno's into a utility
+ function.
+ - s3: smbd: Add the core functions to prevent symlink open races.
+ - s3: smbd: Use the new non_widelink_open() function.
+ * The initial CVE-2017-2619 fix caused a regression when the configuration
+ option "follow symlink = no" was set, requiring these changes:
+ - s3: smbd: Fix incorrect logic exposed by fix for the security bug 12496
+ (CVE-2017-2619).
+ - s3: smbd: Fix "follow symlink = no" regression part 2.
+ - s3: smbd: Fix "follow symlink = no" regression part 2.
+ * The regression fix was accompanied by these unit test changes/updates:
+ - s3: Test for CVE-2017-2619 regression with "follow symlinks = no".
+ - s3: Fixup test for CVE-2017-2619 regression with "follow symlinks = no"
+ - s3: Test for CVE-2017-2619 regression with "follow symlinks = no" - part 2
+
+ -- Roberto C. Sanchez <roberto at debian.org> Fri, 31 Mar 2017 17:58:52 -0400
+
samba (2:3.6.6-6+deb7u11) wheezy-security; urgency=medium
* Non-maintainer upload by the LTS Team.
diff --git a/debian/patches/CVE-2017-2619-prerequisites.patch b/debian/patches/CVE-2017-2619-prerequisites.patch
new file mode 100644
index 0000000..0fa8bf3
--- /dev/null
+++ b/debian/patches/CVE-2017-2619-prerequisites.patch
@@ -0,0 +1,270 @@
+Description: This patch is a consolidation of several commits (8234c6a, 629e302, 0a3b024, bc3714f, d302cb6, 94f7d0c, 33ead72, 66ee839, 77cacee) cherry-picked from Samba's upstream Git repository (v3-6-stable branch) because they contain changes which are dependencies of the CVE-2017-2619 patch (which upstream based upon version 3.6.25); this was done in lieu of upgrading wheezy from Samba 3.6.6 to 3.6.25
+origin: upstream , https://git.samba.org/?p=samba.git;a=commitdiff;h=8234c6a , https://git.samba.org/?p=samba.git;a=commitdiff;h=629e302 , https://git.samba.org/?p=samba.git;a=commitdiff;h=0a3b024 , https://git.samba.org/?p=samba.git;a=commitdiff;h=bc3714f , https://git.samba.org/?p=samba.git;a=commitdiff;h=d302cb6 , https://git.samba.org/?p=samba.git;a=commitdiff;h=94f7d0c , https://git.samba.org/?p=samba.git;a=commitdiff;h=33ead72 , https://git.samba.org/?p=samba.git;a=commitdiff;h=66e [...]
+
+--- samba-3.6.6.orig/source3/smbd/dir.c
++++ samba-3.6.6/source3/smbd/dir.c
+@@ -50,6 +50,8 @@
+ struct name_cache_entry *name_cache;
+ unsigned int name_cache_index;
+ unsigned int file_number;
++ files_struct *fsp; /* Back pointer to containing fsp, only
++ set from OpenDir_fsp(). */
+ };
+
+ struct dptr_struct {
+@@ -1428,7 +1430,9 @@
+
+ if (fsp->is_directory && fsp->fh->fd != -1) {
+ dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr);
+- if (dirp->dir == NULL) {
++ if (dirp->dir != NULL) {
++ dirp->fsp = fsp;
++ } else {
+ DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned "
+ "NULL (%s)\n",
+ dirp->dir_path,
+--- samba-3.6.6.orig/source3/modules/vfs_dirsort.c
++++ samba-3.6.6/source3/modules/vfs_dirsort.c
+@@ -30,40 +30,60 @@
+ struct dirsort_privates {
+ long pos;
+ SMB_STRUCT_DIRENT *directory_list;
+- long number_of_entries;
+- time_t mtime;
++ unsigned int number_of_entries;
++ struct timespec mtime;
+ SMB_STRUCT_DIR *source_directory;
+- int fd;
++ files_struct *fsp; /* If open via FDOPENDIR. */
++ struct smb_filename *smb_fname; /* If open via OPENDIR */
+ };
+
+ static void free_dirsort_privates(void **datap) {
+- struct dirsort_privates *data = (struct dirsort_privates *) *datap;
+- SAFE_FREE(data->directory_list);
+- SAFE_FREE(data);
+- *datap = NULL;
+-
+- return;
++ TALLOC_FREE(*datap);
+ }
+
+-static bool open_and_sort_dir (vfs_handle_struct *handle)
++static bool get_sorted_dir_mtime(vfs_handle_struct *handle,
++ struct dirsort_privates *data,
++ struct timespec *ret_mtime)
+ {
+- SMB_STRUCT_DIRENT *dp;
+- struct stat dir_stat;
+- long current_pos;
+- struct dirsort_privates *data = NULL;
++ int ret;
++ struct timespec mtime;
+
+- SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates,
+- return false);
++ if (data->fsp) {
++ ret = fsp_stat(data->fsp);
++ mtime = data->fsp->fsp_name->st.st_ex_mtime;
++ } else {
++ ret = SMB_VFS_STAT(handle->conn, data->smb_fname);
++ mtime = data->smb_fname->st.st_ex_mtime;
++ }
++
++ if (ret == -1) {
++ return false;
++ }
++
++ *ret_mtime = mtime;
++
++ return true;
++}
++
++static bool open_and_sort_dir(vfs_handle_struct *handle,
++ struct dirsort_privates *data)
++{
++ unsigned int i = 0;
++ unsigned int total_count = 0;
+
+ data->number_of_entries = 0;
+
+- if (fstat(data->fd, &dir_stat) == 0) {
+- data->mtime = dir_stat.st_mtime;
++ if (get_sorted_dir_mtime(handle, data, &data->mtime) == false) {
++ return false;
+ }
+
+ while (SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL)
+ != NULL) {
+- data->number_of_entries++;
++ total_count++;
++ }
++
++ if (total_count == 0) {
++ return false;
+ }
+
+ /* Open the underlying directory and count the number of entries
+@@ -71,21 +91,26 @@
+ SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory);
+
+ /* Set up an array and read the directory entries into it */
+- SAFE_FREE(data->directory_list); /* destroy previous cache if needed */
+- data->directory_list = (SMB_STRUCT_DIRENT *)SMB_MALLOC(
+- data->number_of_entries * sizeof(SMB_STRUCT_DIRENT));
++ TALLOC_FREE(data->directory_list); /* destroy previous cache if needed */
++ data->directory_list = talloc_zero_array(data,
++ SMB_STRUCT_DIRENT,
++ total_count);
+ if (!data->directory_list) {
+ return false;
+ }
+- current_pos = data->pos;
+- data->pos = 0;
+- while ((dp = SMB_VFS_NEXT_READDIR(handle, data->source_directory,
+- NULL)) != NULL) {
+- data->directory_list[data->pos++] = *dp;
++ for (i = 0; i < total_count; i++) {
++ SMB_STRUCT_DIRENT *dp = SMB_VFS_NEXT_READDIR(handle,
++ data->source_directory,
++ NULL);
++ if (dp == NULL) {
++ break;
++ }
++ data->directory_list[i] = *dp;
+ }
+
++ data->number_of_entries = i;
++
+ /* Sort the directory entries by name */
+- data->pos = current_pos;
+ TYPESAFE_QSORT(data->directory_list, data->number_of_entries, compare_dirent);
+ return true;
+ }
+@@ -94,12 +119,11 @@
+ const char *fname, const char *mask,
+ uint32 attr)
+ {
++ NTSTATUS status;
+ struct dirsort_privates *data = NULL;
+
+ /* set up our private data about this directory */
+- data = (struct dirsort_privates *)SMB_MALLOC(
+- sizeof(struct dirsort_privates));
+-
++ data = talloc_zero(handle->conn, struct dirsort_privates);
+ if (!data) {
+ return NULL;
+ }
+@@ -107,20 +131,34 @@
+ data->directory_list = NULL;
+ data->pos = 0;
+
++ status = create_synthetic_smb_fname(data,
++ fname,
++ NULL,
++ NULL,
++ &data->smb_fname);
++ if (!NT_STATUS_IS_OK(status)) {
++ TALLOC_FREE(data);
++ return NULL;
++ }
++
+ /* Open the underlying directory and count the number of entries */
+ data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask,
+ attr);
+
+- data->fd = dirfd(data->source_directory);
+-
+- SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
+- struct dirsort_privates, return NULL);
++ if (data->source_directory == NULL) {
++ TALLOC_FREE(data);
++ return NULL;
++ }
+
+- if (!open_and_sort_dir(handle)) {
++ if (!open_and_sort_dir(handle, data)) {
+ SMB_VFS_NEXT_CLOSEDIR(handle,data->source_directory);
++ TALLOC_FREE(data);
+ return NULL;
+ }
+
++ SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
++ struct dirsort_privates, return NULL);
++
+ return data->source_directory;
+ }
+
+@@ -132,37 +170,35 @@
+ struct dirsort_privates *data = NULL;
+
+ /* set up our private data about this directory */
+- data = (struct dirsort_privates *)SMB_MALLOC(
+- sizeof(struct dirsort_privates));
+-
++ data = talloc_zero(handle->conn, struct dirsort_privates);
+ if (!data) {
+ return NULL;
+ }
+
+ data->directory_list = NULL;
+ data->pos = 0;
++ data->fsp = fsp;
+
+ /* Open the underlying directory and count the number of entries */
+ data->source_directory = SMB_VFS_NEXT_FDOPENDIR(handle, fsp, mask,
+ attr);
+
+ if (data->source_directory == NULL) {
+- SAFE_FREE(data);
++ TALLOC_FREE(data);
+ return NULL;
+ }
+
+- data->fd = dirfd(data->source_directory);
+-
+- SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
+- struct dirsort_privates, return NULL);
+-
+- if (!open_and_sort_dir(handle)) {
++ if (!open_and_sort_dir(handle, data)) {
+ SMB_VFS_NEXT_CLOSEDIR(handle,data->source_directory);
++ TALLOC_FREE(data);
+ /* fd is now closed. */
+ fsp->fh->fd = -1;
+ return NULL;
+ }
+
++ SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
++ struct dirsort_privates, return NULL);
++
+ return data->source_directory;
+ }
+
+@@ -171,21 +207,18 @@
+ SMB_STRUCT_STAT *sbuf)
+ {
+ struct dirsort_privates *data = NULL;
+- time_t current_mtime;
+- struct stat dir_stat;
++ struct timespec current_mtime;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates,
+ return NULL);
+
+- if (fstat(data->fd, &dir_stat) == -1) {
++ if (get_sorted_dir_mtime(handle, data, ¤t_mtime) == false) {
+ return NULL;
+ }
+
+- current_mtime = dir_stat.st_mtime;
+-
+ /* throw away cache and re-read the directory if we've changed */
+- if (current_mtime > data->mtime) {
+- open_and_sort_dir(handle);
++ if (timespec_compare(¤t_mtime, &data->mtime) > 1) {
++ open_and_sort_dir(handle, data);
+ }
+
+ if (data->pos >= data->number_of_entries) {
diff --git a/debian/patches/CVE-2017-2619-race-condition-fix.patch b/debian/patches/CVE-2017-2619-race-condition-fix.patch
new file mode 100644
index 0000000..a96d6be
--- /dev/null
+++ b/debian/patches/CVE-2017-2619-race-condition-fix.patch
@@ -0,0 +1,1150 @@
+Description: This patch is a consolidation of several patches described by the Git commit summaries below
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-2619
+bug: https://bugzilla.samba.org/show_bug.cgi?id=12496
+
+From ec1bca1d5315549e945c93cbf5e3abdb695de782 Mon Sep 17 00:00:00 2001
+From: Jeremy Allison <jra at 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 at samba.org>
+Signed-off-by: Jeremy Allison <jra at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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/debian/patches/CVE-2017-2619-regression-bug-12721-fix.patch b/debian/patches/CVE-2017-2619-regression-bug-12721-fix.patch
new file mode 100644
index 0000000..cefdd86
--- /dev/null
+++ b/debian/patches/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 at 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 at samba.org>
+Reviewed-by: Uri Simchoni <uri at 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 at 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 at samba.org>
+Reviewed-by: Ralph Boehme <slow at 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 at 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 at samba.org>
+Reviewed-by: Ralph Boehme <slow at 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/debian/patches/CVE-2017-2619-tests.patch b/debian/patches/CVE-2017-2619-tests.patch
new file mode 100644
index 0000000..41c8461
--- /dev/null
+++ b/debian/patches/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 at 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 at samba.org>
+Reviewed-by: Uri Simchoni <uri at 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 at 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 at samba.org>
+Reviewed-by: Ralph Boehme <slow at 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 at 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 at samba.org>
+Reviewed-by: Ralph Boehme <slow at samba.org>
+
+Autobuild-User(master): Ralph Böhme <slow at 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/debian/patches/series b/debian/patches/series
index e576e83..5774787 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -53,3 +53,7 @@ netlogon_credentials_regression.patch
bug9669_regression.patch
fix_netapp.patch
security-CVE-2016-2125-Don-t-pass-GSS_C_DELEG_FLAG-by-def.patch
+CVE-2017-2619-prerequisites.patch
+CVE-2017-2619-race-condition-fix.patch
+CVE-2017-2619-regression-bug-12721-fix.patch
+CVE-2017-2619-tests.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-samba/samba.git
More information about the Pkg-samba-maint
mailing list