FW: patch for safer/saner permissions setting

Cole, Timothy D. timothy_d_cole at md.northgrum.com
Mon Jun 14 16:24:19 GMT 1999


I originally sent this to samba-bugs, but didn't see any response...
apologies if this has already hit CVS in some form or another; I can't use
CVS from behind the firewall, and the samba-cvs archives seem to be b0rked
as well.

--- begin forwarded message ---

> I've been playing with the permissions setting in 2.0.4 from an NT client,
> and I'm finding that:
> 
>   1. most of the time you want to allow the user to set permissions
> broader than the creation mask if they want
>   
>   2. existing permission bits always get silently mangled (by the creation
> mask and the forced mode, as well as suid/sgid/sticky bits being
> stripped), even when the user doesn't explicitly change them. This can be
> downright  _dangerous_  in some cases, particularly with force mode
> 
> The attached patch (against 2.0.4, although it should apply to 2.0.4b
> fine) addresses the first issue by adding "allow mask" and "allow
> directory mask" configuration parameters (defaulting to 0000), which are
> ored with the creation mask when determining what permission bits the user
> can set (so, if she desires, the sysadmin can allow users to set a more
> liberal permissions than allowed by the creation mask alone).  The patch
> also allows Samba to preserve any permission bits that the user hasn't
> directly modified.
> 
--- snip ---

diff -u3 -r samba-2.0.4.orig/source/include/proto.h
samba-2.0.4/source/include/proto.h
--- samba-2.0.4.orig/source/include/proto.h	Mon May 17 19:27:59 1999
+++ samba-2.0.4/source/include/proto.h	Tue Jun  1 11:50:24 1999
@@ -1152,8 +1152,10 @@
 BOOL lp_mangle_locks(int );
 int lp_create_mode(int );
 int lp_force_create_mode(int );
+int lp_allow_mode(int );
 int lp_dir_mode(int );
 int lp_force_dir_mode(int );
+int lp_allow_dir_mode(int );
 int lp_max_connections(int );
 int lp_defaultcase(int );
 int lp_minprintspace(int );
diff -u3 -r samba-2.0.4.orig/source/param/loadparm.c
samba-2.0.4/source/param/loadparm.c
--- samba-2.0.4.orig/source/param/loadparm.c	Mon May 17 19:37:43 1999
+++ samba-2.0.4/source/param/loadparm.c	Tue Jun  1 11:54:09 1999
@@ -294,8 +294,10 @@
   int  iMinPrintSpace;
   int  iCreate_mask;
   int  iCreate_force_mode;
+  int  iAllow_mask;
   int  iDir_mask;
   int  iDir_force_mode;
+  int  iAllow_dir_mask;
   int  iMaxConnections;
   int  iDefaultCase;
   int  iPrinting;
@@ -389,8 +391,10 @@
   0,       /* iMinPrintSpace */
   0744,    /* iCreate_mask */
   0000,    /* iCreate_force_mode */
+  0000,    /* iAllow_mask */
   0755,    /* iDir_mask */
   0000,    /* iDir_force_mode */
+  0000,    /* iAllow_dir_mask */
   0,       /* iMaxConnections */
   CASE_LOWER, /* iDefaultCase */
   DEFAULT_PRINTING, /* iPrinting */
@@ -572,9 +576,13 @@
   {"create mask",      P_OCTAL,   P_LOCAL,  &sDefault.iCreate_mask,
NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
   {"create mode",      P_OCTAL,   P_LOCAL,  &sDefault.iCreate_mask,
NULL,   NULL,  FLAG_GLOBAL},
   {"force create mode",P_OCTAL,   P_LOCAL,  &sDefault.iCreate_force_mode,
NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"allow mask",       P_OCTAL,   P_LOCAL,  &sDefault.iAllow_mask,
NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"allow mode",       P_OCTAL,   P_LOCAL,  &sDefault.iAllow_mask,
NULL,   NULL,  FLAG_GLOBAL},
   {"directory mask",   P_OCTAL,   P_LOCAL,  &sDefault.iDir_mask,
NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
   {"directory mode",   P_OCTAL,   P_LOCAL,  &sDefault.iDir_mask,
NULL,   NULL,  FLAG_GLOBAL},
   {"force directory mode",   P_OCTAL,   P_LOCAL,
&sDefault.iDir_force_mode,        NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"allow directory mask",       P_OCTAL,   P_LOCAL,
&sDefault.iAllow_dir_mask,      NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"allow directory mode",       P_OCTAL,   P_LOCAL,
&sDefault.iAllow_dir_mask,      NULL,   NULL,  FLAG_GLOBAL},
   {"guest only",       P_BOOL,    P_LOCAL,  &sDefault.bGuest_only,
NULL,   NULL,  FLAG_SHARE},
   {"only guest",       P_BOOL,    P_LOCAL,  &sDefault.bGuest_only,
NULL,   NULL,  0},
   {"guest ok",         P_BOOL,    P_LOCAL,  &sDefault.bGuest_ok,
NULL,   NULL,  FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
@@ -1337,8 +1345,10 @@
 
 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
+FN_LOCAL_INTEGER(lp_allow_mode,iAllow_mask)
 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
+FN_LOCAL_INTEGER(lp_allow_dir_mode,iAllow_dir_mask)
 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
@@ -1346,8 +1356,6 @@
 FN_LOCAL_INTEGER(lp_oplock_contention_limit,iOplockContentionLimit)
 
 FN_LOCAL_CHAR(lp_magicchar,magic_char)
-
-
 
 /* local prototypes */
 static int    strwicmp( char *psz1, char *psz2 );
diff -u3 -r samba-2.0.4.orig/source/smbd/nttrans.c
samba-2.0.4/source/smbd/nttrans.c
--- samba-2.0.4.orig/source/smbd/nttrans.c	Fri May 14 21:06:39 1999
+++ samba-2.0.4/source/smbd/nttrans.c	Tue Jun  1 14:24:55 1999
@@ -2238,6 +2238,28 @@
               fsp->fsp_name, (unsigned int)user, (unsigned int)grp,
strerror(errno) ));
         return(UNIXERROR(ERRDOS,ERRnoaccess));
       }
+
+      /*
+       * Recheck the current state of the file, which may have changed.
+       * (suid/sgid bits, for instance)
+       */
+
+      if(fsp->is_directory) {
+        if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
+          return(UNIXERROR(ERRDOS,ERRnoaccess));
+        }
+      } else {
+
+        int ret;
+    
+        if(fsp->fd_ptr == NULL)
+          ret = dos_stat(fsp->fsp_name, &sbuf);
+        else
+          ret = sys_fstat(fsp->fd_ptr->fd,&sbuf);
+    
+        if(ret != 0)
+          return(UNIXERROR(ERRDOS,ERRnoaccess));
+      }
   }
 
   /*
@@ -2249,20 +2271,26 @@
     free_sec_desc(&psd);
 
     /*
-     * Check to see if we need to change anything.
+     * Don't mangle unmodified permissions, but enforce limits on modified
bits.
      */
 
     if(fsp->is_directory) {
 
-      perms &= lp_dir_mode(SNUM(conn));
-      perms |= lp_force_dir_mode(SNUM(conn));
+      perms &= lp_dir_mode(SNUM(conn)) | lp_allow_dir_mode(SNUM(conn)) |
sbuf.st_mode;
+      perms |= lp_force_dir_mode(SNUM(conn)) & (sbuf.st_mode ^ perms);
 
     } else {
 
-      perms &= lp_create_mode(SNUM(conn)); 
-      perms |= lp_force_create_mode(SNUM(conn));
+      perms &= lp_create_mode(SNUM(conn)) | lp_allow_mode(SNUM(conn)) |
sbuf.st_mode; 
+      perms |= lp_force_create_mode(SNUM(conn)) & (sbuf.st_mode ^ perms);
 
     }
+
+    /*
+     * Preserve special bits.
+     */
+
+    perms |= sbuf.st_mode & ~0777;
 
     /*
      * Do we need to chmod ? 


More information about the samba-technical mailing list