2 Unix SMB/CIFS implementation.
4 POSIX NTVFS backend - ACL support
6 Copyright (C) Andrew Tridgell 2004
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "system/passwd.h"
24 #include "auth/auth.h"
25 #include "vfs_posix.h"
26 #include "librpc/gen_ndr/xattr.h"
27 #include "libcli/security/security.h"
28 #include "param/param.h"
29 #include "../lib/util/unix_privs.h"
30 #include "lib/util/samba_modules.h"
32 /* the list of currently registered ACL backends */
33 static struct pvfs_acl_backend {
34 const struct pvfs_acl_ops *ops;
36 static int num_backends;
39 register a pvfs acl backend.
41 The 'name' can be later used by other backends to find the operations
42 structure for this backend.
44 NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops)
46 struct pvfs_acl_ops *new_ops;
48 if (pvfs_acl_backend_byname(ops->name) != NULL) {
49 DEBUG(0,("pvfs acl backend '%s' already registered\n", ops->name));
50 return NT_STATUS_OBJECT_NAME_COLLISION;
53 backends = talloc_realloc(talloc_autofree_context(), backends, struct pvfs_acl_backend, num_backends+1);
54 NT_STATUS_HAVE_NO_MEMORY(backends);
56 new_ops = (struct pvfs_acl_ops *)talloc_memdup(backends, ops, sizeof(*ops));
57 new_ops->name = talloc_strdup(new_ops, ops->name);
59 backends[num_backends].ops = new_ops;
63 DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
70 return the operations structure for a named backend
72 const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
76 for (i=0;i<num_backends;i++) {
77 if (strcmp(backends[i].ops->name, name) == 0) {
78 return backends[i].ops;
85 NTSTATUS pvfs_acl_init(void)
87 static bool initialized = false;
88 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
89 STATIC_pvfs_acl_MODULES_PROTO;
90 init_module_fn static_init[] = { STATIC_pvfs_acl_MODULES };
91 init_module_fn *shared_init;
93 if (initialized) return NT_STATUS_OK;
96 shared_init = load_samba_modules(NULL, "pvfs_acl");
98 run_init_functions(NULL, static_init);
99 run_init_functions(NULL, shared_init);
101 talloc_free(shared_init);
108 map a single access_mask from generic to specific bits for files/dirs
110 static uint32_t pvfs_translate_mask(uint32_t access_mask)
112 if (access_mask & SEC_MASK_GENERIC) {
113 if (access_mask & SEC_GENERIC_READ) access_mask |= SEC_RIGHTS_FILE_READ;
114 if (access_mask & SEC_GENERIC_WRITE) access_mask |= SEC_RIGHTS_FILE_WRITE;
115 if (access_mask & SEC_GENERIC_EXECUTE) access_mask |= SEC_RIGHTS_FILE_EXECUTE;
116 if (access_mask & SEC_GENERIC_ALL) access_mask |= SEC_RIGHTS_FILE_ALL;
117 access_mask &= ~SEC_MASK_GENERIC;
124 map any generic access bits in the given acl
125 this relies on the fact that the mappings for files and directories
128 static void pvfs_translate_generic_bits(struct security_acl *acl)
134 for (i=0;i<acl->num_aces;i++) {
135 struct security_ace *ace = &acl->aces[i];
136 ace->access_mask = pvfs_translate_mask(ace->access_mask);
142 setup a default ACL for a file
144 static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
145 struct ntvfs_request *req,
146 struct pvfs_filename *name, int fd,
147 struct security_descriptor **psd)
149 struct security_descriptor *sd;
151 struct security_ace ace;
155 *psd = security_descriptor_initialise(req);
157 return NT_STATUS_NO_MEMORY;
161 ids = talloc_zero_array(sd, struct id_map, 2);
162 NT_STATUS_HAVE_NO_MEMORY(ids);
164 ids[0].xid.id = name->st.st_uid;
165 ids[0].xid.type = ID_TYPE_UID;
168 ids[1].xid.id = name->st.st_gid;
169 ids[1].xid.type = ID_TYPE_GID;
172 status = wbc_xids_to_sids(ids, 2);
173 NT_STATUS_NOT_OK_RETURN(status);
175 sd->owner_sid = talloc_steal(sd, ids[0].sid);
176 sd->group_sid = talloc_steal(sd, ids[1].sid);
179 sd->type |= SEC_DESC_DACL_PRESENT;
181 mode = name->st.st_mode;
184 we provide up to 4 ACEs
192 /* setup owner ACE */
193 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
195 ace.trustee = *sd->owner_sid;
198 if (mode & S_IRUSR) {
199 if (mode & S_IWUSR) {
200 ace.access_mask |= SEC_RIGHTS_FILE_ALL;
202 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
205 if (mode & S_IWUSR) {
206 ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
208 if (ace.access_mask) {
209 security_descriptor_dacl_add(sd, &ace);
213 /* setup group ACE */
214 ace.trustee = *sd->group_sid;
216 if (mode & S_IRGRP) {
217 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
219 if (mode & S_IWGRP) {
220 /* note that delete is not granted - this matches posix behaviour */
221 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
223 if (ace.access_mask) {
224 security_descriptor_dacl_add(sd, &ace);
227 /* setup other ACE */
228 ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD);
230 if (mode & S_IROTH) {
231 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
233 if (mode & S_IWOTH) {
234 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
236 if (ace.access_mask) {
237 security_descriptor_dacl_add(sd, &ace);
240 /* setup system ACE */
241 ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM);
242 ace.access_mask = SEC_RIGHTS_FILE_ALL;
243 security_descriptor_dacl_add(sd, &ace);
250 omit any security_descriptor elements not specified in the given
253 static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
255 if (!(secinfo_flags & SECINFO_OWNER)) {
256 sd->owner_sid = NULL;
258 if (!(secinfo_flags & SECINFO_GROUP)) {
259 sd->group_sid = NULL;
261 if (!(secinfo_flags & SECINFO_DACL)) {
264 if (!(secinfo_flags & SECINFO_SACL)) {
269 static bool pvfs_privileged_access(uid_t uid)
273 if (uid_wrapper_enabled()) {
274 setenv("UID_WRAPPER_MYUID", "1", 1);
279 if (uid_wrapper_enabled()) {
280 unsetenv("UID_WRAPPER_MYUID");
283 return (uid == euid);
287 answer a setfileinfo for an ACL
289 NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
290 struct ntvfs_request *req,
291 struct pvfs_filename *name, int fd,
292 uint32_t access_mask,
293 union smb_setfileinfo *info)
295 uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
296 struct security_descriptor *new_sd, *sd, orig_sd;
297 NTSTATUS status = NT_STATUS_NOT_FOUND;
304 if (pvfs->acl_ops != NULL) {
305 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
307 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
308 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
310 if (!NT_STATUS_IS_OK(status)) {
314 ids = talloc(req, struct id_map);
315 NT_STATUS_HAVE_NO_MEMORY(ids);
316 ZERO_STRUCT(ids->xid);
318 ids->status = ID_UNKNOWN;
320 new_sd = info->set_secdesc.in.sd;
323 old_uid = name->st.st_uid;
324 old_gid = name->st.st_gid;
326 /* only set the elements that have been specified */
327 if (secinfo_flags & SECINFO_OWNER) {
328 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
329 return NT_STATUS_ACCESS_DENIED;
331 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
332 ids->sid = new_sd->owner_sid;
333 status = wbc_sids_to_xids(ids, 1);
334 NT_STATUS_NOT_OK_RETURN(status);
336 if (ids->xid.type == ID_TYPE_BOTH ||
337 ids->xid.type == ID_TYPE_UID) {
338 new_uid = ids->xid.id;
341 sd->owner_sid = new_sd->owner_sid;
344 if (secinfo_flags & SECINFO_GROUP) {
345 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
346 return NT_STATUS_ACCESS_DENIED;
348 if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
349 ids->sid = new_sd->group_sid;
350 status = wbc_sids_to_xids(ids, 1);
351 NT_STATUS_NOT_OK_RETURN(status);
353 if (ids->xid.type == ID_TYPE_BOTH ||
354 ids->xid.type == ID_TYPE_GID) {
355 new_gid = ids->xid.id;
359 sd->group_sid = new_sd->group_sid;
362 if (secinfo_flags & SECINFO_DACL) {
363 if (!(access_mask & SEC_STD_WRITE_DAC)) {
364 return NT_STATUS_ACCESS_DENIED;
366 sd->dacl = new_sd->dacl;
367 pvfs_translate_generic_bits(sd->dacl);
368 sd->type |= SEC_DESC_DACL_PRESENT;
371 if (secinfo_flags & SECINFO_SACL) {
372 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
373 return NT_STATUS_ACCESS_DENIED;
375 sd->sacl = new_sd->sacl;
376 pvfs_translate_generic_bits(sd->sacl);
377 sd->type |= SEC_DESC_SACL_PRESENT;
380 if (secinfo_flags & SECINFO_PROTECTED_DACL) {
381 if (new_sd->type & SEC_DESC_DACL_PROTECTED) {
382 sd->type |= SEC_DESC_DACL_PROTECTED;
384 sd->type &= ~SEC_DESC_DACL_PROTECTED;
388 if (secinfo_flags & SECINFO_PROTECTED_SACL) {
389 if (new_sd->type & SEC_DESC_SACL_PROTECTED) {
390 sd->type |= SEC_DESC_SACL_PROTECTED;
392 sd->type &= ~SEC_DESC_SACL_PROTECTED;
396 if (new_uid == old_uid) {
400 if (new_gid == old_gid) {
404 /* if there's something to change try it */
405 if (new_uid != -1 || new_gid != -1) {
408 ret = chown(name->full_name, new_uid, new_gid);
410 ret = fchown(fd, new_uid, new_gid);
412 if (errno == EPERM) {
413 if (pvfs_privileged_access(name->st.st_uid)) {
416 /* try again as root if we have SEC_PRIV_RESTORE or
417 SEC_PRIV_TAKE_OWNERSHIP */
418 if (security_token_has_privilege(req->session_info->security_token,
420 security_token_has_privilege(req->session_info->security_token,
421 SEC_PRIV_TAKE_OWNERSHIP)) {
423 privs = root_privileges();
425 ret = chown(name->full_name, new_uid, new_gid);
427 ret = fchown(fd, new_uid, new_gid);
434 return pvfs_map_errno(pvfs, errno);
438 /* we avoid saving if the sd is the same. This means when clients
439 copy files and end up copying the default sd that we don't
440 needlessly use xattrs */
441 if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
442 status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
450 answer a fileinfo query for the ACL
452 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs,
453 struct ntvfs_request *req,
454 struct pvfs_filename *name, int fd,
455 union smb_fileinfo *info)
457 NTSTATUS status = NT_STATUS_NOT_FOUND;
458 struct security_descriptor *sd;
461 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
463 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
464 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
466 if (!NT_STATUS_IS_OK(status)) {
470 normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
472 info->query_secdesc.out.sd = sd;
479 check the read only bit against any of the write access bits
481 static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
483 if ((pvfs->flags & PVFS_FLAG_READONLY) &&
484 (access_mask & (SEC_FILE_WRITE_DATA |
485 SEC_FILE_APPEND_DATA |
487 SEC_FILE_WRITE_ATTRIBUTE |
490 SEC_STD_WRITE_OWNER |
491 SEC_DIR_DELETE_CHILD))) {
498 see if we are a member of the appropriate unix group
500 static bool pvfs_group_member(struct pvfs_state *pvfs, gid_t gid)
504 if (getegid() == gid) {
507 ngroups = getgroups(0, NULL);
511 groups = talloc_array(pvfs, gid_t, ngroups);
512 if (groups == NULL) {
515 if (getgroups(ngroups, groups) != ngroups) {
519 for (i=0; i<ngroups; i++) {
520 if (groups[i] == gid) break;
527 default access check function based on unix permissions
528 doing this saves on building a full security descriptor
529 for the common case of access check on files with no
532 If name is NULL then treat as a new file creation
534 static NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
535 struct ntvfs_request *req,
536 struct pvfs_filename *name,
537 uint32_t *access_mask)
539 uint32_t max_bits = 0;
540 struct security_token *token = req->session_info->security_token;
542 if (pvfs_read_only(pvfs, *access_mask)) {
543 return NT_STATUS_ACCESS_DENIED;
547 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
548 } else if (pvfs_privileged_access(name->st.st_uid)) {
549 /* use the IxUSR bits */
550 if ((name->st.st_mode & S_IWUSR)) {
551 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
552 } else if ((name->st.st_mode & (S_IRUSR | S_IXUSR))) {
553 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
555 } else if (pvfs_group_member(pvfs, name->st.st_gid)) {
556 /* use the IxGRP bits */
557 if ((name->st.st_mode & S_IWGRP)) {
558 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
559 } else if ((name->st.st_mode & (S_IRGRP | S_IXGRP))) {
560 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
563 /* use the IxOTH bits */
564 if ((name->st.st_mode & S_IWOTH)) {
565 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
566 } else if ((name->st.st_mode & (S_IROTH | S_IXOTH))) {
567 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
571 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
572 *access_mask |= max_bits;
573 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
576 if ((*access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
577 security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
578 max_bits |= SEC_FLAG_SYSTEM_SECURITY;
581 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_RESTORE) &&
582 security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
583 max_bits |= ~(SEC_RIGHTS_PRIV_RESTORE);
585 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_BACKUP) &&
586 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
587 max_bits |= ~(SEC_RIGHTS_PRIV_BACKUP);
590 if (*access_mask & ~max_bits) {
591 DEBUG(5,(__location__ " denied access to '%s' - wanted 0x%08x but got 0x%08x (missing 0x%08x)\n",
592 name?name->full_name:"(new file)", *access_mask, max_bits, *access_mask & ~max_bits));
593 return NT_STATUS_ACCESS_DENIED;
596 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
597 /* on SMB, this bit is always granted, even if not
599 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
607 check the security descriptor on a file, if any
609 *access_mask is modified with the access actually granted
611 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
612 struct ntvfs_request *req,
613 struct pvfs_filename *name,
614 uint32_t *access_mask)
616 struct security_token *token = req->session_info->security_token;
617 struct xattr_NTACL *acl;
619 struct security_descriptor *sd;
620 bool allow_delete = false;
622 /* on SMB2 a blank access mask is always denied */
623 if (pvfs->ntvfs->ctx->protocol >= PROTOCOL_SMB2_02 &&
625 return NT_STATUS_ACCESS_DENIED;
628 if (pvfs_read_only(pvfs, *access_mask)) {
629 return NT_STATUS_ACCESS_DENIED;
632 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
633 *access_mask & SEC_STD_DELETE) {
634 status = pvfs_access_check_parent(pvfs, req,
635 name, SEC_DIR_DELETE_CHILD);
636 if (NT_STATUS_IS_OK(status)) {
638 *access_mask &= ~SEC_STD_DELETE;
642 acl = talloc(req, struct xattr_NTACL);
644 return NT_STATUS_NO_MEMORY;
647 /* expand the generic access bits to file specific bits */
648 *access_mask = pvfs_translate_mask(*access_mask);
649 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
650 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
653 status = pvfs_acl_load(pvfs, name, -1, acl);
654 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
656 status = pvfs_access_check_unix(pvfs, req, name, access_mask);
659 if (!NT_STATUS_IS_OK(status)) {
663 switch (acl->version) {
668 return NT_STATUS_INVALID_ACL;
671 /* check the acl against the required access mask */
672 status = se_access_check(sd, token, *access_mask, access_mask);
675 /* if we used a NT acl, then allow access override if the
676 share allows for posix permission override
678 if (NT_STATUS_IS_OK(status)) {
679 name->allow_override = (pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) != 0;
683 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
684 /* on SMB, this bit is always granted, even if not
686 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
690 *access_mask |= SEC_STD_DELETE;
698 a simplified interface to access check, designed for calls that
699 do not take or return an access check mask
701 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs,
702 struct ntvfs_request *req,
703 struct pvfs_filename *name,
704 uint32_t access_needed)
706 if (access_needed == 0) {
709 return pvfs_access_check(pvfs, req, name, &access_needed);
713 access check for creating a new file/directory
715 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs,
716 struct ntvfs_request *req,
717 struct pvfs_filename *name,
718 uint32_t *access_mask,
720 struct security_descriptor **sd)
722 struct pvfs_filename *parent;
724 uint32_t parent_mask;
725 bool allow_delete = false;
727 if (pvfs_read_only(pvfs, *access_mask)) {
728 return NT_STATUS_ACCESS_DENIED;
731 status = pvfs_resolve_parent(pvfs, req, name, &parent);
732 NT_STATUS_NOT_OK_RETURN(status);
735 parent_mask = SEC_DIR_ADD_SUBDIR;
737 parent_mask = SEC_DIR_ADD_FILE;
739 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
740 *access_mask & SEC_STD_DELETE) {
741 parent_mask |= SEC_DIR_DELETE_CHILD;
744 status = pvfs_access_check(pvfs, req, parent, &parent_mask);
745 if (NT_STATUS_IS_OK(status)) {
746 if (parent_mask & SEC_DIR_DELETE_CHILD) {
749 } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
751 * on ACCESS_DENIED we get the rejected bits
752 * remove the non critical SEC_DIR_DELETE_CHILD
753 * and check if something else was rejected.
755 parent_mask &= ~SEC_DIR_DELETE_CHILD;
756 if (parent_mask != 0) {
757 return NT_STATUS_ACCESS_DENIED;
759 status = NT_STATUS_OK;
765 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, sd);
769 if (!NT_STATUS_IS_OK(status)) {
773 /* expand the generic access bits to file specific bits */
774 *access_mask = pvfs_translate_mask(*access_mask);
776 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
777 *access_mask |= SEC_RIGHTS_FILE_ALL;
778 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
781 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
782 /* on SMB, this bit is always granted, even if not
784 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
788 *access_mask |= SEC_STD_DELETE;
795 access check for creating a new file/directory - no access mask supplied
797 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs,
798 struct ntvfs_request *req,
799 struct pvfs_filename *name,
800 uint32_t access_mask)
802 struct pvfs_filename *parent;
805 status = pvfs_resolve_parent(pvfs, req, name, &parent);
806 if (!NT_STATUS_IS_OK(status)) {
810 status = pvfs_access_check_simple(pvfs, req, parent, access_mask);
811 if (NT_STATUS_IS_OK(status) && parent->allow_override) {
812 name->allow_override = true;
819 determine if an ACE is inheritable
821 static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
822 const struct security_ace *ace,
826 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
829 if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
833 if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
834 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
842 this is the core of ACL inheritance. It copies any inheritable
843 aces from the parent SD to the child SD. Note that the algorithm
844 depends on whether the child is a container or not
846 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs,
847 struct security_descriptor *parent_sd,
848 struct security_descriptor *sd,
853 for (i=0;i<parent_sd->dacl->num_aces;i++) {
854 struct security_ace ace = parent_sd->dacl->aces[i];
856 const struct dom_sid *creator = NULL, *new_id = NULL;
859 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
863 orig_flags = ace.flags;
865 /* see the RAW-ACLS inheritance test for details on these rules */
869 ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
871 if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
872 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
874 if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
879 /* the CREATOR sids are special when inherited */
880 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
881 creator = pvfs->sid_cache.creator_owner;
882 new_id = sd->owner_sid;
883 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
884 creator = pvfs->sid_cache.creator_group;
885 new_id = sd->group_sid;
887 new_id = &ace.trustee;
890 if (creator && container &&
891 (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
892 uint32_t flags = ace.flags;
894 ace.trustee = *new_id;
896 status = security_descriptor_dacl_add(sd, &ace);
897 if (!NT_STATUS_IS_OK(status)) {
901 ace.trustee = *creator;
902 ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
903 status = security_descriptor_dacl_add(sd, &ace);
904 } else if (container &&
905 !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
906 status = security_descriptor_dacl_add(sd, &ace);
908 ace.trustee = *new_id;
909 status = security_descriptor_dacl_add(sd, &ace);
912 if (!NT_STATUS_IS_OK(status)) {
923 calculate the ACL on a new file/directory based on the inherited ACL
924 from the parent. If there is no inherited ACL then return a NULL
925 ACL, which means the default ACL should be used
927 NTSTATUS pvfs_acl_inherited_sd(struct pvfs_state *pvfs,
929 struct ntvfs_request *req,
930 struct pvfs_filename *parent,
932 struct security_descriptor **ret_sd)
934 struct xattr_NTACL *acl;
936 struct security_descriptor *parent_sd, *sd;
938 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
942 acl = talloc(req, struct xattr_NTACL);
944 TALLOC_FREE(tmp_ctx);
945 return NT_STATUS_NO_MEMORY;
948 status = pvfs_acl_load(pvfs, parent, -1, acl);
949 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
950 talloc_free(tmp_ctx);
953 if (!NT_STATUS_IS_OK(status)) {
954 TALLOC_FREE(tmp_ctx);
958 switch (acl->version) {
960 parent_sd = acl->info.sd;
963 talloc_free(tmp_ctx);
964 return NT_STATUS_INVALID_ACL;
967 if (parent_sd == NULL ||
968 parent_sd->dacl == NULL ||
969 parent_sd->dacl->num_aces == 0) {
970 /* go with the default ACL */
971 talloc_free(tmp_ctx);
975 /* create the new sd */
976 sd = security_descriptor_initialise(req);
978 TALLOC_FREE(tmp_ctx);
979 return NT_STATUS_NO_MEMORY;
982 ids = talloc_array(sd, struct id_map, 2);
984 TALLOC_FREE(tmp_ctx);
985 return NT_STATUS_NO_MEMORY;
988 ids[0].xid.id = geteuid();
989 ids[0].xid.type = ID_TYPE_UID;
991 ids[0].status = ID_UNKNOWN;
993 ids[1].xid.id = getegid();
994 ids[1].xid.type = ID_TYPE_GID;
996 ids[1].status = ID_UNKNOWN;
998 status = wbc_xids_to_sids(ids, 2);
999 if (!NT_STATUS_IS_OK(status)) {
1000 TALLOC_FREE(tmp_ctx);
1004 sd->owner_sid = talloc_steal(sd, ids[0].sid);
1005 sd->group_sid = talloc_steal(sd, ids[1].sid);
1007 sd->type |= SEC_DESC_DACL_PRESENT;
1009 /* fill in the aces from the parent */
1010 status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
1011 if (!NT_STATUS_IS_OK(status)) {
1012 TALLOC_FREE(tmp_ctx);
1016 /* if there is nothing to inherit then we fallback to the
1018 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
1019 talloc_free(tmp_ctx);
1020 return NT_STATUS_OK;
1023 *ret_sd = talloc_steal(mem_ctx, sd);
1025 talloc_free(tmp_ctx);
1026 return NT_STATUS_OK;
1031 setup an ACL on a new file/directory based on the inherited ACL from
1032 the parent. If there is no inherited ACL then we don't set anything,
1033 as the default ACL applies anyway
1035 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
1036 struct ntvfs_request *req,
1037 struct pvfs_filename *name,
1040 struct xattr_NTACL acl;
1042 struct security_descriptor *sd;
1043 struct pvfs_filename *parent;
1046 /* form the parents path */
1047 status = pvfs_resolve_parent(pvfs, req, name, &parent);
1048 NT_STATUS_NOT_OK_RETURN(status);
1050 container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
1052 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, &sd);
1053 if (!NT_STATUS_IS_OK(status)) {
1054 talloc_free(parent);
1059 return NT_STATUS_OK;
1065 status = pvfs_acl_save(pvfs, name, fd, &acl);
1067 talloc_free(parent);
1073 return the maximum allowed access mask
1075 NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
1076 struct ntvfs_request *req,
1077 struct pvfs_filename *name,
1078 uint32_t *maximal_access)
1080 *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
1081 return pvfs_access_check(pvfs, req, name, maximal_access);