summaryrefslogtreecommitdiff
path: root/source3/smbd/dosmode.c
diff options
context:
space:
mode:
authorTim Prouty <tprouty@samba.org>2009-07-06 14:36:16 -0700
committerTim Prouty <tprouty@samba.org>2009-07-06 15:38:41 -0700
commit99bd4fda0cd97eb211549a511a2ff6153c2bde2d (patch)
treedb1e4d3424b6bd1215a341f727ef94c748244454 /source3/smbd/dosmode.c
parent0f6e10886f3f778fe301ee981873f29d295d39c5 (diff)
downloadsamba-99bd4fda0cd97eb211549a511a2ff6153c2bde2d.tar.gz
samba-99bd4fda0cd97eb211549a511a2ff6153c2bde2d.tar.bz2
samba-99bd4fda0cd97eb211549a511a2ff6153c2bde2d.zip
s3: Plumb smb_filename around SMB_VFS_CHFLAGS
SMB_VFS_CHFLAGS isn't actually getting the smb_filename struct for now since it only operates on the basefile. This is the strategy for all path-based operations that will never actually operate on a stream. By clarifying the meaning of path based operations that don't take an smb_filename struct, modules that implement streams such as vfs_onefs no longer need to implement SMB_VFS_CHFLAGS to ensure it's only called on the base_name.
Diffstat (limited to 'source3/smbd/dosmode.c')
-rw-r--r--source3/smbd/dosmode.c93
1 files changed, 49 insertions, 44 deletions
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 03ac0897ef..2006b75d52 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -429,15 +429,14 @@ static bool get_stat_dos_flags(connection_struct *conn,
****************************************************************************/
static bool set_stat_dos_flags(connection_struct *conn,
- const char *fname,
- SMB_STRUCT_STAT *sbuf,
- uint32_t dosmode,
- bool *attributes_changed)
+ const struct smb_filename *smb_fname,
+ uint32_t dosmode,
+ bool *attributes_changed)
{
uint32_t new_flags = 0;
int error = 0;
- SMB_ASSERT(sbuf && VALID_STAT(*sbuf));
+ SMB_ASSERT(VALID_STAT(smb_fname->st));
SMB_ASSERT(attributes_changed);
*attributes_changed = false;
@@ -446,23 +445,25 @@ static bool set_stat_dos_flags(connection_struct *conn,
return false;
}
- DEBUG(5, ("Setting stat dos attributes for %s.\n", fname));
+ DEBUG(5, ("Setting stat dos attributes for %s.\n",
+ smb_fname_str_dbg(smb_fname)));
- new_flags = (sbuf->st_ex_flags & ~UF_DOS_FLAGS) |
+ new_flags = (smb_fname->st.st_ex_flags & ~UF_DOS_FLAGS) |
dos_attributes_to_stat_dos_flags(dosmode);
/* Return early if no flags changed. */
- if (new_flags == sbuf->st_ex_flags)
+ if (new_flags == smb_fname->st.st_ex_flags)
return true;
DEBUG(5, ("Setting stat dos attributes=0x%x, prev=0x%x\n", new_flags,
- sbuf->st_ex_flags));
+ smb_fname->st.st_ex_flags));
/* Set new flags with chflags. */
- error = SMB_VFS_CHFLAGS(conn, fname, new_flags);
+ error = SMB_VFS_CHFLAGS(conn, smb_fname->base_name, new_flags);
if (error) {
DEBUG(0, ("Failed setting new stat dos attributes (0x%x) on "
- "file %s! errno=%d\n", new_flags, fname, errno));
+ "file %s! errno=%d\n", new_flags,
+ smb_fname_str_dbg(smb_fname), errno));
return false;
}
@@ -545,52 +546,56 @@ uint32 dos_mode(connection_struct *conn, const char *path, const SMB_STRUCT_STAT
chmod a file - but preserve some bits.
********************************************************************/
-int file_set_dosmode(connection_struct *conn, const char *fname,
- uint32 dosmode, SMB_STRUCT_STAT *st,
- const char *parent_dir,
- bool newfile)
+int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
+ uint32 dosmode, const char *parent_dir, bool newfile)
{
- SMB_STRUCT_STAT st1;
int mask=0;
mode_t tmp;
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);
- DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname));
+ DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n",
+ dosmode, smb_fname_str_dbg(smb_fname)));
- if (st == NULL) {
- SET_STAT_INVALID(st1);
- st = &st1;
- }
-
- if (!VALID_STAT(*st)) {
- if (vfs_stat_smb_fname(conn,fname,st))
+ if (!VALID_STAT(smb_fname->st)) {
+ if (SMB_VFS_STAT(conn, smb_fname))
return(-1);
}
- unixmode = st->st_ex_mode;
+ unixmode = smb_fname->st.st_ex_mode;
- get_acl_group_bits(conn, fname, &st->st_ex_mode);
+ get_acl_group_bits(conn, smb_fname->base_name,
+ &smb_fname->st.st_ex_mode);
- if (S_ISDIR(st->st_ex_mode))
+ if (S_ISDIR(smb_fname->st.st_ex_mode))
dosmode |= aDIR;
else
dosmode &= ~aDIR;
- old_mode = dos_mode(conn,fname,st);
+ 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);
if (dosmode & FILE_ATTRIBUTE_OFFLINE) {
if (!(old_mode & FILE_ATTRIBUTE_OFFLINE)) {
lret = SMB_VFS_SET_OFFLINE(conn, fname);
if (lret == -1) {
- DEBUG(0, ("set_dos_mode: client has asked to set "
- "FILE_ATTRIBUTE_OFFLINE to %s/%s but there was "
- "an error while setting it or it is not supported.\n",
- parent_dir, fname));
+ DEBUG(0, ("set_dos_mode: client has asked to "
+ "set FILE_ATTRIBUTE_OFFLINE to "
+ "%s/%s but there was an error while "
+ "setting it or it is not "
+ "supported.\n", parent_dir,
+ smb_fname_str_dbg(smb_fname)));
}
}
}
@@ -599,7 +604,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
old_mode &= ~FILE_ATTRIBUTE_OFFLINE;
if (old_mode == dosmode) {
- st->st_ex_mode = unixmode;
+ smb_fname->st.st_ex_mode = unixmode;
return(0);
}
@@ -607,26 +612,26 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
{
bool attributes_changed;
- if (set_stat_dos_flags(conn, fname, st, dosmode,
+ if (set_stat_dos_flags(conn, smb_fname, dosmode,
&attributes_changed))
{
if (!newfile && attributes_changed) {
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
- st->st_ex_mode = unixmode;
+ 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, st, dosmode)) {
+ if (set_ea_dos_attribute(conn, fname, &smb_fname->st, dosmode)) {
if (!newfile) {
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
- st->st_ex_mode = unixmode;
+ smb_fname->st.st_ex_mode = unixmode;
return 0;
}
@@ -648,10 +653,10 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
if (!MAP_HIDDEN(conn))
mask |= S_IXOTH;
- unixmode |= (st->st_ex_mode & mask);
+ unixmode |= (smb_fname->st.st_ex_mode & mask);
/* if we previously had any r bits set then leave them alone */
- if ((tmp = st->st_ex_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
+ if ((tmp = smb_fname->st.st_ex_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
unixmode |= tmp;
}
@@ -659,7 +664,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
/* if we previously had any w bits set then leave them alone
whilst adding in the new w bits, if the new mode is not rdonly */
if (!IS_DOS_READONLY(dosmode)) {
- unixmode |= (st->st_ex_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
+ unixmode |= (smb_fname->st.st_ex_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
}
ret = SMB_VFS_CHMOD(conn, fname, unixmode);
@@ -668,7 +673,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
- st->st_ex_mode = unixmode;
+ smb_fname->st.st_ex_mode = unixmode;
return 0;
}
@@ -693,8 +698,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
* break batch oplocks open by others. JRA.
*/
files_struct *fsp;
- if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, fname, st,
- &fsp)))
+ if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, fname,
+ &smb_fname->st, &fsp)))
return -1;
become_root();
ret = SMB_VFS_FCHMOD(fsp, unixmode);
@@ -705,7 +710,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
if (ret == 0) {
- st->st_ex_mode = unixmode;
+ smb_fname->st.st_ex_mode = unixmode;
}
}