]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/patches/samba/CVE-2017-2619.patch
Merge remote-tracking branch 'origin/next'
[ipfire-2.x.git] / src / patches / samba / CVE-2017-2619.patch
diff --git a/src/patches/samba/CVE-2017-2619.patch b/src/patches/samba/CVE-2017-2619.patch
deleted file mode 100644 (file)
index 149e085..0000000
+++ /dev/null
@@ -1,1328 +0,0 @@
-From a398754c9bb1639f762979765de6c540c714b5cb Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 20 Mar 2017 11:32:19 -0700
-Subject: [PATCH 01/15] CVE-2017-2619: s3/smbd: re-open directory after
- dptr_CloseDir()
-
-dptr_CloseDir() will close and invalidate the fsp's file descriptor, we
-have to reopen it.
-
-Bug: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Ralph Bohme <slow@samba.org>
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/open.c      |  2 +-
- source3/smbd/proto.h     |  2 ++
- source3/smbd/smb2_find.c | 17 +++++++++++++++++
- 3 files changed, 20 insertions(+), 1 deletion(-)
-
-diff --git a/source3/smbd/open.c b/source3/smbd/open.c
-index 441b8cd4362..35eee0a1485 100644
---- a/source3/smbd/open.c
-+++ b/source3/smbd/open.c
-@@ -197,7 +197,7 @@ static NTSTATUS check_base_file_access(struct connection_struct *conn,
-  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)
-diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
-index f5fad2bbb50..594edfa1e98 100644
---- a/source3/smbd/proto.h
-+++ b/source3/smbd/proto.h
-@@ -603,6 +603,8 @@ NTSTATUS smb1_file_se_access_check(connection_struct *conn,
-                               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,
-diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
-index 6fe6545c128..9dd3176497b 100644
---- a/source3/smbd/smb2_find.c
-+++ b/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,
-@@ -301,7 +302,23 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
-       }
-       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);
-+              }
-       }
-       wcard_has_wild = ms_has_wild(in_file_name);
--- 
-2.13.5
-
-
-From a35fa98b99aa60132eb2c083d6393c28905e2045 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Tue, 28 Feb 2017 09:24:07 -0800
-Subject: [PATCH 02/15] s3: vfs: dirsort doesn't handle opendir of "."
- correctly.
-
-Needs to store $cwd path for correct sorting.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12499
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/modules/vfs_dirsort.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c
-index 66582e67890..dbcf0b16ed3 100644
---- a/source3/modules/vfs_dirsort.c
-+++ b/source3/modules/vfs_dirsort.c
-@@ -153,6 +153,10 @@ static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle,
-               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);
--- 
-2.13.5
-
-
-From 23d2849d724a0f5bdf51dc7d7db438ed9fb4c2a9 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 13 Mar 2017 13:44:42 -0700
-Subject: [PATCH 03/15] s3: VFS: vfs_streams_xattr.c: Make streams_xattr_open()
- store the same path as streams_xattr_recheck().
-
-If the open is changing directories, fsp->fsp_name->base_name
-will be the full path from the share root, whilst
-smb_fname will be relative to the $cwd.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12546
-
-Back-ported from a24ba3e4083200ec9885363efc5769f43183fb6b
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/modules/vfs_streams_xattr.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
-index 731c813f4d7..be46f8dc1e6 100644
---- a/source3/modules/vfs_streams_xattr.c
-+++ b/source3/modules/vfs_streams_xattr.c
-@@ -511,8 +511,15 @@ static int streams_xattr_open(vfs_handle_struct *handle,
-         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;
--- 
-2.13.5
-
-
-From 91935aaf77c70e3e2436af1d6e4a538d29fd4276 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 13 Mar 2017 13:54:04 -0700
-Subject: [PATCH 04/15] vfs_streams_xattr: use fsp, not base_fsp
-
-The base_fsp's fd is always -1 as it's closed after being openend in
-create_file_unixpath().
-
-Additionally in streams_xattr_open force using of SMB_VFS_FSETXATTR() by
-sticking the just created fd into the fsp (and removing it afterwards).
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12591
-
-Back-ported from 021189e32ba507832b5e821e5cda8a2889225955.
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/modules/vfs_streams_xattr.c | 205 +++++++++++++++++-------------------
- 1 file changed, 99 insertions(+), 106 deletions(-)
-
-diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
-index be46f8dc1e6..a4ab84bba71 100644
---- a/source3/modules/vfs_streams_xattr.c
-+++ b/source3/modules/vfs_streams_xattr.c
-@@ -229,7 +229,7 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
-               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 @@ static int streams_xattr_open(vfs_handle_struct *handle,
-       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 @@ static int streams_xattr_open(vfs_handle_struct *handle,
-       /* 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;
-+              /* 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;
-+              }
--        hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp,
--                            baseflags, mode);
-+              /*
-+               * 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;
--      TALLOC_FREE(smb_fname_base);
-+              hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp,
-+                                    baseflags, mode);
--        /* 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);
--        }
-+              TALLOC_FREE(smb_fname_base);
--        if (hostfd == -1) {
--              goto fail;
--        }
-+              /* 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);
-+              }
--      status = get_ea_value(talloc_tos(), handle->conn, NULL,
--                            smb_fname->base_name, xattr_name, &ea);
-+              if (hostfd == -1) {
-+                      goto fail;
-+              }
--      DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status)));
-+              status = get_ea_value(talloc_tos(), handle->conn, NULL,
-+                                    smb_fname->base_name, xattr_name, &ea);
--      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.
--               */
--              DEBUG(10, ("streams_xattr_open: base file %s not around, "
--                         "returning ENOENT\n", smb_fname->base_name));
--              errno = ENOENT;
--              goto fail;
--      }
-+              DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status)));
--      if (!NT_STATUS_IS_OK(status)) {
--              /*
--               * The attribute does not exist
--               */
-+              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.
-+                       */
-+                      DEBUG(10, ("streams_xattr_open: base file %s not around, "
-+                                 "returning ENOENT\n", smb_fname->base_name));
-+                      errno = ENOENT;
-+                      goto fail;
-+              }
--                if (flags & O_CREAT) {
-+              if (!NT_STATUS_IS_OK(status)) {
-                       /*
--                       * Darn, xattrs need at least 1 byte
-+                       * The attribute does not exist
-                        */
--                        char null = '\0';
--                      DEBUG(10, ("creating attribute %s on file %s\n",
--                                 xattr_name, smb_fname->base_name));
-+                      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) {
-@@ -868,7 +861,7 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
-               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;
-@@ -892,13 +885,13 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
-         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);
-       }
-@@ -932,7 +925,7 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle,
-               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;
-@@ -977,7 +970,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
-               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;
-@@ -1002,13 +995,13 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
-       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);
-       }
--- 
-2.13.5
-
-
-From 3f3c731faaa59f4d3ce7e49c12795c40e048d29f Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 19 Dec 2016 11:55:56 -0800
-Subject: [PATCH 05/15] s3: smbd: Create wrapper function for OpenDir in
- preparation for making robust.
-
-CVE-2017-2619
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/dir.c | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
-diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
-index 18ecf066824..ebe2641f813 100644
---- a/source3/smbd/dir.c
-+++ b/source3/smbd/dir.c
-@@ -1367,7 +1367,8 @@ static int smb_Dir_destructor(struct smb_Dir *dirp)
-  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)
-@@ -1407,6 +1408,18 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
-       return NULL;
- }
-+struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
-+                      const char *name,
-+                      const char *mask,
-+                      uint32_t attr)
-+{
-+      return OpenDir_internal(mem_ctx,
-+                              conn,
-+                              name,
-+                              mask,
-+                              attr);
-+}
-+
- /*******************************************************************
-  Open a directory from an fsp.
- ********************************************************************/
--- 
-2.13.5
-
-
-From 7efeb067c1586e0f1cfbb775b1efcb3b92005140 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 19 Dec 2016 16:25:26 -0800
-Subject: [PATCH 06/15] s3: smbd: Opendir_internal() early return if
- SMB_VFS_OPENDIR failed.
-
-CVE-2017-2619
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/dir.c | 14 +++++++-------
- 1 file changed, 7 insertions(+), 7 deletions(-)
-
-diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
-index ebe2641f813..65327dd0dd1 100644
---- a/source3/smbd/dir.c
-+++ b/source3/smbd/dir.c
-@@ -1380,6 +1380,13 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx,
-               return NULL;
-       }
-+      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));
-@@ -1394,13 +1401,6 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx,
-       }
-       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:
--- 
-2.13.5
-
-
-From 49d22a0c51ef1f78f0488a7c35131887704e987b Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 19 Dec 2016 16:35:00 -0800
-Subject: [PATCH 07/15] s3: smbd: Create and use open_dir_safely(). Use from
- OpenDir().
-
-Hardens OpenDir against TOC/TOU races.
-
-CVE-2017-2619
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/dir.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++------
- 1 file changed, 59 insertions(+), 7 deletions(-)
-
-diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
-index 65327dd0dd1..2d168c3ba9f 100644
---- a/source3/smbd/dir.c
-+++ b/source3/smbd/dir.c
-@@ -1390,12 +1390,6 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx,
-       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;
--              goto fail;
--      }
--
-       if (sconn && !sconn->using_smb2) {
-               sconn->searches.dirhandles_open++;
-       }
-@@ -1408,12 +1402,70 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx,
-       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 OpenDir_internal(mem_ctx,
-+      return open_dir_safely(mem_ctx,
-                               conn,
-                               name,
-                               mask,
--- 
-2.13.5
-
-
-From 6426ae1f9ef53158a6fbe1912dfec40d834115fe Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 19 Dec 2016 12:13:20 -0800
-Subject: [PATCH 08/15] s3: smbd: OpenDir_fsp() use early returns.
-
-CVE-2017-2619
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/dir.c | 34 +++++++++++++++++++++-------------
- 1 file changed, 21 insertions(+), 13 deletions(-)
-
-diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
-index 2d168c3ba9f..6aed4a6da46 100644
---- a/source3/smbd/dir.c
-+++ b/source3/smbd/dir.c
-@@ -1485,7 +1485,17 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
-       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;
-@@ -1502,18 +1512,16 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
-       }
-       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) {
-+                      return NULL;
-               }
-       }
--- 
-2.13.5
-
-
-From f6581858ce665b880c5fea465ec61b1b0c504d89 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 19 Dec 2016 12:15:59 -0800
-Subject: [PATCH 09/15] s3: smbd: OpenDir_fsp() - Fix memory leak on error.
-
-CVE-2017-2619
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/dir.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
-index 6aed4a6da46..efd1a73aab6 100644
---- a/source3/smbd/dir.c
-+++ b/source3/smbd/dir.c
-@@ -1521,7 +1521,7 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
-                       dirp->dir_path,
-                       strerror(errno)));
-               if (errno != ENOSYS) {
--                      return NULL;
-+                      goto fail;
-               }
-       }
--- 
-2.13.5
-
-
-From bacba6987e58d44886d04b1dd5e36f7781dcd9b0 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 19 Dec 2016 12:32:07 -0800
-Subject: [PATCH 10/15] s3: smbd: Move the reference counting and destructor
- setup to just before retuning success.
-
-CVE-2017-2619
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/dir.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
-index efd1a73aab6..5eca128c033 100644
---- a/source3/smbd/dir.c
-+++ b/source3/smbd/dir.c
-@@ -1507,11 +1507,6 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
-               goto fail;
-       }
--      if (sconn && !sconn->using_smb2) {
--              sconn->searches.dirhandles_open++;
--      }
--      talloc_set_destructor(dirp, smb_Dir_destructor);
--
-       dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr);
-       if (dirp->dir != NULL) {
-               dirp->fsp = fsp;
-@@ -1536,6 +1531,11 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
-               goto fail;
-       }
-+      if (sconn && !sconn->using_smb2) {
-+              sconn->searches.dirhandles_open++;
-+      }
-+      talloc_set_destructor(dirp, smb_Dir_destructor);
-+
-       return dirp;
-   fail:
--- 
-2.13.5
-
-
-From 34b3d05b55f5c40de76ba65d6b028818518a519f Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 19 Dec 2016 12:35:32 -0800
-Subject: [PATCH 11/15] s3: smbd: Correctly fallback to open_dir_safely if
- FDOPENDIR not supported on system.
-
-CVE-2017-2619
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/dir.c | 15 +++++++--------
- 1 file changed, 7 insertions(+), 8 deletions(-)
-
-diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
-index 5eca128c033..7690cb18c1a 100644
---- a/source3/smbd/dir.c
-+++ b/source3/smbd/dir.c
-@@ -1521,14 +1521,13 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
-       }
-       if (dirp->dir == NULL) {
--              /* FDOPENDIR didn't work. Use OPENDIR instead. */
--              dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr);
--      }
--
--      if (!dirp->dir) {
--              DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", dirp->dir_path,
--                       strerror(errno) ));
--              goto fail;
-+              /* 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 (sconn && !sconn->using_smb2) {
--- 
-2.13.5
-
-
-From 84bc8b232a4495bff270b7800833ef6785937576 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Thu, 15 Dec 2016 12:52:13 -0800
-Subject: [PATCH 12/15] s3: smbd: Remove O_NOFOLLOW guards. We insist on
- O_NOFOLLOW existing.
-
-CVE-2017-2619
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/open.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
-diff --git a/source3/smbd/open.c b/source3/smbd/open.c
-index 35eee0a1485..8417f8aca4a 100644
---- a/source3/smbd/open.c
-+++ b/source3/smbd/open.c
-@@ -205,8 +205,7 @@ NTSTATUS fd_open(struct connection_struct *conn,
-       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.
-        */
-@@ -214,7 +213,6 @@ NTSTATUS fd_open(struct connection_struct *conn,
-       if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
-               flags |= O_NOFOLLOW;
-       }
--#endif
-       fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
-       if (fsp->fh->fd == -1) {
--- 
-2.13.5
-
-
-From af0c5a266ae65ad2a638fe48a7ad7d77417f97d7 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Thu, 15 Dec 2016 12:56:08 -0800
-Subject: [PATCH 13/15] s3: smbd: Move special handling of symlink errno's into
- a utility function.
-
-CVE-2017-2619
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/open.c | 30 ++++++++++++++++++++++++++++--
- 1 file changed, 28 insertions(+), 2 deletions(-)
-
-diff --git a/source3/smbd/open.c b/source3/smbd/open.c
-index 8417f8aca4a..e727e89e9d8 100644
---- a/source3/smbd/open.c
-+++ b/source3/smbd/open.c
-@@ -194,6 +194,31 @@ static NTSTATUS check_base_file_access(struct connection_struct *conn,
- }
- /****************************************************************************
-+ 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;
-+}
-+
-+/****************************************************************************
-  fd support routines - attempt to do a dos_open.
- ****************************************************************************/
-@@ -216,8 +241,9 @@ NTSTATUS fd_open(struct connection_struct *conn,
-       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) {
--- 
-2.13.5
-
-
-From c3bc4ff0367d7a3ebfd64db6defddea0bc3a5f4a Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Thu, 15 Dec 2016 13:04:46 -0800
-Subject: [PATCH 14/15] s3: smbd: Add the core functions to prevent symlink
- open races.
-
-CVE-2017-2619
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/open.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 242 insertions(+)
-
-diff --git a/source3/smbd/open.c b/source3/smbd/open.c
-index e727e89e9d8..0998adc416a 100644
---- a/source3/smbd/open.c
-+++ b/source3/smbd/open.c
-@@ -218,6 +218,248 @@ static int link_errno_convert(int err)
-       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.
- ****************************************************************************/
--- 
-2.13.5
-
-
-From 6a88d1cf3deb54a784f50c8eba3b9a24a65c1b34 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Thu, 15 Dec 2016 13:06:31 -0800
-Subject: [PATCH 15/15] s3: smbd: Use the new non_widelink_open() function.
-
-CVE-2017-2619
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
----
- source3/smbd/open.c | 23 ++++++++++++++++++++++-
- 1 file changed, 22 insertions(+), 1 deletion(-)
-
-diff --git a/source3/smbd/open.c b/source3/smbd/open.c
-index 0998adc416a..65ca14ec8b8 100644
---- a/source3/smbd/open.c
-+++ b/source3/smbd/open.c
-@@ -481,7 +481,28 @@ NTSTATUS fd_open(struct connection_struct *conn,
-               flags |= O_NOFOLLOW;
-       }
--      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) {
-               int posix_errno = link_errno_convert(errno);
-               status = map_nt_error_from_unix(posix_errno);
--- 
-2.13.5
-