s4: update setntacl and getntacl to select the adaquate backend (fs/tdb) for storing...
[Samba/ekacnet.git] / source4 / ntvfs / posix / pvfs_acl.c
blobc20358be2aed56426ece9d7d0f4e81575e97d63e
1 /*
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/>.
22 #include "includes.h"
23 #include "auth/auth.h"
24 #include "vfs_posix.h"
25 #include "librpc/gen_ndr/xattr.h"
26 #include "libcli/security/security.h"
27 #include "param/param.h"
30 /* the list of currently registered ACL backends */
31 static struct pvfs_acl_backend {
32 const struct pvfs_acl_ops *ops;
33 } *backends = NULL;
34 static int num_backends;
37 register a pvfs acl backend.
39 The 'name' can be later used by other backends to find the operations
40 structure for this backend.
42 NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops)
44 struct pvfs_acl_ops *new_ops;
46 if (pvfs_acl_backend_byname(ops->name) != NULL) {
47 DEBUG(0,("pvfs acl backend '%s' already registered\n", ops->name));
48 return NT_STATUS_OBJECT_NAME_COLLISION;
51 backends = talloc_realloc(talloc_autofree_context(), backends, struct pvfs_acl_backend, num_backends+1);
52 NT_STATUS_HAVE_NO_MEMORY(backends);
54 new_ops = (struct pvfs_acl_ops *)talloc_memdup(backends, ops, sizeof(*ops));
55 new_ops->name = talloc_strdup(new_ops, ops->name);
57 backends[num_backends].ops = new_ops;
59 num_backends++;
61 DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
63 return NT_STATUS_OK;
68 return the operations structure for a named backend
70 const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
72 int i;
74 for (i=0;i<num_backends;i++) {
75 if (strcmp(backends[i].ops->name, name) == 0) {
76 return backends[i].ops;
80 return NULL;
83 NTSTATUS pvfs_acl_init(struct loadparm_context *lp_ctx)
85 static bool initialized = false;
86 extern NTSTATUS pvfs_acl_nfs4_init(void);
87 extern NTSTATUS pvfs_acl_xattr_init(void);
88 init_module_fn static_init[] = { STATIC_pvfs_acl_MODULES };
89 init_module_fn *shared_init;
91 if (initialized) return NT_STATUS_OK;
92 initialized = true;
94 shared_init = load_samba_modules(NULL, lp_ctx, "pvfs_acl");
96 run_init_functions(static_init);
97 run_init_functions(shared_init);
99 talloc_free(shared_init);
101 return NT_STATUS_OK;
106 map a single access_mask from generic to specific bits for files/dirs
108 static uint32_t pvfs_translate_mask(uint32_t access_mask)
110 if (access_mask & SEC_MASK_GENERIC) {
111 if (access_mask & SEC_GENERIC_READ) access_mask |= SEC_RIGHTS_FILE_READ;
112 if (access_mask & SEC_GENERIC_WRITE) access_mask |= SEC_RIGHTS_FILE_WRITE;
113 if (access_mask & SEC_GENERIC_EXECUTE) access_mask |= SEC_RIGHTS_FILE_EXECUTE;
114 if (access_mask & SEC_GENERIC_ALL) access_mask |= SEC_RIGHTS_FILE_ALL;
115 access_mask &= ~SEC_MASK_GENERIC;
117 return access_mask;
122 map any generic access bits in the given acl
123 this relies on the fact that the mappings for files and directories
124 are the same
126 static void pvfs_translate_generic_bits(struct security_acl *acl)
128 unsigned i;
130 if (!acl) return;
132 for (i=0;i<acl->num_aces;i++) {
133 struct security_ace *ace = &acl->aces[i];
134 ace->access_mask = pvfs_translate_mask(ace->access_mask);
140 setup a default ACL for a file
142 static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
143 struct ntvfs_request *req,
144 struct pvfs_filename *name, int fd,
145 struct security_descriptor **psd)
147 struct security_descriptor *sd;
148 NTSTATUS status;
149 struct security_ace ace;
150 mode_t mode;
151 struct id_mapping *ids;
152 struct composite_context *ctx;
154 *psd = security_descriptor_initialise(req);
155 if (*psd == NULL) {
156 return NT_STATUS_NO_MEMORY;
158 sd = *psd;
160 ids = talloc_zero_array(sd, struct id_mapping, 2);
161 NT_STATUS_HAVE_NO_MEMORY(ids);
163 ids[0].unixid = talloc(ids, struct unixid);
164 NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid);
166 ids[0].unixid->id = name->st.st_uid;
167 ids[0].unixid->type = ID_TYPE_UID;
168 ids[0].sid = NULL;
170 ids[1].unixid = talloc(ids, struct unixid);
171 NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid);
173 ids[1].unixid->id = name->st.st_gid;
174 ids[1].unixid->type = ID_TYPE_GID;
175 ids[1].sid = NULL;
177 ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
178 NT_STATUS_HAVE_NO_MEMORY(ctx);
180 status = wbc_xids_to_sids_recv(ctx, &ids);
181 NT_STATUS_NOT_OK_RETURN(status);
183 sd->owner_sid = talloc_steal(sd, ids[0].sid);
184 sd->group_sid = talloc_steal(sd, ids[1].sid);
186 talloc_free(ids);
187 sd->type |= SEC_DESC_DACL_PRESENT;
189 mode = name->st.st_mode;
192 we provide up to 4 ACEs
193 - Owner
194 - Group
195 - Everyone
196 - Administrator
200 /* setup owner ACE */
201 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
202 ace.flags = 0;
203 ace.trustee = *sd->owner_sid;
204 ace.access_mask = 0;
206 if (mode & S_IRUSR) {
207 if (mode & S_IWUSR) {
208 ace.access_mask |= SEC_RIGHTS_FILE_ALL;
209 } else {
210 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
213 if (mode & S_IWUSR) {
214 ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
216 if (ace.access_mask) {
217 security_descriptor_dacl_add(sd, &ace);
221 /* setup group ACE */
222 ace.trustee = *sd->group_sid;
223 ace.access_mask = 0;
224 if (mode & S_IRGRP) {
225 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
227 if (mode & S_IWGRP) {
228 /* note that delete is not granted - this matches posix behaviour */
229 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
231 if (ace.access_mask) {
232 security_descriptor_dacl_add(sd, &ace);
235 /* setup other ACE */
236 ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD);
237 ace.access_mask = 0;
238 if (mode & S_IROTH) {
239 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
241 if (mode & S_IWOTH) {
242 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
244 if (ace.access_mask) {
245 security_descriptor_dacl_add(sd, &ace);
248 /* setup system ACE */
249 ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM);
250 ace.access_mask = SEC_RIGHTS_FILE_ALL;
251 security_descriptor_dacl_add(sd, &ace);
253 return NT_STATUS_OK;
258 omit any security_descriptor elements not specified in the given
259 secinfo flags
261 static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
263 if (!(secinfo_flags & SECINFO_OWNER)) {
264 sd->owner_sid = NULL;
266 if (!(secinfo_flags & SECINFO_GROUP)) {
267 sd->group_sid = NULL;
269 if (!(secinfo_flags & SECINFO_DACL)) {
270 sd->dacl = NULL;
272 if (!(secinfo_flags & SECINFO_SACL)) {
273 sd->sacl = NULL;
278 answer a setfileinfo for an ACL
280 NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
281 struct ntvfs_request *req,
282 struct pvfs_filename *name, int fd,
283 uint32_t access_mask,
284 union smb_setfileinfo *info)
286 uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
287 struct security_descriptor *new_sd, *sd, orig_sd;
288 NTSTATUS status = NT_STATUS_NOT_FOUND;
289 uid_t old_uid = -1;
290 gid_t old_gid = -1;
291 uid_t new_uid = -1;
292 gid_t new_gid = -1;
293 struct id_mapping *ids;
294 struct composite_context *ctx;
296 if (pvfs->acl_ops != NULL) {
297 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
299 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
300 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
302 if (!NT_STATUS_IS_OK(status)) {
303 return status;
306 ids = talloc(req, struct id_mapping);
307 NT_STATUS_HAVE_NO_MEMORY(ids);
308 ids->unixid = NULL;
309 ids->sid = NULL;
310 ids->status = NT_STATUS_NONE_MAPPED;
312 new_sd = info->set_secdesc.in.sd;
313 orig_sd = *sd;
315 old_uid = name->st.st_uid;
316 old_gid = name->st.st_gid;
318 /* only set the elements that have been specified */
319 if (secinfo_flags & SECINFO_OWNER) {
320 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
321 return NT_STATUS_ACCESS_DENIED;
323 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
324 ids->sid = new_sd->owner_sid;
325 ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
326 NT_STATUS_HAVE_NO_MEMORY(ctx);
327 status = wbc_sids_to_xids_recv(ctx, &ids);
328 NT_STATUS_NOT_OK_RETURN(status);
330 if (ids->unixid->type == ID_TYPE_BOTH ||
331 ids->unixid->type == ID_TYPE_UID) {
332 new_uid = ids->unixid->id;
335 sd->owner_sid = new_sd->owner_sid;
337 if (secinfo_flags & SECINFO_GROUP) {
338 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
339 return NT_STATUS_ACCESS_DENIED;
341 if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
342 ids->sid = new_sd->group_sid;
343 ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
344 NT_STATUS_HAVE_NO_MEMORY(ctx);
345 status = wbc_sids_to_xids_recv(ctx, &ids);
346 NT_STATUS_NOT_OK_RETURN(status);
348 if (ids->unixid->type == ID_TYPE_BOTH ||
349 ids->unixid->type == ID_TYPE_GID) {
350 new_gid = ids->unixid->id;
354 sd->group_sid = new_sd->group_sid;
356 if (secinfo_flags & SECINFO_DACL) {
357 if (!(access_mask & SEC_STD_WRITE_DAC)) {
358 return NT_STATUS_ACCESS_DENIED;
360 sd->dacl = new_sd->dacl;
361 pvfs_translate_generic_bits(sd->dacl);
363 if (secinfo_flags & SECINFO_SACL) {
364 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
365 return NT_STATUS_ACCESS_DENIED;
367 sd->sacl = new_sd->sacl;
368 pvfs_translate_generic_bits(sd->sacl);
371 if (new_uid == old_uid) {
372 new_uid = -1;
375 if (new_gid == old_gid) {
376 new_gid = -1;
379 /* if there's something to change try it */
380 if (new_uid != -1 || new_gid != -1) {
381 int ret;
382 if (fd == -1) {
383 ret = chown(name->full_name, new_uid, new_gid);
384 } else {
385 ret = fchown(fd, new_uid, new_gid);
387 if (errno == EPERM && uwrap_enabled()) {
388 ret = 0;
390 if (ret == -1) {
391 return pvfs_map_errno(pvfs, errno);
395 /* we avoid saving if the sd is the same. This means when clients
396 copy files and end up copying the default sd that we don't
397 needlessly use xattrs */
398 if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
399 status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
402 return status;
407 answer a fileinfo query for the ACL
409 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs,
410 struct ntvfs_request *req,
411 struct pvfs_filename *name, int fd,
412 union smb_fileinfo *info)
414 NTSTATUS status = NT_STATUS_NOT_FOUND;
415 struct security_descriptor *sd;
417 if (pvfs->acl_ops) {
418 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
420 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
421 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
423 if (!NT_STATUS_IS_OK(status)) {
424 return status;
427 normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
429 info->query_secdesc.out.sd = sd;
431 return NT_STATUS_OK;
436 check the read only bit against any of the write access bits
438 static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
440 if ((pvfs->flags & PVFS_FLAG_READONLY) &&
441 (access_mask & (SEC_FILE_WRITE_DATA |
442 SEC_FILE_APPEND_DATA |
443 SEC_FILE_WRITE_EA |
444 SEC_FILE_WRITE_ATTRIBUTE |
445 SEC_STD_DELETE |
446 SEC_STD_WRITE_DAC |
447 SEC_STD_WRITE_OWNER |
448 SEC_DIR_DELETE_CHILD))) {
449 return true;
451 return false;
455 see if we are a member of the appropriate unix group
457 static bool pvfs_group_member(struct pvfs_state *pvfs, gid_t gid)
459 int i, ngroups;
460 gid_t *groups;
461 if (getegid() == gid) {
462 return true;
464 ngroups = getgroups(0, NULL);
465 if (ngroups == 0) {
466 return false;
468 groups = talloc_array(pvfs, gid_t, ngroups);
469 if (groups == NULL) {
470 return false;
472 if (getgroups(ngroups, groups) != ngroups) {
473 talloc_free(groups);
474 return false;
476 for (i=0; i<ngroups; i++) {
477 if (groups[i] == gid) break;
479 talloc_free(groups);
480 return i < ngroups;
484 default access check function based on unix permissions
485 doing this saves on building a full security descriptor
486 for the common case of access check on files with no
487 specific NT ACL
489 If name is NULL then treat as a new file creation
491 NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
492 struct ntvfs_request *req,
493 struct pvfs_filename *name,
494 uint32_t *access_mask)
496 uid_t uid = geteuid();
497 uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL;
498 struct security_token *token = req->session_info->security_token;
500 if (pvfs_read_only(pvfs, *access_mask)) {
501 return NT_STATUS_ACCESS_DENIED;
504 if (name == NULL || uid == name->st.st_uid) {
505 max_bits |= SEC_STD_ALL;
506 } else if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
507 max_bits |= SEC_STD_DELETE;
510 if (name == NULL ||
511 (name->st.st_mode & S_IWOTH) ||
512 ((name->st.st_mode & S_IWGRP) &&
513 pvfs_group_member(pvfs, name->st.st_gid))) {
514 max_bits |= SEC_STD_ALL;
517 if (uwrap_enabled()) {
518 /* when running with the uid wrapper, files will be created
519 owned by the ruid, but we may have a different simulated
520 euid. We need to force the permission bits as though the
521 files owner matches the euid */
522 max_bits |= SEC_STD_ALL;
525 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
526 *access_mask |= max_bits;
527 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
530 if ((*access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
531 security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
532 max_bits |= SEC_FLAG_SYSTEM_SECURITY;
535 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_RESTORE) &&
536 security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
537 max_bits |= ~(SEC_RIGHTS_PRIV_RESTORE);
539 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_BACKUP) &&
540 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
541 max_bits |= ~(SEC_RIGHTS_PRIV_BACKUP);
544 if (*access_mask & ~max_bits) {
545 DEBUG(0,(__location__ " denied access to '%s' - wanted 0x%08x but got 0x%08x (missing 0x%08x)\n",
546 name?name->full_name:"(new file)", *access_mask, max_bits, *access_mask & ~max_bits));
547 return NT_STATUS_ACCESS_DENIED;
550 if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
551 /* on SMB, this bit is always granted, even if not
552 asked for */
553 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
556 return NT_STATUS_OK;
561 check the security descriptor on a file, if any
563 *access_mask is modified with the access actually granted
565 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
566 struct ntvfs_request *req,
567 struct pvfs_filename *name,
568 uint32_t *access_mask)
570 struct security_token *token = req->session_info->security_token;
571 struct xattr_NTACL *acl;
572 NTSTATUS status;
573 struct security_descriptor *sd;
575 /* on SMB2 a blank access mask is always denied */
576 if (pvfs->ntvfs->ctx->protocol == PROTOCOL_SMB2 &&
577 *access_mask == 0) {
578 return NT_STATUS_ACCESS_DENIED;
581 if (pvfs_read_only(pvfs, *access_mask)) {
582 return NT_STATUS_ACCESS_DENIED;
585 acl = talloc(req, struct xattr_NTACL);
586 if (acl == NULL) {
587 return NT_STATUS_NO_MEMORY;
590 /* expand the generic access bits to file specific bits */
591 *access_mask = pvfs_translate_mask(*access_mask);
592 if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
593 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
596 status = pvfs_acl_load(pvfs, name, -1, acl);
597 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
598 talloc_free(acl);
599 return pvfs_access_check_unix(pvfs, req, name, access_mask);
601 if (!NT_STATUS_IS_OK(status)) {
602 return status;
605 switch (acl->version) {
606 case 1:
607 sd = acl->info.sd;
608 break;
609 default:
610 return NT_STATUS_INVALID_ACL;
613 /* check the acl against the required access mask */
614 status = sec_access_check(sd, token, *access_mask, access_mask);
616 if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
617 /* on SMB, this bit is always granted, even if not
618 asked for */
619 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
622 talloc_free(acl);
624 return status;
629 a simplified interface to access check, designed for calls that
630 do not take or return an access check mask
632 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs,
633 struct ntvfs_request *req,
634 struct pvfs_filename *name,
635 uint32_t access_needed)
637 if (access_needed == 0) {
638 return NT_STATUS_OK;
640 return pvfs_access_check(pvfs, req, name, &access_needed);
644 access check for creating a new file/directory
646 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs,
647 struct ntvfs_request *req,
648 struct pvfs_filename *name,
649 uint32_t *access_mask,
650 bool container,
651 struct security_descriptor **sd)
653 struct pvfs_filename *parent;
654 NTSTATUS status;
656 if (pvfs_read_only(pvfs, *access_mask)) {
657 return NT_STATUS_ACCESS_DENIED;
660 status = pvfs_resolve_parent(pvfs, req, name, &parent);
661 NT_STATUS_NOT_OK_RETURN(status);
663 status = pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE);
664 NT_STATUS_NOT_OK_RETURN(status);
666 if (*sd == NULL) {
667 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, sd);
670 talloc_free(parent);
671 if (!NT_STATUS_IS_OK(status)) {
672 return status;
675 /* expand the generic access bits to file specific bits */
676 *access_mask = pvfs_translate_mask(*access_mask);
678 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
679 *access_mask |= SEC_RIGHTS_FILE_ALL;
680 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
683 if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
684 /* on SMB, this bit is always granted, even if not
685 asked for */
686 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
689 return NT_STATUS_OK;
693 access check for creating a new file/directory - no access mask supplied
695 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs,
696 struct ntvfs_request *req,
697 struct pvfs_filename *name,
698 uint32_t access_mask)
700 struct pvfs_filename *parent;
701 NTSTATUS status;
703 status = pvfs_resolve_parent(pvfs, req, name, &parent);
704 if (!NT_STATUS_IS_OK(status)) {
705 return status;
708 return pvfs_access_check_simple(pvfs, req, parent, access_mask);
713 determine if an ACE is inheritable
715 static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
716 const struct security_ace *ace,
717 bool container)
719 if (!container) {
720 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
723 if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
724 return true;
727 if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
728 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
729 return true;
732 return false;
736 this is the core of ACL inheritance. It copies any inheritable
737 aces from the parent SD to the child SD. Note that the algorithm
738 depends on whether the child is a container or not
740 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs,
741 struct security_descriptor *parent_sd,
742 struct security_descriptor *sd,
743 bool container)
745 int i;
747 for (i=0;i<parent_sd->dacl->num_aces;i++) {
748 struct security_ace ace = parent_sd->dacl->aces[i];
749 NTSTATUS status;
750 const struct dom_sid *creator = NULL, *new_id = NULL;
751 uint32_t orig_flags;
753 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
754 continue;
757 orig_flags = ace.flags;
759 /* see the RAW-ACLS inheritance test for details on these rules */
760 if (!container) {
761 ace.flags = 0;
762 } else {
763 ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
765 if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
766 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
768 if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
769 ace.flags = 0;
773 /* the CREATOR sids are special when inherited */
774 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
775 creator = pvfs->sid_cache.creator_owner;
776 new_id = sd->owner_sid;
777 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
778 creator = pvfs->sid_cache.creator_group;
779 new_id = sd->group_sid;
780 } else {
781 new_id = &ace.trustee;
784 if (creator && container &&
785 (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
786 uint32_t flags = ace.flags;
788 ace.trustee = *new_id;
789 ace.flags = 0;
790 status = security_descriptor_dacl_add(sd, &ace);
791 if (!NT_STATUS_IS_OK(status)) {
792 return status;
795 ace.trustee = *creator;
796 ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
797 status = security_descriptor_dacl_add(sd, &ace);
798 } else if (container &&
799 !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
800 status = security_descriptor_dacl_add(sd, &ace);
801 } else {
802 ace.trustee = *new_id;
803 status = security_descriptor_dacl_add(sd, &ace);
806 if (!NT_STATUS_IS_OK(status)) {
807 return status;
811 return NT_STATUS_OK;
817 calculate the ACL on a new file/directory based on the inherited ACL
818 from the parent. If there is no inherited ACL then return a NULL
819 ACL, which means the default ACL should be used
821 NTSTATUS pvfs_acl_inherited_sd(struct pvfs_state *pvfs,
822 TALLOC_CTX *mem_ctx,
823 struct ntvfs_request *req,
824 struct pvfs_filename *parent,
825 bool container,
826 struct security_descriptor **ret_sd)
828 struct xattr_NTACL *acl;
829 NTSTATUS status;
830 struct security_descriptor *parent_sd, *sd;
831 struct id_mapping *ids;
832 struct composite_context *ctx;
833 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
835 *ret_sd = NULL;
837 acl = talloc(req, struct xattr_NTACL);
838 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(acl, tmp_ctx);
840 status = pvfs_acl_load(pvfs, parent, -1, acl);
841 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
842 talloc_free(tmp_ctx);
843 return NT_STATUS_OK;
845 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
847 switch (acl->version) {
848 case 1:
849 parent_sd = acl->info.sd;
850 break;
851 default:
852 talloc_free(tmp_ctx);
853 return NT_STATUS_INVALID_ACL;
856 if (parent_sd == NULL ||
857 parent_sd->dacl == NULL ||
858 parent_sd->dacl->num_aces == 0) {
859 /* go with the default ACL */
860 talloc_free(tmp_ctx);
861 return NT_STATUS_OK;
864 /* create the new sd */
865 sd = security_descriptor_initialise(req);
866 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sd, tmp_ctx);
868 ids = talloc_array(sd, struct id_mapping, 2);
869 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ids, tmp_ctx);
871 ids[0].unixid = talloc(ids, struct unixid);
872 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ids[0].unixid, tmp_ctx);
873 ids[0].unixid->id = geteuid();
874 ids[0].unixid->type = ID_TYPE_UID;
875 ids[0].sid = NULL;
876 ids[0].status = NT_STATUS_NONE_MAPPED;
878 ids[1].unixid = talloc(ids, struct unixid);
879 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ids[1].unixid, tmp_ctx);
880 ids[1].unixid->id = getegid();
881 ids[1].unixid->type = ID_TYPE_GID;
882 ids[1].sid = NULL;
883 ids[1].status = NT_STATUS_NONE_MAPPED;
885 ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
886 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ctx, tmp_ctx);
888 status = wbc_xids_to_sids_recv(ctx, &ids);
889 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
891 sd->owner_sid = talloc_steal(sd, ids[0].sid);
892 sd->group_sid = talloc_steal(sd, ids[1].sid);
894 sd->type |= SEC_DESC_DACL_PRESENT;
896 /* fill in the aces from the parent */
897 status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
898 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
900 /* if there is nothing to inherit then we fallback to the
901 default acl */
902 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
903 talloc_free(tmp_ctx);
904 return NT_STATUS_OK;
907 *ret_sd = talloc_steal(mem_ctx, sd);
909 talloc_free(tmp_ctx);
910 return NT_STATUS_OK;
915 setup an ACL on a new file/directory based on the inherited ACL from
916 the parent. If there is no inherited ACL then we don't set anything,
917 as the default ACL applies anyway
919 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
920 struct ntvfs_request *req,
921 struct pvfs_filename *name,
922 int fd)
924 struct xattr_NTACL acl;
925 NTSTATUS status;
926 struct security_descriptor *sd;
927 struct pvfs_filename *parent;
928 bool container;
930 /* form the parents path */
931 status = pvfs_resolve_parent(pvfs, req, name, &parent);
932 NT_STATUS_NOT_OK_RETURN(status);
934 container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
936 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, &sd);
937 if (!NT_STATUS_IS_OK(status)) {
938 talloc_free(parent);
939 return status;
942 if (sd == NULL) {
943 return NT_STATUS_OK;
946 acl.version = 1;
947 acl.info.sd = sd;
949 status = pvfs_acl_save(pvfs, name, fd, &acl);
950 talloc_free(sd);
951 talloc_free(parent);
953 return status;
957 return the maximum allowed access mask
959 NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
960 struct ntvfs_request *req,
961 struct pvfs_filename *name,
962 uint32_t *maximal_access)
964 *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
965 return pvfs_access_check(pvfs, req, name, maximal_access);