smbd: Use has_other_nonposix_opens in smb_posix_unlink
[kai/samba-autobuild/.git] / source3 / smbd / trans2.c
index 65c2cb079aa39cd29fe98778de5113c702dc92f5..0003c3682e3cce33866d30dbc94159ed130c755d 100644 (file)
@@ -32,7 +32,6 @@
 #include "../libcli/auth/libcli_auth.h"
 #include "../librpc/gen_ndr/xattr.h"
 #include "../librpc/gen_ndr/ndr_security.h"
-#include "../librpc/gen_ndr/open_files.h"
 #include "libcli/security/security.h"
 #include "trans2.h"
 #include "auth.h"
@@ -41,6 +40,7 @@
 #include "printing.h"
 #include "lib/util_ea.h"
 #include "lib/readdir_attr.h"
+#include "messages.h"
 
 #define DIR_ENTRY_SAFETY_MARGIN 4096
 
@@ -55,7 +55,7 @@ static char *store_file_unix_basic_info2(connection_struct *conn,
                                const SMB_STRUCT_STAT *psbuf);
 
 /****************************************************************************
- Check if an open file handle or pathname is a symlink.
+ Check if an open file handle or smb_fname is a symlink.
 ****************************************************************************/
 
 static NTSTATUS refuse_symlink(connection_struct *conn,
@@ -68,14 +68,22 @@ static NTSTATUS refuse_symlink(connection_struct *conn,
        if (fsp) {
                pst = &fsp->fsp_name->st;
        } else {
+               pst = &smb_fname->st;
+       }
+
+       if (!VALID_STAT(*pst)) {
                int ret = vfs_stat_smb_basename(conn,
-                               smb_fname->base_name,
+                               smb_fname,
                                &sbuf);
-               if (ret == -1) {
+               if (ret == -1 && errno != ENOENT) {
                        return map_nt_error_from_unix(errno);
+               } else if (ret == -1) {
+                       /* it's not a symlink.. */
+                       return NT_STATUS_OK;
                }
                pst = &sbuf;
        }
+
        if (S_ISLNK(pst->st_ex_mode)) {
                return NT_STATUS_ACCESS_DENIED;
        }
@@ -138,6 +146,9 @@ uint64_t smb_roundup(connection_struct *conn, uint64_t val)
 uint64_t get_FileIndex(connection_struct *conn, const SMB_STRUCT_STAT *psbuf)
 {
        uint64_t file_index;
+       if (conn->sconn->aapl_zero_file_id) {
+               return 0;
+       }
        if (conn->base_share_dev == psbuf->st_ex_dev) {
                return (uint64_t)psbuf->st_ex_ino;
        }
@@ -146,6 +157,17 @@ uint64_t get_FileIndex(connection_struct *conn, const SMB_STRUCT_STAT *psbuf)
        return file_index;
 }
 
+
+/********************************************************************
+ Globally (for this connection / multi-channel) disable file-ID
+ calculation. This is required to be global because it serves
+ Macs in AAPL mode, which is globally set.
+********************************************************************/
+void aapl_force_zero_file_id(struct smbd_server_connection *sconn)
+{
+       sconn->aapl_zero_file_id = true;
+}
+
 /****************************************************************************
  Utility functions for dealing with extended attributes.
 ****************************************************************************/
@@ -181,9 +203,12 @@ bool samba_private_attr_name(const char *unix_ea_name)
  Get one EA value. Fill in a struct ea_struct.
 ****************************************************************************/
 
-NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
-                     files_struct *fsp, const char *fname,
-                     const char *ea_name, struct ea_struct *pea)
+NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx,
+                       connection_struct *conn,
+                       files_struct *fsp,
+                       const struct smb_filename *smb_fname,
+                       const char *ea_name,
+                       struct ea_struct *pea)
 {
        /* Get the value of this xattr. Max size is 64k. */
        size_t attr_size = 256;
@@ -200,7 +225,8 @@ NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
        if (fsp && fsp->fh->fd != -1) {
                sizeret = SMB_VFS_FGETXATTR(fsp, ea_name, val, attr_size);
        } else {
-               sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
+               sizeret = SMB_VFS_GETXATTR(conn, smb_fname,
+                               ea_name, val, attr_size);
        }
 
        if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
@@ -237,12 +263,14 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
                                char ***pnames,
                                size_t *pnum_names)
 {
+       char smallbuf[1024];
        /* Get a list of all xattrs. Max namesize is 64k. */
        size_t ea_namelist_size = 1024;
-       char *ea_namelist = NULL;
+       char *ea_namelist = smallbuf;
+       char *to_free = NULL;
 
        char *p;
-       char **names, **tmp;
+       char **names;
        size_t num_names;
        ssize_t sizeret = -1;
        NTSTATUS status;
@@ -252,10 +280,6 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
        }
        *pnum_names = 0;
 
-       if (!lp_ea_support(SNUM(conn))) {
-               return NT_STATUS_OK;
-       }
-
        status = refuse_symlink(conn, fsp, smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                /*
@@ -264,54 +288,45 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
                return NT_STATUS_OK;
        }
 
-       /*
-        * TALLOC the result early to get the talloc hierarchy right.
-        */
-
-       names = talloc_array(mem_ctx, char *, 1);
-       if (names == NULL) {
-               DEBUG(0, ("talloc failed\n"));
-               return NT_STATUS_NO_MEMORY;
+       if (fsp && fsp->fh->fd != -1) {
+               sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
+                                            ea_namelist_size);
+       } else {
+               sizeret = SMB_VFS_LISTXATTR(conn,
+                                           smb_fname,
+                                           ea_namelist,
+                                           ea_namelist_size);
        }
 
-       while (ea_namelist_size <= 65536) {
-
-               ea_namelist = talloc_realloc(
-                       names, ea_namelist, char, ea_namelist_size);
+       if ((sizeret == -1) && (errno == ERANGE)) {
+               ea_namelist_size = 65536;
+               ea_namelist = talloc_array(mem_ctx, char, ea_namelist_size);
                if (ea_namelist == NULL) {
-                       DEBUG(0, ("talloc failed\n"));
-                       TALLOC_FREE(names);
                        return NT_STATUS_NO_MEMORY;
                }
+               to_free = ea_namelist;
 
                if (fsp && fsp->fh->fd != -1) {
                        sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
                                                     ea_namelist_size);
                } else {
                        sizeret = SMB_VFS_LISTXATTR(conn,
-                                       smb_fname->base_name,
-                                       ea_namelist,
-                                       ea_namelist_size);
-               }
-
-               if ((sizeret == -1) && (errno == ERANGE)) {
-                       ea_namelist_size *= 2;
-               }
-               else {
-                       break;
+                                                   smb_fname,
+                                                   ea_namelist,
+                                                   ea_namelist_size);
                }
        }
 
        if (sizeret == -1) {
-               TALLOC_FREE(names);
-               return map_nt_error_from_unix(errno);
+               status = map_nt_error_from_unix(errno);
+               TALLOC_FREE(to_free);
+               return status;
        }
 
-       DEBUG(10, ("%s: ea_namelist size = %u\n",
-                  __func__, (unsigned int)sizeret));
+       DBG_DEBUG("ea_namelist size = %zd\n", sizeret);
 
        if (sizeret == 0) {
-               TALLOC_FREE(names);
+               TALLOC_FREE(to_free);
                return NT_STATUS_OK;
        }
 
@@ -320,7 +335,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
         */
 
        if (ea_namelist[sizeret-1] != '\0') {
-               TALLOC_FREE(names);
+               TALLOC_FREE(to_free);
                return NT_STATUS_INTERNAL_ERROR;
        }
 
@@ -333,26 +348,45 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
                num_names += 1;
        }
 
