Reformat spacing to be even.
[samba.git] / source3 / smbd / posix_acls.c
index ec16bf203196dbbdbeb668ae7f6f1702456228e6..e59f54c2b12d3e94dbda5917b89b7e255b42cf83 100644 (file)
@@ -1123,8 +1123,8 @@ uint32_t map_canon_ace_perms(int snum,
  Map NT perms to a UNIX mode_t.
 ****************************************************************************/
 
-#define FILE_SPECIFIC_READ_BITS (FILE_READ_DATA|FILE_READ_EA|FILE_READ_ATTRIBUTES)
-#define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA|FILE_WRITE_ATTRIBUTES)
+#define FILE_SPECIFIC_READ_BITS (FILE_READ_DATA|FILE_READ_EA)
+#define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA)
 #define FILE_SPECIFIC_EXECUTE_BITS (FILE_EXECUTE)
 
 static mode_t map_nt_perms( uint32 *mask, int type)
@@ -1342,12 +1342,12 @@ static bool uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
 ****************************************************************************/
 
 static bool ensure_canon_entry_valid(canon_ace **pp_ace,
-                                    const struct share_params *params,
-                                    const bool is_directory,
-                                                       const DOM_SID *pfile_owner_sid,
-                                                       const DOM_SID *pfile_grp_sid,
-                                                       const SMB_STRUCT_STAT *pst,
-                                                       bool setting_acl)
+                               const struct share_params *params,
+                               const bool is_directory,
+                               const DOM_SID *pfile_owner_sid,
+                               const DOM_SID *pfile_grp_sid,
+                               const SMB_STRUCT_STAT *pst,
+                               bool setting_acl)
 {
        canon_ace *pace;
        bool got_user = False;
@@ -1397,29 +1397,32 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
                pace->unix_ug.uid = pst->st_ex_uid;
                pace->trustee = *pfile_owner_sid;
                pace->attr = ALLOW_ACE;
+               /* Start with existing permissions, principle of least
+                  surprises for the user. */
+               pace->perms = pst->st_ex_mode;
 
                if (setting_acl) {
                        /* See if the owning user is in any of the other groups in
-                          the ACE. If so, OR in the permissions from that group. */
+                          the ACE, or if there's a matching user entry.
+                          If so, OR in the permissions from that entry. */
 
-                       bool group_matched = False;
                        canon_ace *pace_iter;
 
                        for (pace_iter = *pp_ace; pace_iter; pace_iter = pace_iter->next) {
-                               if (pace_iter->type == SMB_ACL_GROUP_OBJ || pace_iter->type == SMB_ACL_GROUP) {
+                               if (pace_iter->type == SMB_ACL_USER &&
+                                               pace_iter->unix_ug.uid == pace->unix_ug.uid) {
+                                       pace->perms |= pace_iter->perms;
+                               } else if (pace_iter->type == SMB_ACL_GROUP_OBJ || pace_iter->type == SMB_ACL_GROUP) {
                                        if (uid_entry_in_group(pace, pace_iter)) {
                                                pace->perms |= pace_iter->perms;
-                                               group_matched = True;
                                        }
                                }
                        }
 
-                       /* If we only got an "everyone" perm, just use that. */
-                       if (!group_matched) {
+                       if (pace->perms == 0) {
+                               /* If we only got an "everyone" perm, just use that. */
                                if (got_other)
                                        pace->perms = pace_other->perms;
-                               else
-                                       pace->perms = 0;
                        }
 
                        apply_default_perms(params, is_directory, pace, S_IRUSR);
@@ -1484,6 +1487,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
  Check if a POSIX ACL has the required SMB_ACL_USER_OBJ and SMB_ACL_GROUP_OBJ entries.
  If it does not have them, check if there are any entries where the trustee is the
  file owner or the owning group, and map these to SMB_ACL_USER_OBJ and SMB_ACL_GROUP_OBJ.
+ Note we must not do this to default directory ACLs.
 ****************************************************************************/
 
 static void check_owning_objs(canon_ace *ace, DOM_SID *pfile_owner_sid, DOM_SID *pfile_grp_sid)
@@ -1908,17 +1912,15 @@ static bool create_canon_ace_lists(files_struct *fsp,
                dir_ace = NULL;
        } else {
                /*
-                * Check if we have SMB_ACL_USER_OBJ and SMB_ACL_GROUP_OBJ entries in each
-                * ACL. If we don't have them, check if any SMB_ACL_USER/SMB_ACL_GROUP
-                * entries can be converted to *_OBJ. Usually we will already have these
-                * entries in the Default ACL, and the Access ACL will not have them.
+                * Check if we have SMB_ACL_USER_OBJ and SMB_ACL_GROUP_OBJ entries in
+                * the file ACL. If we don't have them, check if any SMB_ACL_USER/SMB_ACL_GROUP
+                * entries can be converted to *_OBJ. Don't do this for the default
+                * ACL, we will create them separately for this if needed inside
+                * ensure_canon_entry_valid().
                 */
                if (file_ace) {
                        check_owning_objs(file_ace, pfile_owner_sid, pfile_grp_sid);
                }
-               if (dir_ace) {
-                       check_owning_objs(dir_ace, pfile_owner_sid, pfile_grp_sid);
-               }
        }
 
        *ppfile_ace = file_ace;
@@ -2239,44 +2241,6 @@ static void process_deny_list( canon_ace **pp_ace_list )
        *pp_ace_list = ace_list;
 }
 
-/****************************************************************************
- Create a default mode that will be used if a security descriptor entry has
- no user/group/world entries.
-****************************************************************************/
-
-static mode_t create_default_mode(files_struct *fsp, bool interitable_mode)
-{
-       int snum = SNUM(fsp->conn);
-       mode_t and_bits = (mode_t)0;
-       mode_t or_bits = (mode_t)0;
-       mode_t mode;
-
-       if (interitable_mode) {
-               mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE,
-                                fsp->fsp_name, NULL);
-       } else {
-               mode = S_IRUSR;
-       }
-
-       if (fsp->is_directory)
-               mode |= (S_IWUSR|S_IXUSR);
-
-       /*
-        * Now AND with the create mode/directory mode bits then OR with the
-        * force create mode/force directory mode bits.
-        */
-
-       if (fsp->is_directory) {
-               and_bits = lp_dir_security_mask(snum);
-               or_bits = lp_force_dir_security_mode(snum);
-       } else {
-               and_bits = lp_security_mask(snum);
-               or_bits = lp_force_security_mode(snum);
-       }
-
-       return ((mode & and_bits)|or_bits);
-}
-
 /****************************************************************************
  Unpack a SEC_DESC into two canonical ace lists. We don't depend on this
  succeeding.
@@ -2291,7 +2255,6 @@ static bool unpack_canon_ace(files_struct *fsp,
                                uint32 security_info_sent,
                                const SEC_DESC *psd)
 {
-       SMB_STRUCT_STAT st;
        canon_ace *file_ace = NULL;
        canon_ace *dir_ace = NULL;
 
@@ -2355,17 +2318,8 @@ static bool unpack_canon_ace(files_struct *fsp,
 
        print_canon_ace_list( "file ace - before valid", file_ace);
 
-       st = *pst;
-
-       /*
-        * A default 3 element mode entry for a file should be r-- --- ---.
-        * A default 3 element mode entry for a directory should be rwx --- ---.
-        */
-
-       st.st_ex_mode = create_default_mode(fsp, False);
-
        if (!ensure_canon_entry_valid(&file_ace, fsp->conn->params,
-                       fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) {
+                       fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) {
                free_canon_ace_list(file_ace);
                free_canon_ace_list(dir_ace);
                return False;
@@ -2373,16 +2327,8 @@ static bool unpack_canon_ace(files_struct *fsp,
 
        print_canon_ace_list( "dir ace - before valid", dir_ace);
 
-       /*
-        * A default inheritable 3 element mode entry for a directory should be the
-        * mode Samba will use to create a file within. Ensure user rwx bits are set if
-        * it's a directory.
-        */
-
-       st.st_ex_mode = create_default_mode(fsp, True);
-
        if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp->conn->params,
-                       fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) {
+                       fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) {
                free_canon_ace_list(file_ace);
                free_canon_ace_list(dir_ace);
                return False;