s4:idmap Adjust code to new idmap structure names and layout.
[Samba/gebeck_regimport.git] / source4 / ntvfs / posix / pvfs_acl.c
blob97c5341007f09a92a9046dbc3e73bc3ae9f9ff23
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"
28 #include "../lib/util/unix_privs.h"
30 #if defined(UID_WRAPPER)
31 #if !defined(UID_WRAPPER_REPLACE) && !defined(UID_WRAPPER_NOT_REPLACE)
32 #define UID_WRAPPER_REPLACE
33 #include "../uid_wrapper/uid_wrapper.h"
34 #endif
35 #else
36 #define uwrap_enabled() 0
37 #endif
39 /* the list of currently registered ACL backends */
40 static struct pvfs_acl_backend {
41 const struct pvfs_acl_ops *ops;
42 } *backends = NULL;
43 static int num_backends;
46 register a pvfs acl backend.
48 The 'name' can be later used by other backends to find the operations
49 structure for this backend.
51 NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops)
53 struct pvfs_acl_ops *new_ops;
55 if (pvfs_acl_backend_byname(ops->name) != NULL) {
56 DEBUG(0,("pvfs acl backend '%s' already registered\n", ops->name));
57 return NT_STATUS_OBJECT_NAME_COLLISION;
60 backends = talloc_realloc(talloc_autofree_context(), backends, struct pvfs_acl_backend, num_backends+1);
61 NT_STATUS_HAVE_NO_MEMORY(backends);
63 new_ops = (struct pvfs_acl_ops *)talloc_memdup(backends, ops, sizeof(*ops));
64 new_ops->name = talloc_strdup(new_ops, ops->name);
66 backends[num_backends].ops = new_ops;
68 num_backends++;
70 DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
72 return NT_STATUS_OK;
77 return the operations structure for a named backend
79 const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
81 int i;
83 for (i=0;i<num_backends;i++) {
84 if (strcmp(backends[i].ops->name, name) == 0) {
85 return backends[i].ops;
89 return NULL;
92 NTSTATUS pvfs_acl_init(struct loadparm_context *lp_ctx)
94 static bool initialized = false;
95 extern NTSTATUS pvfs_acl_nfs4_init(void);
96 extern NTSTATUS pvfs_acl_xattr_init(void);
97 init_module_fn static_init[] = { STATIC_pvfs_acl_MODULES };
98 init_module_fn *shared_init;
100 if (initialized) return NT_STATUS_OK;
101 initialized = true;
103 shared_init = load_samba_modules(NULL, lp_ctx, "pvfs_acl");
105 run_init_functions(static_init);
106 run_init_functions(shared_init);
108 talloc_free(shared_init);
110 return NT_STATUS_OK;
115 map a single access_mask from generic to specific bits for files/dirs
117 static uint32_t pvfs_translate_mask(uint32_t access_mask)
119 if (access_mask & SEC_MASK_GENERIC) {
120 if (access_mask & SEC_GENERIC_READ) access_mask |= SEC_RIGHTS_FILE_READ;
121 if (access_mask & SEC_GENERIC_WRITE) access_mask |= SEC_RIGHTS_FILE_WRITE;
122 if (access_mask & SEC_GENERIC_EXECUTE) access_mask |= SEC_RIGHTS_FILE_EXECUTE;
123 if (access_mask & SEC_GENERIC_ALL) access_mask |= SEC_RIGHTS_FILE_ALL;
124 access_mask &= ~SEC_MASK_GENERIC;
126 return access_mask;
131 map any generic access bits in the given acl
132 this relies on the fact that the mappings for files and directories
133 are the same
135 static void pvfs_translate_generic_bits(struct security_acl *acl)
137 unsigned i;
139 if (!acl) return;
141 for (i=0;i<acl->num_aces;i++) {
142 struct security_ace *ace = &acl->aces[i];
143 ace->access_mask = pvfs_translate_mask(ace->access_mask);
149 setup a default ACL for a file
151 static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
152 struct ntvfs_request *req,
153 struct pvfs_filename *name, int fd,
154 struct security_descriptor **psd)
156 struct security_descriptor *sd;
157 NTSTATUS status;
158 struct security_ace ace;
159 mode_t mode;
160 struct id_map *ids;
161 struct composite_context *ctx;
163 *psd = security_descriptor_initialise(req);
164 if (*psd == NULL) {
165 return NT_STATUS_NO_MEMORY;
167 sd = *psd;
169 ids = talloc_zero_array(sd, struct id_map, 2);
170 NT_STATUS_HAVE_NO_MEMORY(ids);
172 ids[0].xid.id = name->st.st_uid;
173 ids[0].xid.type = ID_TYPE_UID;
174 ids[0].sid = NULL;
176 ids[1].xid.id = name->st.st_gid;
177 ids[1].xid.type = ID_TYPE_GID;
178 ids[1].sid = NULL;
180 ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
181 NT_STATUS_HAVE_NO_MEMORY(ctx);
183 status = wbc_xids_to_sids_recv(ctx, &ids);
184 NT_STATUS_NOT_OK_RETURN(status);
186 sd->owner_sid = talloc_steal(sd, ids[0].sid);
187 sd->group_sid = talloc_steal(sd, ids[1].sid);
189 talloc_free(ids);
190 sd->type |= SEC_DESC_DACL_PRESENT;
192 mode = name->st.st_mode;
195 we provide up to 4 ACEs
196 - Owner
197 - Group
198 - Everyone
199 - Administrator
203 /* setup owner ACE */
204 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
205 ace.flags = 0;
206 ace.trustee = *sd->owner_sid;
207 ace.access_mask = 0;
209 if (mode & S_IRUSR) {
210 if (mode & S_IWUSR) {
211 ace.access_mask |= SEC_RIGHTS_FILE_ALL;
212 } else {
213 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
216 if (mode & S_IWUSR) {
217 ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
219 if (ace.access_mask) {
220 security_descriptor_dacl_add(sd, &ace);
224 /* setup group ACE */
225 ace.trustee = *sd->group_sid;
226 ace.access_mask = 0;
227 if (mode & S_IRGRP) {
228 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
230 if (mode & S_IWGRP) {
231 /* note that delete is not granted - this matches posix behaviour */
232 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
234 if (ace.access_mask) {
235 security_descriptor_dacl_add(sd, &ace);
238 /* setup other ACE */
239 ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD);
240 ace.access_mask = 0;
241 if (mode & S_IROTH) {
242 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
244 if (mode & S_IWOTH) {
245 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
247 if (ace.access_mask) {
248 security_descriptor_dacl_add(sd, &ace);
251 /* setup system ACE */
252 ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM);
253 ace.access_mask = SEC_RIGHTS_FILE_ALL;
254 security_descriptor_dacl_add(sd, &ace);
256 return NT_STATUS_OK;
261 omit any security_descriptor elements not specified in the given
262 secinfo flags
264 static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
266 if (!(secinfo_flags & SECINFO_OWNER)) {
267 sd->owner_sid = NULL;
269 if (!(secinfo_flags & SECINFO_GROUP)) {
270 sd->group_sid = NULL;
272 if (!(secinfo_flags & SECINFO_DACL)) {
273 sd->dacl = NULL;
275 if (!(secinfo_flags & SECINFO_SACL)) {
276 sd->sacl = NULL;
281 answer a setfileinfo for an ACL
283 NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
284 struct ntvfs_request *req,
285 struct pvfs_filename *name, int fd,
286 uint32_t access_mask,
287 union smb_setfileinfo *info)
289 uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
290 struct security_descriptor *new_sd, *sd, orig_sd;
291 NTSTATUS status = NT_STATUS_NOT_FOUND;
292 uid_t old_uid = -1;
293 gid_t old_gid = -1;
294 uid_t new_uid = -1;
295 gid_t new_gid = -1;
296 struct id_map *ids;
297 struct composite_context *ctx;
299 if (pvfs->acl_ops != NULL) {
300 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
302 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
303 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
305 if (!NT_STATUS_IS_OK(status)) {
306 return status;
309 ids = talloc(req, struct id_map);
310 NT_STATUS_HAVE_NO_MEMORY(ids);
311 ZERO_STRUCT(ids->xid);
312 ids->sid = NULL;
313 ids->status = ID_UNKNOWN;
315 new_sd = info->set_secdesc.in.sd;
316 orig_sd = *sd;
318 old_uid = name->st.st_uid;
319 old_gid = name->st.st_gid;
321 /* only set the elements that have been specified */
322 if (secinfo_flags & SECINFO_OWNER) {
323 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
324 return NT_STATUS_ACCESS_DENIED;
326 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
327 ids->sid = new_sd->owner_sid;
328 ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
329 NT_STATUS_HAVE_NO_MEMORY(ctx);
330 status = wbc_sids_to_xids_recv(ctx, &ids);
331 NT_STATUS_NOT_OK_RETURN(status);
333 if (ids->xid.type == ID_TYPE_BOTH ||
334 ids->xid.type == ID_TYPE_UID) {
335 new_uid = ids->xid.id;
338 sd->owner_sid = new_sd->owner_sid;
340 if (secinfo_flags & SECINFO_GROUP) {
341 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
342 return NT_STATUS_ACCESS_DENIED;
344 if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
345 ids->sid = new_sd->group_sid;
346 ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
347 NT_STATUS_HAVE_NO_MEMORY(ctx);
348 status = wbc_sids_to_xids_recv(ctx, &ids);
349 NT_STATUS_NOT_OK_RETURN(status);
351 if (ids->xid.type == ID_TYPE_BOTH ||
352 ids->xid.type == ID_TYPE_GID) {
353 new_gid = ids->xid.id;
357 sd->group_sid = new_sd->group_sid;
359 if (secinfo_flags & SECINFO_DACL) {
360 if (!(access_mask & SEC_STD_WRITE_DAC)) {
361 return NT_STATUS_ACCESS_DENIED;
363 sd->dacl = new_sd->dacl;
364 pvfs_translate_generic_bits(sd->dacl);
366 if (secinfo_flags & SECINFO_SACL) {
367 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
368 return NT_STATUS_ACCESS_DENIED;
370 sd->sacl = new_sd->sacl;
371 pvfs_translate_generic_bits(sd->sacl);
374 if (new_uid == old_uid) {
375 new_uid = -1;
378 if (new_gid == old_gid) {
379 new_gid = -1;
382 /* if there's something to change try it */
383 if (new_uid != -1 || new_gid != -1) {
384 int ret;
385 if (fd == -1) {
386 ret = chown(name->full_name, new_uid, new_gid);
387 } else {
388 ret = fchown(fd, new_uid, new_gid);
390 if (errno == EPERM) {
391 if (uwrap_enabled()) {
392 ret = 0;
393 } else {
394 /* try again as root if we have SEC_PRIV_RESTORE or
395 SEC_PRIV_TAKE_OWNERSHIP */
396 if (security_token_has_privilege(req->session_info->security_token,
397 SEC_PRIV_RESTORE) ||
398 security_token_has_privilege(req->session_info->security_token,
399 SEC_PRIV_TAKE_OWNERSHIP)) {
400 void *privs;
401 privs = root_privileges();
402 if (fd == -1) {
403 ret = chown(name->full_name, new_uid, new_gid);
404 } else {
405 ret = fchown(fd, new_uid, new_gid);
407 talloc_free(privs);
411 if (ret == -1) {
412 return pvfs_map_errno(pvfs, errno);
416 /* we avoid saving if the sd is the same. This means when clients
417 copy files and end up copying the default sd that we don't
418 needlessly use xattrs */
419 if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
420 status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
423 return status;
428 answer a fileinfo query for the ACL
430 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs,
431 struct ntvfs_request *req,
432 struct pvfs_filename *name, int fd,
433 union smb_fileinfo *info)
435 NTSTATUS status = NT_STATUS_NOT_FOUND;
436 struct security_descriptor *sd;
438 if (pvfs->acl_ops) {
439 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
441 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
442 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
444 if (!NT_STATUS_IS_OK(status)) {
445 return status;
448 normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
450 info->query_secdesc.out.sd = sd;
452 return NT_STATUS_OK;
457 check the read only bit against any of the write access bits
459 static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
461 if ((pvfs->flags & PVFS_FLAG_READONLY) &&
462 (access_mask & (SEC_FILE_WRITE_DATA |
463 SEC_FILE_APPEND_DATA |
464 SEC_FILE_WRITE_EA |
465 SEC_FILE_WRITE_ATTRIBUTE |
466 SEC_STD_DELETE |
467 SEC_STD_WRITE_DAC |
468 SEC_STD_WRITE_OWNER |
469 SEC_DIR_DELETE_CHILD))) {
470 return true;
472 return false;
476 see if we are a member of the appropriate unix group
478 static bool pvfs_group_member(struct pvfs_state *pvfs, gid_t gid)
480 int i, ngroups;
481 gid_t *groups;
482 if (getegid() == gid) {
483 return true;
485 ngroups = getgroups(0, NULL);
486 if (ngroups == 0) {
487 return false;
489 groups = talloc_array(pvfs, gid_t, ngroups);
490 if (groups == NULL) {
491 return false;
493 if (getgroups(ngroups, groups) != ngroups) {
494 talloc_free(groups);
495 return false;
497 for (i=0; i<ngroups; i++) {
498 if (groups[i] == gid) break;
500 talloc_free(groups);
501 return i < ngroups;
505 default access check function based on unix permissions
506 doing this saves on building a full security descriptor
507 for the common case of access check on files with no
508 specific NT ACL
510 If name is NULL then treat as a new file creation
512 NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
513 struct ntvfs_request *req,
514 struct pvfs_filename *name,
515 uint32_t *access_mask)
517 uid_t uid = geteuid();
518 uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL;
519 struct security_token *token = req->session_info->security_token;
521 if (pvfs_read_only(pvfs, *access_mask)) {
522 return NT_STATUS_ACCESS_DENIED;
525 if (name == NULL || uid == name->st.st_uid) {
526 max_bits |= SEC_STD_ALL;
527 } else if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
528 max_bits |= SEC_STD_DELETE;
531 if (name == NULL ||
532 (name->st.st_mode & S_IWOTH) ||
533 ((name->st.st_mode & S_IWGRP) &&
534 pvfs_group_member(pvfs, name->st.st_gid))) {
535 max_bits |= SEC_STD_ALL;
538 if (uwrap_enabled()) {
539 /* when running with the uid wrapper, files will be created
540 owned by the ruid, but we may have a different simulated
541 euid. We need to force the permission bits as though the
542 files owner matches the euid */
543 max_bits |= SEC_STD_ALL;
546 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
547 *access_mask |= max_bits;
548 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
551 if ((*access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
552 security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
553 max_bits |= SEC_FLAG_SYSTEM_SECURITY;
556 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_RESTORE) &&
557 security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
558 max_bits |= ~(SEC_RIGHTS_PRIV_RESTORE);
560 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_BACKUP) &&
561 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
562 max_bits |= ~(SEC_RIGHTS_PRIV_BACKUP);
565 if (*access_mask & ~max_bits) {
566 DEBUG(0,(__location__ " denied access to '%s' - wanted 0x%08x but got 0x%08x (missing 0x%08x)\n",
567 name?name->full_name:"(new file)", *access_mask, max_bits, *access_mask & ~max_bits));
568 return NT_STATUS_ACCESS_DENIED;
571 if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
572 /* on SMB, this bit is always granted, even if not
573 asked for */
574 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
577 return NT_STATUS_OK;
582 check the security descriptor on a file, if any
584 *access_mask is modified with the access actually granted
586 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
587 struct ntvfs_request *req,
588 struct pvfs_filename *name,
589 uint32_t *access_mask)
591 struct security_token *token = req->session_info->security_token;
592 struct xattr_NTACL *acl;
593 NTSTATUS status;
594 struct security_descriptor *sd;
596 /* on SMB2 a blank access mask is always denied */
597 if (pvfs->ntvfs->ctx->protocol == PROTOCOL_SMB2 &&
598 *access_mask == 0) {
599 return NT_STATUS_ACCESS_DENIED;
602 if (pvfs_read_only(pvfs, *access_mask)) {
603 return NT_STATUS_ACCESS_DENIED;
606 acl = talloc(req, struct xattr_NTACL);
607 if (acl == NULL) {
608 return NT_STATUS_NO_MEMORY;
611 /* expand the generic access bits to file specific bits */
612 *access_mask = pvfs_translate_mask(*access_mask);
613 if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
614 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
617 status = pvfs_acl_load(pvfs, name, -1, acl);
618 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
619 talloc_free(acl);
620 return pvfs_access_check_unix(pvfs, req, name, access_mask);
622 if (!NT_STATUS_IS_OK(status)) {
623 return status;
626 switch (acl->version) {
627 case 1:
628 sd = acl->info.sd;
629 break;
630 default:
631 return NT_STATUS_INVALID_ACL;
634 /* check the acl against the required access mask */
635 status = sec_access_check(sd, token, *access_mask, access_mask);
637 if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
638 /* on SMB, this bit is always granted, even if not
639 asked for */
640 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
643 talloc_free(acl);
645 return status;
650 a simplified interface to access check, designed for calls that
651 do not take or return an access check mask
653 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs,
654 struct ntvfs_request *req,
655 struct pvfs_filename *name,
656 uint32_t access_needed)
658 if (access_needed == 0) {
659 return NT_STATUS_OK;
661 return pvfs_access_check(pvfs, req, name, &access_needed);
665 access check for creating a new file/directory
667 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs,
668 struct ntvfs_request *req,
669 struct pvfs_filename *name,
670 uint32_t *access_mask,
671 bool container,
672 struct security_descriptor **sd)
674 struct pvfs_filename *parent;
675 NTSTATUS status;
677 if (pvfs_read_only(pvfs, *access_mask)) {
678 return NT_STATUS_ACCESS_DENIED;
681 status = pvfs_resolve_parent(pvfs, req, name, &parent);
682 NT_STATUS_NOT_OK_RETURN(status);
684 status = pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE);
685 NT_STATUS_NOT_OK_RETURN(status);
687 if (*sd == NULL) {
688 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, sd);
691 talloc_free(parent);
692 if (!NT_STATUS_IS_OK(status)) {
693 return status;
696 /* expand the generic access bits to file specific bits */
697 *access_mask = pvfs_translate_mask(*access_mask);
699 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
700 *access_mask |= SEC_RIGHTS_FILE_ALL;
701 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
704 if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
705 /* on SMB, this bit is always granted, even if not
706 asked for */
707 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
710 return NT_STATUS_OK;
714 access check for creating a new file/directory - no access mask supplied
716 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs,
717 struct ntvfs_request *req,
718 struct pvfs_filename *name,
719 uint32_t access_mask)
721 struct pvfs_filename *parent;
722 NTSTATUS status;
724 status = pvfs_resolve_parent(pvfs, req, name, &parent);
725 if (!NT_STATUS_IS_OK(status)) {
726 return status;
729 return pvfs_access_check_simple(pvfs, req, parent, access_mask);
734 determine if an ACE is inheritable
736 static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
737 const struct security_ace *ace,
738 bool container)
740 if (!container) {
741 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
744 if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
745 return true;
748 if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
749 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
750 return true;
753 return false;
757 this is the core of ACL inheritance. It copies any inheritable
758 aces from the parent SD to the child SD. Note that the algorithm
759 depends on whether the child is a container or not
761 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs,
762 struct security_descriptor *parent_sd,
763 struct security_descriptor *sd,
764 bool container)
766 int i;
768 for (i=0;i<parent_sd->dacl->num_aces;i++) {
769 struct security_ace ace = parent_sd->dacl->aces[i];
770 NTSTATUS status;
771 const struct dom_sid *creator = NULL, *new_id = NULL;
772 uint32_t orig_flags;
774 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
775 continue;
778 orig_flags = ace.flags;
780 /* see the RAW-ACLS inheritance test for details on these rules */
781 if (!container) {
782 ace.flags = 0;
783 } else {
784 ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
786 if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
787 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
789 if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
790 ace.flags = 0;
794 /* the CREATOR sids are special when inherited */
795 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
796 creator = pvfs->sid_cache.creator_owner;
797 new_id = sd->owner_sid;
798 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
799 creator = pvfs->sid_cache.creator_group;
800 new_id = sd->group_sid;
801 } else {
802 new_id = &ace.trustee;
805 if (creator && container &&
806 (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
807 uint32_t flags = ace.flags;
809 ace.trustee = *new_id;
810 ace.flags = 0;
811 status = security_descriptor_dacl_add(sd, &ace);
812 if (!NT_STATUS_IS_OK(status)) {
813 return status;
816 ace.trustee = *creator;
817 ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
818 status = security_descriptor_dacl_add(sd, &ace);
819 } else if (container &&
820 !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
821 status = security_descriptor_dacl_add(sd, &ace);
822 } else {
823 ace.trustee = *new_id;
824 status = security_descriptor_dacl_add(sd, &ace);
827 if (!NT_STATUS_IS_OK(status)) {
828 return status;
832 return NT_STATUS_OK;
838 calculate the ACL on a new file/directory based on the inherited ACL
839 from the parent. If there is no inherited ACL then return a NULL
840 ACL, which means the default ACL should be used
842 NTSTATUS pvfs_acl_inherited_sd(struct pvfs_state *pvfs,
843 TALLOC_CTX *mem_ctx,
844 struct ntvfs_request *req,
845 struct pvfs_filename *parent,
846 bool container,
847 struct security_descriptor **ret_sd)
849 struct xattr_NTACL *acl;
850 NTSTATUS status;
851 struct security_descriptor *parent_sd, *sd;
852 struct id_map *ids;
853 struct composite_context *ctx;
854 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
856 *ret_sd = NULL;
858 acl = talloc(req, struct xattr_NTACL);
859 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(acl, tmp_ctx);
861 status = pvfs_acl_load(pvfs, parent, -1, acl);
862 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
863 talloc_free(tmp_ctx);
864 return NT_STATUS_OK;
866 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
868 switch (acl->version) {
869 case 1:
870 parent_sd = acl->info.sd;
871 break;
872 default:
873 talloc_free(tmp_ctx);
874 return NT_STATUS_INVALID_ACL;
877 if (parent_sd == NULL ||
878 parent_sd->dacl == NULL ||
879 parent_sd->dacl->num_aces == 0) {
880 /* go with the default ACL */
881 talloc_free(tmp_ctx);
882 return NT_STATUS_OK;
885 /* create the new sd */
886 sd = security_descriptor_initialise(req);
887 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sd, tmp_ctx);
889 ids = talloc_array(sd, struct id_map, 2);
890 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ids, tmp_ctx);
892 ids[0].xid.id = geteuid();
893 ids[0].xid.type = ID_TYPE_UID;
894 ids[0].sid = NULL;
895 ids[0].status = ID_UNKNOWN;
897 ids[1].xid.id = getegid();
898 ids[1].xid.type = ID_TYPE_GID;
899 ids[1].sid = NULL;
900 ids[1].status = ID_UNKNOWN;
902 ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
903 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ctx, tmp_ctx);
905 status = wbc_xids_to_sids_recv(ctx, &ids);
906 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
908 sd->owner_sid = talloc_steal(sd, ids[0].sid);
909 sd->group_sid = talloc_steal(sd, ids[1].sid);
911 sd->type |= SEC_DESC_DACL_PRESENT;
913 /* fill in the aces from the parent */
914 status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
915 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
917 /* if there is nothing to inherit then we fallback to the
918 default acl */
919 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
920 talloc_free(tmp_ctx);
921 return NT_STATUS_OK;
924 *ret_sd = talloc_steal(mem_ctx, sd);
926 talloc_free(tmp_ctx);
927 return NT_STATUS_OK;
932 setup an ACL on a new file/directory based on the inherited ACL from
933 the parent. If there is no inherited ACL then we don't set anything,
934 as the default ACL applies anyway
936 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
937 struct ntvfs_request *req,
938 struct pvfs_filename *name,
939 int fd)
941 struct xattr_NTACL acl;
942 NTSTATUS status;
943 struct security_descriptor *sd;
944 struct pvfs_filename *parent;
945 bool container;
947 /* form the parents path */
948 status = pvfs_resolve_parent(pvfs, req, name, &parent);
949 NT_STATUS_NOT_OK_RETURN(status);
951 container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
953 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, &sd);
954 if (!NT_STATUS_IS_OK(status)) {
955 talloc_free(parent);
956 return status;
959 if (sd == NULL) {
960 return NT_STATUS_OK;
963 acl.version = 1;
964 acl.info.sd = sd;
966 status = pvfs_acl_save(pvfs, name, fd, &acl);
967 talloc_free(sd);
968 talloc_free(parent);
970 return status;
974 return the maximum allowed access mask
976 NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
977 struct ntvfs_request *req,
978 struct pvfs_filename *name,
979 uint32_t *maximal_access)
981 *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
982 return pvfs_access_check(pvfs, req, name, maximal_access);