s3: Plumb smb_filename through dos_mode() and related funtions
authorTim Prouty <tprouty@samba.org>
Wed, 8 Jul 2009 19:24:03 +0000 (12:24 -0700)
committerTim Prouty <tprouty@samba.org>
Thu, 9 Jul 2009 04:36:03 +0000 (21:36 -0700)
12 files changed:
source3/include/proto.h
source3/modules/nfs4_acls.c
source3/modules/onefs_open.c
source3/smbd/dir.c
source3/smbd/dosmode.c
source3/smbd/fileio.c
source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/posix_acls.c
source3/smbd/reply.c
source3/smbd/smb2_create.c
source3/smbd/trans2.c

index ef252c28466786c729819514eee05eeed5b83cf5..471084c264b0adb5f69b23e10564b792cb18c1f6 100644 (file)
@@ -6237,9 +6237,10 @@ bool smbd_setup_mdns_registration(struct tevent_context *ev,
 mode_t unix_mode(connection_struct *conn, int dosmode,
                 const struct smb_filename *smb_fname,
                 const char *inherit_from_dir);
-uint32 dos_mode_msdfs(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf);
+uint32 dos_mode_msdfs(connection_struct *conn,
+                     const struct smb_filename *smb_fname);
 int dos_attributes_to_stat_dos_flags(uint32_t dosmode);
-uint32 dos_mode(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf);
+uint32 dos_mode(connection_struct *conn, const struct smb_filename *smb_fname);
 int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
                     uint32 dosmode, const char *parent_dir, bool newfile);
 int file_ntimes(connection_struct *conn, const struct smb_filename *smb_fname,
@@ -6596,8 +6597,8 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func
                                 uint32 *pcreate_disposition,
                                 uint32 *pcreate_options);
 NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn,
-                         const char *fname,
-                         SMB_STRUCT_STAT *psbuf, files_struct **result);
+                         struct smb_filename *smb_fname,
+                         files_struct **result);
 NTSTATUS close_file_fchmod(struct smb_request *req, files_struct *fsp);
 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
                          struct smb_filename *smb_dname);
@@ -6718,7 +6719,8 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info,
                           SEC_DESC **ppdesc);
 NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
                          uint32_t security_info, SEC_DESC **ppdesc);
-int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid);
+int try_chown(connection_struct *conn, struct smb_filename *smb_fname,
+             uid_t uid, gid_t gid);
 NTSTATUS append_parent_acl(files_struct *fsp,
                                const SEC_DESC *pcsd,
                                SEC_DESC **pp_new_sd);
index 70bdaa8826e5d50ca917bcb03e7a237327e0d797..9b3c8725d5b9768c8d7fc40990c8078390568126 100644 (file)
@@ -743,12 +743,22 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
                }
                if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) ||
                    ((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) {
-                       if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
+                       struct smb_filename *smb_fname = NULL;
+                       NTSTATUS status;
+
+                       status = create_synthetic_smb_fname_split(talloc_tos(),
+                           fsp->fsp_name, NULL, &smb_fname);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               return status;
+                       }
+                       if(try_chown(fsp->conn, smb_fname, newUID, newGID)) {
                                DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
                                         fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, 
                                         strerror(errno)));
+                               TALLOC_FREE(smb_fname);
                                return map_nt_error_from_unix(errno);
                        }
