r6895: Add "acl check permissions" to turn on/off the new behaviour of
authorJeremy Allison <jra@samba.org>
Wed, 18 May 2005 23:37:35 +0000 (23:37 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:56:56 +0000 (10:56 -0500)
checking for write access in a directory before delete. Also
controls checking for write access before labeling a file read-only
if DOS attributes are not being stored in EA's.
Docuementation to follow.
Jeremy.
(This used to be commit dd1a5e6e499dd721c5bb8d56a61810a7454a3449)

source3/param/loadparm.c
source3/smbd/dosmode.c
source3/smbd/nttrans.c
source3/smbd/posix_acls.c

index 8043f8864d676a49ffa509017c6426011108de96..0ddd6bb0c71ad715d08c554341633d18723cddd7 100644 (file)
@@ -436,6 +436,7 @@ typedef struct
        BOOL bMap_acl_inherit;
        BOOL bAfs_Share;
        BOOL bEASupport;
+       BOOL bAclCheckPermissions;
        int iallocation_roundup_size;
        param_opt_struct *param_opt;
 
@@ -563,6 +564,7 @@ static service sDefault = {
        False,                  /* bMap_acl_inherit */
        False,                  /* bAfs_Share */
        False,                  /* bEASupport */
+       True,                   /* bAclCheckPermissions */
        SMB_ROUNDUP_ALLOCATION_SIZE,            /* iallocation_roundup_size */
        
        NULL,                   /* Parametric options */
@@ -865,6 +867,7 @@ static struct parm_struct parm_table[] = {
        {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, 
        {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, 
 
+       {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
        {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
        {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE}, 
        {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
@@ -1968,6 +1971,7 @@ FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
+FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
index 3a0e81e5feffc51c712b607e44ff11d20ee03c34..65ea2807e777efad83718dd29e7ee70810a6e4eb 100644 (file)
@@ -116,13 +116,18 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL c
  Change a unix mode to a dos mode.
 ****************************************************************************/
 
-uint32 dos_mode_from_sbuf(connection_struct *conn, SMB_STRUCT_STAT *sbuf)
+uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
 {
        int result = 0;
 
-       if ((sbuf->st_mode & S_IWUSR) == 0)
+       if (lp_acl_check_permissions(SNUM(conn))) {
+               if (!can_write_to_file(conn, path, sbuf)) {
+                       result |= aRONLY;
+               }
+       } else if ((sbuf->st_mode & S_IWUSR) == 0) {
                result |= aRONLY;
-       
+       }
+
        if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
                result |= aARCH;
 
@@ -291,7 +296,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
                return result;
        }
 
-       result = dos_mode_from_sbuf(conn, sbuf);
+       result = dos_mode_from_sbuf(conn, path, sbuf);
 
        /* Now do any modifications that depend on the path name. */
        /* hide files with a name starting with a . */
@@ -433,9 +438,11 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
 
 int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times)
 {
+       SMB_STRUCT_STAT sbuf;
        int ret = -1;
 
        errno = 0;
+       ZERO_STRUCT(sbuf);
 
        if(SMB_VFS_UTIME(conn,fname, times) == 0)
                return 0;
@@ -453,7 +460,7 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times
         */
 
        /* Check if we have write access. */
-       if (can_write_to_file(conn, fname)) {
+       if (can_write_to_file(conn, fname, &sbuf)) {
                /* We are allowed to become root and change the filetime. */
                become_root();
                ret = SMB_VFS_UTIME(conn,fname, times);
index a37ae5548f7e849872081e69bf9ceef755e60bf4..a0f94d616dfbbd59fbd67540a5170c90cb12b4db 100644 (file)
@@ -802,7 +802,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
        if (desired_access & DELETE_ACCESS) {
 #else
        /* Setting FILE_SHARE_DELETE is the hint. */
-       if ((share_access & FILE_SHARE_DELETE) && (desired_access & DELETE_ACCESS)) {
+       if (lp_acl_check_permissions(SNUM(conn)) && (share_access & FILE_SHARE_DELETE) && (desired_access & DELETE_ACCESS)) {
 #endif
                status = can_delete(conn, fname, file_attributes, bad_path, True);
                /* We're only going to fail here if it's access denied, as that's the
@@ -1422,7 +1422,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        if (desired_access & DELETE_ACCESS) {
 #else
        /* Setting FILE_SHARE_DELETE is the hint. */
-       if ((share_access & FILE_SHARE_DELETE) && (desired_access & DELETE_ACCESS)) {
+       if (lp_acl_check_permissions(SNUM(conn)) && (share_access & FILE_SHARE_DELETE) && (desired_access & DELETE_ACCESS)) {
 #endif
                status = can_delete(conn, fname, file_attributes, bad_path, True);
                /* We're only going to fail here if it's access denied, as that's the
index b31e97c76f827a2676701e869cdeb59ceb5ccba3..b5052eec2561c8fd6389b19d7ebf8ae8190a1a90 100644 (file)
@@ -4006,9 +4006,8 @@ BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname)
  this to successfully check for ability to write for dos filetimes.
 ****************************************************************************/
 
-BOOL can_write_to_file(connection_struct *conn, const char *fname)
+BOOL can_write_to_file(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
 {
-       SMB_STRUCT_STAT sbuf;  
        int ret;
 
        if (!CAN_WRITE(conn)) {
@@ -4020,22 +4019,24 @@ BOOL can_write_to_file(connection_struct *conn, const char *fname)
                return True;
        }
 
-       /* Get the file permission mask and owners. */
-       if(SMB_VFS_STAT(conn, fname, &sbuf) != 0) {
-               return False;
+       if (!VALID_STAT(*psbuf)) {
+               /* Get the file permission mask and owners. */
+               if(SMB_VFS_STAT(conn, fname, psbuf) != 0) {
+                       return False;
+               }
        }
 
        /* Check primary owner write access. */
-       if (current_user.uid == sbuf.st_uid) {
-               return (sbuf.st_mode & S_IWUSR) ? True : False;
+       if (current_user.uid == psbuf->st_uid) {
+               return (psbuf->st_mode & S_IWUSR) ? True : False;
        }
 
        /* Check group or explicit user acl entry write access. */
-       ret = check_posix_acl_group_write(conn, fname, &sbuf);
+       ret = check_posix_acl_group_write(conn, fname, psbuf);
        if (ret == 0 || ret == 1) {
                return ret ? True : False;
        }
 
        /* Finally check other write access. */
-       return (sbuf.st_mode & S_IWOTH) ? True : False;
+       return (psbuf->st_mode & S_IWOTH) ? True : False;
 }