Include uid_wrapper correctly.
[Samba/bjacke.git] / source4 / ntvfs / posix / pvfs_acl.c
blobb253b8ab2d4f211019cf5fd98ae937d63d09efac
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 "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;
35 } *backends = NULL;
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;
61 num_backends++;
63 DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
65 return NT_STATUS_OK;
70 return the operations structure for a named backend
72 const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
74 int i;
76 for (i=0;i<num_backends;i++) {
77 if (strcmp(backends[i].ops->name, name) == 0) {
78 return backends[i].ops;
82 return NULL;
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;
94 initialized = true;
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);
103 return NT_STATUS_OK;
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;
119 return access_mask;
124 map any generic access bits in the given acl
125 this relies on the fact that the mappings for files and directories
126 are the same
128 static void pvfs_translate_generic_bits(struct security_acl *acl)
130 unsigned i;
132 if (!acl) return;
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;
150 NTSTATUS status;
151 struct security_ace ace;
152 mode_t mode;
153 struct id_map *ids;
154 struct composite_context *ctx;
156 *psd = security_descriptor_initialise(req);
157 if (*psd == NULL) {
158 return NT_STATUS_NO_MEMORY;
160 sd = *psd;
162 ids = talloc_zero_array(sd, struct id_map, 2);
163 NT_STATUS_HAVE_NO_MEMORY(ids);
165 ids[0].xid.id = name->st.st_uid;
166 ids[0].xid.type = ID_TYPE_UID;
167 ids[0].sid = NULL;
169 ids[1].xid.id = name->st.st_gid;
170 ids[1].xid.type = ID_TYPE_GID;
171 ids[1].sid = NULL;
173 ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
174 NT_STATUS_HAVE_NO_MEMORY(ctx);
176 status = wbc_xids_to_sids_recv(ctx, &ids);
177 NT_STATUS_NOT_OK_RETURN(status);
179 sd->owner_sid = talloc_steal(sd, ids[0].sid);
180 sd->group_sid = talloc_steal(sd, ids[1].sid);
182 talloc_free(ids);
183 sd->type |= SEC_DESC_DACL_PRESENT;
185 mode = name->st.st_mode;
188 we provide up to 4 ACEs
189 - Owner
190 - Group
191 - Everyone
192 - Administrator
196 /* setup owner ACE */
197 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
198 ace.flags = 0;
199 ace.trustee = *sd->owner_sid;
200 ace.access_mask = 0;
202 if (mode & S_IRUSR) {
203 if (mode & S_IWUSR) {
204 ace.access_mask |= SEC_RIGHTS_FILE_ALL;
205 } else {
206 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
209 if (mode & S_IWUSR) {
210 ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
212 if (ace.access_mask) {
213 security_descriptor_dacl_add(sd, &ace);
217 /* setup group ACE */
218 ace.trustee = *sd->group_sid;
219 ace.access_mask = 0;
220 if (mode & S_IRGRP) {
221 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
223 if (mode & S_IWGRP) {
224 /* note that delete is not granted - this matches posix behaviour */
225 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
227 if (ace.access_mask) {
228 security_descriptor_dacl_add(sd, &ace);
231 /* setup other ACE */
232 ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD);
233 ace.access_mask = 0;
234 if (mode & S_IROTH) {
235 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
237 if (mode & S_IWOTH) {
238 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
240 if (ace.access_mask) {
241 security_descriptor_dacl_add(sd, &ace);
244 /* setup system ACE */
245 ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM);
246 ace.access_mask = SEC_RIGHTS_FILE_ALL;
247 security_descriptor_dacl_add(sd, &ace);
249 return NT_STATUS_OK;
254 omit any security_descriptor elements not specified in the given
255 secinfo flags
257 static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
259 if (!(secinfo_flags & SECINFO_OWNER)) {
260 sd->owner_sid = NULL;
262 if (!(secinfo_flags & SECINFO_GROUP)) {
263 sd->group_sid = NULL;
265 if (!(secinfo_flags & SECINFO_DACL)) {
266 sd->dacl = NULL;
268 if (!(secinfo_flags & SECINFO_SACL)) {
269 sd->sacl = NULL;
274 answer a setfileinfo for an ACL
276 NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
277 struct ntvfs_request *req,
278 struct pvfs_filename *name, int fd,
279 uint32_t access_mask,
280 union smb_setfileinfo *info)
282 uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
283 struct security_descriptor *new_sd, *sd, orig_sd;
284 NTSTATUS status = NT_STATUS_NOT_FOUND;
285 uid_t old_uid = -1;
286 gid_t old_gid = -1;
287 uid_t new_uid = -1;
288 gid_t new_gid = -1;
289 struct id_map *ids;
290 struct composite_context *ctx;
292 if (pvfs->acl_ops != NULL) {
293 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
295 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
296 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
298 if (!NT_STATUS_IS_OK(status)) {
299 return status;
302 ids = talloc(req, struct id_map);
303 NT_STATUS_HAVE_NO_MEMORY(ids);
304 ZERO_STRUCT(ids->xid);
305 ids->sid = NULL;
306 ids->status = ID_UNKNOWN;
308 new_sd = info->set_secdesc.in.sd;
309 orig_sd = *sd;
311 old_uid = name->st.st_uid;
312 old_gid = name->st.st_gid;
314 /* only set the elements that have been specified */
315 if (secinfo_flags & SECINFO_OWNER) {
316 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
317 return NT_STATUS_ACCESS_DENIED;
319 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
320 ids->sid = new_sd->owner_sid;
321 ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
322 NT_STATUS_HAVE_NO_MEMORY(ctx);
323 status = wbc_sids_to_xids_recv(ctx, &ids);
324 NT_STATUS_NOT_OK_RETURN(status);
326 if (ids->xid.type == ID_TYPE_BOTH ||
327 ids->xid.type == ID_TYPE_UID) {
328 new_uid = ids->xid.id;
331 sd->owner_sid = new_sd->owner_sid;
333 if (secinfo_flags & SECINFO_GROUP) {
334 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
335 return NT_STATUS_ACCESS_DENIED;
337 if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
338 ids->sid = new_sd->group_sid;
339 ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
340 NT_STATUS_HAVE_NO_MEMORY(ctx);
341 status = wbc_sids_to_xids_recv(ctx, &ids);
342 NT_STATUS_NOT_OK_RETURN(status);
344 if (ids->xid.type == ID_TYPE_BOTH ||
345 ids->xid.type == ID_TYPE_GID) {
346 new_gid = ids->xid.id;
350 sd->group_sid = new_sd->group_sid;
352 if (secinfo_flags & SECINFO_DACL) {
353 if (!(access_mask & SEC_STD_WRITE_DAC)) {
354 return NT_STATUS_ACCESS_DENIED;
356 sd->dacl = new_sd->dacl;
357 pvfs_translate_generic_bits(sd->dacl);
359 if (secinfo_flags & SECINFO_SACL) {
360 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
361 return NT_STATUS_ACCESS_DENIED;
363 sd->sacl = new_sd->sacl;
364 pvfs_translate_generic_bits(sd->sacl);
367 if (new_uid == old_uid) {
368 new_uid = -1;
371 if (new_gid == old_gid) {
372 new_gid = -1;
375 /* if there's something to change try it */
376 if (new_uid != -1 || new_gid != -1) {
377 int ret;
378 if (fd == -1) {
379 ret = chown(name->full_name, new_uid, new_gid);
380 } else {
381 ret = fchown(fd, new_uid, new_gid);
383 if (errno == EPERM) {
384 if (uwrap_enabled()) {
385 ret = 0;
386 } else {
387 /* try again as root if we have SEC_PRIV_RESTORE or
388 SEC_PRIV_TAKE_OWNERSHIP */
389 if (security_token_has_privilege(req->session_info->security_token,
390 SEC_PRIV_RESTORE) ||
391 security_token_has_privilege(req->session_info->security_token,
392 SEC_PRIV_TAKE_OWNERSHIP)) {
393 void *privs;
394 privs = root_privileges();
395 if (fd == -1) {
396 ret = chown(name->full_name, new_uid, new_gid);
397 } else {
398 ret = fchown(fd, new_uid, new_gid);
400 talloc_free(privs);
404 if (ret == -1) {
405 return pvfs_map_errno(pvfs, errno);
409 /* we avoid saving if the sd is the same. This means when clients
410 copy files and end up copying the default sd that we don't
411 needlessly use xattrs */
412 if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
413 status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
416 return status;
421 answer a fileinfo query for the ACL
423 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs,
424 struct ntvfs_request *req,
425 struct pvfs_filename *name, int fd,
426 union smb_fileinfo *info)
428 NTSTATUS status = NT_STATUS_NOT_FOUND;
429 struct security_descriptor *sd;
431 if (pvfs->acl_ops) {
432 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
434 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
435 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
437 if (!NT_STATUS_IS_OK(status)) {
438 return status;
441 normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
443 info->query_secdesc.out.sd = sd;
445 return NT_STATUS_OK;
450 check the read only bit against any of the write access bits
452 static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
454 if ((pvfs->flags & PVFS_FLAG_READONLY) &&
455 (access_mask & (SEC_FILE_WRITE_DATA |
456 SEC_FILE_APPEND_DATA |
457 SEC_FILE_WRITE_EA |
458 SEC_FILE_WRITE_ATTRIBUTE |
459 SEC_STD_DELETE |
460 SEC_STD_WRITE_DAC |
461 SEC_STD_WRITE_OWNER |
462 SEC_DIR_DELETE_CHILD))) {
463 return true;
465 return false;
469 see if we are a member of the appropriate unix group
471 static bool pvfs_group_member(struct pvfs_state *pvfs, gid_t gid)
473 int i, ngroups;
474 gid_t *groups;
475 if (getegid() == gid) {
476 return true;
478 ngroups = getgroups(0, NULL);
479 if (ngroups == 0) {
480 return false;
482 groups = talloc_array(pvfs, gid_t, ngroups);
483 if (groups == NULL) {
484 return false;
486 if (getgroups(ngroups, groups) != ngroups) {
487 talloc_free(groups);
488 return false;
490 for (i=0; i<ngroups; i++) {
491 if (groups[i] == gid) break;
493 talloc_free(groups);
494 return i < ngroups;
498 default access check function based on unix permissions
499 doing this saves on building a full security descriptor
500 for the common case of access check on files with no
501 specific NT ACL
503 If name is NULL then treat as a new file creation
505 static NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
506 struct ntvfs_request *req,
507 struct pvfs_filename *name,
508 uint32_t *access_mask)
510 uid_t uid = geteuid();
511 uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL;
512 struct security_token *token = req->session_info->security_token;
514 if (pvfs_read_only(pvfs, *access_mask)) {
515 return NT_STATUS_ACCESS_DENIED;
518 if (name == NULL || uid == name->st.st_uid) {
519 max_bits |= SEC_STD_ALL;
520 } else if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
521 max_bits |= SEC_STD_DELETE;
524 if (name == NULL ||
525 (name->st.st_mode & S_IWOTH) ||
526 ((name->st.st_mode & S_IWGRP) &&
527 pvfs_group_member(pvfs, name->st.st_gid))) {
528 max_bits |= SEC_STD_ALL;
531 if (uwrap_enabled()) {
532 /* when running with the uid wrapper, files will be created
533 owned by the ruid, but we may have a different simulated
534 euid. We need to force the permission bits as though the
535 files owner matches the euid */
536 max_bits |= SEC_STD_ALL;
539 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
540 *access_mask |= max_bits;
541 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
544 if ((*access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
545 security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
546 max_bits |= SEC_FLAG_SYSTEM_SECURITY;
549 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_RESTORE) &&
550 security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
551 max_bits |= ~(SEC_RIGHTS_PRIV_RESTORE);
553 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_BACKUP) &&
554 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
555 max_bits |= ~(SEC_RIGHTS_PRIV_BACKUP);
558 if (*access_mask & ~max_bits) {
559 DEBUG(0,(__location__ " denied access to '%s' - wanted 0x%08x but got 0x%08x (missing 0x%08x)\n",
560 name?name->full_name:"(new file)", *access_mask, max_bits, *access_mask & ~max_bits));
561 return NT_STATUS_ACCESS_DENIED;
564 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
565 /* on SMB, this bit is always granted, even if not
566 asked for */
567 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
570 return NT_STATUS_OK;
575 check the security descriptor on a file, if any
577 *access_mask is modified with the access actually granted
579 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
580 struct ntvfs_request *req,
581 struct pvfs_filename *name,
582 uint32_t *access_mask)
584 struct security_token *token = req->session_info->security_token;
585 struct xattr_NTACL *acl;
586 NTSTATUS status;
587 struct security_descriptor *sd;
588 bool allow_delete = false;
590 /* on SMB2 a blank access mask is always denied */
591 if (pvfs->ntvfs->ctx->protocol >= PROTOCOL_SMB2_02 &&
592 *access_mask == 0) {
593 return NT_STATUS_ACCESS_DENIED;
596 if (pvfs_read_only(pvfs, *access_mask)) {
597 return NT_STATUS_ACCESS_DENIED;
600 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
601 *access_mask & SEC_STD_DELETE) {
602 status = pvfs_access_check_parent(pvfs, req,
603 name, SEC_DIR_DELETE_CHILD);
604 if (NT_STATUS_IS_OK(status)) {
605 allow_delete = true;
606 *access_mask &= ~SEC_STD_DELETE;
610 acl = talloc(req, struct xattr_NTACL);
611 if (acl == NULL) {
612 return NT_STATUS_NO_MEMORY;
615 /* expand the generic access bits to file specific bits */
616 *access_mask = pvfs_translate_mask(*access_mask);
617 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
618 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
621 status = pvfs_acl_load(pvfs, name, -1, acl);
622 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
623 talloc_free(acl);
624 status = pvfs_access_check_unix(pvfs, req, name, access_mask);
625 goto done;
627 if (!NT_STATUS_IS_OK(status)) {
628 return status;
631 switch (acl->version) {
632 case 1:
633 sd = acl->info.sd;
634 break;
635 default:
636 return NT_STATUS_INVALID_ACL;
639 /* check the acl against the required access mask */
640 status = se_access_check(sd, token, *access_mask, access_mask);
641 talloc_free(acl);
642 done:
643 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
644 /* on SMB, this bit is always granted, even if not
645 asked for */
646 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
649 if (allow_delete) {
650 *access_mask |= SEC_STD_DELETE;
653 return status;
658 a simplified interface to access check, designed for calls that
659 do not take or return an access check mask
661 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs,
662 struct ntvfs_request *req,
663 struct pvfs_filename *name,
664 uint32_t access_needed)
666 if (access_needed == 0) {
667 return NT_STATUS_OK;
669 return pvfs_access_check(pvfs, req, name, &access_needed);
673 access check for creating a new file/directory
675 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs,
676 struct ntvfs_request *req,
677 struct pvfs_filename *name,
678 uint32_t *access_mask,
679 bool container,
680 struct security_descriptor **sd)
682 struct pvfs_filename *parent;
683 NTSTATUS status;
684 uint32_t parent_mask;
685 bool allow_delete = false;
687 if (pvfs_read_only(pvfs, *access_mask)) {
688 return NT_STATUS_ACCESS_DENIED;
691 status = pvfs_resolve_parent(pvfs, req, name, &parent);
692 NT_STATUS_NOT_OK_RETURN(status);
694 if (container) {
695 parent_mask = SEC_DIR_ADD_SUBDIR;
696 } else {
697 parent_mask = SEC_DIR_ADD_FILE;
699 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
700 *access_mask & SEC_STD_DELETE) {
701 parent_mask |= SEC_DIR_DELETE_CHILD;
704 status = pvfs_access_check(pvfs, req, parent, &parent_mask);
705 if (NT_STATUS_IS_OK(status)) {
706 if (parent_mask & SEC_DIR_DELETE_CHILD) {
707 allow_delete = true;
709 } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
711 * on ACCESS_DENIED we get the rejected bits
712 * remove the non critical SEC_DIR_DELETE_CHILD
713 * and check if something else was rejected.
715 parent_mask &= ~SEC_DIR_DELETE_CHILD;
716 if (parent_mask != 0) {
717 return NT_STATUS_ACCESS_DENIED;
719 status = NT_STATUS_OK;
720 } else {
721 return status;
724 if (*sd == NULL) {
725 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, sd);
728 talloc_free(parent);
729 if (!NT_STATUS_IS_OK(status)) {
730 return status;
733 /* expand the generic access bits to file specific bits */
734 *access_mask = pvfs_translate_mask(*access_mask);
736 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
737 *access_mask |= SEC_RIGHTS_FILE_ALL;
738 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
741 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
742 /* on SMB, this bit is always granted, even if not
743 asked for */
744 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
747 if (allow_delete) {
748 *access_mask |= SEC_STD_DELETE;
751 return NT_STATUS_OK;
755 access check for creating a new file/directory - no access mask supplied
757 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs,
758 struct ntvfs_request *req,
759 struct pvfs_filename *name,
760 uint32_t access_mask)
762 struct pvfs_filename *parent;
763 NTSTATUS status;
765 status = pvfs_resolve_parent(pvfs, req, name, &parent);
766 if (!NT_STATUS_IS_OK(status)) {
767 return status;
770 return pvfs_access_check_simple(pvfs, req, parent, access_mask);
775 determine if an ACE is inheritable
777 static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
778 const struct security_ace *ace,
779 bool container)
781 if (!container) {
782 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
785 if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
786 return true;
789 if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
790 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
791 return true;
794 return false;
798 this is the core of ACL inheritance. It copies any inheritable
799 aces from the parent SD to the child SD. Note that the algorithm
800 depends on whether the child is a container or not
802 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs,
803 struct security_descriptor *parent_sd,
804 struct security_descriptor *sd,
805 bool container)
807 int i;
809 for (i=0;i<parent_sd->dacl->num_aces;i++) {
810 struct security_ace ace = parent_sd->dacl->aces[i];
811 NTSTATUS status;
812 const struct dom_sid *creator = NULL, *new_id = NULL;
813 uint32_t orig_flags;
815 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
816 continue;
819 orig_flags = ace.flags;
821 /* see the RAW-ACLS inheritance test for details on these rules */
822 if (!container) {
823 ace.flags = 0;
824 } else {
825 ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
827 if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
828 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
830 if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
831 ace.flags = 0;
835 /* the CREATOR sids are special when inherited */
836 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
837 creator = pvfs->sid_cache.creator_owner;
838 new_id = sd->owner_sid;
839 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
840 creator = pvfs->sid_cache.creator_group;
841 new_id = sd->group_sid;
842 } else {
843 new_id = &ace.trustee;
846 if (creator && container &&
847 (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
848 uint32_t flags = ace.flags;
850 ace.trustee = *new_id;
851 ace.flags = 0;
852 status = security_descriptor_dacl_add(sd, &ace);
853 if (!NT_STATUS_IS_OK(status)) {
854 return status;
857 ace.trustee = *creator;
858 ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
859 status = security_descriptor_dacl_add(sd, &ace);
860 } else if (container &&
861 !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
862 status = security_descriptor_dacl_add(sd, &ace);
863 } else {
864 ace.trustee = *new_id;
865 status = security_descriptor_dacl_add(sd, &ace);
868 if (!NT_STATUS_IS_OK(status)) {
869 return status;
873 return NT_STATUS_OK;
879 calculate the ACL on a new file/directory based on the inherited ACL
880 from the parent. If there is no inherited ACL then return a NULL
881 ACL, which means the default ACL should be used
883 NTSTATUS pvfs_acl_inherited_sd(struct pvfs_state *pvfs,
884 TALLOC_CTX *mem_ctx,
885 struct ntvfs_request *req,
886 struct pvfs_filename *parent,
887 bool container,
888 struct security_descriptor **ret_sd)
890 struct xattr_NTACL *acl;
891 NTSTATUS status;
892 struct security_descriptor *parent_sd, *sd;
893 struct id_map *ids;
894 struct composite_context *ctx;
895 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
897 *ret_sd = NULL;
899 acl = talloc(req, struct xattr_NTACL);
900 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(acl, tmp_ctx);
902 status = pvfs_acl_load(pvfs, parent, -1, acl);
903 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
904 talloc_free(tmp_ctx);
905 return NT_STATUS_OK;
907 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
909 switch (acl->version) {
910 case 1:
911 parent_sd = acl->info.sd;
912 break;
913 default:
914 talloc_free(tmp_ctx);
915 return NT_STATUS_INVALID_ACL;
918 if (parent_sd == NULL ||
919 parent_sd->dacl == NULL ||
920 parent_sd->dacl->num_aces == 0) {
921 /* go with the default ACL */
922 talloc_free(tmp_ctx);
923 return NT_STATUS_OK;
926 /* create the new sd */
927 sd = security_descriptor_initialise(req);
928 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sd, tmp_ctx);
930 ids = talloc_array(sd, struct id_map, 2);
931 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ids, tmp_ctx);
933 ids[0].xid.id = geteuid();
934 ids[0].xid.type = ID_TYPE_UID;
935 ids[0].sid = NULL;
936 ids[0].status = ID_UNKNOWN;
938 ids[1].xid.id = getegid();
939 ids[1].xid.type = ID_TYPE_GID;
940 ids[1].sid = NULL;
941 ids[1].status = ID_UNKNOWN;
943 ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
944 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ctx, tmp_ctx);
946 status = wbc_xids_to_sids_recv(ctx, &ids);
947 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
949 sd->owner_sid = talloc_steal(sd, ids[0].sid);
950 sd->group_sid = talloc_steal(sd, ids[1].sid);
952 sd->type |= SEC_DESC_DACL_PRESENT;
954 /* fill in the aces from the parent */
955 status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
956 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
958 /* if there is nothing to inherit then we fallback to the
959 default acl */
960 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
961 talloc_free(tmp_ctx);
962 return NT_STATUS_OK;
965 *ret_sd = talloc_steal(mem_ctx, sd);
967 talloc_free(tmp_ctx);
968 return NT_STATUS_OK;
973 setup an ACL on a new file/directory based on the inherited ACL from
974 the parent. If there is no inherited ACL then we don't set anything,
975 as the default ACL applies anyway
977 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
978 struct ntvfs_request *req,
979 struct pvfs_filename *name,
980 int fd)
982 struct xattr_NTACL acl;
983 NTSTATUS status;
984 struct security_descriptor *sd;
985 struct pvfs_filename *parent;
986 bool container;
988 /* form the parents path */
989 status = pvfs_resolve_parent(pvfs, req, name, &parent);
990 NT_STATUS_NOT_OK_RETURN(status);
992 container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
994 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, &sd);
995 if (!NT_STATUS_IS_OK(status)) {
996 talloc_free(parent);
997 return status;
1000 if (sd == NULL) {
1001 return NT_STATUS_OK;
1004 acl.version = 1;
1005 acl.info.sd = sd;
1007 status = pvfs_acl_save(pvfs, name, fd, &acl);
1008 talloc_free(sd);
1009 talloc_free(parent);
1011 return status;
1015 return the maximum allowed access mask
1017 NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
1018 struct ntvfs_request *req,
1019 struct pvfs_filename *name,
1020 uint32_t *maximal_access)
1022 *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
1023 return pvfs_access_check(pvfs, req, name, maximal_access);