-       tmp = talloc_realloc(mem_ctx, names, char *, num_names);
-       if (tmp == NULL) {
+       *pnum_names = num_names;
+
+       if (pnames == NULL) {
+               TALLOC_FREE(to_free);
+               return NT_STATUS_OK;
+       }
+
+       names = talloc_array(mem_ctx, char *, num_names);
+       if (names == NULL) {
                DEBUG(0, ("talloc failed\n"));
-               TALLOC_FREE(names);
+               TALLOC_FREE(to_free);
                return NT_STATUS_NO_MEMORY;
        }
 
-       names = tmp;
+       if (ea_namelist == smallbuf) {
+               ea_namelist = talloc_memdup(names, smallbuf, sizeret);
+               if (ea_namelist == NULL) {
+                       TALLOC_FREE(names);
+                       return NT_STATUS_NO_MEMORY;
+               }
+       } else {
+               talloc_steal(names, ea_namelist);
+
+               ea_namelist = talloc_realloc(names, ea_namelist, char,
+                                            sizeret);
+               if (ea_namelist == NULL) {
+                       TALLOC_FREE(names);
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
        num_names = 0;
 
        for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
                names[num_names++] = p;
        }
 
-       if (pnames) {
-               *pnames = names;
-       } else {
-               TALLOC_FREE(names);
-       }
-       *pnum_names = num_names;
+       *pnames = names;
+
        return NT_STATUS_OK;
 }
 
@@ -377,6 +411,10 @@ static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx,
        *pea_total_len = 0;
        *ea_list = NULL;
 
+       if (!lp_ea_support(SNUM(conn))) {
+               return NT_STATUS_OK;
+       }
+
        if (fsp) {
                posix_pathnames =
                        (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
@@ -396,7 +434,6 @@ static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx,
        }
 
        if (num_names == 0) {
-               *ea_list = NULL;
                return NT_STATUS_OK;
        }
 
@@ -425,7 +462,7 @@ static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx,
                status = get_ea_value(listp,
                                        conn,
                                        fsp,
-                                       smb_fname->base_name,
+                                       smb_fname,
                                        names[i],
                                        &listp->ea);
 
@@ -767,7 +804,7 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
                                DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
                                        unix_ea_name, smb_fname->base_name));
                                ret = SMB_VFS_REMOVEXATTR(conn,
-                                               smb_fname->base_name,
+                                               smb_fname,
                                                unix_ea_name);
                        }
 #ifdef ENOATTR
