r10979: After discussions on IRC about profile shares,
authorJeremy Allison <jra@samba.org>
Fri, 14 Oct 2005 01:09:37 +0000 (01:09 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:04:59 +0000 (11:04 -0500)
added new parameter : map readonly = [yes|no|permissions]
If yes: map inverse of user "w" bit to mean readonly.
If no: never set DOS readonly bit.
If permissions: check file permissions for user and set readonly
bit if the current user cannot write.
If store dos attributes is set to yes then this parameter
is ignored.
Jeremy.
(This used to be commit da4238d18c7a57d1264db8517fb027a10a11baed)

source3/include/smb.h
source3/param/loadparm.c
source3/smbd/dosmode.c

index 922864ecff14a8246b57a95e749dc529712ef124..e3d151f9ed4cd1b1a79a80cb1b65a20e3f171ca8 100644 (file)
@@ -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 */
index dc2784804d53c009690f40a733ee3435e58fcf48..383b1d704786b1c79774bf26cb8e74121ff58f8a 100644 (file)
@@ -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)
index efbd5f04cb957103f8a3428de5b1af4b945496dd..fec148b8e637df51872b517cd0ead29c375077dd 100644 (file)
@@ -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;