+                       TALLOC_FREE(smb_fname);
 
                        DEBUG(10,("chown %s, %u, %u succeeded.\n",
                                  fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
index 20ce814518f83bbc231241821e933620a97d082f..60a1790f642850682f5d78af95c1b9c17036b5d4 100644 (file)
@@ -591,8 +591,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
        if (!posix_open) {
                new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
                if (file_existed) {
-                       existing_dos_attributes = dos_mode(conn, fname,
-                                                          &smb_fname->st);
+                       existing_dos_attributes = dos_mode(conn, smb_fname);
                }
        }
 
index 723fb6fd6f2f1168b53cc4639a545f478e770fa5..642fb09362c0c86428e64d3132a404e38acbca01 100644 (file)
@@ -876,6 +876,8 @@ bool get_dir_entry(TALLOC_CTX *ctx,
                    mask_match_search(filename,mask,False) ||
                    mangle_mask_match(conn,filename,mask)) {
                        char mname[13];
+                       struct smb_filename *smb_fname = NULL;
+                       NTSTATUS status;
 
                        if (!mangle_is_8_3(filename, False, conn->params)) {
                                if (!name_to_8_3(filename,mname,False,
@@ -905,51 +907,47 @@ bool get_dir_entry(TALLOC_CTX *ctx,
                                return False;
                        }
 
-                       if (!VALID_STAT(sbuf)) {
-                               struct smb_filename *smb_fname = NULL;
-                               NTSTATUS status;
-
-                               /* Create smb_fname with NULL stream_name. */
-                               status =
-                                   create_synthetic_smb_fname(ctx, pathreal,
-                                                              NULL, NULL,
-                                                              &smb_fname);
-                               if (!NT_STATUS_IS_OK(status)) {
-                                       TALLOC_FREE(pathreal);
-                                       TALLOC_FREE(filename);
-                                       return NULL;
-                               }
+                       /* Create smb_fname with NULL stream_name. */
+                       status = create_synthetic_smb_fname(ctx, pathreal,
+                                                           NULL, &sbuf,
+                                                           &smb_fname);
 
+                       TALLOC_FREE(pathreal);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               TALLOC_FREE(filename);
+                               return false;
+                       }
+
+                       if (!VALID_STAT(smb_fname->st)) {
                                if ((SMB_VFS_STAT(conn, smb_fname)) != 0) {
                                        DEBUG(5,("Couldn't stat 1 [%s]. Error "
-                                                "= %s\n", pathreal,
+                                                "= %s\n",
+                                                smb_fname_str_dbg(smb_fname),
                                                 strerror(errno)));
                                        TALLOC_FREE(smb_fname);
-                                       TALLOC_FREE(pathreal);
                                        TALLOC_FREE(filename);
                                        continue;
                                }
-                               sbuf = smb_fname->st;
-                               TALLOC_FREE(smb_fname);
                        }
 
-                       *mode = dos_mode(conn,pathreal,&sbuf);
+                       *mode = dos_mode(conn, smb_fname);
 
                        if (!dir_check_ftype(conn,*mode,dirtype)) {
                                DEBUG(5,("[%s] attribs 0x%x didn't match 0x%x\n",filename,(unsigned int)*mode,(unsigned int)dirtype));
-                               TALLOC_FREE(pathreal);
+                               TALLOC_FREE(smb_fname);
                                TALLOC_FREE(filename);
                                continue;
                        }
 
-                       *size = sbuf.st_ex_size;
-                       *date = sbuf.st_ex_mtime;
+                       *size = smb_fname->st.st_ex_size;
+                       *date = smb_fname->st.st_ex_mtime;
 
                        if (ask_sharemode) {
                                struct timespec write_time_ts;
                                struct file_id fileid;
 
-                               fileid = vfs_file_id_from_sbuf(conn, &sbuf);
+                               fileid = vfs_file_id_from_sbuf(conn,
+                                                              &smb_fname->st);
                                get_file_infos(fileid, NULL, &write_time_ts);
                                if (!null_timespec(write_time_ts)) {
                                        *date = write_time_ts;
@@ -959,7 +957,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
                        DEBUG(3,("get_dir_entry mask=[%s] found %s "
                                "fname=%s (%s)\n",
                                mask,
-                               pathreal,
+                               smb_fname_str_dbg(smb_fname),
                                dname,
                                filename));
 
@@ -969,7 +967,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
                        *pp_fname_out = filename;
 
                        DirCacheAdd(conn->dirptr->dir_hnd, dname, curoff);
-                       TALLOC_FREE(pathreal);
+                       TALLOC_FREE(smb_fname);
                }
 
                if (!found)
index 9bd097c0bbe5dd644e0807dd1ad261be7ff56a64..ca926aa33c55a031e3bc05d7734f4289372a54a9 100644 (file)
@@ -158,45 +158,38 @@ mode_t unix_mode(connection_struct *conn, int dosmode,
  Change a unix mode to a dos mode.
 ****************************************************************************/
 
-static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf)
+static uint32 dos_mode_from_sbuf(connection_struct *conn,
+                                const struct smb_filename *smb_fname)
 {
        int result = 0;
        enum mapreadonly_options ro_opts = (enum mapreadonly_options)lp_map_readonly(SNUM(conn));
 
        if (ro_opts == MAP_READONLY_YES) {
                /* Original Samba method - map inverse of user "w" bit. */
-               if ((sbuf->st_ex_mode & S_IWUSR) == 0) {
+               if ((smb_fname->st.st_ex_mode & S_IWUSR) == 0) {
                        result |= aRONLY;
                }
        } else if (ro_opts == MAP_READONLY_PERMISSIONS) {
-               struct smb_filename *smb_fname = NULL;
-               NTSTATUS status;
-
-               status = create_synthetic_smb_fname_split(talloc_tos(), path,
-                                                         sbuf, &smb_fname);
-               if (NT_STATUS_IS_OK(status)) {
-                       /* Check actual permissions for read-only. */
-                       if (!can_write_to_file(conn, smb_fname)) {
-                               result |= aRONLY;
-                       }
+               /* Check actual permissions for read-only. */
+               if (!can_write_to_file(conn, smb_fname)) {
+                       result |= aRONLY;
                }
-               TALLOC_FREE(smb_fname);
        } /* Else never set the readonly bit. */
 
-       if (MAP_ARCHIVE(conn) && ((sbuf->st_ex_mode & S_IXUSR) != 0))
+       if (MAP_ARCHIVE(conn) && ((smb_fname->st.st_ex_mode & S_IXUSR) != 0))
                result |= aARCH;
 
-       if (MAP_SYSTEM(conn) && ((sbuf->st_ex_mode & S_IXGRP) != 0))
+       if (MAP_SYSTEM(conn) && ((smb_fname->st.st_ex_mode & S_IXGRP) != 0))
                result |= aSYSTEM;
 
-       if (MAP_HIDDEN(conn) && ((sbuf->st_ex_mode & S_IXOTH) != 0))
+       if (MAP_HIDDEN(conn) && ((smb_fname->st.st_ex_mode & S_IXOTH) != 0))
                result |= aHIDDEN;   
 
-       if (S_ISDIR(sbuf->st_ex_mode))
+       if (S_ISDIR(smb_fname->st.st_ex_mode))
                result = aDIR | (result & aRONLY);
 
-       result |= set_sparse_flag(sbuf);
-       result |= set_link_read_only_flag(sbuf);
+       result |= set_sparse_flag(&smb_fname->st);
+       result |= set_link_read_only_flag(&smb_fname->st);
 
        DEBUG(8,("dos_mode_from_sbuf returning "));
 
@@ -214,7 +207,9 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, cons
  Get DOS attributes from an EA.
 ****************************************************************************/
 
-static bool get_ea_dos_attribute(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf, uint32 *pattr)
+static bool get_ea_dos_attribute(connection_struct *conn,
+                                const struct smb_filename *smb_fname,
+                                uint32 *pattr)
 {
        ssize_t sizeret;
        fstring attrstr;
@@ -227,7 +222,9 @@ static bool get_ea_dos_attribute(connection_struct *conn, const char *path, cons
        /* Don't reset pattr to zero as we may already have filename-based attributes we
           need to preserve. */
 
-       sizeret = SMB_VFS_GETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, sizeof(attrstr));
+       sizeret = SMB_VFS_GETXATTR(conn, smb_fname->base_name,
+                                  SAMBA_XATTR_DOS_ATTRIB, attrstr,
+                                  sizeof(attrstr));
        if (sizeret == -1) {
                if (errno == ENOSYS
 #if defined(ENOTSUP)
@@ -235,23 +232,28 @@ static bool get_ea_dos_attribute(connection_struct *conn, const char *path, cons
 #else
                                ) {
 #endif
-                       DEBUG(1,("get_ea_dos_attributes: Cannot get attribute from EA on file %s: Error = %s\n",
-                               path, strerror(errno) ));
+                       DEBUG(1,("get_ea_dos_attributes: Cannot get attribute "
+                                "from EA on file %s: Error = %s\n",
+                                smb_fname_str_dbg(smb_fname),
+                                strerror(errno)));
                        set_store_dos_attributes(SNUM(conn), False);
                }
                return False;
        }
        /* Null terminate string. */
        attrstr[sizeret] = 0;
-       DEBUG(10,("get_ea_dos_attribute: %s attrstr = %s\n", path, attrstr));
+       DEBUG(10,("get_ea_dos_attribute: %s attrstr = %s\n",
+                 smb_fname_str_dbg(smb_fname), attrstr));
 
        if (sizeret < 2 || attrstr[0] != '0' || attrstr[1] != 'x' ||
                        sscanf(attrstr, "%x", &dosattr) != 1) {
-               DEBUG(1,("get_ea_dos_attributes: Badly formed DOSATTRIB on file %s - %s\n", path, attrstr));
+               DEBUG(1,("get_ea_dos_attributes: Badly formed DOSATTRIB on "
+                        "file %s - %s\n", smb_fname_str_dbg(smb_fname),
+                        attrstr));
                 return False;
         }
 
-       if (S_ISDIR(sbuf->st_ex_mode)) {
+       if (S_ISDIR(smb_fname->st.st_ex_mode)) {
                dosattr |= aDIR;
        }
        *pattr = (uint32)(dosattr & SAMBA_ATTRIBUTES_MASK);
@@ -273,7 +275,9 @@ static bool get_ea_dos_attribute(connection_struct *conn, const char *path, cons
  Set DOS attributes in an EA.
 ****************************************************************************/
 
-static bool set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf, uint32 dosmode)
+static bool set_ea_dos_attribute(connection_struct *conn,
+                                struct smb_filename *smb_fname,
+                                uint32 dosmode)
 {
        fstring attrstr;
        files_struct *fsp = NULL;
@@ -284,7 +288,9 @@ static bool set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_
        }
 
        snprintf(attrstr, sizeof(attrstr)-1, "0x%x", dosmode & SAMBA_ATTRIBUTES_MASK);
-       if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == -1) {
+       if (SMB_VFS_SETXATTR(conn, smb_fname->base_name,
+                            SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr),
+                            0) == -1) {
                if((errno != EPERM) && (errno != EACCES)) {
                        if (errno == ENOSYS
 #if defined(ENOTSUP)
@@ -292,8 +298,10 @@ static bool set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_
 #else
                                ) {
 #endif
-                               DEBUG(1,("set_ea_dos_attributes: Cannot set attribute EA on file %s: Error = %s\n",
-                                       path, strerror(errno) ));
+                               DEBUG(1,("set_ea_dos_attributes: Cannot set "
+                                        "attribute EA on file %s: Error = %s\n",
+                                        smb_fname_str_dbg(smb_fname),
+                                        strerror(errno) ));
                                set_store_dos_attributes(SNUM(conn), False);
                        }
                        return False;
@@ -313,18 +321,21 @@ static bool set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_
                 * are not violating security in doing the setxattr.
                 */
 
-               if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, path, sbuf,
+               if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, smb_fname,
                                                      &fsp)))
                        return ret;
                become_root();
-               if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == 0) {
+               if (SMB_VFS_SETXATTR(conn, smb_fname->base_name,
+                                    SAMBA_XATTR_DOS_ATTRIB, attrstr,
+                                    strlen(attrstr), 0) == 0) {
                        ret = True;
                }
                unbecome_root();
                close_file_fchmod(NULL, fsp);
                return ret;
        }
-       DEBUG(10,("set_ea_dos_attribute: set EA %s on file %s\n", attrstr, path));
+       DEBUG(10,("set_ea_dos_attribute: set EA %s on file %s\n", attrstr,
+                 smb_fname_str_dbg(smb_fname)));
        return True;
 }
 
@@ -332,25 +343,25 @@ static bool set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_
  Change a unix mode to a dos mode for an ms dfs link.
 ****************************************************************************/
 
-uint32 dos_mode_msdfs(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *psbuf)
+uint32 dos_mode_msdfs(connection_struct *conn,
+                     const struct smb_filename *smb_fname)
 {
-       SMB_STRUCT_STAT sbuf = *psbuf;
        uint32 result = 0;
 
-       DEBUG(8,("dos_mode_msdfs: %s\n", path));
+       DEBUG(8,("dos_mode_msdfs: %s\n", smb_fname_str_dbg(smb_fname)));
 
-       if (!VALID_STAT(sbuf)) {
+       if (!VALID_STAT(smb_fname->st)) {
                return 0;
        }
 
        /* First do any modifications that depend on the path name. */
        /* hide files with a name starting with a . */
        if (lp_hide_dot_files(SNUM(conn))) {
-               const char *p = strrchr_m(path,'/');
+               const char *p = strrchr_m(smb_fname->base_name, '/');
                if (p) {
                        p++;
                } else {
-                       p = path;
+                       p = smb_fname->base_name;
                }
 
                /* Only . and .. are not hidden. */
@@ -360,11 +371,12 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path, const SMB_STRUC
                }
        }
 
-       result |= dos_mode_from_sbuf(conn, path, &sbuf);
+       result |= dos_mode_from_sbuf(conn, smb_fname);
 
        /* Optimization : Only call is_hidden_path if it's not already
           hidden. */
-       if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) {
+       if (!(result & aHIDDEN) &&
+           IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
                result |= aHIDDEN;
        }
 
@@ -410,34 +422,34 @@ int dos_attributes_to_stat_dos_flags(uint32_t dosmode)
 ****************************************************************************/
 
 static bool get_stat_dos_flags(connection_struct *conn,
-                              const char *fname,
-                              const SMB_STRUCT_STAT *sbuf,
+                              const struct smb_filename *smb_fname,
                               uint32_t *dosmode)
 {
-       SMB_ASSERT(sbuf && VALID_STAT(*sbuf));
+       SMB_ASSERT(VALID_STAT(smb_fname->st));
        SMB_ASSERT(dosmode);
 
        if (!lp_store_dos_attributes(SNUM(conn))) {
                return false;
        }
 
-       DEBUG(5, ("Getting stat dos attributes for %s.\n", fname));
+       DEBUG(5, ("Getting stat dos attributes for %s.\n",
+                 smb_fname_str_dbg(smb_fname)));
 
-       if (sbuf->st_ex_flags & UF_DOS_ARCHIVE)
+       if (smb_fname->st.st_ex_flags & UF_DOS_ARCHIVE)
                *dosmode |= aARCH;
-       if (sbuf->st_ex_flags & UF_DOS_HIDDEN)
+       if (smb_fname->st.st_ex_flags & UF_DOS_HIDDEN)
                *dosmode |= aHIDDEN;
-       if (sbuf->st_ex_flags & UF_DOS_RO)
+       if (smb_fname->st.st_ex_flags & UF_DOS_RO)
                *dosmode |= aRONLY;
-       if (sbuf->st_ex_flags & UF_DOS_SYSTEM)
+       if (smb_fname->st.st_ex_flags & UF_DOS_SYSTEM)
                *dosmode |= aSYSTEM;
-       if (sbuf->st_ex_flags & UF_DOS_NOINDEX)
+       if (smb_fname->st.st_ex_flags & UF_DOS_NOINDEX)
                *dosmode |= FILE_ATTRIBUTE_NONINDEXED;
-       if (S_ISDIR(sbuf->st_ex_mode))
+       if (S_ISDIR(smb_fname->st.st_ex_mode))
                *dosmode |= aDIR;
 
-       *dosmode |= set_sparse_flag(sbuf);
-       *dosmode |= set_link_read_only_flag(sbuf);
+       *dosmode |= set_sparse_flag(smb_fname->st);
+       *dosmode |= set_link_read_only_flag(smb_fname->st);
 
        return true;
 }
@@ -494,26 +506,26 @@ static bool set_stat_dos_flags(connection_struct *conn,
  Change a unix mode to a dos mode.
 ****************************************************************************/
 
-uint32 dos_mode(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *psbuf)
+uint32 dos_mode(connection_struct *conn, const struct smb_filename *smb_fname)
 {
-       SMB_STRUCT_STAT sbuf = *psbuf;
+       SMB_STRUCT_STAT sbuf;
        uint32 result = 0;
        bool offline, used_stat_dos_flags = false;
 
-       DEBUG(8,("dos_mode: %s\n", path));
+       DEBUG(8,("dos_mode: %s\n", smb_fname_str_dbg(smb_fname)));
 
-       if (!VALID_STAT(sbuf)) {
+       if (!VALID_STAT(smb_fname->st)) {
                return 0;
        }
 
        /* First do any modifications that depend on the path name. */
        /* hide files with a name starting with a . */
        if (lp_hide_dot_files(SNUM(conn))) {
-               const char *p = strrchr_m(path,'/');
+               const char *p = strrchr_m(smb_fname->base_name,'/');
                if (p) {
                        p++;
                } else {
-                       p = path;
+                       p = smb_fname->base_name;
                }
 
                /* Only . and .. are not hidden. */
@@ -524,25 +536,27 @@ uint32 dos_mode(connection_struct *conn, const char *path, const SMB_STRUCT_STAT
        }
 
 #ifdef HAVE_STAT_DOS_FLAGS
-       used_stat_dos_flags = get_stat_dos_flags(conn, path, &sbuf, &result);
+       used_stat_dos_flags = get_stat_dos_flags(conn, smb_fname, &result);
 #endif
        if (!used_stat_dos_flags) {
                /* Get the DOS attributes from an EA by preference. */
-               if (get_ea_dos_attribute(conn, path, &sbuf, &result)) {
-                       result |= set_sparse_flag(&sbuf);
+               if (get_ea_dos_attribute(conn, smb_fname, &result)) {
+                       result |= set_sparse_flag(&smb_fname->st);
                } else {
-                       result |= dos_mode_from_sbuf(conn, path, &sbuf);
+                       result |= dos_mode_from_sbuf(conn, smb_fname);
                }
        }
 
-       offline = SMB_VFS_IS_OFFLINE(conn, path, &sbuf);
+       sbuf = smb_fname->st;
+       offline = SMB_VFS_IS_OFFLINE(conn, smb_fname->base_name, &sbuf);
        if (S_ISREG(sbuf.st_ex_mode) && offline) {
                result |= FILE_ATTRIBUTE_OFFLINE;
        }
 
        /* Optimization : Only call is_hidden_path if it's not already
           hidden. */
-       if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) {
+       if (!(result & aHIDDEN) &&
+           IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
                result |= aHIDDEN;
        }
 
@@ -572,8 +586,6 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
        mode_t unixmode;
        int ret = -1, lret = -1;
        uint32_t old_mode;
-       char *fname = NULL;
-       NTSTATUS status;
 
        /* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */
        dosmode &= (SAMBA_ATTRIBUTES_MASK | FILE_ATTRIBUTE_OFFLINE);
@@ -596,17 +608,11 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
        else
                dosmode &= ~aDIR;
 
-       status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
-               return -1;
-       }
-
-       old_mode = dos_mode(conn, fname, &smb_fname->st);
+       old_mode = dos_mode(conn, smb_fname);
 
        if (dosmode & FILE_ATTRIBUTE_OFFLINE) {
                if (!(old_mode & FILE_ATTRIBUTE_OFFLINE)) {
-                       lret = SMB_VFS_SET_OFFLINE(conn, fname);
+                       lret = SMB_VFS_SET_OFFLINE(conn, smb_fname->base_name);
                        if (lret == -1) {
                                DEBUG(0, ("set_dos_mode: client has asked to "
                                          "set FILE_ATTRIBUTE_OFFLINE to "
@@ -635,19 +641,20 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
                {
                        if (!newfile && attributes_changed) {
                                notify_fname(conn, NOTIFY_ACTION_MODIFIED,
-                                   FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+                                   FILE_NOTIFY_CHANGE_ATTRIBUTES,
+                                   smb_fname->base_name);
                        }
                        smb_fname->st.st_ex_mode = unixmode;
                        return 0;
                }
        }
 #endif
-
        /* Store the DOS attributes in an EA by preference. */
-       if (set_ea_dos_attribute(conn, fname, &smb_fname->st, dosmode)) {
+       if (set_ea_dos_attribute(conn, smb_fname, dosmode)) {
                if (!newfile) {
                        notify_fname(conn, NOTIFY_ACTION_MODIFIED,
-                               FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+                                    FILE_NOTIFY_CHANGE_ATTRIBUTES,
+                                    smb_fname->base_name);
                }
                smb_fname->st.st_ex_mode = unixmode;
                return 0;
@@ -685,11 +692,12 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
                unixmode |= (smb_fname->st.st_ex_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
        }
 
-       ret = SMB_VFS_CHMOD(conn, fname, unixmode);
+       ret = SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode);
        if (ret == 0) {
                if(!newfile || (lret != -1)) {
                        notify_fname(conn, NOTIFY_ACTION_MODIFIED,
-                                    FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+                                    FILE_NOTIFY_CHANGE_ATTRIBUTES,
+                                    smb_fname->base_name);
                }
                smb_fname->st.st_ex_mode = unixmode;
                return 0;
@@ -716,8 +724,8 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
                 * break batch oplocks open by others. JRA.
                 */
                files_struct *fsp;
-               if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, fname,
-                                    &smb_fname->st, &fsp)))
+               if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, smb_fname,
+                                    &fsp)))
                        return -1;
                become_root();
                ret = SMB_VFS_FCHMOD(fsp, unixmode);
@@ -725,7 +733,8 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
                close_file_fchmod(NULL, fsp);
                if (!newfile) {
                        notify_fname(conn, NOTIFY_ACTION_MODIFIED,
-                               FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+                                    FILE_NOTIFY_CHANGE_ATTRIBUTES,
+                                    smb_fname->base_name);
                }
                if (ret == 0) {
                        smb_fname->st.st_ex_mode = unixmode;
index caaebf6217b50e7407a38139044a35b5b399e43f..0c13b845df86482cd7d8b74945013ed5105db316 100644 (file)
@@ -284,32 +284,28 @@ ssize_t write_file(struct smb_request *req,
        }
 
        if (!fsp->modified) {
-               SMB_STRUCT_STAT st;
+               struct smb_filename *smb_fname = NULL;
+               NTSTATUS status;
+
                fsp->modified = True;
 
-               if (SMB_VFS_FSTAT(fsp, &st) == 0) {
+               status = create_synthetic_smb_fname_split(talloc_tos(),
+                                                         fsp->fsp_name, NULL,
+                                                         &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       errno = map_errno_from_nt_status(status);
+                       return -1;
+               }
+
+               if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == 0) {
                        int dosmode;
                        trigger_write_time_update(fsp);
-                       dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
+                       dosmode = dos_mode(fsp->conn, smb_fname);
                        if ((lp_store_dos_attributes(SNUM(fsp->conn)) ||
                                        MAP_ARCHIVE(fsp->conn)) &&
                                        !IS_DOS_ARCHIVE(dosmode)) {
-                               struct smb_filename *smb_fname = NULL;
-                               NTSTATUS status;
-
-                               status = create_synthetic_smb_fname_split(
-                                           talloc_tos(), fsp->fsp_name, &st,
-                                           &smb_fname);
-                               if (!NT_STATUS_IS_OK(status)) {
-                                       errno =
-                                           map_errno_from_nt_status(status);
-                                       return -1;
-                               }
-
                                file_set_dosmode(fsp->conn, smb_fname,
                                                dosmode | aARCH, NULL, false);
-                               st = smb_fname->st;
-                               TALLOC_FREE(smb_fname);
                        }
 
                        /*
@@ -318,10 +314,12 @@ ssize_t write_file(struct smb_request *req,
                         */
 
                        if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) {
-                               setup_write_cache(fsp, st.st_ex_size);
+                               setup_write_cache(fsp,
+                                                 smb_fname->st.st_ex_size);
                                wcp = fsp->wcp;
                        }
                }
+               TALLOC_FREE(smb_fname);
        }
 
 #ifdef WITH_PROFILE
index 5d676470c8a6e3e26016d7850decc5c29ca2ccf0..e28e6f3a84365f392ae2be6fc385abd7c04ee498 100644 (file)
@@ -620,7 +620,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
        }
 
        file_len = smb_fname->st.st_ex_size;
-       fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st);
+       fattr = dos_mode(conn, smb_fname);
        if (fattr == 0) {
                fattr = FILE_ATTRIBUTE_NORMAL;
        }
@@ -704,7 +704,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
        }
 
        DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n",
-                fsp->fnum, fsp->fsp_name));
+               fsp->fnum, smb_fname_str_dbg(smb_fname)));
 
        chain_reply(req);
  out:
@@ -1111,7 +1111,7 @@ static void call_nt_transact_create(connection_struct *conn,
        }
 
        file_len = smb_fname->st.st_ex_size;
-       fattr = dos_mode(conn, fsp->fsp_name, &smb_fname->st);
+       fattr = dos_mode(conn, smb_fname);
        if (fattr == 0) {
                fattr = FILE_ATTRIBUTE_NORMAL;
        }
@@ -1194,7 +1194,8 @@ static void call_nt_transact_create(connection_struct *conn,
                SIVAL(p,0,perms);
        }
 
-       DEBUG(5,("call_nt_transact_create: open name = %s\n", fsp->fsp_name));
+       DEBUG(5,("call_nt_transact_create: open name = %s\n",
+                smb_fname_str_dbg(smb_fname)));
 
        /* Send the required number of replies */
        send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
@@ -1236,7 +1237,6 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
                                struct smb_filename *smb_fname_dst,
                                uint32 attrs)
 {
-       char *oldname = NULL;
        files_struct *fsp1,*fsp2;
        uint32 fattr;
        int info;
@@ -1255,13 +1255,8 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
                goto out;
        }
 
-       status = get_full_smb_filename(ctx, smb_fname_src, &oldname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
        /* Ensure attributes match. */
-       fattr = dos_mode(conn, oldname, &smb_fname_src->st);
+       fattr = dos_mode(conn, smb_fname_src);
        if ((fattr & ~attrs) & (aHIDDEN | aSYSTEM)) {
                status = NT_STATUS_NO_SUCH_FILE;
                goto out;
@@ -1367,7 +1362,6 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
                        smb_fname_str_dbg(smb_fname_dst)));
        }
 
-       TALLOC_FREE(oldname);
        return status;
 }
 
index a58cffa2578c96959f8f0d36332b9afad04c554b..e73b3e4fdd396e7a2ada7112111f28dafd7ed2ca 100644 (file)
@@ -1567,8 +1567,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
        if (!posix_open) {
                new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
                if (file_existed) {
-                       existing_dos_attributes = dos_mode(conn, fname,
-                                                          &smb_fname->st);
+                       existing_dos_attributes = dos_mode(conn, smb_fname);
                }
        }
 
@@ -2265,14 +2264,13 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
 ****************************************************************************/
 
 NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn,
-                         const char *fname,
-                         SMB_STRUCT_STAT *psbuf, files_struct **result)
+                         struct smb_filename *smb_fname,
+                         files_struct **result)
 {
-       struct smb_filename *smb_fname = NULL;
        files_struct *fsp = NULL;
        NTSTATUS status;
 
-       if (!VALID_STAT(*psbuf)) {
+       if (!VALID_STAT(smb_fname->st)) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
@@ -2281,12 +2279,6 @@ NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn,
                return status;
        }
 
-       status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
-                                                 &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
         status = SMB_VFS_CREATE_FILE(
                conn,                                   /* conn */
                NULL,                                   /* req */
@@ -2303,10 +2295,7 @@ NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn,
                NULL,                                   /* sd */
                NULL,                                   /* ea_list */
                &fsp,                                   /* result */
-               NULL);                                  /* psbuf */
-
-       *psbuf = smb_fname->st;
-       TALLOC_FREE(smb_fname);
+               NULL);                                  /* pinfo */
 
        /*
         * This is not a user visible file open.
index 0c7f4b7bb7f0d658cccb988b35e0efc02b9d464d..76eee9b56aa560bf8566248cc04ed2455b3ee14f 100644 (file)
@@ -2560,36 +2560,23 @@ static bool current_user_in_group(gid_t gid)
 ****************************************************************************/
 
 static bool acl_group_override(connection_struct *conn,
-                               const SMB_STRUCT_STAT *psbuf,
-                               const char *fname)
+                              const struct smb_filename *smb_fname)
 {
-       struct smb_filename *smb_fname = NULL;
-       NTSTATUS status;
-
        if ((errno != EPERM) && (errno != EACCES)) {
                return false;
        }
 
        /* file primary group == user primary or supplementary group */
        if (lp_acl_group_control(SNUM(conn)) &&
-                       current_user_in_group(psbuf->st_ex_gid)) {
+           current_user_in_group(smb_fname->st.st_ex_gid)) {
                return true;
        }
 
-       status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
-                                                 &smb_fname);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               return false;
-       }
-
        /* user has writeable permission */
        if (lp_dos_filemode(SNUM(conn)) &&
            can_write_to_file(conn, smb_fname)) {
-               TALLOC_FREE(smb_fname);
                return true;
        }