@@ -789,7 +826,7 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
                                DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
                                        unix_ea_name, smb_fname->base_name));
                                ret = SMB_VFS_SETXATTR(conn,
-                                               smb_fname->base_name,
+                                               smb_fname,
                                                unix_ea_name,
                                                ea_list->ea.value.data,
                                                ea_list->ea.value.length,
@@ -1192,7 +1229,7 @@ static void call_trans2open(connection_struct *conn,
        uint32_t create_disposition;
        uint32_t create_options = 0;
        uint32_t private_flags = 0;
-       uint32_t ucf_flags = (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+       uint32_t ucf_flags = ucf_flags_from_smb_request(req);
        TALLOC_CTX *ctx = talloc_tos();
 
        /*
@@ -1256,7 +1293,6 @@ static void call_trans2open(connection_struct *conn,
 
        status = filename_convert(ctx,
                                conn,
-                               req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
                                ucf_flags,
                                NULL,
@@ -1541,18 +1577,18 @@ static NTSTATUS unix_perms_from_wire( connection_struct *conn,
 ****************************************************************************/
 
 static bool check_msdfs_link(connection_struct *conn,
-                               const char *pathname,
-                               SMB_STRUCT_STAT *psbuf)
+                               struct smb_filename *smb_fname)
 {
        int saved_errno = errno;
        if(lp_host_msdfs() &&
                lp_msdfs_root(SNUM(conn)) &&
-               is_msdfs_link(conn, pathname, psbuf)) {
+               is_msdfs_link(conn, smb_fname)) {
 
                DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
                        "as a directory\n",
-                       pathname));
-               psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
+                       smb_fname->base_name));
+               smb_fname->st.st_ex_mode =
+                       (smb_fname->st.st_ex_mode & 0xFFF) | S_IFDIR;
                errno = saved_errno;
                return true;
        }
@@ -1672,6 +1708,7 @@ static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX *ctx,
 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX *ctx,
                                        void *private_data,
                                        struct smb_filename *smb_fname,
+                                       bool get_dosmode,
                                        uint32_t *_mode)
 {
        struct smbd_dirptr_lanman2_state *state =
@@ -1693,8 +1730,7 @@ static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX *ctx,
                 * directories */
 
                ms_dfs_link = check_msdfs_link(state->conn,
-                                              smb_fname->base_name,
-                                              &smb_fname->st);
+                                              smb_fname);
                if (!ms_dfs_link) {
                        DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
                                 "Couldn't stat [%s] (%s)\n",
@@ -1706,7 +1742,7 @@ static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX *ctx,
 
        if (ms_dfs_link) {
                mode = dos_mode_msdfs(state->conn, smb_fname);
-       } else {
+       } else if (get_dosmode) {
                mode = dos_mode(state->conn, smb_fname);
        }
 
@@ -2415,15 +2451,18 @@ NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
                               int requires_resume_key,
                               bool dont_descend,
                               bool ask_sharemode,
+                              bool get_dosmode,
                               uint8_t align,
                               bool do_pad,
                               char **ppdata,
                               char *base_data,
                               char *end_data,
                               int space_remaining,
+                              struct smb_filename **_smb_fname,
                               bool *got_exact_match,
                               int *_last_entry_off,
-                              struct ea_list *name_list)
+                              struct ea_list *name_list,
+                              struct file_id *file_id)
 {
        const char *p;
        const char *mask = NULL;
@@ -2435,11 +2474,17 @@ NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
        bool ok;
        uint64_t last_entry_off = 0;
        NTSTATUS status;
+       enum mangled_names_options mangled_names;
+       bool marshall_with_83_names;
+
+       mangled_names = lp_mangled_names(conn->params);
 
        ZERO_STRUCT(state);
        state.conn = conn;
        state.info_level = info_level;
-       state.check_mangled_names = lp_mangled_names(conn->params);
+       if (mangled_names != MANGLED_NAMES_NO) {
+               state.check_mangled_names = true;
+       }
        state.has_wild = dptr_has_wild(dirptr);
        state.got_exact_match = false;
 
@@ -2462,6 +2507,7 @@ NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
                                   dirtype,
                                   dont_descend,
                                   ask_sharemode,
+                                  get_dosmode,
                                   smbd_dirptr_lanman2_match_fn,
                                   smbd_dirptr_lanman2_mode_fn,
                                   &state,
@@ -2475,12 +2521,14 @@ NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
 
        *got_exact_match = state.got_exact_match;
 
+       marshall_with_83_names = (mangled_names == MANGLED_NAMES_YES);
+
        status = smbd_marshall_dir_entry(ctx,
                                     conn,
                                     flags2,
                                     info_level,
                                     name_list,
-                                    state.check_mangled_names,
+                                    marshall_with_83_names,
                                     requires_resume_key,
                                     mode,
                                     fname,
@@ -2496,15 +2544,38 @@ NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
                DEBUG(1,("Conversion error: illegal character: %s\n",
                         smb_fname_str_dbg(smb_fname)));
        }
-       TALLOC_FREE(fname);
+
+       if (file_id != NULL) {
+               *file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+       }
+
+       if (!NT_STATUS_IS_OK(status) &&
+           !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
+       {
+               TALLOC_FREE(smb_fname);
+               TALLOC_FREE(fname);
+               return status;
+       }
+
+       if (_smb_fname != NULL) {
+               struct smb_filename *name = NULL;
+
+               name = synthetic_smb_fname(ctx, fname, NULL, &smb_fname->st, 0);
+               if (name == NULL) {
+                       TALLOC_FREE(smb_fname);
+                       TALLOC_FREE(fname);
+                       return NT_STATUS_NO_MEMORY;
+               }
+               *_smb_fname = name;
+       }
+
        TALLOC_FREE(smb_fname);
+       TALLOC_FREE(fname);
+
        if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
                dptr_SeekDir(dirptr, prev_dirpos);
                return status;
        }
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
 
        *_last_entry_off = last_entry_off;
        return NT_STATUS_OK;
@@ -2539,11 +2610,12 @@ static NTSTATUS get_lanman2_dir_entry(TALLOC_CTX *ctx,
        return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
                                         path_mask, dirtype, info_level,
                                         requires_resume_key, dont_descend, ask_sharemode,
-                                        align, do_pad,
+                                        true, align, do_pad,
                                         ppdata, base_data, end_data,
                                         space_remaining,
+                                        NULL,
                                         got_exact_match,
-                                        last_entry_off, name_list);
+                                        last_entry_off, name_list, NULL);
 }
 
 /****************************************************************************
@@ -2590,7 +2662,7 @@ static void call_trans2findfirst(connection_struct *conn,
        struct dptr_struct *dirptr = NULL;
        struct smbd_server_connection *sconn = req->sconn;
        uint32_t ucf_flags = UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP |
-                       (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+                       ucf_flags_from_smb_request(req);
        bool backup_priv = false;
        bool as_root = false;
 
@@ -2686,7 +2758,6 @@ close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_da
                                &smb_dname);
        } else {
                ntstatus = filename_convert(talloc_tos(), conn,
-                                   req->flags2 & FLAGS2_DFS_PATHNAMES,
                                    directory,
                                    ucf_flags,
                                    &mask_contains_wcard,
@@ -2819,9 +2890,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
        dptr_num = dptr_dnum(dirptr);
        DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
 
-       /* Initialize per TRANS2_FIND_FIRST operation data */
-       dptr_init_search_op(dirptr);
-
        /* We don't need to check for VOL here as this is returned by
                a different TRANS2 call. */
 
