diff options
Diffstat (limited to 'source3/smbd/dosmode.c')
-rw-r--r-- | source3/smbd/dosmode.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index d3813f9b41..a2e617c117 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -31,23 +31,6 @@ static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf) } /**************************************************************************** - Work out whether this file is offline -****************************************************************************/ - -static uint32 set_offline_flag(connection_struct *conn, const char *const path) -{ - if (ISDOT(path) || ISDOTDOT(path)) { - return 0; - } - - if (!lp_dmapi_support(SNUM(conn)) || !dmapi_have_session()) { - return 0; - } - - return dmapi_file_flags(path); -} - -/**************************************************************************** Change a dos mode to a unix mode. Base permission for files: if creating file and inheriting (i.e. parent_dir != NULL) @@ -366,6 +349,7 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) { uint32 result = 0; + bool offline; DEBUG(8,("dos_mode: %s\n", path)); @@ -395,8 +379,10 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) result |= dos_mode_from_sbuf(conn, path, sbuf); } - if (S_ISREG(sbuf->st_mode)) { - result |= set_offline_flag(conn, path); + + offline = SMB_VFS_IS_OFFLINE(conn, path, sbuf); + if (S_ISREG(sbuf->st_mode) && offline) { + result |= FILE_ATTRIBUTE_OFFLINE; } /* Optimization : Only call is_hidden_path if it's not already @@ -432,10 +418,11 @@ int file_set_dosmode(connection_struct *conn, const char *fname, int mask=0; mode_t tmp; mode_t unixmode; - int ret = -1; + 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)); @@ -458,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); } @@ -505,10 +509,11 @@ int file_set_dosmode(connection_struct *conn, const char *fname, unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) { - if (!newfile) { + ret = SMB_VFS_CHMOD(conn, fname, unixmode); + if (ret == 0) { + if(!newfile || (lret != -1)) { notify_fname(conn, NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); + FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); } st->st_mode = unixmode; return 0; |