-       TALLOC_FREE(smb_fname);
 
        return false;
 }
@@ -2615,6 +2602,14 @@ static bool set_canon_ace_list(files_struct *fsp,
        SMB_ACL_TYPE_T the_acl_type = (default_ace ? SMB_ACL_TYPE_DEFAULT : SMB_ACL_TYPE_ACCESS);
        bool needs_mask = False;
        mode_t mask_perms = 0;
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
+
+       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
+                                                 psbuf, &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto fail;
+       }
 
 #if defined(POSIX_ACL_NEEDS_MASK)
        /* HP-UX always wants to have a mask (called "class" there). */
@@ -2632,7 +2627,7 @@ static bool set_canon_ace_list(files_struct *fsp,
                                default_ace ? "default" : "file", strerror(errno) ));
                }
                *pacl_set_support = False;
-               return False;
+               goto fail;
        }
 
        if( DEBUGLVL( 10 )) {
@@ -2772,7 +2767,8 @@ static bool set_canon_ace_list(files_struct *fsp,
         */
 
        if(default_ace || fsp->is_directory || fsp->fh->fd == -1) {
-               if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name, the_acl_type, the_acl) == -1) {
+               if (SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname->base_name,
+                                            the_acl_type, the_acl) == -1) {
                        /*
                         * Some systems allow all the above calls and only fail with no ACL support
                         * when attempting to apply the acl. HPUX with HFS is an example of this. JRA.
@@ -2781,14 +2777,18 @@ static bool set_canon_ace_list(files_struct *fsp,
                                *pacl_set_support = False;
                        }
 
-                       if (acl_group_override(conn, psbuf, fsp->fsp_name)) {
+                       if (acl_group_override(conn, smb_fname)) {
                                int sret;
 
-                               DEBUG(5,("set_canon_ace_list: acl group control on and current user in file %s primary group.\n",
-                                       fsp->fsp_name ));
+                               DEBUG(5,("set_canon_ace_list: acl group "
+                                        "control on and current user in file "
+                                        "%s primary group.\n",
+                                        smb_fname_str_dbg(smb_fname)));
 
                                become_root();
-                               sret = SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name, the_acl_type, the_acl);
+                               sret = SMB_VFS_SYS_ACL_SET_FILE(conn,
+                                   smb_fname->base_name, the_acl_type,
+                                   the_acl);
                                unbecome_root();
                                if (sret == 0) {
                                        ret = True;     
@@ -2796,9 +2796,13 @@ static bool set_canon_ace_list(files_struct *fsp,
                        }
 
                        if (ret == False) {
-                               DEBUG(2,("set_canon_ace_list: sys_acl_set_file type %s failed for file %s (%s).\n",
-                                               the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file",
-                                               fsp->fsp_name, strerror(errno) ));
+                               DEBUG(2,("set_canon_ace_list: "
+                                        "sys_acl_set_file type %s failed for "
+                                        "file %s (%s).\n",
+                                        the_acl_type == SMB_ACL_TYPE_DEFAULT ?
+                                        "directory default" : "file",
+                                        smb_fname_str_dbg(smb_fname),
+                                        strerror(errno)));
                                goto fail;
                        }
                }
@@ -2812,11 +2816,13 @@ static bool set_canon_ace_list(files_struct *fsp,
                                *pacl_set_support = False;
                        }
 
-                       if (acl_group_override(conn, psbuf, fsp->fsp_name)) {
+                       if (acl_group_override(conn, smb_fname)) {
                                int sret;
 
-                               DEBUG(5,("set_canon_ace_list: acl group control on and current user in file %s primary group.\n",
-                                       fsp->fsp_name ));
+                               DEBUG(5,("set_canon_ace_list: acl group "
+                                        "control on and current user in file "
+                                        "%s primary group.\n",
+                                        smb_fname_str_dbg(smb_fname)));
 
                                become_root();
                                sret = SMB_VFS_SYS_ACL_SET_FD(fsp, the_acl);
@@ -2827,8 +2833,11 @@ static bool set_canon_ace_list(files_struct *fsp,
                        }
 
                        if (ret == False) {
-                               DEBUG(2,("set_canon_ace_list: sys_acl_set_file failed for file %s (%s).\n",
-                                               fsp->fsp_name, strerror(errno) ));
+                               DEBUG(2,("set_canon_ace_list: "
+                                        "sys_acl_set_file failed for file %s "
+                                        "(%s).\n",
+                                        smb_fname_str_dbg(smb_fname),
+                                        strerror(errno) ));
                                goto fail;
                        }
                }
@@ -2841,6 +2850,7 @@ static bool set_canon_ace_list(files_struct *fsp,
        if (the_acl != NULL) {
                SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
        }
+       TALLOC_FREE(smb_fname);
 
        return ret;
 }
@@ -3405,11 +3415,11 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
      then allow chown to the currently authenticated user.
 ****************************************************************************/
 
-int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
+int try_chown(connection_struct *conn, struct smb_filename *smb_fname,
+             uid_t uid, gid_t gid)
 {
        int ret;
        files_struct *fsp;
-       SMB_STRUCT_STAT st;
 
        if(!CAN_WRITE(conn)) {
                return -1;
@@ -3417,7 +3427,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
 
        /* Case (1). */
        /* try the direct way first */
-       ret = SMB_VFS_CHOWN(conn, fname, uid, gid);
+       ret = SMB_VFS_CHOWN(conn, smb_fname->base_name, uid, gid);
        if (ret == 0)
                return 0;
 
@@ -3436,7 +3446,8 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
 
                        become_root();
                        /* Keep the current file gid the same - take ownership doesn't imply group change. */
-                       ret = SMB_VFS_CHOWN(conn, fname, uid, (gid_t)-1);
+                       ret = SMB_VFS_CHOWN(conn, smb_fname->base_name, uid,
+                                           (gid_t)-1);
                        unbecome_root();
                        return ret;
                }
@@ -3457,11 +3468,11 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
                return -1;
        }
 
-       if (vfs_stat_smb_fname(conn,fname,&st)) {
+       if (SMB_VFS_STAT(conn, smb_fname)) {
                return -1;
        }
 
-       if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, fname, &st, &fsp))) {
+       if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, smb_fname, &fsp))) {
                return -1;
        }
 