@@ -3189,9 +3257,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                dptr_TellDir(dirptr),
                (int)backup_priv));
 
-       /* Initialize per TRANS2_FIND_NEXT operation data */
-       dptr_init_search_op(dirptr);
-
        /* We don't need to check for VOL here as this is returned by
                a different TRANS2 call. */
 
@@ -3410,7 +3475,8 @@ NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
        ZERO_STRUCT(smb_fname);
        smb_fname.base_name = discard_const_p(char, filename);
 
-       if(SMB_VFS_STAT(conn, &smb_fname) != 0) {
+       if(info_level != SMB_FS_QUOTA_INFORMATION
+          && SMB_VFS_STAT(conn, &smb_fname) != 0) {
                DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
                return map_nt_error_from_unix(errno);
        }
@@ -3438,8 +3504,8 @@ NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
                {
                        uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
                        data_len = 18;
-                       df_ret = get_dfree_info(conn, filename, &bsize, &dfree,
-                                               &dsize);
+                       df_ret = get_dfree_info(conn, &smb_fname, &bsize,
+                                               &dfree, &dsize);
                        if (df_ret == (uint64_t)-1) {
                                return map_nt_error_from_unix(errno);
                        }
@@ -3463,6 +3529,12 @@ NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
                                (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
 
+                       /*
+                        * For large drives, return max values and not modulo.
+                        */
+                       dsize = MIN(dsize, UINT32_MAX);
+                       dfree = MIN(dfree, UINT32_MAX);
+
                        SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
                        SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
                        SIVAL(pdata,l1_cUnit,dsize);
@@ -3589,8 +3661,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
                {
                        uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
                        data_len = 24;
-                       df_ret = get_dfree_info(conn, filename, &bsize, &dfree,
-                                               &dsize);
+                       df_ret = get_dfree_info(conn, &smb_fname, &bsize,
+                                               &dfree, &dsize);
                        if (df_ret == (uint64_t)-1) {
                                return map_nt_error_from_unix(errno);
                        }
@@ -3623,8 +3695,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                {
                        uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
                        data_len = 32;
-                       df_ret = get_dfree_info(conn, filename, &bsize, &dfree,
-                                               &dsize);
+                       df_ret = get_dfree_info(conn, &smb_fname, &bsize,
+                                               &dfree, &dsize);
                        if (df_ret == (uint64_t)-1) {
                                return map_nt_error_from_unix(errno);
                        }
@@ -3712,9 +3784,11 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                                return NT_STATUS_ACCESS_DENIED;
                        }
 
-                       if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
+                       status = vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE,
+                                                NULL, &quotas);
+                       if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn))));
-                               return map_nt_error_from_unix(errno);
+                               return status;
                        }
 
                        data_len = 48;
