]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_acl_common: Windows style default ACL
authorRalph Boehme <slow@samba.org>
Thu, 25 Aug 2016 05:45:34 +0000 (07:45 +0200)
committerKarolin Seeger <kseeger@samba.org>
Fri, 16 Sep 2016 10:05:34 +0000 (12:05 +0200)
Reintroduce Windows style default ACL, but this time as an optional
feature, not changing default behaviour.

Original bugreport that got reverted because it changed the default
behaviour: https://bugzilla.samba.org/show_bug.cgi?id=12028

Bug: https://bugzilla.samba.org/show_bug.cgi?id=12177

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 0730cb7e1ce33dbc5fc48a7363204c1220400c68)

source3/modules/vfs_acl_common.c

index e8eaa4fcd2c30134a5fb7e4abb52edf39087cc08..44fef12a377bb68dcb9da3a92c0030eae55271fe 100644 (file)
@@ -507,6 +507,78 @@ static NTSTATUS make_default_acl_posix(TALLOC_CTX *ctx,
        return NT_STATUS_OK;
 }
 
+static NTSTATUS make_default_acl_windows(TALLOC_CTX *ctx,
+                                        const char *name,
+                                        SMB_STRUCT_STAT *psbuf,
+                                        struct security_descriptor **ppdesc)
+{
+       struct dom_sid owner_sid, group_sid;
+       size_t size = 0;
+       struct security_ace aces[4];
+       uint32_t access_mask = 0;
+       mode_t mode = psbuf->st_ex_mode;
+       struct security_acl *new_dacl = NULL;
+       int idx = 0;
+
+       DBG_DEBUG("file [%s] mode [0%o]\n", name, (int)mode);
+
+       uid_to_sid(&owner_sid, psbuf->st_ex_uid);
+       gid_to_sid(&group_sid, psbuf->st_ex_gid);
+
+       /*
+        * We provide 2 ACEs:
+        * - Owner
+        * - NT System
+        */
+
+       if (mode & S_IRUSR) {
+               if (mode & S_IWUSR) {
+                       access_mask |= SEC_RIGHTS_FILE_ALL;
+               } else {
+                       access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
+               }
+       }
+       if (mode & S_IWUSR) {
+               access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
+       }
+
+       init_sec_ace(&aces[idx],
+                    &owner_sid,
+                    SEC_ACE_TYPE_ACCESS_ALLOWED,
+                    access_mask,
+                    0);
+       idx++;
+
+       init_sec_ace(&aces[idx],
+                    &global_sid_System,
+                    SEC_ACE_TYPE_ACCESS_ALLOWED,
+                    SEC_RIGHTS_FILE_ALL,
+                    0);
+       idx++;
+
+       new_dacl = make_sec_acl(ctx,
+                               NT4_ACL_REVISION,
+                               idx,
+                               aces);
+
+       if (!new_dacl) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       *ppdesc = make_sec_desc(ctx,
+                               SECURITY_DESCRIPTOR_REVISION_1,
+                               SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
+                               &owner_sid,
+                               &group_sid,
+                               NULL,
+                               new_dacl,
+                               &size);
+       if (!*ppdesc) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
+
 static NTSTATUS make_default_filesystem_acl(TALLOC_CTX *ctx,
                                            struct acl_common_config *config,
                                            const char *name,
@@ -521,6 +593,10 @@ static NTSTATUS make_default_filesystem_acl(TALLOC_CTX *ctx,
                status =  make_default_acl_posix(ctx, name, psbuf, ppdesc);
                break;
 
+       case DEFAULT_ACL_WINDOWS:
+               status =  make_default_acl_windows(ctx, name, psbuf, ppdesc);
+               break;
+
        default:
                DBG_ERR("unknown acl style %d", config->default_acl_style);
                status = NT_STATUS_INTERNAL_ERROR;