Fix bug 6892 - When a chown operation is issued via Windows Explorer, all ACLS are...
authorJeremy Allison <jra@samba.org>
Wed, 25 Nov 2009 18:20:38 +0000 (10:20 -0800)
committerJeremy Allison <jra@samba.org>
Wed, 25 Nov 2009 18:20:38 +0000 (10:20 -0800)
Merges existing DACLs when a ACL set operation comes in with only owner or group values set.
Jeremy.

source3/modules/vfs_acl_common.c

index a12f1057616e932e37fd9d2eebce6996d3417eb6..0bb0bca2db146bc96c9460f597d84df5d14a9532 100644 (file)
@@ -617,25 +617,46 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
                        CONST_DISCARD(struct security_descriptor *,psd));
        }
 
-       /* Ensure owner and group are set. */
-       if (!psd->owner_sid || !psd->group_sid) {
-               DOM_SID owner_sid, group_sid;
-               struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
+        /* Ensure we have OWNER/GROUP/DACL set. */
+
+       if ((security_info_sent & (OWNER_SECURITY_INFORMATION|
+                               GROUP_SECURITY_INFORMATION|
+                               DACL_SECURITY_INFORMATION)) !=
+                               (OWNER_SECURITY_INFORMATION|
+                                GROUP_SECURITY_INFORMATION|
+                                DACL_SECURITY_INFORMATION)) {
+               /* No we don't - read from the existing SD. */
+               struct security_descriptor *nc_psd = NULL;
+
+               status = get_nt_acl_internal(handle, fsp,
+                               NULL,
+                               (OWNER_SECURITY_INFORMATION|
+                                GROUP_SECURITY_INFORMATION|
+                                DACL_SECURITY_INFORMATION),
+                               &nc_psd);
 
-               if (!nc_psd) {
-                       return NT_STATUS_OK;
-               }
-               status = vfs_stat_fsp(fsp);
                if (!NT_STATUS_IS_OK(status)) {
-                       /* Lower level acl set succeeded,
-                        * so still return OK. */
-                       return NT_STATUS_OK;
+                       return status;
                }
-               create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid);
+
                /* This is safe as nc_psd is discarded at fn exit. */
-               nc_psd->owner_sid = &owner_sid;
-               nc_psd->group_sid = &group_sid;
-               security_info_sent |= (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION);
+               if (security_info_sent & OWNER_SECURITY_INFORMATION) {
+                       nc_psd->owner_sid = psd->owner_sid;
+               }
+               security_info_sent |= OWNER_SECURITY_INFORMATION;
+
+               if (security_info_sent & GROUP_SECURITY_INFORMATION) {
+                       nc_psd->group_sid = psd->group_sid;
+               }
+               security_info_sent |= GROUP_SECURITY_INFORMATION;
+
+               if (security_info_sent & DACL_SECURITY_INFORMATION) {
+                       nc_psd->dacl = dup_sec_acl(talloc_tos(), psd->dacl);
+                       if (nc_psd->dacl == NULL) {
+                               return NT_STATUS_NO_MEMORY;
+                       }
+               }
+               security_info_sent |= DACL_SECURITY_INFORMATION;
                psd = nc_psd;
        }