@@ -3507,8 +3518,8 @@ NTSTATUS append_parent_acl(files_struct *fsp,
                return NT_STATUS_NO_MEMORY;
        }
 
-       status = create_synthetic_smb_fname_split(mem_ctx, parent_name, NULL,
-                                                 &smb_dname);
+       status = create_synthetic_smb_fname(mem_ctx, parent_name, NULL, NULL,
+                                           &smb_dname);
        if (!NT_STATUS_IS_OK(status)) {
                goto fail;
        }
@@ -3530,16 +3541,16 @@ NTSTATUS append_parent_acl(files_struct *fsp,
                &parent_fsp,                            /* result */
                &info);                                 /* pinfo */
 
-       TALLOC_FREE(smb_fname);
-
        if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(smb_dname);
                return status;
        }
 
-       status = SMB_VFS_GET_NT_ACL(parent_fsp->conn, parent_fsp->fsp_name,
+       status = SMB_VFS_GET_NT_ACL(parent_fsp->conn, smb_dname->base_name,
                                    DACL_SECURITY_INFORMATION, &parent_sd );
 
        close_file(NULL, parent_fsp, NORMAL_CLOSE);
+       TALLOC_FREE(smb_dname);
 
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -3686,7 +3697,6 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
        connection_struct *conn = fsp->conn;
        uid_t user = (uid_t)-1;
        gid_t grp = (gid_t)-1;
-       SMB_STRUCT_STAT sbuf;
        DOM_SID file_owner_sid;
        DOM_SID file_grp_sid;
        canon_ace *file_ace_list = NULL;
@@ -3697,12 +3707,21 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
        bool set_acl_as_root = false;
        bool acl_set_support = false;
        bool ret = false;
+       struct smb_filename *smb_fname = NULL;
+
+       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
+                                                 NULL, &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
 
-       DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name ));
+       DEBUG(10,("set_nt_acl: called for file %s\n",
+                 smb_fname_str_dbg(smb_fname)));
 
        if (!CAN_WRITE(conn)) {
                DEBUG(10,("set acl rejected on read-only share\n"));
-               return NT_STATUS_MEDIA_WRITE_PROTECTED;
+               status = NT_STATUS_MEDIA_WRITE_PROTECTED;
+               goto out;
        }
 
        /*
@@ -3710,15 +3729,19 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
         */
 
        if(fsp->is_directory || fsp->fh->fd == -1) {
-               if(vfs_stat_smb_fname(fsp->conn,fsp->fsp_name, &sbuf) != 0)
-                       return map_nt_error_from_unix(errno);
+               if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) {
+                       status = map_nt_error_from_unix(errno);
+                       goto out;
+               }
        } else {
-               if(SMB_VFS_FSTAT(fsp, &sbuf) != 0)
-                       return map_nt_error_from_unix(errno);
+               if(SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
+                       status = map_nt_error_from_unix(errno);
+                       goto out;
+               }
        }
 
        /* Save the original element we check against. */