@@ -3848,7 +3922,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                                return NT_STATUS_INVALID_LEVEL;
                        }
 
-                       rc = SMB_VFS_STATVFS(conn, filename, &svfs);
+                       rc = SMB_VFS_STATVFS(conn, &smb_fname, &svfs);
 
                        if (!rc) {
                                data_len = 56;
@@ -3982,7 +4056,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                                SIVAL(pdata,84,0x100); /* Don't support mac... */
                                break;
                        }
-                       /* drop through */
+
+                       FALL_THROUGH;
                default:
                        return NT_STATUS_INVALID_LEVEL;
        }
@@ -3991,6 +4066,86 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
        return status;
 }
 
+static NTSTATUS smb_set_fsquota(connection_struct *conn,
+                       struct smb_request *req,
+                       files_struct *fsp,
+                       const DATA_BLOB *qdata)
+{
+       NTSTATUS status;
+       SMB_NTQUOTA_STRUCT quotas;
+
+       ZERO_STRUCT(quotas);
+
+       /* access check */
+       if ((get_current_uid(conn) != 0) || !CAN_WRITE(conn)) {
+               DEBUG(3, ("set_fsquota: access_denied service [%s] user [%s]\n",
+                         lp_servicename(talloc_tos(), SNUM(conn)),
+                         conn->session_info->unix_info->unix_name));
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       if (!check_fsp_ntquota_handle(conn, req,
+                                     fsp)) {
+               DEBUG(1, ("set_fsquota: no valid QUOTA HANDLE\n"));
+               return NT_STATUS_INVALID_HANDLE;
+       }
+
+       /* note: normally there're 48 bytes,
+        * but we didn't use the last 6 bytes for now
+        * --metze
+        */
+       if (qdata->length < 42) {
+               DEBUG(0,("set_fsquota: requires total_data(%u) >= 42 bytes!\n",
+                       (unsigned int)qdata->length));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       /* unknown_1 24 NULL bytes in pdata*/
+
+       /* the soft quotas 8 bytes (uint64_t)*/
+       quotas.softlim = BVAL(qdata->data,24);
+
+       /* the hard quotas 8 bytes (uint64_t)*/
+       quotas.hardlim = BVAL(qdata->data,32);
+
+       /* quota_flags 2 bytes **/
+       quotas.qflags = SVAL(qdata->data,40);
+
+       /* unknown_2 6 NULL bytes follow*/
+
+       /* now set the quotas */
+       if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
+               DEBUG(1, ("vfs_set_ntquota() failed for service [%s]\n",
+                         lp_servicename(talloc_tos(), SNUM(conn))));
+               status =  map_nt_error_from_unix(errno);
+       } else {
+               status = NT_STATUS_OK;
+       }
+       return status;
+}
+
+NTSTATUS smbd_do_setfsinfo(connection_struct *conn,
+                                struct smb_request *req,
+                                TALLOC_CTX *mem_ctx,
+                                uint16_t info_level,
+                                files_struct *fsp,
+                               const DATA_BLOB *pdata)
+{
+       switch (info_level) {
+               case SMB_FS_QUOTA_INFORMATION:
+               {
+                       return smb_set_fsquota(conn,
+                                               req,
+                                               fsp,
+                                               pdata);
+               }
+
+               default:
+                       break;
+       }
+       return NT_STATUS_INVALID_LEVEL;
+}
+
 /****************************************************************************
  Reply to a TRANS2_QFSINFO (query filesystem info).
 ****************************************************************************/
@@ -4218,63 +4373,22 @@ static void call_trans2setfsinfo(connection_struct *conn,
 
                case SMB_FS_QUOTA_INFORMATION:
                        {
+                               NTSTATUS status;
+                               DATA_BLOB qdata = {
+                                               .data = (uint8_t *)pdata,
+                                               .length = total_data
+                               };
                                files_struct *fsp = NULL;
-                               SMB_NTQUOTA_STRUCT quotas;
-
-                               ZERO_STRUCT(quotas);
-
-                               /* access check */
-                               if ((get_current_uid(conn) != 0) || !CAN_WRITE(conn)) {
-                                       DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
-                                                lp_servicename(talloc_tos(), SNUM(conn)),
-                                                conn->session_info->unix_info->unix_name));
-                                       reply_nterror(req, NT_STATUS_ACCESS_DENIED);
-                                       return;
-                               }
-
-                               /* note: normally there're 48 bytes,
-                                * but we didn't use the last 6 bytes for now 
-                                * --metze 
-                                */
                                fsp = file_fsp(req, SVAL(params,0));
 
-                               if (!check_fsp_ntquota_handle(conn, req,
-                                                             fsp)) {
-                                       DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
-                                       reply_nterror(
-                                               req, NT_STATUS_INVALID_HANDLE);
-                                       return;
-                               }
-
-                               if (total_data < 42) {
-                                       DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
-                                               total_data));
-                                       reply_nterror(
-                                               req,
-                                               NT_STATUS_INVALID_PARAMETER);
-                                       return;
-                               }
-
-                               /* unknown_1 24 NULL bytes in pdata*/
-
-                               /* the soft quotas 8 bytes (uint64_t)*/
-                               quotas.softlim = BVAL(pdata,24);
-
-                               /* the hard quotas 8 bytes (uint64_t)*/
-                               quotas.hardlim = BVAL(pdata,32);
-
-                               /* quota_flags 2 bytes **/
-                               quotas.qflags = SVAL(pdata,40);
-
-                               /* unknown_2 6 NULL bytes follow*/
-
-                               /* now set the quotas */
-                               if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
-                                       DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn))));
-                                       reply_nterror(req, map_nt_error_from_unix(errno));
+                               status = smb_set_fsquota(conn,
+                                                       req,
+                                                       fsp,
+                                                       &qdata);
+                               if (!NT_STATUS_IS_OK(status)) {
+                                       reply_nterror(req, status);
                                        return;
                                }
