diff -rub /tmp/samba-3.0.32//source/smbd/dosmode.c ./source/smbd/dosmode.c --- /tmp/samba-3.0.32//source/smbd/dosmode.c Mon Aug 25 23:09:21 2008 +++ ./source/smbd/dosmode.c Mon Nov 24 21:59:34 2008 @@ -143,27 +143,50 @@ return(result); } -/**************************************************************************** - Change a unix mode to a dos mode. -****************************************************************************/ +/* + * logic formerly in dos_mode_from_sbuf - but into seperate function as this + * should also be used elsewhere (or rather an improved version of this + * function + */ -static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) +BOOL is_readonly(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) { - int result = 0; enum mapreadonly_options ro_opts = (enum mapreadonly_options)lp_map_readonly(SNUM(conn)); + DEBUG(10,("is_readonly ro_opts %s\n",((ro_opts == MAP_READONLY_YES) ? "Yes" : + ((ro_opts == MAP_READONLY_NO) ? "No" : + ((ro_opts == MAP_READONLY_PERMISSIONS) ? "Permissions" : "INVALID"))))); + if (ro_opts == MAP_READONLY_YES) { - /* Original Samba method - map inverse of user "w" bit. */ + /* + * FIXME - we should really do away with this legacy stuff + * + * Original Samba method - map inverse of user "w" bit. + */ if ((sbuf->st_mode & S_IWUSR) == 0) { - result |= aRONLY; + return (True); } } else if (ro_opts == MAP_READONLY_PERMISSIONS) { /* Check actual permissions for read-only. */ if (!can_write_to_file(conn, path, sbuf)) { - result |= aRONLY; + return (True); } - } /* Else never set the readonly bit. */ + } + return (False); +} +/**************************************************************************** + Change a unix mode to a dos mode. +****************************************************************************/ + +static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) +{ + int result = 0; + + if (is_readonly(conn, path, sbuf)) + result |= aRONLY; + /* Else never set the readonly bit. */ + if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) result |= aARCH; diff -rub /tmp/samba-3.0.32//source/smbd/posix_acls.c ./source/smbd/posix_acls.c --- /tmp/samba-3.0.32//source/smbd/posix_acls.c Mon Aug 25 23:09:21 2008 +++ ./source/smbd/posix_acls.c Mon Nov 24 21:57:35 2008 @@ -4275,11 +4275,6 @@ return True; } - /* Check primary owner write access. */ - if (current_user.ut.uid == sbuf.st_uid) { - return (sbuf.st_mode & S_IWUSR) ? True : False; - } - #ifdef S_ISVTX /* sticky bit means delete only by owner or root. */ if (sbuf.st_mode & S_ISVTX) { @@ -4316,6 +4311,8 @@ BOOL can_access_file(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, uint32 access_mask) { + enum mapreadonly_options ro_opts = (enum mapreadonly_options)lp_map_readonly(SNUM(conn)); + if (!(access_mask & (FILE_READ_DATA|FILE_WRITE_DATA))) { return False; } @@ -4339,7 +4336,8 @@ } /* Check primary owner access. */ - if (current_user.ut.uid == psbuf->st_uid) { + if ((ro_opts == MAP_READONLY_YES) && + (current_user.ut.uid == psbuf->st_uid)) { switch (access_mask) { case FILE_READ_DATA: return (psbuf->st_mode & S_IRUSR) ? True : False;