diff options
Diffstat (limited to 'source3/smbd/dosmode.c')
-rw-r--r-- | source3/smbd/dosmode.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index c1af18d80b..9db3e208b5 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -200,3 +200,71 @@ int dos_chmod(connection_struct *conn,char *fname,int dosmode,struct stat *st) return(sys_chmod(fname,unixmode)); } + +/******************************************************************* +Wrapper around sys_utime that possibly allows DOS semantics rather +than POSIX. +*******************************************************************/ +int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) +{ + extern struct current_user current_user; + struct stat sb; + int ret = -1; + + errno = 0; + + if(sys_utime(fname, times) == 0) + return 0; + + if((errno != EPERM) && (errno != EACCES)) + return -1; + + if(!lp_dos_filetimes(SNUM(conn))) + return -1; + + /* We have permission (given by the Samba admin) to + break POSIX semantics and allow a user to change + the time on a file they don't own but can write to + (as DOS does). + */ + + if(sys_stat(fname,&sb) != 0) + return -1; + + /* Check if we have write access. */ + if (CAN_WRITE(conn)) { + if (((sb.st_mode & S_IWOTH) || + conn->admin_user || + ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) || + ((sb.st_mode & S_IWGRP) && + in_group(sb.st_gid,current_user.gid, + current_user.ngroups,current_user.groups)))) { + /* We are allowed to become root and change the filetime. */ + become_root(False); + ret = sys_utime(fname, times); + unbecome_root(False); + } + } + + return ret; +} + +/******************************************************************* +Change a filetime - possibly allowing DOS semantics. +*******************************************************************/ +BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime) +{ + struct utimbuf times; + + if (null_mtime(mtime)) return(True); + + times.modtime = times.actime = mtime; + + if (file_utime(conn, fname, ×)) { + DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); + } + + return(True); +} + + |