The posix acl version of set_nt_acl() could set the stat_ex
[samba.git] / source3 / smbd / posix_acls.c
index 15ea4d5fb2a92fad08163d2279fb0ee07faab938..828053811b291b2cf967f899ed350baf1964db81 100644 (file)
@@ -1068,7 +1068,7 @@ bool nt4_compatible_acls(void)
  not get. Deny entries are implicit on get with ace->perms = 0.
 ****************************************************************************/
 
-static uint32_t map_canon_ace_perms(int snum,
+uint32_t map_canon_ace_perms(int snum,
                                enum security_ace_type *pacl_type,
                                mode_t perms,
                                bool directory_ace)
@@ -1570,7 +1570,7 @@ static bool dup_owning_ace(canon_ace *dir_ace, canon_ace *ace)
 ****************************************************************************/
 
 static bool create_canon_ace_lists(files_struct *fsp,
-                                       SMB_STRUCT_STAT *pst,
+                                       const SMB_STRUCT_STAT *pst,
                                        DOM_SID *pfile_owner_sid,
                                        DOM_SID *pfile_grp_sid,
                                        canon_ace **ppfile_ace,
@@ -2305,7 +2305,7 @@ static mode_t create_default_mode(files_struct *fsp, bool interitable_mode)
 ****************************************************************************/
 
 static bool unpack_canon_ace(files_struct *fsp,
-                               SMB_STRUCT_STAT *pst,
+                               const SMB_STRUCT_STAT *pst,
                                DOM_SID *pfile_owner_sid,
                                DOM_SID *pfile_grp_sid,
                                canon_ace **ppfile_ace,
@@ -2313,6 +2313,7 @@ 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;
 
@@ -2376,14 +2377,17 @@ 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 --- ---.
         */
 
-       pst->st_ex_mode = create_default_mode(fsp, False);
+       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, pst, True)) {
+       if (!ensure_canon_entry_valid(&file_ace, fsp->conn->params,
+                       fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) {
                free_canon_ace_list(file_ace);
                free_canon_ace_list(dir_ace);
                return False;
@@ -2397,9 +2401,10 @@ static bool unpack_canon_ace(files_struct *fsp,
         * it's a directory.
         */
 
-       pst->st_ex_mode = create_default_mode(fsp, True);
+       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, pst, True)) {
+       if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp->conn->params,
+                       fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) {
                free_canon_ace_list(file_ace);
                free_canon_ace_list(dir_ace);
                return False;
@@ -3460,49 +3465,41 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
        SMB_ACL_T posix_acl = NULL;
        SMB_ACL_T def_acl = NULL;
        struct pai_val *pal;
-       struct smb_filename *smb_fname = NULL;
-       NTSTATUS status;
+       struct smb_filename smb_fname;
        int ret;
 
        *ppdesc = NULL;
 
        DEBUG(10,("posix_get_nt_acl: called for file %s\n", name ));
 
-       status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
-                                           &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
+       ZERO_STRUCT(smb_fname);
+       smb_fname.base_name = discard_const_p(char, name);
 
        /* Get the stat struct for the owner info. */
        if (lp_posix_pathnames()) {
-               ret = SMB_VFS_LSTAT(conn, smb_fname);
+               ret = SMB_VFS_LSTAT(conn, &smb_fname);
        } else {
-               ret = SMB_VFS_STAT(conn, smb_fname);
+               ret = SMB_VFS_STAT(conn, &smb_fname);
        }
 
        if (ret == -1) {
-               status = map_nt_error_from_unix(errno);
-               goto out;
+               return map_nt_error_from_unix(errno);
        }
 
        /* Get the ACL from the path. */
        posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS);
 
        /* If it's a directory get the default POSIX ACL. */
-       if(S_ISDIR(smb_fname->st.st_ex_mode)) {
+       if(S_ISDIR(smb_fname.st.st_ex_mode)) {
                def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT);
                def_acl = free_empty_sys_acl(conn, def_acl);
        }
 
        pal = load_inherited_info(conn, name);
 
-       status = posix_get_nt_acl_common(conn, name, &smb_fname->st, pal,
-                                        posix_acl, def_acl, security_info,
-                                        ppdesc);
- out:
-       TALLOC_FREE(smb_fname);
-       return status;
+       return posix_get_nt_acl_common(conn, name, &smb_fname.st, pal,
+                                      posix_acl, def_acl, security_info,
+                                      ppdesc);
 }
 
 /****************************************************************************
@@ -4094,6 +4091,9 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
        free_canon_ace_list(file_ace_list);
        free_canon_ace_list(dir_ace_list);
 
+       /* Ensure the stat struct in the fsp is correct. */
+       status = vfs_stat_fsp(fsp);
+
        return NT_STATUS_OK;
 }