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(void);
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(static_init);
99 run_init_functions(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(pvfs->ntvfs->ctx->event_ctx, 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)) {
270 answer a setfileinfo for an ACL
272 NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
273 struct ntvfs_request *req,
274 struct pvfs_filename *name, int fd,
275 uint32_t access_mask,
276 union smb_setfileinfo *info)
278 uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
279 struct security_descriptor *new_sd, *sd, orig_sd;
280 NTSTATUS status = NT_STATUS_NOT_FOUND;
287 if (pvfs->acl_ops != NULL) {
288 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
290 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
291 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
293 if (!NT_STATUS_IS_OK(status)) {
297 ids = talloc(req, struct id_map);
298 NT_STATUS_HAVE_NO_MEMORY(ids);
299 ZERO_STRUCT(ids->xid);
301 ids->status = ID_UNKNOWN;
303 new_sd = info->set_secdesc.in.sd;
306 old_uid = name->st.st_uid;
307 old_gid = name->st.st_gid;
309 /* only set the elements that have been specified */
310 if (secinfo_flags & SECINFO_OWNER) {
311 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
312 return NT_STATUS_ACCESS_DENIED;
314 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
315 ids->sid = new_sd->owner_sid;
316 status = wbc_sids_to_xids(pvfs->ntvfs->ctx->event_ctx,
318 NT_STATUS_NOT_OK_RETURN(status);
320 if (ids->xid.type == ID_TYPE_BOTH ||
321 ids->xid.type == ID_TYPE_UID) {
322 new_uid = ids->xid.id;
325 sd->owner_sid = new_sd->owner_sid;
328 if (secinfo_flags & SECINFO_GROUP) {
329 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
330 return NT_STATUS_ACCESS_DENIED;
332 if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
333 ids->sid = new_sd->group_sid;
334 status = wbc_sids_to_xids(pvfs->ntvfs->ctx->event_ctx,
336 NT_STATUS_NOT_OK_RETURN(status);
338 if (ids->xid.type == ID_TYPE_BOTH ||
339 ids->xid.type == ID_TYPE_GID) {
340 new_gid = ids->xid.id;
344 sd->group_sid = new_sd->group_sid;
347 if (secinfo_flags & SECINFO_DACL) {
348 if (!(access_mask & SEC_STD_WRITE_DAC)) {
349 return NT_STATUS_ACCESS_DENIED;
351 sd->dacl = new_sd->dacl;
352 pvfs_translate_generic_bits(sd->dacl);
353 sd->type |= SEC_DESC_DACL_PRESENT;
356 if (secinfo_flags & SECINFO_SACL) {
357 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
358 return NT_STATUS_ACCESS_DENIED;
360 sd->sacl = new_sd->sacl;
361 pvfs_translate_generic_bits(sd->sacl);
362 sd->type |= SEC_DESC_SACL_PRESENT;
365 if (secinfo_flags & SECINFO_PROTECTED_DACL) {
366 if (new_sd->type & SEC_DESC_DACL_PROTECTED) {
367 sd->type |= SEC_DESC_DACL_PROTECTED;
369 sd->type &= ~SEC_DESC_DACL_PROTECTED;
373 if (secinfo_flags & SECINFO_PROTECTED_SACL) {
374 if (new_sd->type & SEC_DESC_SACL_PROTECTED) {
375 sd->type |= SEC_DESC_SACL_PROTECTED;
377 sd->type &= ~SEC_DESC_SACL_PROTECTED;
381 if (new_uid == old_uid) {
385 if (new_gid == old_gid) {
389 /* if there's something to change try it */
390 if (new_uid != -1 || new_gid != -1) {
393 ret = chown(name->full_name, new_uid, new_gid);
395 ret = fchown(fd, new_uid, new_gid);
397 if (errno == EPERM) {
398 if (uwrap_enabled()) {
401 /* try again as root if we have SEC_PRIV_RESTORE or
402 SEC_PRIV_TAKE_OWNERSHIP */
403 if (security_token_has_privilege(req->session_info->security_token,
405 security_token_has_privilege(req->session_info->security_token,
406 SEC_PRIV_TAKE_OWNERSHIP)) {
408 privs = root_privileges();
410 ret = chown(name->full_name, new_uid, new_gid);
412 ret = fchown(fd, new_uid, new_gid);
419 return pvfs_map_errno(pvfs, errno);
423 /* we avoid saving if the sd is the same. This means when clients
424 copy files and end up copying the default sd that we don't
425 needlessly use xattrs */
426 if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
427 status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
435 answer a fileinfo query for the ACL
437 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs,
438 struct ntvfs_request *req,
439 struct pvfs_filename *name, int fd,
440 union smb_fileinfo *info)
442 NTSTATUS status = NT_STATUS_NOT_FOUND;
443 struct security_descriptor *sd;
446 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
448 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
449 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
451 if (!NT_STATUS_IS_OK(status)) {
455 normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
457 info->query_secdesc.out.sd = sd;
464 check the read only bit against any of the write access bits
466 static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
468 if ((pvfs->flags & PVFS_FLAG_READONLY) &&
469 (access_mask & (SEC_FILE_WRITE_DATA |
470 SEC_FILE_APPEND_DATA |
472 SEC_FILE_WRITE_ATTRIBUTE |
475 SEC_STD_WRITE_OWNER |
476 SEC_DIR_DELETE_CHILD))) {
483 see if we are a member of the appropriate unix group
485 static bool pvfs_group_member(struct pvfs_state *pvfs, gid_t gid)
489 if (getegid() == gid) {
492 ngroups = getgroups(0, NULL);
496 groups = talloc_array(pvfs, gid_t, ngroups);
497 if (groups == NULL) {
500 if (getgroups(ngroups, groups) != ngroups) {
504 for (i=0; i<ngroups; i++) {
505 if (groups[i] == gid) break;
512 default access check function based on unix permissions
513 doing this saves on building a full security descriptor
514 for the common case of access check on files with no
517 If name is NULL then treat as a new file creation
519 static NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
520 struct ntvfs_request *req,
521 struct pvfs_filename *name,
522 uint32_t *access_mask)
524 uid_t uid = geteuid();
525 uint32_t max_bits = 0;
526 struct security_token *token = req->session_info->security_token;
528 if (pvfs_read_only(pvfs, *access_mask)) {
529 return NT_STATUS_ACCESS_DENIED;
533 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
534 } else if (uid == name->st.st_uid || uwrap_enabled()) {
535 /* use the IxUSR bits */
536 if ((name->st.st_mode & S_IWUSR)) {
537 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
538 } else if ((name->st.st_mode & (S_IRUSR | S_IXUSR))) {
539 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
541 } else if (pvfs_group_member(pvfs, name->st.st_gid)) {
542 /* use the IxGRP bits */
543 if ((name->st.st_mode & S_IWGRP)) {
544 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
545 } else if ((name->st.st_mode & (S_IRGRP | S_IXGRP))) {
546 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
549 /* use the IxOTH bits */
550 if ((name->st.st_mode & S_IWOTH)) {
551 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
552 } else if ((name->st.st_mode & (S_IROTH | S_IXOTH))) {
553 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
557 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
558 *access_mask |= max_bits;
559 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
562 if ((*access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
563 security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
564 max_bits |= SEC_FLAG_SYSTEM_SECURITY;
567 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_RESTORE) &&
568 security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
569 max_bits |= ~(SEC_RIGHTS_PRIV_RESTORE);
571 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_BACKUP) &&
572 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
573 max_bits |= ~(SEC_RIGHTS_PRIV_BACKUP);
576 if (*access_mask & ~max_bits) {
577 DEBUG(5,(__location__ " denied access to '%s' - wanted 0x%08x but got 0x%08x (missing 0x%08x)\n",
578 name?name->full_name:"(new file)", *access_mask, max_bits, *access_mask & ~max_bits));
579 return NT_STATUS_ACCESS_DENIED;
582 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
583 /* on SMB, this bit is always granted, even if not
585 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
593 check the security descriptor on a file, if any
595 *access_mask is modified with the access actually granted
597 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
598 struct ntvfs_request *req,
599 struct pvfs_filename *name,
600 uint32_t *access_mask)
602 struct security_token *token = req->session_info->security_token;
603 struct xattr_NTACL *acl;
605 struct security_descriptor *sd;
606 bool allow_delete = false;
608 /* on SMB2 a blank access mask is always denied */
609 if (pvfs->ntvfs->ctx->protocol >= PROTOCOL_SMB2_02 &&
611 return NT_STATUS_ACCESS_DENIED;
614 if (pvfs_read_only(pvfs, *access_mask)) {
615 return NT_STATUS_ACCESS_DENIED;
618 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
619 *access_mask & SEC_STD_DELETE) {
620 status = pvfs_access_check_parent(pvfs, req,
621 name, SEC_DIR_DELETE_CHILD);
622 if (NT_STATUS_IS_OK(status)) {
624 *access_mask &= ~SEC_STD_DELETE;
628 acl = talloc(req, struct xattr_NTACL);
630 return NT_STATUS_NO_MEMORY;
633 /* expand the generic access bits to file specific bits */
634 *access_mask = pvfs_translate_mask(*access_mask);
635 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
636 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
639 status = pvfs_acl_load(pvfs, name, -1, acl);
640 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
642 status = pvfs_access_check_unix(pvfs, req, name, access_mask);
645 if (!NT_STATUS_IS_OK(status)) {
649 switch (acl->version) {
654 return NT_STATUS_INVALID_ACL;
657 /* check the acl against the required access mask */
658 status = se_access_check(sd, token, *access_mask, access_mask);
661 /* if we used a NT acl, then allow access override if the
662 share allows for posix permission override
664 if (NT_STATUS_IS_OK(status)) {
665 name->allow_override = (pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) != 0;
669 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
670 /* on SMB, this bit is always granted, even if not
672 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
676 *access_mask |= SEC_STD_DELETE;
684 a simplified interface to access check, designed for calls that
685 do not take or return an access check mask
687 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs,
688 struct ntvfs_request *req,
689 struct pvfs_filename *name,
690 uint32_t access_needed)
692 if (access_needed == 0) {
695 return pvfs_access_check(pvfs, req, name, &access_needed);
699 access check for creating a new file/directory
701 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs,
702 struct ntvfs_request *req,
703 struct pvfs_filename *name,
704 uint32_t *access_mask,
706 struct security_descriptor **sd)
708 struct pvfs_filename *parent;
710 uint32_t parent_mask;
711 bool allow_delete = false;
713 if (pvfs_read_only(pvfs, *access_mask)) {
714 return NT_STATUS_ACCESS_DENIED;
717 status = pvfs_resolve_parent(pvfs, req, name, &parent);
718 NT_STATUS_NOT_OK_RETURN(status);
721 parent_mask = SEC_DIR_ADD_SUBDIR;
723 parent_mask = SEC_DIR_ADD_FILE;
725 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
726 *access_mask & SEC_STD_DELETE) {
727 parent_mask |= SEC_DIR_DELETE_CHILD;
730 status = pvfs_access_check(pvfs, req, parent, &parent_mask);
731 if (NT_STATUS_IS_OK(status)) {
732 if (parent_mask & SEC_DIR_DELETE_CHILD) {
735 } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
737 * on ACCESS_DENIED we get the rejected bits
738 * remove the non critical SEC_DIR_DELETE_CHILD
739 * and check if something else was rejected.
741 parent_mask &= ~SEC_DIR_DELETE_CHILD;
742 if (parent_mask != 0) {
743 return NT_STATUS_ACCESS_DENIED;
745 status = NT_STATUS_OK;
751 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, sd);
755 if (!NT_STATUS_IS_OK(status)) {
759 /* expand the generic access bits to file specific bits */
760 *access_mask = pvfs_translate_mask(*access_mask);
762 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
763 *access_mask |= SEC_RIGHTS_FILE_ALL;
764 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
767 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
768 /* on SMB, this bit is always granted, even if not
770 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
774 *access_mask |= SEC_STD_DELETE;
781 access check for creating a new file/directory - no access mask supplied
783 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs,
784 struct ntvfs_request *req,
785 struct pvfs_filename *name,
786 uint32_t access_mask)
788 struct pvfs_filename *parent;
791 status = pvfs_resolve_parent(pvfs, req, name, &parent);
792 if (!NT_STATUS_IS_OK(status)) {
796 status = pvfs_access_check_simple(pvfs, req, parent, access_mask);
797 if (NT_STATUS_IS_OK(status) && parent->allow_override) {
798 name->allow_override = true;
805 determine if an ACE is inheritable
807 static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
808 const struct security_ace *ace,
812 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
815 if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
819 if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
820 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
828 this is the core of ACL inheritance. It copies any inheritable
829 aces from the parent SD to the child SD. Note that the algorithm
830 depends on whether the child is a container or not
832 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs,
833 struct security_descriptor *parent_sd,
834 struct security_descriptor *sd,
839 for (i=0;i<parent_sd->dacl->num_aces;i++) {
840 struct security_ace ace = parent_sd->dacl->aces[i];
842 const struct dom_sid *creator = NULL, *new_id = NULL;
845 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
849 orig_flags = ace.flags;
851 /* see the RAW-ACLS inheritance test for details on these rules */
855 ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
857 if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
858 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
860 if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
865 /* the CREATOR sids are special when inherited */
866 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
867 creator = pvfs->sid_cache.creator_owner;
868 new_id = sd->owner_sid;
869 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
870 creator = pvfs->sid_cache.creator_group;
871 new_id = sd->group_sid;
873 new_id = &ace.trustee;
876 if (creator && container &&
877 (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
878 uint32_t flags = ace.flags;
880 ace.trustee = *new_id;
882 status = security_descriptor_dacl_add(sd, &ace);
883 if (!NT_STATUS_IS_OK(status)) {
887 ace.trustee = *creator;
888 ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
889 status = security_descriptor_dacl_add(sd, &ace);
890 } else if (container &&
891 !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
892 status = security_descriptor_dacl_add(sd, &ace);
894 ace.trustee = *new_id;
895 status = security_descriptor_dacl_add(sd, &ace);
898 if (!NT_STATUS_IS_OK(status)) {
909 calculate the ACL on a new file/directory based on the inherited ACL
910 from the parent. If there is no inherited ACL then return a NULL
911 ACL, which means the default ACL should be used
913 NTSTATUS pvfs_acl_inherited_sd(struct pvfs_state *pvfs,
915 struct ntvfs_request *req,
916 struct pvfs_filename *parent,
918 struct security_descriptor **ret_sd)
920 struct xattr_NTACL *acl;
922 struct security_descriptor *parent_sd, *sd;
924 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
928 acl = talloc(req, struct xattr_NTACL);
930 TALLOC_FREE(tmp_ctx);
931 return NT_STATUS_NO_MEMORY;
934 status = pvfs_acl_load(pvfs, parent, -1, acl);
935 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
936 talloc_free(tmp_ctx);
939 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
941 switch (acl->version) {
943 parent_sd = acl->info.sd;
946 talloc_free(tmp_ctx);
947 return NT_STATUS_INVALID_ACL;
950 if (parent_sd == NULL ||
951 parent_sd->dacl == NULL ||
952 parent_sd->dacl->num_aces == 0) {
953 /* go with the default ACL */
954 talloc_free(tmp_ctx);
958 /* create the new sd */
959 sd = security_descriptor_initialise(req);
961 TALLOC_FREE(tmp_ctx);
962 return NT_STATUS_NO_MEMORY;
965 ids = talloc_array(sd, struct id_map, 2);
967 TALLOC_FREE(tmp_ctx);
968 return NT_STATUS_NO_MEMORY;
971 ids[0].xid.id = geteuid();
972 ids[0].xid.type = ID_TYPE_UID;
974 ids[0].status = ID_UNKNOWN;
976 ids[1].xid.id = getegid();
977 ids[1].xid.type = ID_TYPE_GID;
979 ids[1].status = ID_UNKNOWN;
981 status = wbc_xids_to_sids(pvfs->ntvfs->ctx->event_ctx, ids, 2);
982 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
984 sd->owner_sid = talloc_steal(sd, ids[0].sid);
985 sd->group_sid = talloc_steal(sd, ids[1].sid);
987 sd->type |= SEC_DESC_DACL_PRESENT;
989 /* fill in the aces from the parent */
990 status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
991 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
993 /* if there is nothing to inherit then we fallback to the
995 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
996 talloc_free(tmp_ctx);
1000 *ret_sd = talloc_steal(mem_ctx, sd);
1002 talloc_free(tmp_ctx);
1003 return NT_STATUS_OK;
1008 setup an ACL on a new file/directory based on the inherited ACL from
1009 the parent. If there is no inherited ACL then we don't set anything,
1010 as the default ACL applies anyway
1012 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
1013 struct ntvfs_request *req,
1014 struct pvfs_filename *name,
1017 struct xattr_NTACL acl;
1019 struct security_descriptor *sd;
1020 struct pvfs_filename *parent;
1023 /* form the parents path */
1024 status = pvfs_resolve_parent(pvfs, req, name, &parent);
1025 NT_STATUS_NOT_OK_RETURN(status);
1027 container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
1029 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, &sd);
1030 if (!NT_STATUS_IS_OK(status)) {
1031 talloc_free(parent);
1036 return NT_STATUS_OK;
1042 status = pvfs_acl_save(pvfs, name, fd, &acl);
1044 talloc_free(parent);
1050 return the maximum allowed access mask
1052 NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
1053 struct ntvfs_request *req,
1054 struct pvfs_filename *name,
1055 uint32_t *maximal_access)
1057 *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
1058 return pvfs_access_check(pvfs, req, name, maximal_access);