summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/dosmode.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index eb18f65fca..f068f1f655 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -419,9 +419,10 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
mode_t tmp;
mode_t unixmode;
int ret = -1, lret = -1;
+ uint32_t old_mode;
/* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */
- dosmode &= SAMBA_ATTRIBUTES_MASK;
+ dosmode &= SAMBA_ATTRIBUTES_MASK | FILE_ATTRIBUTE_OFFLINE;
DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname));
@@ -444,7 +445,24 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
else
dosmode &= ~aDIR;
- if (dos_mode(conn,fname,st) == dosmode) {
+ old_mode = dos_mode(conn,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));
+ }
+ }
+ }
+
+ dosmode &= ~FILE_ATTRIBUTE_OFFLINE;
+ old_mode &= ~FILE_ATTRIBUTE_OFFLINE;
+
+ if (old_mode == dosmode) {
st->st_mode = unixmode;
return(0);
}
@@ -491,16 +509,6 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
}
- if (dosmode & 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));
- }
- }
-
ret = SMB_VFS_CHMOD(conn, fname, unixmode);
if (ret == 0) {
if(!newfile || (lret != -1)) {