CVE-2017-2619 (Symlink race allows access outside share definition)
https://www.samba.org/samba/history/samba-4.4.12.html
Here's a backport. Build / test reports on -stable would be
appreciated.
Index: Makefile
===================================================================
RCS file: /d/cvs/ports/net/samba/Makefile,v
retrieving revision 1.227.2.2
diff -u -p -r1.227.2.2 Makefile
--- Makefile 18 Feb 2017 09:45:51 -0000 1.227.2.2
+++ Makefile 25 Mar 2017 16:18:48 -0000
@@ -15,7 +15,7 @@ PKGNAME-tevent = tevent-${TEVENT_V}
PKGNAME-util = samba-util-${VERSION}
PKGNAME-docs = samba-docs-${VERSION}
-REVISION-main = 1
+REVISION-main = 2
REVISION-ldb = 0
REVISION-tevent = 0
Index: patches/patch-source3_smbd_dir_c
===================================================================
RCS file: patches/patch-source3_smbd_dir_c
diff -N patches/patch-source3_smbd_dir_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-source3_smbd_dir_c 25 Mar 2017 16:20:56 -0000
@@ -0,0 +1,206 @@
+$OpenBSD$
+
+CVE-2017-2619 (Symlink race allows access outside share definition)
+
+--- source3/smbd/dir.c.orig Sat Mar 25 17:19:25 2017
++++ source3/smbd/dir.c Sat Mar 25 17:19:50 2017
+@@ -1588,7 +1588,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_t attr)
+@@ -1600,27 +1601,21 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connectio
+ 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:
+@@ -1628,6 +1623,76 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connectio
+ 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.
+ ********************************************************************/
+@@ -1641,9 +1706,19 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx
+ 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;
+ dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn));
+
+@@ -1653,36 +1728,33 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx
+ 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;
+
Index: patches/patch-source3_smbd_open_c
===================================================================
RCS file: patches/patch-source3_smbd_open_c
diff -N patches/patch-source3_smbd_open_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-source3_smbd_open_c 25 Mar 2017 16:21:02 -0000
@@ -0,0 +1,338 @@
+$OpenBSD$
+
+CVE-2017-2619 (Symlink race allows access outside share definition)
+
+--- source3/smbd/open.c.orig Sat Mar 25 17:19:25 2017
++++ source3/smbd/open.c Sat Mar 25 17:19:50 2017
+@@ -345,6 +345,268 @@ static NTSTATUS check_base_file_access(struct connecti
+ }
+
+ /****************************************************************************
++ 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;
++ }
++
++ smb_fname_rel = synthetic_smb_fname(talloc_tos(),
++ final_component,
++ smb_fname->stream_name,
++ &smb_fname->st);
++
++ 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_flags & FSP_POSIX_FLAGS_OPEN) {
++ /* Never follow symlinks on posix open. */
++ goto out;
++ }
++ if (!lp_follow_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.
+ ****************************************************************************/
+
+@@ -356,8 +618,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.
+ */
+@@ -365,29 +626,31 @@ NTSTATUS fd_open(struct connection_struct *conn,
+ if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ||
!lp_follow_symlinks(SNUM(conn))) {
+ flags |= O_NOFOLLOW;
+ }
+-#endif
+
+- fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
+- if (fsp->fh->fd == -1) {
+- int posix_errno = errno;
+-#ifdef O_NOFOLLOW
+-#if defined(ENOTSUP) && defined(OSF1)
+- /* handle special Tru64 errno */
+- if (errno == ENOTSUP) {
+- posix_errno = ELOOP;
++ /* 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;
+ }
+-#endif /* ENOTSUP */
+-#ifdef EFTYPE
+- /* fix broken NetBSD errno */
+- if (errno == EFTYPE) {
+- posix_errno = ELOOP;
+- }
+-#endif /* EFTYPE */
+- /* fix broken FreeBSD errno */
+- if (errno == EMLINK) {
+- posix_errno = ELOOP;
+- }
+-#endif /* O_NOFOLLOW */
++ /*
++ * 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);
+ if (errno == EMFILE) {
+ static time_t last_warned = 0L;
Index: patches/patch-source3_smbd_smb2_query_directory_c
===================================================================
RCS file: patches/patch-source3_smbd_smb2_query_directory_c
diff -N patches/patch-source3_smbd_smb2_query_directory_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-source3_smbd_smb2_query_directory_c 25 Mar 2017 16:21:05
-0000
@@ -0,0 +1,38 @@
+$OpenBSD$
+
+CVE-2017-2619 (Symlink race allows access outside share definition)
+
+--- source3/smbd/smb2_query_directory.c.orig Sat Mar 25 17:19:26 2017
++++ source3/smbd/smb2_query_directory.c Sat Mar 25 17:19:50 2017
+@@ -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_query_directory_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+@@ -322,7 +323,23 @@ static struct tevent_req *smbd_smb2_query_directory_se
+ }
+
+ 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 (!smbreq->posix_pathnames) {
Index: patches/patch-source4_torture_smb2_dir_c
===================================================================
RCS file: patches/patch-source4_torture_smb2_dir_c
diff -N patches/patch-source4_torture_smb2_dir_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-source4_torture_smb2_dir_c 25 Mar 2017 16:21:09 -0000
@@ -0,0 +1,50 @@
+$OpenBSD$
+
+CVE-2017-2619 (Symlink race allows access outside share definition)
+
+--- source4/torture/smb2/dir.c.orig Sat Mar 25 17:19:28 2017
++++ source4/torture/smb2/dir.c Sat Mar 25 17:19:50 2017
+@@ -674,7 +674,7 @@ bool fill_result(void *private_data,
+ return true;
+ }
+
+-enum continue_type {CONT_SINGLE, CONT_INDEX, CONT_RESTART};
++enum continue_type {CONT_SINGLE, CONT_INDEX, CONT_RESTART, CONT_REOPEN};
+
+ static NTSTATUS multiple_smb2_search(struct smb2_tree *tree,
+ TALLOC_CTX *tctx,
+@@ -700,6 +700,9 @@ static NTSTATUS multiple_smb2_search(struct smb2_tree
+
+ /* The search should start from the beginning everytime */
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
++ if (cont_type == CONT_REOPEN) {
++ f.in.continue_flags = SMB2_CONTINUE_FLAG_REOPEN;
++ }
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+@@ -803,18 +806,23 @@ static bool test_many_files(struct torture_context *tc
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "SINGLE",
SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
CONT_SINGLE},
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "INDEX",
SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
CONT_INDEX},
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "RESTART",
SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
CONT_RESTART},
++ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "REOPEN",
SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
CONT_REOPEN},
+ {"SMB2_FIND_DIRECTORY_INFO", "SINGLE",
SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO,
CONT_SINGLE},
+ {"SMB2_FIND_DIRECTORY_INFO", "INDEX",
SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO,
CONT_INDEX},
+ {"SMB2_FIND_DIRECTORY_INFO", "RESTART",
SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO,
CONT_RESTART},
++ {"SMB2_FIND_DIRECTORY_INFO", "REOPEN",
SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO,
CONT_REOPEN},
+ {"SMB2_FIND_FULL_DIRECTORY_INFO", "SINGLE",
SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,
CONT_SINGLE},
+ {"SMB2_FIND_FULL_DIRECTORY_INFO", "INDEX",
SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,
CONT_INDEX},
+ {"SMB2_FIND_FULL_DIRECTORY_INFO", "RESTART",
SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,
CONT_RESTART},
++ {"SMB2_FIND_FULL_DIRECTORY_INFO", "REOPEN",
SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,
CONT_REOPEN},
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "SINGLE",
SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO,
CONT_SINGLE},
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "INDEX",
SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO,
CONT_INDEX},
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "RESTART",
SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO,
CONT_RESTART},
++ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "REOPEN",
SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO,
CONT_REOPEN},
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "SINGLE",
SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO,
CONT_SINGLE},
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "INDEX",
SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO,
CONT_INDEX},
+- {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "RESTART",
SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO,
CONT_RESTART}
++ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "RESTART",
SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO,
CONT_RESTART},
++ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "REOPEN",
SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO,
CONT_REOPEN},
+ };
+
+ smb2_deltree(tree, DNAME);
--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE