lib/util: consolidate module loading into common code
[Samba/gebeck_regimport.git] / source4 / ntvfs / posix / pvfs_acl.c
blob8157d862ec2fdb06d911428ebff5091dd961c87b
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"
29 #include "lib/util/samba_modules.h"
31 #if defined(UID_WRAPPER)
32 #if !defined(UID_WRAPPER_REPLACE) && !defined(UID_WRAPPER_NOT_REPLACE)
33 #define UID_WRAPPER_REPLACE
34 #include "../uid_wrapper/uid_wrapper.h"
35 #endif
36 #else
37 #define uwrap_enabled() 0
38 #endif
40 /* the list of currently registered ACL backends */
41 static struct pvfs_acl_backend {
42 const struct pvfs_acl_ops *ops;
43 } *backends = NULL;
44 static int num_backends;
47 register a pvfs acl backend.
49 The 'name' can be later used by other backends to find the operations
50 structure for this backend.
52 NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops)
54 struct pvfs_acl_ops *new_ops;
56 if (pvfs_acl_backend_byname(ops->name) != NULL) {
57 DEBUG(0,("pvfs acl backend '%s' already registered\n", ops->name));
58 return NT_STATUS_OBJECT_NAME_COLLISION;
61 backends = talloc_realloc(talloc_autofree_context(), backends, struct pvfs_acl_backend, num_backends+1);
62 NT_STATUS_HAVE_NO_MEMORY(backends);
64 new_ops = (struct pvfs_acl_ops *)talloc_memdup(backends, ops, sizeof(*ops));
65 new_ops->name = talloc_strdup(new_ops, ops->name);
67 backends[num_backends].ops = new_ops;
69 num_backends++;
71 DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
73 return NT_STATUS_OK;
78 return the operations structure for a named backend
80 const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
82 int i;
84 for (i=0;i<num_backends;i++) {
85 if (strcmp(backends[i].ops->name, name) == 0) {
86 return backends[i].ops;
90 return NULL;
93 NTSTATUS pvfs_acl_init(void)
95 static bool initialized = false;
96 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
97 STATIC_pvfs_acl_MODULES_PROTO;
98 init_module_fn static_init[] = { STATIC_pvfs_acl_MODULES };
99 init_module_fn *shared_init;
101 if (initialized) return NT_STATUS_OK;
102 initialized = true;
104 shared_init = load_samba_modules(NULL, "pvfs_acl");
106 run_init_functions(static_init);
107 run_init_functions(shared_init);
109 talloc_free(shared_init);
111 return NT_STATUS_OK;
116 map a single access_mask from generic to specific bits for files/dirs
118 static uint32_t pvfs_translate_mask(uint32_t access_mask)
120 if (access_mask & SEC_MASK_GENERIC) {
121 if (access_mask & SEC_GENERIC_READ) access_mask |= SEC_RIGHTS_FILE_READ;
122 if (access_mask & SEC_GENERIC_WRITE) access_mask |= SEC_RIGHTS_FILE_WRITE;
123 if (access_mask & SEC_GENERIC_EXECUTE) access_mask |= SEC_RIGHTS_FILE_EXECUTE;
124 if (access_mask & SEC_GENERIC_ALL) access_mask |= SEC_RIGHTS_FILE_ALL;
125 access_mask &= ~SEC_MASK_GENERIC;
127 return access_mask;
132 map any generic access bits in the given acl
133 this relies on the fact that the mappings for files and directories
134 are the same
136 static void pvfs_translate_generic_bits(struct security_acl *acl)
138 unsigned i;
140 if (!acl) return;
142 for (i=0;i<acl->num_aces;i++) {
143 struct security_ace *ace = &acl->aces[i];
144 ace->access_mask = pvfs_translate_mask(ace->access_mask);
150 setup a default ACL for a file
152 static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
153 struct ntvfs_request *req,
154 struct pvfs_filename *name, int fd,
155 struct security_descriptor **psd)
157 struct security_descriptor *sd;
158 NTSTATUS status;
159 struct security_ace ace;
160 mode_t mode;
161 struct id_map *ids;
162 struct composite_context *ctx;
164 *psd = security_descriptor_initialise(req);
165 if (*psd == NULL) {
166 return NT_STATUS_NO_MEMORY;
168 sd = *psd;
170 ids = talloc_zero_array(sd, struct id_map, 2);
171 NT_STATUS_HAVE_NO_MEMORY(ids);
173 ids[0].xid.id = name->st.st_uid;
174 ids[0].xid.type = ID_TYPE_UID;
175 ids[0].sid = NULL;
177 ids[1].xid.id = name->st.st_gid;
178 ids[1].xid.type = ID_TYPE_GID;
179 ids[1].sid = NULL;
181 ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
182 NT_STATUS_HAVE_NO_MEMORY(ctx);
184 status = wbc_xids_to_sids_recv(ctx, &ids);
185 NT_STATUS_NOT_OK_RETURN(status);
187 sd->owner_sid = talloc_steal(sd, ids[0].sid);
188 sd->group_sid = talloc_steal(sd, ids[1].sid);
190 talloc_free(ids);
191 sd->type |= SEC_DESC_DACL_PRESENT;
193 mode = name->st.st_mode;
196 we provide up to 4 ACEs
197 - Owner
198 - Group
199 - Everyone
200 - Administrator
204 /* setup owner ACE */
205 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
206 ace.flags = 0;
207 ace.trustee = *sd->owner_sid;
208 ace.access_mask = 0;
210 if (mode & S_IRUSR) {
211 if (mode & S_IWUSR) {
212 ace.access_mask |= SEC_RIGHTS_FILE_ALL;
213 } else {
214 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
217 if (mode & S_IWUSR) {
218 ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
220 if (ace.access_mask) {
221 security_descriptor_dacl_add(sd, &ace);
225 /* setup group ACE */
226 ace.trustee = *sd->group_sid;
227 ace.access_mask = 0;
228 if (mode & S_IRGRP) {
229 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
231 if (mode & S_IWGRP) {
232 /* note that delete is not granted - this matches posix behaviour */
233 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
235 if (ace.access_mask) {
236 security_descriptor_dacl_add(sd, &ace);
239 /* setup other ACE */
240 ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD);
241 ace.access_mask = 0;
242 if (mode & S_IROTH) {
243 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
245 if (mode & S_IWOTH) {
246 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
248 if (ace.access_mask) {
249 security_descriptor_dacl_add(sd, &ace);
252 /* setup system ACE */
253 ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM);
254 ace.access_mask = SEC_RIGHTS_FILE_ALL;
255 security_descriptor_dacl_add(sd, &ace);
257 return NT_STATUS_OK;
262 omit any security_descriptor elements not specified in the given
263 secinfo flags
265 static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
267 if (!(secinfo_flags & SECINFO_OWNER)) {
268 sd->owner_sid = NULL;
270 if (!(secinfo_flags & SECINFO_GROUP)) {
271 sd->group_sid = NULL;
273 if (!(secinfo_flags & SECINFO_DACL)) {
274 sd->dacl = NULL;
276 if (!(secinfo_flags & SECINFO_SACL)) {
277 sd->sacl = NULL;
282 answer a setfileinfo for an ACL
284 NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
285 struct ntvfs_request *req,
286 struct pvfs_filename *name, int fd,
287 uint32_t access_mask,
288 union smb_setfileinfo *info)
290 uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
291 struct security_descriptor *new_sd, *sd, orig_sd;
292 NTSTATUS status = NT_STATUS_NOT_FOUND;
293 uid_t old_uid = -1;
294 gid_t old_gid = -1;
295 uid_t new_uid = -1;
296 gid_t new_gid = -1;
297 struct id_map *ids;
298 struct composite_context *ctx;
300 if (pvfs->acl_ops != NULL) {
301 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
303 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
304 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
306 if (!NT_STATUS_IS_OK(status)) {
307 return status;
310 ids = talloc(req, struct id_map);
311 NT_STATUS_HAVE_NO_MEMORY(ids);
312 ZERO_STRUCT(ids->xid);
313 ids->sid = NULL;
314 ids->status = ID_UNKNOWN;
316 new_sd = info->set_secdesc.in.sd;
317 orig_sd = *sd;
319 old_uid = name->st.st_uid;
320 old_gid = name->st.st_gid;
322 /* only set the elements that have been specified */
323 if (secinfo_flags & SECINFO_OWNER) {
324 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
325 return NT_STATUS_ACCESS_DENIED;
327 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
328 ids->sid = new_sd->owner_sid;
329 ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
330 NT_STATUS_HAVE_NO_MEMORY(ctx);
331 status = wbc_sids_to_xids_recv(ctx, &ids);
332 NT_STATUS_NOT_OK_RETURN(status);
334 if (ids->xid.type == ID_TYPE_BOTH ||
335 ids->xid.type == ID_TYPE_UID) {
336 new_uid = ids->xid.id;
339 sd->owner_sid = new_sd->owner_sid;
341 if (secinfo_flags & SECINFO_GROUP) {
342 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
343 return NT_STATUS_ACCESS_DENIED;
345 if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
346 ids->sid = new_sd->group_sid;
347 ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
348 NT_STATUS_HAVE_NO_MEMORY(ctx);
349 status = wbc_sids_to_xids_recv(ctx, &ids);
350 NT_STATUS_NOT_OK_RETURN(status);
352 if (ids->xid.type == ID_TYPE_BOTH ||
353 ids->xid.type == ID_TYPE_GID) {
354 new_gid = ids->xid.id;
358 sd->group_sid = new_sd->group_sid;
360 if (secinfo_flags & SECINFO_DACL) {
361 if (!(access_mask & SEC_STD_WRITE_DAC)) {
362 return NT_STATUS_ACCESS_DENIED;
364 sd->dacl = new_sd->dacl;
365 pvfs_translate_generic_bits(sd->dacl);
367 if (secinfo_flags & SECINFO_SACL) {
368 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
369 return NT_STATUS_ACCESS_DENIED;
371 sd->sacl = new_sd->sacl;
372 pvfs_translate_generic_bits(sd->sacl);
375 if (new_uid == old_uid) {
376 new_uid = -1;
379 if (new_gid == old_gid) {
380 new_gid = -1;
383 /* if there's something to change try it */
384 if (new_uid != -1 || new_gid != -1) {
385 int ret;
386 if (fd == -1) {
387 ret = chown(name->full_name, new_uid, new_gid);
388 } else {
389 ret = fchown(fd, new_uid, new_gid);
391 if (errno == EPERM) {
392 if (uwrap_enabled()) {
393 ret = 0;
394 } else {
395 /* try again as root if we have SEC_PRIV_RESTORE or
396 SEC_PRIV_TAKE_OWNERSHIP */
397 if (security_token_has_privilege(req->session_info->security_token,
398 SEC_PRIV_RESTORE) ||
399 security_token_has_privilege(req->session_info->security_token,
400 SEC_PRIV_TAKE_OWNERSHIP)) {
401 void *privs;
402 privs = root_privileges();
403 if (fd == -1) {
404 ret = chown(name->full_name, new_uid, new_gid);
405 } else {
406 ret = fchown(fd, new_uid, new_gid);
408 talloc_free(privs);
412 if (ret == -1) {
413 return pvfs_map_errno(pvfs, errno);
417 /* we avoid saving if the sd is the same. This means when clients
418 copy files and end up copying the default sd that we don't
419 needlessly use xattrs */
420 if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
421 status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
424 return status;
429 answer a fileinfo query for the ACL
431 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs,
432 struct ntvfs_request *req,
433 struct pvfs_filename *name, int fd,
434 union smb_fileinfo *info)
436 NTSTATUS status = NT_STATUS_NOT_FOUND;
437 struct security_descriptor *sd;
439 if (pvfs->acl_ops) {
440 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
442 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
443 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
445 if (!NT_STATUS_IS_OK(status)) {
446 return status;
449 normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
451 info->query_secdesc.out.sd = sd;
453 return NT_STATUS_OK;
458 check the read only bit against any of the write access bits
460 static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
462 if ((pvfs->flags & PVFS_FLAG_READONLY) &&
463 (access_mask & (SEC_FILE_WRITE_DATA |
464 SEC_FILE_APPEND_DATA |
465 SEC_FILE_WRITE_EA |
466 SEC_FILE_WRITE_ATTRIBUTE |
467 SEC_STD_DELETE |
468 SEC_STD_WRITE_DAC |
469 SEC_STD_WRITE_OWNER |
470 SEC_DIR_DELETE_CHILD))) {
471 return true;
473 return false;
477 see if we are a member of the appropriate unix group
479 static bool pvfs_group_member(struct pvfs_state *pvfs, gid_t gid)
481 int i, ngroups;
482 gid_t *groups;
483 if (getegid() == gid) {
484 return true;
486 ngroups = getgroups(0, NULL);
487 if (ngroups == 0) {
488 return false;
490 groups = talloc_array(pvfs, gid_t, ngroups);
491 if (groups == NULL) {
492 return false;
494 if (getgroups(ngroups, groups) != ngroups) {
495 talloc_free(groups);
496 return false;
498 for (i=0; i<ngroups; i++) {
499 if (groups[i] == gid) break;
501 talloc_free(groups);
502 return i < ngroups;
506 default access check function based on unix permissions
507 doing this saves on building a full security descriptor
508 for the common case of access check on files with no
509 specific NT ACL
511 If name is NULL then treat as a new file creation
513 static NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
514 struct ntvfs_request *req,
515 struct pvfs_filename *name,
516 uint32_t *access_mask)
518 uid_t uid = geteuid();
519 uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL;
520 struct security_token *token = req->session_info->security_token;
522 if (pvfs_read_only(pvfs, *access_mask)) {
523 return NT_STATUS_ACCESS_DENIED;
526 if (name == NULL || uid == name->st.st_uid) {
527 max_bits |= SEC_STD_ALL;
528 } else if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
529 max_bits |= SEC_STD_DELETE;
532 if (name == NULL ||
533 (name->st.st_mode & S_IWOTH) ||
534 ((name->st.st_mode & S_IWGRP) &&
535 pvfs_group_member(pvfs, name->st.st_gid))) {
536 max_bits |= SEC_STD_ALL;
539 if (uwrap_enabled()) {
540 /* when running with the uid wrapper, files will be created
541 owned by the ruid, but we may have a different simulated
542 euid. We need to force the permission bits as though the
543 files owner matches the euid */
544 max_bits |= SEC_STD_ALL;
547 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
548 *access_mask |= max_bits;
549 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
552 if ((*access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
553 security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
554 max_bits |= SEC_FLAG_SYSTEM_SECURITY;
557 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_RESTORE) &&
558 security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
559 max_bits |= ~(SEC_RIGHTS_PRIV_RESTORE);
561 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_BACKUP) &&
562 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
563 max_bits |= ~(SEC_RIGHTS_PRIV_BACKUP);
566 if (*access_mask & ~max_bits) {
567 DEBUG(0,(__location__ " denied access to '%s' - wanted 0x%08x but got 0x%08x (missing 0x%08x)\n",
568 name?name->full_name:"(new file)", *access_mask, max_bits, *access_mask & ~max_bits));
569 return NT_STATUS_ACCESS_DENIED;
572 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
573 /* on SMB, this bit is always granted, even if not
574 asked for */
575 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
578 return NT_STATUS_OK;
583 check the security descriptor on a file, if any
585 *access_mask is modified with the access actually granted
587 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
588 struct ntvfs_request *req,
589 struct pvfs_filename *name,
590 uint32_t *access_mask)
592 struct security_token *token = req->session_info->security_token;
593 struct xattr_NTACL *acl;
594 NTSTATUS status;
595 struct security_descriptor *sd;
596 bool allow_delete = false;
598 /* on SMB2 a blank access mask is always denied */
599 if (pvfs->ntvfs->ctx->protocol >= PROTOCOL_SMB2_02 &&
600 *access_mask == 0) {
601 return NT_STATUS_ACCESS_DENIED;
604 if (pvfs_read_only(pvfs, *access_mask)) {
605 return NT_STATUS_ACCESS_DENIED;
608 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
609 *access_mask & SEC_STD_DELETE) {
610 status = pvfs_access_check_parent(pvfs, req,
611 name, SEC_DIR_DELETE_CHILD);
612 if (NT_STATUS_IS_OK(status)) {
613 allow_delete = true;
614 *access_mask &= ~SEC_STD_DELETE;
618 acl = talloc(req, struct xattr_NTACL);
619 if (acl == NULL) {
620 return NT_STATUS_NO_MEMORY;
623 /* expand the generic access bits to file specific bits */
624 *access_mask = pvfs_translate_mask(*access_mask);
625 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
626 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
629 status = pvfs_acl_load(pvfs, name, -1, acl);
630 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
631 talloc_free(acl);
632 status = pvfs_access_check_unix(pvfs, req, name, access_mask);
633 goto done;
635 if (!NT_STATUS_IS_OK(status)) {
636 return status;
639 switch (acl->version) {
640 case 1:
641 sd = acl->info.sd;
642 break;
643 default:
644 return NT_STATUS_INVALID_ACL;
647 /* check the acl against the required access mask */
648 status = se_access_check(sd, token, *access_mask, access_mask);
649 talloc_free(acl);
650 done:
651 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
652 /* on SMB, this bit is always granted, even if not
653 asked for */
654 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
657 if (allow_delete) {
658 *access_mask |= SEC_STD_DELETE;
661 return status;
666 a simplified interface to access check, designed for calls that
667 do not take or return an access check mask
669 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs,
670 struct ntvfs_request *req,
671 struct pvfs_filename *name,
672 uint32_t access_needed)
674 if (access_needed == 0) {
675 return NT_STATUS_OK;
677 return pvfs_access_check(pvfs, req, name, &access_needed);
681 access check for creating a new file/directory
683 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs,
684 struct ntvfs_request *req,
685 struct pvfs_filename *name,
686 uint32_t *access_mask,
687 bool container,
688 struct security_descriptor **sd)
690 struct pvfs_filename *parent;
691 NTSTATUS status;
692 uint32_t parent_mask;
693 bool allow_delete = false;
695 if (pvfs_read_only(pvfs, *access_mask)) {
696 return NT_STATUS_ACCESS_DENIED;
699 status = pvfs_resolve_parent(pvfs, req, name, &parent);
700 NT_STATUS_NOT_OK_RETURN(status);
702 if (container) {
703 parent_mask = SEC_DIR_ADD_SUBDIR;
704 } else {
705 parent_mask = SEC_DIR_ADD_FILE;
707 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
708 *access_mask & SEC_STD_DELETE) {
709 parent_mask |= SEC_DIR_DELETE_CHILD;
712 status = pvfs_access_check(pvfs, req, parent, &parent_mask);
713 if (NT_STATUS_IS_OK(status)) {
714 if (parent_mask & SEC_DIR_DELETE_CHILD) {
715 allow_delete = true;
717 } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
719 * on ACCESS_DENIED we get the rejected bits
720 * remove the non critical SEC_DIR_DELETE_CHILD
721 * and check if something else was rejected.
723 parent_mask &= ~SEC_DIR_DELETE_CHILD;
724 if (parent_mask != 0) {
725 return NT_STATUS_ACCESS_DENIED;
727 status = NT_STATUS_OK;
728 } else {
729 return status;
732 if (*sd == NULL) {
733 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, sd);
736 talloc_free(parent);
737 if (!NT_STATUS_IS_OK(status)) {
738 return status;
741 /* expand the generic access bits to file specific bits */
742 *access_mask = pvfs_translate_mask(*access_mask);
744 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
745 *access_mask |= SEC_RIGHTS_FILE_ALL;
746 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
749 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
750 /* on SMB, this bit is always granted, even if not
751 asked for */
752 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
755 if (allow_delete) {
756 *access_mask |= SEC_STD_DELETE;
759 return NT_STATUS_OK;
763 access check for creating a new file/directory - no access mask supplied
765 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs,
766 struct ntvfs_request *req,
767 struct pvfs_filename *name,
768 uint32_t access_mask)
770 struct pvfs_filename *parent;
771 NTSTATUS status;
773 status = pvfs_resolve_parent(pvfs, req, name, &parent);
774 if (!NT_STATUS_IS_OK(status)) {
775 return status;
778 return pvfs_access_check_simple(pvfs, req, parent, access_mask);
783 determine if an ACE is inheritable
785 static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
786 const struct security_ace *ace,
787 bool container)
789 if (!container) {
790 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
793 if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
794 return true;
797 if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
798 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
799 return true;
802 return false;
806 this is the core of ACL inheritance. It copies any inheritable
807 aces from the parent SD to the child SD. Note that the algorithm
808 depends on whether the child is a container or not
810 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs,
811 struct security_descriptor *parent_sd,
812 struct security_descriptor *sd,
813 bool container)
815 int i;
817 for (i=0;i<parent_sd->dacl->num_aces;i++) {
818 struct security_ace ace = parent_sd->dacl->aces[i];
819 NTSTATUS status;
820 const struct dom_sid *creator = NULL, *new_id = NULL;
821 uint32_t orig_flags;
823 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
824 continue;
827 orig_flags = ace.flags;
829 /* see the RAW-ACLS inheritance test for details on these rules */
830 if (!container) {
831 ace.flags = 0;
832 } else {
833 ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
835 if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
836 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
838 if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
839 ace.flags = 0;
843 /* the CREATOR sids are special when inherited */
844 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
845 creator = pvfs->sid_cache.creator_owner;
846 new_id = sd->owner_sid;
847 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
848 creator = pvfs->sid_cache.creator_group;
849 new_id = sd->group_sid;
850 } else {
851 new_id = &ace.trustee;
854 if (creator && container &&
855 (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
856 uint32_t flags = ace.flags;
858 ace.trustee = *new_id;
859 ace.flags = 0;
860 status = security_descriptor_dacl_add(sd, &ace);
861 if (!NT_STATUS_IS_OK(status)) {
862 return status;
865 ace.trustee = *creator;
866 ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
867 status = security_descriptor_dacl_add(sd, &ace);
868 } else if (container &&
869 !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
870 status = security_descriptor_dacl_add(sd, &ace);
871 } else {
872 ace.trustee = *new_id;
873 status = security_descriptor_dacl_add(sd, &ace);
876 if (!NT_STATUS_IS_OK(status)) {
877 return status;
881 return NT_STATUS_OK;
887 calculate the ACL on a new file/directory based on the inherited ACL
888 from the parent. If there is no inherited ACL then return a NULL
889 ACL, which means the default ACL should be used
891 NTSTATUS pvfs_acl_inherited_sd(struct pvfs_state *pvfs,
892 TALLOC_CTX *mem_ctx,
893 struct ntvfs_request *req,
894 struct pvfs_filename *parent,
895 bool container,
896 struct security_descriptor **ret_sd)
898 struct xattr_NTACL *acl;
899 NTSTATUS status;
900 struct security_descriptor *parent_sd, *sd;
901 struct id_map *ids;
902 struct composite_context *ctx;
903 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
905 *ret_sd = NULL;
907 acl = talloc(req, struct xattr_NTACL);
908 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(acl, tmp_ctx);
910 status = pvfs_acl_load(pvfs, parent, -1, acl);
911 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
912 talloc_free(tmp_ctx);
913 return NT_STATUS_OK;
915 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
917 switch (acl->version) {
918 case 1:
919 parent_sd = acl->info.sd;
920 break;
921 default:
922 talloc_free(tmp_ctx);
923 return NT_STATUS_INVALID_ACL;
926 if (parent_sd == NULL ||
927 parent_sd->dacl == NULL ||
928 parent_sd->dacl->num_aces == 0) {
929 /* go with the default ACL */
930 talloc_free(tmp_ctx);
931 return NT_STATUS_OK;
934 /* create the new sd */
935 sd = security_descriptor_initialise(req);
936 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sd, tmp_ctx);
938 ids = talloc_array(sd, struct id_map, 2);
939 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ids, tmp_ctx);
941 ids[0].xid.id = geteuid();
942 ids[0].xid.type = ID_TYPE_UID;
943 ids[0].sid = NULL;
944 ids[0].status = ID_UNKNOWN;
946 ids[1].xid.id = getegid();
947 ids[1].xid.type = ID_TYPE_GID;
948 ids[1].sid = NULL;
949 ids[1].status = ID_UNKNOWN;
951 ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
952 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ctx, tmp_ctx);
954 status = wbc_xids_to_sids_recv(ctx, &ids);
955 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
957 sd->owner_sid = talloc_steal(sd, ids[0].sid);
958 sd->group_sid = talloc_steal(sd, ids[1].sid);
960 sd->type |= SEC_DESC_DACL_PRESENT;
962 /* fill in the aces from the parent */
963 status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
964 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
966 /* if there is nothing to inherit then we fallback to the
967 default acl */
968 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
969 talloc_free(tmp_ctx);
970 return NT_STATUS_OK;
973 *ret_sd = talloc_steal(mem_ctx, sd);
975 talloc_free(tmp_ctx);
976 return NT_STATUS_OK;
981 setup an ACL on a new file/directory based on the inherited ACL from
982 the parent. If there is no inherited ACL then we don't set anything,
983 as the default ACL applies anyway
985 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
986 struct ntvfs_request *req,
987 struct pvfs_filename *name,
988 int fd)
990 struct xattr_NTACL acl;
991 NTSTATUS status;
992 struct security_descriptor *sd;
993 struct pvfs_filename *parent;
994 bool container;
996 /* form the parents path */
997 status = pvfs_resolve_parent(pvfs, req, name, &parent);
998 NT_STATUS_NOT_OK_RETURN(status);
1000 container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
1002 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, &sd);
1003 if (!NT_STATUS_IS_OK(status)) {
1004 talloc_free(parent);
1005 return status;
1008 if (sd == NULL) {
1009 return NT_STATUS_OK;
1012 acl.version = 1;
1013 acl.info.sd = sd;
1015 status = pvfs_acl_save(pvfs, name, fd, &acl);
1016 talloc_free(sd);
1017 talloc_free(parent);
1019 return status;
1023 return the maximum allowed access mask
1025 NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
1026 struct ntvfs_request *req,
1027 struct pvfs_filename *name,
1028 uint32_t *maximal_access)
1030 *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
1031 return pvfs_access_check(pvfs, req, name, maximal_access);