]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
nfs4_acls: Use correct owner information for ACL after owner change
authorChristof Schmitt <cs@samba.org>
Wed, 17 Jul 2019 22:29:06 +0000 (15:29 -0700)
committerKarolin Seeger <kseeger@samba.org>
Mon, 26 Aug 2019 10:23:29 +0000 (10:23 +0000)
After a chown, the cached stat data is obviously no longer valid. The
code in smb_set_nt_acl_nfs4 checked the file correctly, but did only use
a local buffer for the stat data. So later checks of the stat buffer
under the fsp->fsp_name->st would still see the old information.

Fix this by removing the local stat buffer and always update the one
under fsp->fsp_name->st.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032

Signed-off-by: Christof Schmitt <cs@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
(cherry picked from commit 86f7af84f04b06ed96b30f936ace92aa0937be06)

source3/modules/nfs4_acls.c

index 74b66a2c39287941a152bd437e90f06615bc8c55..eb76696948b792a8f0d3775483aa012ebe6ccaa9 100644 (file)
@@ -994,11 +994,11 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
        struct SMB4ACL_T *theacl = NULL;
        bool    result, is_directory;
 
-       SMB_STRUCT_STAT sbuf;
        bool set_acl_as_root = false;
        uid_t newUID = (uid_t)-1;
        gid_t newGID = (gid_t)-1;
        int saved_errno;
+       NTSTATUS status;
        TALLOC_CTX *frame = talloc_stackframe();
 
        DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp)));
@@ -1022,25 +1022,29 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
                pparams = &params;
        }
 
-       if (smbacl4_fGetFileOwner(fsp, &sbuf)) {
+       status = vfs_stat_fsp(fsp);
+       if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(frame);
-               return map_nt_error_from_unix(errno);
+               return status;
        }
 
-       is_directory = S_ISDIR(sbuf.st_ex_mode);
+       is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
 
        if (pparams->do_chown) {
                /* chown logic is a copy/paste from posix_acl.c:set_nt_acl */
-               NTSTATUS status = unpack_nt_owners(fsp->conn, &newUID, &newGID,
-                                                  security_info_sent, psd);
+
+               uid_t old_uid = fsp->fsp_name->st.st_ex_uid;
+               uid_t old_gid = fsp->fsp_name->st.st_ex_uid;
+               status = unpack_nt_owners(fsp->conn, &newUID, &newGID,
+                                         security_info_sent, psd);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(8, ("unpack_nt_owners failed"));
                        TALLOC_FREE(frame);
                        return status;
                }
-               if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) ||
-                   ((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) {
-
+               if (((newUID != (uid_t)-1) && (old_uid != newUID)) ||
+                   ((newGID != (gid_t)-1) && (old_gid != newGID)))
+               {
                        status = try_chown(fsp, newUID, newGID);
                        if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(3,("chown %s, %u, %u failed. Error = "
@@ -1055,11 +1059,14 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
                        DEBUG(10,("chown %s, %u, %u succeeded.\n",
                                  fsp_str_dbg(fsp), (unsigned int)newUID,
                                  (unsigned int)newGID));
-                       if (smbacl4_GetFileOwner(fsp->conn,
-                                                fsp->fsp_name,
-                                                &sbuf)){
+
+                       /*
+                        * Owner change, need to update stat info.
+                        */
+                       status = vfs_stat_fsp(fsp);
+                       if (!NT_STATUS_IS_OK(status)) {
                                TALLOC_FREE(frame);
-                               return map_nt_error_from_unix(errno);
+                               return status;
                        }
 
                        /* If we successfully chowned, we know we must
@@ -1077,7 +1084,8 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
        }
 
        theacl = smbacl4_win2nfs4(frame, is_directory, psd->dacl, pparams,
-                                 sbuf.st_ex_uid, sbuf.st_ex_gid);
+                                 fsp->fsp_name->st.st_ex_uid,
+                                 fsp->fsp_name->st.st_ex_gid);
        if (!theacl) {
                TALLOC_FREE(frame);
                return map_nt_error_from_unix(errno);