summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h12
-rw-r--r--source3/modules/nfs4_acls.c12
-rw-r--r--source3/modules/onefs_open.c3
-rw-r--r--source3/smbd/dir.c48
-rw-r--r--source3/smbd/dosmode.c177
-rw-r--r--source3/smbd/fileio.c34
-rw-r--r--source3/smbd/nttrans.c18
-rw-r--r--source3/smbd/open.c21
-rw-r--r--source3/smbd/posix_acls.c260
-rw-r--r--source3/smbd/reply.c65
-rw-r--r--source3/smbd/smb2_create.c13
-rw-r--r--source3/smbd/trans2.c120
12 files changed, 436 insertions, 347 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index ef252c2846..471084c264 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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);
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
index 70bdaa8826..9b3c8725d5 100644
--- a/source3/modules/nfs4_acls.c
+++ b/source3/modules/nfs4_acls.c
@@ -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));
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c
index 20ce814518..60a1790f64 100644
--- a/source3/modules/onefs_open.c
+++ b/source3/modules/onefs_open.c
@@ -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);
}
}
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 723fb6fd6f..642fb09362 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -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)
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 9bd097c0bb..ca926aa33c 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -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;
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index caaebf6217..0c13b845df 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -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
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 5d676470c8..e28e6f3a84 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -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;
}
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index a58cffa257..e73b3e4fdd 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -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.
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 0c7f4b7bb7..76eee9b56a 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -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;
}
/****************************************************************************
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 0afaf56c96..483f68947e 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -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
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index a936a0892e..bdff1939e5 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -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;
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 0dd2ca2e3c..62280ddde0 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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;
}