diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/smb.h | 3 | ||||
-rw-r--r-- | source3/param/loadparm.c | 21 | ||||
-rw-r--r-- | source3/smbd/dosmode.c | 13 |
3 files changed, 31 insertions, 6 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h index 922864ecff..e3d151f9ed 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1723,4 +1723,7 @@ typedef struct uuid_flat { uint8 info[UUID_FLAT_SIZE]; } UUID_FLAT; +/* map readonly options */ +enum mapreadonly_options {MAP_READONLY_NO, MAP_READONLY_YES, MAP_READONLY_PERMISSIONS}; + #endif /* _SMB_H */ diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index dc2784804d..383b1d7047 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -439,6 +439,7 @@ typedef struct int iallocation_roundup_size; int iAioReadSize; int iAioWriteSize; + int iMap_readonly; param_opt_struct *param_opt; char dummy[3]; /* for alignment */ @@ -572,6 +573,7 @@ static service sDefault = { SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */ 0, /* iAioReadSize */ 0, /* iAioWriteSize */ + MAP_READONLY_YES, /* iMap_readonly */ NULL, /* Parametric options */ @@ -692,6 +694,18 @@ static const struct enum_list enum_announce_as[] = { {-1, NULL} }; +static const struct enum_list enum_map_readonly[] = { + {MAP_READONLY_NO, "no"}, + {MAP_READONLY_NO, "false"}, + {MAP_READONLY_NO, "0"}, + {MAP_READONLY_YES, "yes"}, + {MAP_READONLY_YES, "true"}, + {MAP_READONLY_YES, "1"}, + {MAP_READONLY_PERMISSIONS, "permissions"}, + {MAP_READONLY_PERMISSIONS, "perms"}, + {-1, NULL} +}; + static const struct enum_list enum_case[] = { {CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, @@ -1046,9 +1060,11 @@ static struct parm_struct parm_table[] = { {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, - {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, - {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"map read only", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED }, {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED}, @@ -1995,6 +2011,7 @@ FN_LOCAL_INTEGER(lp_block_size, iBlock_size) FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size) FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize) FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize) +FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly) FN_LOCAL_CHAR(lp_magicchar, magic_char) FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time) FN_GLOBAL_INTEGER(lp_winbind_max_idle_children, &Globals.winbind_max_idle_children) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index efbd5f04cb..fec148b8e6 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -129,14 +129,19 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL c uint32 dos_mode_from_sbuf(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)); - if (lp_acl_check_permissions(SNUM(conn))) { + if (ro_opts == MAP_READONLY_YES) { + /* Original Samba method - map inverse of user "w" bit. */ + if ((sbuf->st_mode & S_IWUSR) == 0) { + result |= aRONLY; + } + } else if (ro_opts == MAP_READONLY_PERMISSIONS) { + /* Check actual permissions for read-only. */ if (!can_write_to_file(conn, path, sbuf)) { result |= aRONLY; } - } else if ((sbuf->st_mode & S_IWUSR) == 0) { - result |= aRONLY; - } + } /* Else never set the readonly bit. */ if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) result |= aARCH; |