2 Unix SMB/CIFS implementation.
4 POSIX NTVFS backend - ACL support
6 Copyright (C) Andrew Tridgell 2004
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "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"
36 #define uwrap_enabled() 0
39 /* the list of currently registered ACL backends */
40 static struct pvfs_acl_backend
{
41 const struct pvfs_acl_ops
*ops
;
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
;
70 DEBUG(3,("NTVFS backend '%s' registered\n", ops
->name
));
77 return the operations structure for a named backend
79 const struct pvfs_acl_ops
*pvfs_acl_backend_byname(const char *name
)
83 for (i
=0;i
<num_backends
;i
++) {
84 if (strcmp(backends
[i
].ops
->name
, name
) == 0) {
85 return backends
[i
].ops
;
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
;
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
);
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
;
131 map any generic access bits in the given acl
132 this relies on the fact that the mappings for files and directories
135 static void pvfs_translate_generic_bits(struct security_acl
*acl
)
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
;
158 struct security_ace ace
;
161 struct composite_context
*ctx
;
163 *psd
= security_descriptor_initialise(req
);
165 return NT_STATUS_NO_MEMORY
;
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
;
176 ids
[1].xid
.id
= name
->st
.st_gid
;
177 ids
[1].xid
.type
= ID_TYPE_GID
;
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
);
190 sd
->type
|= SEC_DESC_DACL_PRESENT
;
192 mode
= name
->st
.st_mode
;
195 we provide up to 4 ACEs
203 /* setup owner ACE */
204 ace
.type
= SEC_ACE_TYPE_ACCESS_ALLOWED
;
206 ace
.trustee
= *sd
->owner_sid
;
209 if (mode
& S_IRUSR
) {
210 if (mode
& S_IWUSR
) {
211 ace
.access_mask
|= SEC_RIGHTS_FILE_ALL
;
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
;
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
);
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
);
261 omit any security_descriptor elements not specified in the given
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
)) {
275 if (!(secinfo_flags
& SECINFO_SACL
)) {
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
;
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
)) {
309 ids
= talloc(req
, struct id_map
);
310 NT_STATUS_HAVE_NO_MEMORY(ids
);
311 ZERO_STRUCT(ids
->xid
);
313 ids
->status
= ID_UNKNOWN
;
315 new_sd
= info
->set_secdesc
.in
.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
) {
378 if (new_gid
== old_gid
) {
382 /* if there's something to change try it */
383 if (new_uid
!= -1 || new_gid
!= -1) {
386 ret
= chown(name
->full_name
, new_uid
, new_gid
);
388 ret
= fchown(fd
, new_uid
, new_gid
);
390 if (errno
== EPERM
) {
391 if (uwrap_enabled()) {
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
,
398 security_token_has_privilege(req
->session_info
->security_token
,
399 SEC_PRIV_TAKE_OWNERSHIP
)) {
401 privs
= root_privileges();
403 ret
= chown(name
->full_name
, new_uid
, new_gid
);
405 ret
= fchown(fd
, new_uid
, new_gid
);
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
);
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
;
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
)) {
448 normalise_sd_flags(sd
, info
->query_secdesc
.in
.secinfo_flags
);
450 info
->query_secdesc
.out
.sd
= sd
;
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
|
465 SEC_FILE_WRITE_ATTRIBUTE
|
468 SEC_STD_WRITE_OWNER
|
469 SEC_DIR_DELETE_CHILD
))) {
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
)
482 if (getegid() == gid
) {
485 ngroups
= getgroups(0, NULL
);
489 groups
= talloc_array(pvfs
, gid_t
, ngroups
);
490 if (groups
== NULL
) {
493 if (getgroups(ngroups
, groups
) != ngroups
) {
497 for (i
=0; i
<ngroups
; i
++) {
498 if (groups
[i
] == gid
) break;
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
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
;
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
574 *access_mask
|= SEC_FILE_READ_ATTRIBUTE
;
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
;
594 struct security_descriptor
*sd
;
596 /* on SMB2 a blank access mask is always denied */
597 if (pvfs
->ntvfs
->ctx
->protocol
== PROTOCOL_SMB2
&&
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
);
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
)) {
620 return pvfs_access_check_unix(pvfs
, req
, name
, access_mask
);
622 if (!NT_STATUS_IS_OK(status
)) {
626 switch (acl
->version
) {
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
640 *access_mask
|= SEC_FILE_READ_ATTRIBUTE
;
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) {
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
,
672 struct security_descriptor
**sd
)
674 struct pvfs_filename
*parent
;
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
);
688 status
= pvfs_acl_inherited_sd(pvfs
, req
, req
, parent
, container
, sd
);
692 if (!NT_STATUS_IS_OK(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
707 *access_mask
|= SEC_FILE_READ_ATTRIBUTE
;
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
;
724 status
= pvfs_resolve_parent(pvfs
, req
, name
, &parent
);
725 if (!NT_STATUS_IS_OK(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
,
741 return (ace
->flags
& SEC_ACE_FLAG_OBJECT_INHERIT
) != 0;
744 if (ace
->flags
& SEC_ACE_FLAG_CONTAINER_INHERIT
) {
748 if ((ace
->flags
& SEC_ACE_FLAG_OBJECT_INHERIT
) &&
749 !(ace
->flags
& SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
)) {
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
,
768 for (i
=0;i
<parent_sd
->dacl
->num_aces
;i
++) {
769 struct security_ace ace
= parent_sd
->dacl
->aces
[i
];
771 const struct dom_sid
*creator
= NULL
, *new_id
= NULL
;
774 if (!pvfs_inheritable_ace(pvfs
, &ace
, container
)) {
778 orig_flags
= ace
.flags
;
780 /* see the RAW-ACLS inheritance test for details on these rules */
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
) {
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
;
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
;
811 status
= security_descriptor_dacl_add(sd
, &ace
);
812 if (!NT_STATUS_IS_OK(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
);
823 ace
.trustee
= *new_id
;
824 status
= security_descriptor_dacl_add(sd
, &ace
);
827 if (!NT_STATUS_IS_OK(status
)) {
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
,
844 struct ntvfs_request
*req
,
845 struct pvfs_filename
*parent
,
847 struct security_descriptor
**ret_sd
)
849 struct xattr_NTACL
*acl
;
851 struct security_descriptor
*parent_sd
, *sd
;
853 struct composite_context
*ctx
;
854 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
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
);
866 NT_STATUS_NOT_OK_RETURN_AND_FREE(status
, tmp_ctx
);
868 switch (acl
->version
) {
870 parent_sd
= acl
->info
.sd
;
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
);
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
;
895 ids
[0].status
= ID_UNKNOWN
;
897 ids
[1].xid
.id
= getegid();
898 ids
[1].xid
.type
= ID_TYPE_GID
;
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
919 if (sd
->dacl
== NULL
|| sd
->dacl
->num_aces
== 0) {
920 talloc_free(tmp_ctx
);
924 *ret_sd
= talloc_steal(mem_ctx
, sd
);
926 talloc_free(tmp_ctx
);
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
,
941 struct xattr_NTACL acl
;
943 struct security_descriptor
*sd
;
944 struct pvfs_filename
*parent
;
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
)) {
966 status
= pvfs_acl_save(pvfs
, name
, fd
, &acl
);
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
);