-       orig_mode = sbuf.st_ex_mode;
+       orig_mode = smb_fname->st.st_ex_mode;
 
        /*
         * Unpack the user/group/world id's.
@@ -3726,7 +3749,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
 
        status = unpack_nt_owners( SNUM(conn), &user, &grp, security_info_sent, psd);
        if (!NT_STATUS_IS_OK(status)) {
-               return status;
+               goto out;
        }
 
        /*
@@ -3735,18 +3758,24 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
         * Noticed by Simo.
         */
 
-       if (((user != (uid_t)-1) && (sbuf.st_ex_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_ex_gid != grp))) {
+       if (((user != (uid_t)-1) && (smb_fname->st.st_ex_uid != user)) ||
+           (( grp != (gid_t)-1) && (smb_fname->st.st_ex_gid != grp))) {
 
                DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
-                               fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
-
-               if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) {
-                       DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n",
-                               fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
+                        smb_fname_str_dbg(smb_fname), (unsigned int)user,
+                        (unsigned int)grp ));
+
+               if(try_chown(fsp->conn, smb_fname, user, grp) == -1) {
+                       DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error "
+                                "= %s.\n", smb_fname_str_dbg(smb_fname),
+                                (unsigned int)user, (unsigned int)grp,
+                                strerror(errno)));
                        if (errno == EPERM) {
-                               return NT_STATUS_INVALID_OWNER;
+                               status = NT_STATUS_INVALID_OWNER;
+                               goto out;
                        }