-
                                break;
                        }
                default:
@@ -5387,7 +5501,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                                return NT_STATUS_DOS(ERRDOS, ERRbadlink);
 #endif
                                link_len = SMB_VFS_READLINK(conn,
-                                                      smb_fname->base_name,
+                                                      smb_fname,
                                                       buffer, PATH_MAX);
                                if (link_len == -1) {
                                        return map_nt_error_from_unix(errno);
@@ -5427,7 +5541,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                                } else {
                                        file_acl =
                                            SMB_VFS_SYS_ACL_GET_FILE(conn,
-                                               smb_fname->base_name,
+                                               smb_fname,
                                                SMB_ACL_TYPE_ACCESS,
                                                talloc_tos());
                                }
@@ -5445,14 +5559,14 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                                                def_acl =
                                                    SMB_VFS_SYS_ACL_GET_FILE(
                                                            conn,
-                                                           fsp->fsp_name->base_name,
+                                                           fsp->fsp_name,
                                                            SMB_ACL_TYPE_DEFAULT,
                                                            talloc_tos());
                                        } else {
                                                def_acl =
                                                    SMB_VFS_SYS_ACL_GET_FILE(
                                                            conn,
-                                                           smb_fname->base_name,
+                                                           smb_fname,
                                                            SMB_ACL_TYPE_DEFAULT,
                                                            talloc_tos());
                                        }
@@ -5706,8 +5820,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
        } else {
                uint32_t name_hash;
                char *fname = NULL;
-               uint32_t ucf_flags = (req->posix_pathnames ?
-                               UCF_POSIX_PATHNAMES : 0);
+               uint32_t ucf_flags = ucf_flags_from_smb_request(req);
 
                /* qpathinfo */
                if (total_params < 7) {
@@ -5726,7 +5839,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
                        }
                        if (info_level == SMB_QUERY_FILE_UNIX_BASIC ||
                                        info_level == SMB_QUERY_FILE_UNIX_INFO2 ||
-                                       info_level == SMB_QUERY_FILE_UNIX_LINK) {
+                                       info_level == SMB_QUERY_FILE_UNIX_LINK ||
+                                       req->posix_pathnames) {
                                ucf_flags |= UCF_UNIX_NAME_LOOKUP;
                        }
                }
@@ -5757,7 +5871,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
 
                status = filename_convert(req,
                                        conn,
-                                       req->flags2 & FLAGS2_DFS_PATHNAMES,
                                        fname,
                                        ucf_flags,
                                        NULL,
@@ -5790,7 +5903,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
                                return;
                        }
 