-                       return map_nt_error_from_unix(errno);
+                       status = map_nt_error_from_unix(errno);
+                       goto out;
                }
 
                /*
@@ -3755,27 +3784,25 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                 */
 
                if(fsp->is_directory) {
-                       if(vfs_stat_smb_fname(fsp->conn, fsp->fsp_name,
-                                             &sbuf) != 0) {
-                               return map_nt_error_from_unix(errno);
+                       if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) {
+                               status = map_nt_error_from_unix(errno);
+                               goto out;
                        }
                } else {
 
                        int sret;
 
                        if(fsp->fh->fd == -1)
-                               sret = vfs_stat_smb_fname(fsp->conn,
-                                                         fsp->fsp_name,
-                                                         &sbuf);
+                               sret = SMB_VFS_STAT(fsp->conn, smb_fname);
                        else
-                               sret = SMB_VFS_FSTAT(fsp, &sbuf);
+                               sret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
 
                        if(sret != 0)
                                return map_nt_error_from_unix(errno);
                }
 
                /* Save the original element we check against. */
-               orig_mode = sbuf.st_ex_mode;
+               orig_mode = smb_fname->st.st_ex_mode;
 
                /* If we successfully chowned, we know we must
                 * be able to set the acl, so do it as root.
@@ -3783,21 +3810,24 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                set_acl_as_root = true;
        }
 
-       create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
+       create_file_sids(&smb_fname->st, &file_owner_sid, &file_grp_sid);
 
-       acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid,
-                                       &file_ace_list, &dir_ace_list, security_info_sent, psd);
+       acl_perms = unpack_canon_ace(fsp, &smb_fname->st, &file_owner_sid,
+                                    &file_grp_sid, &file_ace_list,
+                                    &dir_ace_list, security_info_sent, psd);
 
        /* Ignore W2K traverse DACL set. */
        if (!file_ace_list && !dir_ace_list) {
-               return NT_STATUS_OK;
+               status = NT_STATUS_OK;
+               goto out;
        }
 
        if (!acl_perms) {
                DEBUG(3,("set_nt_acl: cannot set permissions\n"));
                free_canon_ace_list(file_ace_list);
                free_canon_ace_list(dir_ace_list);
-               return NT_STATUS_ACCESS_DENIED;
+               status = NT_STATUS_ACCESS_DENIED;
+               goto out;
        }
 
        /*
@@ -3807,7 +3837,8 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
        if(!(security_info_sent & DACL_SECURITY_INFORMATION) || (psd->dacl == NULL)) {
                free_canon_ace_list(file_ace_list);
                free_canon_ace_list(dir_ace_list);
-               return NT_STATUS_OK;
+               status = NT_STATUS_OK;
+               goto out;
        }
 
        /*
@@ -3819,15 +3850,19 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                if (set_acl_as_root) {
                        become_root();
                }
-               ret = set_canon_ace_list(fsp, file_ace_list, False, &sbuf, &acl_set_support);
+               ret = set_canon_ace_list(fsp, file_ace_list, false,
+                                        &smb_fname->st, &acl_set_support);
                if (set_acl_as_root) {
                        unbecome_root();
                }
                if (acl_set_support && ret == false) {
-                       DEBUG(3,("set_nt_acl: failed to set file acl on file %s (%s).\n", fsp->fsp_name, strerror(errno) ));
+                       DEBUG(3,("set_nt_acl: failed to set file acl on file "
+                                "%s (%s).\n", smb_fname_str_dbg(smb_fname),
+                                strerror(errno)));
                        free_canon_ace_list(file_ace_list);
                        free_canon_ace_list(dir_ace_list);
-                       return map_nt_error_from_unix(errno);
+                       status = map_nt_error_from_unix(errno);
+                       goto out;
                }
        }
 
@@ -3836,15 +3871,21 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                        if (set_acl_as_root) {
                                become_root();
                        }
-                       ret = set_canon_ace_list(fsp, dir_ace_list, True, &sbuf, &acl_set_support);
+                       ret = set_canon_ace_list(fsp, dir_ace_list, true,
+                                                &smb_fname->st,
+                                                &acl_set_support);
                        if (set_acl_as_root) {
                                unbecome_root();
                        }
                        if (ret == false) {
-                               DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) ));
+                               DEBUG(3,("set_nt_acl: failed to set default "
+                                        "acl on directory %s (%s).\n",
+                                        smb_fname_str_dbg(smb_fname),
+                                        strerror(errno) ));
                                free_canon_ace_list(file_ace_list);
                                free_canon_ace_list(dir_ace_list);
-                               return map_nt_error_from_unix(errno);
+                               status = map_nt_error_from_unix(errno);
+                               goto out;
                        }
                } else {
                        int sret = -1;
@@ -3856,18 +3897,24 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                        if (set_acl_as_root) {
                                become_root();
                        }
-                       sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name);
+                       sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn,
+                           smb_fname->base_name);
                        if (set_acl_as_root) {
                                unbecome_root();
                        }
                        if (sret == -1) {
-                               if (acl_group_override(conn, &sbuf, fsp->fsp_name)) {
-                                       DEBUG(5,("set_nt_acl: acl group control on and "
-                                               "current user in file %s primary group. Override delete_def_acl\n",
-                                               fsp->fsp_name ));
+                               if (acl_group_override(conn, smb_fname)) {
+                                       DEBUG(5,("set_nt_acl: acl group "
+                                                "control on and current user "
+                                                "in file %s primary group. "
+                                                "Override delete_def_acl\n",
+                                               smb_fname_str_dbg(smb_fname)));
 
                                        become_root();
-                                       sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name);
+                                       sret =
+                                           SMB_VFS_SYS_ACL_DELETE_DEF_FILE(
+                                                   conn,
+                                                   smb_fname->base_name);
                                        unbecome_root();
                                }
 
@@ -3875,7 +3922,8 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                                        DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno)));
                                        free_canon_ace_list(file_ace_list);
                                        free_canon_ace_list(dir_ace_list);
-                                       return map_nt_error_from_unix(errno);
+                                       status = map_nt_error_from_unix(errno);
+                                       goto out;
                                }
                        }
                }
@@ -3904,41 +3952,54 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                if (!convert_canon_ace_to_posix_perms( fsp, file_ace_list, &posix_perms)) {
                        free_canon_ace_list(file_ace_list);
                        free_canon_ace_list(dir_ace_list);
-                       DEBUG(3,("set_nt_acl: failed to convert file acl to posix permissions for file %s.\n",
-                               fsp->fsp_name ));
-                       return NT_STATUS_ACCESS_DENIED;
+                       DEBUG(3,("set_nt_acl: failed to convert file acl to "
+                                "posix permissions for file %s.\n",
+                                smb_fname_str_dbg(smb_fname)));
+                       status = NT_STATUS_ACCESS_DENIED;
+                       goto out;
                }
 
                if (orig_mode != posix_perms) {
                        int sret = -1;
 
                        DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n",
-                               fsp->fsp_name, (unsigned int)posix_perms ));
+                                smb_fname_str_dbg(smb_fname),
+                                (unsigned int)posix_perms));
 
                        if (set_acl_as_root) {
                                become_root();
                        }
-                       sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms);
+                       sret = SMB_VFS_CHMOD(conn, smb_fname->base_name,
+                                            posix_perms);
                        if (set_acl_as_root) {
                                unbecome_root();
                        }
                        if(sret == -1) {
-                               if (acl_group_override(conn, &sbuf, fsp->fsp_name)) {
-                                       DEBUG(5,("set_nt_acl: acl group control on and "
-                                               "current user in file %s primary group. Override chmod\n",
-                                               fsp->fsp_name ));
+                               if (acl_group_override(conn, smb_fname)) {
+                                       DEBUG(5,("set_nt_acl: acl group "
+                                                "control on and current user "
+                                                "in file %s primary group. "
+                                                "Override chmod\n",
+                                               smb_fname_str_dbg(smb_fname)));
 
                                        become_root();
-                                       sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms);
+                                       sret =
+                                           SMB_VFS_CHMOD(conn,
+                                                         smb_fname->base_name,
+                                                         posix_perms);
                                        unbecome_root();
                                }
 
                                if (sret == -1) {
-                                       DEBUG(3,("set_nt_acl: chmod %s, 0%o failed. Error = %s.\n",
-                                               fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) ));
+                                       DEBUG(3,("set_nt_acl: chmod %s, 0%o "
+                                                "failed. Error = %s.\n",
+                                                smb_fname_str_dbg(smb_fname),
+                                                (unsigned int)posix_perms,
+                                                strerror(errno)));
                                        free_canon_ace_list(file_ace_list);
                                        free_canon_ace_list(dir_ace_list);
-                                       return map_nt_error_from_unix(errno);
+                                       status = map_nt_error_from_unix(errno);
+                                       goto out;
                                }
                        }
                }
@@ -3947,7 +4008,10 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
        free_canon_ace_list(file_ace_list);
        free_canon_ace_list(dir_ace_list);
 
-       return NT_STATUS_OK;
+       status = NT_STATUS_OK;
+ out:
+       TALLOC_FREE(smb_fname);
+       return status;
 }
 
 /****************************************************************************
index 0afaf56c96a443ac3ab9a40964d9a7d75d344c95..483f68947edf198ff9fccd3b57d5aa6aa5b0ff9f 100644 (file)
@@ -1091,7 +1091,7 @@ void reply_getatr(struct smb_request *req)
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
                                &smb_fname,
-                               &fname);
+                               NULL);
                if (!NT_STATUS_IS_OK(status)) {
                        if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                                reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -1110,7 +1110,7 @@ void reply_getatr(struct smb_request *req)
                        goto out;
                }
 
-               mode = dos_mode(conn, fname, &smb_fname->st);
+               mode = dos_mode(conn, smb_fname);
                size = smb_fname->st.st_ex_size;
 
                if (ask_sharemode) {
@@ -1747,7 +1747,7 @@ void reply_open(struct smb_request *req)
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
                                &smb_fname,
-                               &fname);
+                               NULL);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req,
@@ -1760,8 +1760,9 @@ void reply_open(struct smb_request *req)
        }
 
        if (!map_open_params_to_ntcreate(
-                   fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask,
-                   &share_mode, &create_disposition, &create_options)) {
+                   smb_fname->base_name, deny_mode, OPENX_FILE_EXISTS_OPEN,
+                   &access_mask, &share_mode, &create_disposition,
+                   &create_options)) {
                reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
                goto out;
        }
@@ -1793,7 +1794,7 @@ void reply_open(struct smb_request *req)
        }
 
        size = smb_fname->st.st_ex_size;
-       fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st);
+       fattr = dos_mode(conn, smb_fname);
 
        /* Deal with other possible opens having a modified
           write time. JRA. */
@@ -1916,7 +1917,7 @@ void reply_open_and_X(struct smb_request *req)
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
                                &smb_fname,
-                               &fname);
+                               NULL);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req,
@@ -1929,7 +1930,7 @@ void reply_open_and_X(struct smb_request *req)
        }
 
        if (!map_open_params_to_ntcreate(
-                   fname, deny_mode, smb_ofun, &access_mask,
+                   smb_fname->base_name, deny_mode, smb_ofun, &access_mask,
                    &share_mode, &create_disposition, &create_options)) {
                reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
                goto out;
@@ -1980,7 +1981,7 @@ void reply_open_and_X(struct smb_request *req)
                    SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &smb_fname->st);
        }
 
-       fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st);
+       fattr = dos_mode(conn, smb_fname);
        mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
        if (fattr & aDIR) {
                close_file(req, fsp, ERROR_CLOSE);
@@ -2354,13 +2355,22 @@ void reply_ctemp(struct smb_request *req)
 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
                           uint16 dirtype, SMB_STRUCT_STAT *pst)
 {
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
        uint32 fmode;
 
        if (!CAN_WRITE(conn)) {
                return NT_STATUS_MEDIA_WRITE_PROTECTED;
        }
 
-       fmode = dos_mode(conn, fsp->fsp_name, pst);
+       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
+                                                 pst, &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       fmode = dos_mode(conn, smb_fname);
+       TALLOC_FREE(smb_fname);
        if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
                return NT_STATUS_NO_SUCH_FILE;
        }
@@ -2395,13 +2405,14 @@ static NTSTATUS do_unlink(connection_struct *conn,
                        struct smb_filename *smb_fname,
                        uint32 dirtype)
 {
-       char *fname = NULL;
        uint32 fattr;
        files_struct *fsp;
        uint32 dirtype_orig = dirtype;
        NTSTATUS status;
 
-       DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname, dirtype ));
+       DEBUG(10,("do_unlink: %s, dirtype = %d\n",
+                 smb_fname_str_dbg(smb_fname),
+                 dirtype));
 
        if (!CAN_WRITE(conn)) {
                return NT_STATUS_MEDIA_WRITE_PROTECTED;
@@ -2411,12 +2422,7 @@ static NTSTATUS do_unlink(connection_struct *conn,
                return map_nt_error_from_unix(errno);
        }
 
-       status = get_full_smb_filename(smb_fname, smb_fname, &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       fattr = dos_mode(conn, fname, &smb_fname->st);
-       TALLOC_FREE(fname);
+       fattr = dos_mode(conn, smb_fname);
 
        if (dirtype & FILE_ATTRIBUTE_NORMAL) {
                dirtype = aDIR|aARCH|aRONLY;
@@ -6578,7 +6584,6 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
                        bool target_is_directory)
 {
        struct smb_filename *smb_fname_dst_tmp = NULL;
-       char *fname_src = NULL;
        SMB_OFF_T ret=-1;
        files_struct *fsp1,*fsp2;
        uint32 dosattrs;
@@ -6655,14 +6660,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
                goto out;
        }
 
-       status = get_full_smb_filename(talloc_tos(), smb_fname_src, &fname_src);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       dosattrs = dos_mode(conn, fname_src, &smb_fname_src->st);
-
-       TALLOC_FREE(fname_src);
+       dosattrs = dos_mode(conn, smb_fname_src);
 
        if (SMB_VFS_STAT(conn, smb_fname_dst_tmp) == -1) {
                ZERO_STRUCTP(&smb_fname_dst_tmp->st);
@@ -7739,6 +7737,8 @@ void reply_getattrE(struct smb_request *req)
        int mode;
        files_struct *fsp;
        struct timespec create_ts;
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
 
        START_PROFILE(SMBgetattrE);
 
@@ -7763,7 +7763,16 @@ void reply_getattrE(struct smb_request *req)
                return;
        }
 
-       mode = dos_mode(conn,fsp->fsp_name,&sbuf);
+       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
+                                                 &sbuf, &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               END_PROFILE(SMBgetattrE);
+               return;
+       }
+
+       mode = dos_mode(conn, smb_fname);
+       TALLOC_FREE(smb_fname);
 
        /*
         * Convert the times into dos times. Set create
index a936a0892e466e308b4727a10b863718ec91f38c..bdff1939e5f7447e86b0456ad9bfed334acf5a05 100644 (file)
@@ -353,6 +353,16 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
                sbuf = smb_fname->st;
        }
 
+       if (!smb_fname) {
+               status = create_synthetic_smb_fname_split(talloc_tos(),
+                                                         result->fsp_name,
+                                                         &sbuf, &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       tevent_req_nterror(req, status);
+                       goto out;
+               }
+       }
+
        smb2req->compat_chain_fsp = smbreq->chain_fsp;
 
        state->out_oplock_level = 0;
@@ -369,8 +379,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
        state->out_allocation_size      = sbuf.st_ex_blksize * sbuf.st_ex_blocks;
        state->out_end_of_file          = sbuf.st_ex_size;
        state->out_file_attributes      = dos_mode(result->conn,
-                                                  result->fsp_name,
-                                                  &sbuf);
+                                                  smb_fname);
        if (state->out_file_attributes == 0) {
                state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
        }
index 0dd2ca2e3cb8f0e77977c6b59c4e6e11e28927f8..62280ddde03d558383fb258b6337d8069aaccc32 100644 (file)
@@ -964,7 +964,7 @@ static void call_trans2open(connection_struct *conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
                                &smb_fname,
-                               &fname);
+                               NULL);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req,
@@ -981,7 +981,8 @@ static void call_trans2open(connection_struct *conn,
                goto out;
        }
 
-       if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
+       if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
+                               open_ofun,
                                &access_mask,
                                &share_mode,
                                &create_disposition,
@@ -1047,7 +1048,7 @@ static void call_trans2open(connection_struct *conn,
        }
 
        size = get_file_size_stat(&smb_fname->st);
-       fattr = dos_mode(conn, fsp->fsp_name, &smb_fname->st);
+       fattr = dos_mode(conn, smb_fname);
        mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
        inode = smb_fname->st.st_ex_ino;
        if (fattr & aDIR) {
@@ -1388,6 +1389,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
 
                if (got_match) {
                        bool isdots = (ISDOT(dname) || ISDOTDOT(dname));
+                       struct smb_filename *smb_fname = NULL;
+                       NTSTATUS status;
 
                        if (dont_descend && !isdots) {
                                TALLOC_FREE(fname);
@@ -1412,25 +1415,40 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
                                return False;
                        }
 
+                       /* A dirent from dptr_ReadDirName isn't a stream. */
+                       status = create_synthetic_smb_fname(ctx, pathreal,
+                                                           NULL, &sbuf,
+                                                           &smb_fname);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               TALLOC_FREE(fname);
+                       }
+
                        if (INFO_LEVEL_IS_UNIX(info_level)) {
-                               if (vfs_lstat_smb_fname(conn, pathreal,
-                                                       &sbuf) != 0) {
-                                       DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
-                                               pathreal,strerror(errno)));
+                               if (SMB_VFS_LSTAT(conn, smb_fname) != 0) {
+                                       DEBUG(5,("get_lanman2_dir_entry: "
+                                                "Couldn't lstat [%s] (%s)\n",
+                                                smb_fname_str_dbg(smb_fname),
+                                                strerror(errno)));
+                                       TALLOC_FREE(smb_fname);
                                        TALLOC_FREE(pathreal);
                                        TALLOC_FREE(fname);
                                        continue;
                                }