-                       if (INFO_LEVEL_IS_UNIX(info_level)) {
+                       if (INFO_LEVEL_IS_UNIX(info_level) || req->posix_pathnames) {
                                /* Always do lstat for UNIX calls. */
                                if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
                                        DEBUG(3,("call_trans2qfilepathinfo: "
@@ -5836,7 +5949,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
                        }
                }
 
-               if (INFO_LEVEL_IS_UNIX(info_level)) {
+               if (INFO_LEVEL_IS_UNIX(info_level) || req->posix_pathnames) {
                        /* Always do lstat for UNIX calls. */
                        if (SMB_VFS_LSTAT(conn, smb_fname)) {
                                DEBUG(3,("call_trans2qfilepathinfo: "
@@ -6054,8 +6167,7 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
        DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
                  smb_fname_old->base_name, smb_fname_new->base_name));
 
-       if (SMB_VFS_LINK(conn, smb_fname_old->base_name,
-                        smb_fname_new->base_name) != 0) {
+       if (SMB_VFS_LINK(conn, smb_fname_old, smb_fname_new) != 0) {
                status = map_nt_error_from_unix(errno);
                DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
                         nt_errstr(status), smb_fname_old->base_name,
@@ -6243,7 +6355,9 @@ static NTSTATUS smb_set_file_size(connection_struct *conn,
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
-       DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size));
+       DBG_INFO("size: %"PRIu64", file_size_stat=%"PRIu64"\n",
+                (uint64_t)size,
+                get_file_size_stat(psbuf));
 
        if (size == get_file_size_stat(psbuf)) {
                return NT_STATUS_OK;
@@ -6514,10 +6628,9 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
                                       struct smb_request *req,
                                       const char *pdata,
                                       int total_data,
-                                      const struct smb_filename *smb_fname)
+                                      const struct smb_filename *new_smb_fname)
 {
        char *link_target = NULL;
-       const char *newname = smb_fname->base_name;
        TALLOC_CTX *ctx = talloc_tos();
 
        /* Set a symbolic link. */
@@ -6539,9 +6652,9 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
        }
 
        DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
-                       newname, link_target ));
+                       new_smb_fname->base_name, link_target ));
 
-       if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0) {
+       if (SMB_VFS_SYMLINK(conn,link_target,new_smb_fname) != 0) {
                return map_nt_error_from_unix(errno);
        }
 
@@ -6559,7 +6672,7 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
 {
        char *oldname = NULL;
        struct smb_filename *smb_fname_old = NULL;
-       uint32_t ucf_flags = (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+       uint32_t ucf_flags = ucf_flags_from_smb_request(req);
        TALLOC_CTX *ctx = talloc_tos();
        NTSTATUS status = NT_STATUS_OK;
 
@@ -6596,7 +6709,6 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
 
        status = filename_convert(ctx,
                                conn,
-                               req->flags2 & FLAGS2_DFS_PATHNAMES,
                                oldname,
                                ucf_flags,
                                NULL,
@@ -6625,7 +6737,7 @@ static NTSTATUS smb2_file_rename_information(connection_struct *conn,
        char *newname = NULL;
        struct smb_filename *smb_fname_dst = NULL;
        uint32_t ucf_flags = UCF_SAVE_LCOMP |
-               (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+               ucf_flags_from_smb_request(req);
        NTSTATUS status = NT_STATUS_OK;
        TALLOC_CTX *ctx = talloc_tos();
 
@@ -6672,7 +6784,6 @@ static NTSTATUS smb2_file_rename_information(connection_struct *conn,
 
        status = filename_convert(ctx,
                                conn,
-                               req->flags2 & FLAGS2_DFS_PATHNAMES,
                                newname,
                                ucf_flags,
                                NULL,
@@ -6737,7 +6848,7 @@ static NTSTATUS smb_file_link_information(connection_struct *conn,
        struct smb_filename *smb_fname_dst = NULL;
        NTSTATUS status = NT_STATUS_OK;
        uint32_t ucf_flags = UCF_SAVE_LCOMP |
-               (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+               ucf_flags_from_smb_request(req);
        TALLOC_CTX *ctx = talloc_tos();
 
        if (!fsp) {
@@ -6783,7 +6894,6 @@ static NTSTATUS smb_file_link_information(connection_struct *conn,
 
        status = filename_convert(ctx,
                                conn,
-                               req->flags2 & FLAGS2_DFS_PATHNAMES,
                                newname,
                                ucf_flags,
                                NULL,
@@ -6873,15 +6983,16 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
        DEBUG(10,("smb_file_rename_information: got name |%s|\n",
                                newname));
 
-       status = resolve_dfspath_wcard(ctx, conn,
-                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
+       if (req->flags2 & FLAGS2_DFS_PATHNAMES) {
+               status = resolve_dfspath_wcard(ctx, conn,
                                       newname,
-                                      true,
+                                      UCF_COND_ALLOW_WCARD_LCOMP,
                                       !conn->sconn->using_smb2,
                                       &newname,
                                       &dest_has_wcard);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
        }
 
        /* Check the new name has no '/' characters. */
@@ -6924,6 +7035,12 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                 * the newname instead.
                 */
                char *base_name = NULL;
+               uint32_t ucf_flags = UCF_SAVE_LCOMP |
+                       ucf_flags_from_smb_request(req);
+
+               if (dest_has_wcard) {
+                       ucf_flags |= UCF_ALWAYS_ALLOW_WCARD_LCOMP;
+               }
 
                /* newname must *not* be a stream name. */
                if (newname[0] == ':') {
@@ -6956,10 +7073,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                }
 
                status = unix_convert(ctx, conn, base_name, &smb_fname_dst,
-                                     (UCF_SAVE_LCOMP |
-                                         (dest_has_wcard ?
-                                             UCF_ALWAYS_ALLOW_WCARD_LCOMP :
-                                             0)));
+                                       ucf_flags);
 
                /* If an error we expect this to be
                 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
@@ -7059,13 +7173,13 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
                (unsigned int)num_def_acls));
 
        if (valid_file_acls && !set_unix_posix_acl(conn, fsp,
-               smb_fname->base_name, num_file_acls,
+               smb_fname, num_file_acls,
                pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
                return map_nt_error_from_unix(errno);
        }
 
        if (valid_def_acls && !set_unix_posix_default_acl(conn,
-               smb_fname->base_name, &smb_fname->st, num_def_acls,
+               smb_fname, num_def_acls,
                pdata + SMB_POSIX_ACL_HEADER_SIZE +
                (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
                return map_nt_error_from_unix(errno);
@@ -7484,7 +7598,7 @@ static NTSTATUS smb_unix_mknod(connection_struct *conn,
                  (unsigned int)unixmode, smb_fname_str_dbg(smb_fname)));
 
        /* Ok - do the mknod. */
-       if (SMB_VFS_MKNOD(conn, smb_fname->base_name, unixmode, dev) != 0) {
+       if (SMB_VFS_MKNOD(conn, smb_fname, unixmode, dev) != 0) {
                return map_nt_error_from_unix(errno);
        }
 
@@ -7498,7 +7612,7 @@ static NTSTATUS smb_unix_mknod(connection_struct *conn,
                                    &parent, NULL)) {
                        return NT_STATUS_NO_MEMORY;
                }
-               inherit_access_posix_acl(conn, parent, smb_fname->base_name,
+               inherit_access_posix_acl(conn, parent, smb_fname,
                                         unixmode);
                TALLOC_FREE(parent);
        }
@@ -7690,10 +7804,10 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
 
                DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
                          "changing group %u for file %s\n",
-                         (unsigned int)set_owner,
+                         (unsigned int)set_grp,
                          smb_fname_str_dbg(smb_fname)));
                if (fsp && fsp->fh->fd != -1) {
-                       ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
+                       ret = SMB_VFS_FCHOWN(fsp, (uid_t)-1, set_grp);
                } else {
                        /*
                         * UNIX extensions calls must always operate
@@ -7809,7 +7923,7 @@ static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
                        /* XXX: we should be  using SMB_VFS_FCHFLAGS here. */
                        return NT_STATUS_NOT_SUPPORTED;
                } else {
-                       if (SMB_VFS_CHFLAGS(conn, smb_fname->base_name,
+                       if (SMB_VFS_CHFLAGS(conn, smb_fname,
                                            stat_fflags) != 0) {
                                return map_nt_error_from_unix(errno);
                        }
@@ -8195,14 +8309,15 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
                                int total_data,
                                struct smb_filename *smb_fname)
 {
+       struct server_id self = messaging_server_id(conn->sconn->msg_ctx);
        NTSTATUS status = NT_STATUS_OK;
        files_struct *fsp = NULL;
        uint16_t flags = 0;
        char del = 1;
        int info = 0;
        int create_options = 0;
-       int i;
        struct share_mode_lock *lck = NULL;
+       bool other_nonposix_opens;
 
        if (total_data < 2) {
                return NT_STATUS_INVALID_PARAMETER;
@@ -8265,25 +8380,12 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       /*
-        * See if others still have the file open. If this is the case, then
-        * don't delete. If all opens are POSIX delete we can set the delete
-        * on close disposition.
-        */
-       for (i=0; i<lck->data->num_share_modes; i++) {
-               struct share_mode_entry *e = &lck->data->share_modes[i];
-               if (is_valid_share_mode_entry(e)) {
-                       if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
-                               continue;
-                       }
-                       if (share_mode_stale_pid(lck->data, i)) {
-                               continue;
-                       }
-                       /* Fail with sharing violation. */
-                       TALLOC_FREE(lck);
-                       close_file(req, fsp, NORMAL_CLOSE);
-                       return NT_STATUS_SHARING_VIOLATION;
-               }
+       other_nonposix_opens = has_other_nonposix_opens(lck, fsp, self);
+       if (other_nonposix_opens) {
+               /* Fail with sharing violation. */
+               TALLOC_FREE(lck);
+               close_file(req, fsp, NORMAL_CLOSE);
+               return NT_STATUS_SHARING_VIOLATION;
        }
 
        /*
@@ -8454,6 +8556,11 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
                        break;
                }
 
+               /* [MS-SMB2] 3.3.5.21.1 states we MUST fail with STATUS_NOT_SUPPORTED. */
+               case SMB_FILE_VALID_DATA_LENGTH_INFORMATION:
+               case SMB_FILE_SHORT_NAME_INFORMATION:
+                       return NT_STATUS_NOT_SUPPORTED;
+
                /*
                 * CIFS UNIX extensions.
                 */
@@ -8694,8 +8801,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                }
        } else {
                char *fname = NULL;
-               uint32_t ucf_flags = (req->posix_pathnames ?
-                       UCF_POSIX_PATHNAMES : 0);
+               uint32_t ucf_flags = ucf_flags_from_smb_request(req);
 
                /* set path info */
                if (total_params < 7) {
@@ -8736,7 +8842,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                }
 
                status = filename_convert(req, conn,
-                                        req->flags2 & FLAGS2_DFS_PATHNAMES,
                                         fname,
                                         ucf_flags,
                                         NULL,
@@ -8845,7 +8950,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
        char *directory = NULL;
        NTSTATUS status = NT_STATUS_OK;
        struct ea_list *ea_list = NULL;
-       uint32_t ucf_flags = (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+       uint32_t ucf_flags = ucf_flags_from_smb_request(req);
        TALLOC_CTX *ctx = talloc_tos();
 
        if (!CAN_WRITE(conn)) {
@@ -8886,7 +8991,6 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
 
        status = filename_convert(ctx,
                                conn,
-                               req->flags2 & FLAGS2_DFS_PATHNAMES,
                                directory,
                                ucf_flags,
                                NULL,