-                       } else if (!VALID_STAT(sbuf) &&
-                                  vfs_stat_smb_fname(conn, pathreal,
-                                                     &sbuf) != 0) {
+                       } else if (!VALID_STAT(smb_fname->st) &&
+                                  SMB_VFS_STAT(conn, smb_fname) != 0) {
                                /* Needed to show the msdfs symlinks as
                                 * directories */
 
-                               ms_dfs_link = check_msdfs_link(conn, pathreal, &sbuf);
+                               ms_dfs_link =
+                                   check_msdfs_link(conn,
+                                                    smb_fname->base_name,
+                                                    &smb_fname->st);
                                if (!ms_dfs_link) {
-                                       DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
-                                               pathreal,strerror(errno)));
+                                       DEBUG(5,("get_lanman2_dir_entry: "
+                                                "Couldn't stat [%s] (%s)\n",
+                                                smb_fname_str_dbg(smb_fname),
+                                                strerror(errno)));
+                                       TALLOC_FREE(smb_fname);
                                        TALLOC_FREE(pathreal);
                                        TALLOC_FREE(fname);
                                        continue;
@@ -1438,38 +1456,42 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
                        }
 
                        if (ms_dfs_link) {
-                               mode = dos_mode_msdfs(conn,pathreal,&sbuf);
+                               mode = dos_mode_msdfs(conn, smb_fname);
                        } else {
-                               mode = dos_mode(conn,pathreal,&sbuf);
+                               mode = dos_mode(conn, smb_fname);
                        }
 
                        if (!dir_check_ftype(conn,mode,dirtype)) {
                                DEBUG(5,("get_lanman2_dir_entry: [%s] attribs didn't match %x\n",fname,dirtype));
+                               TALLOC_FREE(smb_fname);
                                TALLOC_FREE(pathreal);
                                TALLOC_FREE(fname);
                                continue;
                        }
 
                        if (!(mode & aDIR)) {
-                               file_size = get_file_size_stat(&sbuf);
+                               file_size = get_file_size_stat(&smb_fname->st);
                        }
-                       allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,NULL,&sbuf);
+                       allocation_size =
+                           SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
 
                        if (ask_sharemode) {
                                struct timespec write_time_ts;
                                struct file_id fileid;
 
                                ZERO_STRUCT(write_time_ts);
-                               fileid = vfs_file_id_from_sbuf(conn, &sbuf);
+                               fileid = vfs_file_id_from_sbuf(conn,
+                                                              &smb_fname->st);
                                get_file_infos(fileid, NULL, &write_time_ts);
                                if (!null_timespec(write_time_ts)) {
-                                       update_stat_ex_mtime(&sbuf, write_time_ts);
+                                       update_stat_ex_mtime(&smb_fname->st,
+                                                            write_time_ts);
                                }
                        }
 
-                       mdate_ts = sbuf.st_ex_mtime;
-                       adate_ts = sbuf.st_ex_atime;
-                       create_date_ts = sbuf.st_ex_btime;
+                       mdate_ts = smb_fname->st.st_ex_mtime;
+                       adate_ts = smb_fname->st.st_ex_atime;
+                       create_date_ts = smb_fname->st.st_ex_btime;
 
                        if (lp_dos_filetime_resolution(SNUM(conn))) {
                                dos_filetime_timespec(&create_date_ts);
@@ -1482,11 +1504,14 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
                        adate = convert_timespec_to_time_t(adate_ts);
 
                        DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",
-                               pathreal,fname));
+                                smb_fname_str_dbg(smb_fname), fname));
 
                        found = True;
 
                        dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
+                       sbuf = smb_fname->st;
+
+                       TALLOC_FREE(smb_fname);
                }
 
                if (!found)
@@ -4137,16 +4162,16 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
        DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
                fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
 
-       p = strrchr_m(fname,'/');
+       p = strrchr_m(smb_fname->base_name,'/');
        if (!p)
-               base_name = fname;
+               base_name = smb_fname->base_name;
        else
                base_name = p+1;
 
        if (ms_dfs_link) {
-               mode = dos_mode_msdfs(conn,fname,&sbuf);
+               mode = dos_mode_msdfs(conn, smb_fname);
        } else {
-               mode = dos_mode(conn,fname,&sbuf);
+               mode = dos_mode(conn, smb_fname);
        }
        if (!mode)
                mode = FILE_ATTRIBUTE_NORMAL;
@@ -5072,9 +5097,7 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
        DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode));
 
        /* check the mode isn't different, before changing it */
-       if ((dosmode != 0) && (dosmode != dos_mode(conn,
-                                                  smb_fname_base->base_name,
-                                                  &smb_fname_base->st))) {
+       if ((dosmode != 0) && (dosmode != dos_mode(conn, smb_fname_base))) {
                DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
                          "0x%x\n", smb_fname_str_dbg(smb_fname_base),
                          (unsigned int)dosmode));
@@ -5226,8 +5249,7 @@ static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
                                const char *pdata,
                                int total_data,
                                files_struct *fsp,
-                               const char *fname,
-                               SMB_STRUCT_STAT *psbuf)
+                               const struct smb_filename *smb_fname)
 {
        NTSTATUS status = NT_STATUS_OK;
        bool delete_on_close;
@@ -5242,11 +5264,11 @@ static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
        }
 
        delete_on_close = (CVAL(pdata,0) ? True : False);
-       dosmode = dos_mode(conn, fname, psbuf);
+       dosmode = dos_mode(conn, smb_fname);
 
        DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
                "delete_on_close = %u\n",
-               fsp->fsp_name,
+               smb_fname_str_dbg(smb_fname),
                (unsigned int)dosmode,
                (unsigned int)delete_on_close ));
 
@@ -6748,10 +6770,8 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
                                 struct smb_request *req,
                                const char *pdata,
                                int total_data,
-                               const char *fname,
-                               SMB_STRUCT_STAT *psbuf)
+                               struct smb_filename *smb_fname)
 {
-       struct smb_filename *smb_fname = NULL;
        NTSTATUS status = NT_STATUS_OK;
        files_struct *fsp = NULL;
        uint16 flags = 0;
@@ -6767,29 +6787,23 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
 
        flags = SVAL(pdata,0);
 
-       if (!VALID_STAT(*psbuf)) {
+       if (!VALID_STAT(smb_fname->st)) {
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
        if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
-                       !VALID_STAT_OF_DIR(*psbuf)) {
+                       !VALID_STAT_OF_DIR(smb_fname->st)) {
                return NT_STATUS_NOT_A_DIRECTORY;
        }
 
        DEBUG(10,("smb_posix_unlink: %s %s\n",
                (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
-               fname));
+               smb_fname_str_dbg(smb_fname)));
 
-       if (VALID_STAT_OF_DIR(*psbuf)) {
+       if (VALID_STAT_OF_DIR(smb_fname->st)) {
                create_options |= FILE_DIRECTORY_FILE;
        }
 
-       status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
-                                                 &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
         status = SMB_VFS_CREATE_FILE(
                conn,                                   /* conn */
                req,                                    /* req */
@@ -6808,9 +6822,6 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
                &fsp,                                   /* result */
                &info);                                 /* pinfo */
 
-       *psbuf = smb_fname->st;
-       TALLOC_FREE(smb_fname);
-
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -6854,8 +6865,7 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
                                                &del,
                                                1,
                                                fsp,
-                                               fname,
-                                               psbuf);
+                                               smb_fname);
 
        if (!NT_STATUS_IS_OK(status)) {
                close_file(req, fsp, NORMAL_CLOSE);
@@ -7133,8 +7143,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                                                pdata,
                                                total_data,
                                                fsp,
-                                               fname,
-                                               &sbuf);
+                                               smb_fname);
                        break;
                }
 
@@ -7270,8 +7279,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                        status = smb_posix_unlink(conn, req,
                                                pdata,
                                                total_data,
-                                               fname,
-                                               &sbuf);
+                                               smb_fname);
                        break;
                }