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 "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
;
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
;
63 DEBUG(3,("NTVFS backend '%s' registered\n", ops
->name
));
70 return the operations structure for a named backend
72 const struct pvfs_acl_ops
*pvfs_acl_backend_byname(const char *name
)
76 for (i
=0;i
<num_backends
;i
++) {
77 if (strcmp(backends
[i
].ops
->name
, name
) == 0) {
78 return backends
[i
].ops
;
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
;
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
);
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
;
124 map any generic access bits in the given acl
125 this relies on the fact that the mappings for files and directories
128 static void pvfs_translate_generic_bits(struct security_acl
*acl
)
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
;
151 struct security_ace ace
;
154 struct composite_context
*ctx
;
156 *psd
= security_descriptor_initialise(req
);
158 return NT_STATUS_NO_MEMORY
;
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
;
169 ids
[1].xid
.id
= name
->st
.st_gid
;
170 ids
[1].xid
.type
= ID_TYPE_GID
;
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
);
183 sd
->type
|= SEC_DESC_DACL_PRESENT
;
185 mode
= name
->st
.st_mode
;
188 we provide up to 4 ACEs
196 /* setup owner ACE */
197 ace
.type
= SEC_ACE_TYPE_ACCESS_ALLOWED
;
199 ace
.trustee
= *sd
->owner_sid
;
202 if (mode
& S_IRUSR
) {
203 if (mode
& S_IWUSR
) {
204 ace
.access_mask
|= SEC_RIGHTS_FILE_ALL
;
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
;
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
);
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
);
254 omit any security_descriptor elements not specified in the given
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
)) {
268 if (!(secinfo_flags
& SECINFO_SACL
)) {
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
;
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
)) {
302 ids
= talloc(req
, struct id_map
);
303 NT_STATUS_HAVE_NO_MEMORY(ids
);
304 ZERO_STRUCT(ids
->xid
);
306 ids
->status
= ID_UNKNOWN
;
308 new_sd
= info
->set_secdesc
.in
.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
) {
371 if (new_gid
== old_gid
) {
375 /* if there's something to change try it */
376 if (new_uid
!= -1 || new_gid
!= -1) {
379 ret
= chown(name
->full_name
, new_uid
, new_gid
);
381 ret
= fchown(fd
, new_uid
, new_gid
);
383 if (errno
== EPERM
) {
384 if (uwrap_enabled()) {
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
,
391 security_token_has_privilege(req
->session_info
->security_token
,
392 SEC_PRIV_TAKE_OWNERSHIP
)) {
394 privs
= root_privileges();
396 ret
= chown(name
->full_name
, new_uid
, new_gid
);
398 ret
= fchown(fd
, new_uid
, new_gid
);
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
);
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
;
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
)) {
441 normalise_sd_flags(sd
, info
->query_secdesc
.in
.secinfo_flags
);
443 info
->query_secdesc
.out
.sd
= sd
;
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
|
458 SEC_FILE_WRITE_ATTRIBUTE
|
461 SEC_STD_WRITE_OWNER
|
462 SEC_DIR_DELETE_CHILD
))) {
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
)
475 if (getegid() == gid
) {
478 ngroups
= getgroups(0, NULL
);
482 groups
= talloc_array(pvfs
, gid_t
, ngroups
);
483 if (groups
== NULL
) {
486 if (getgroups(ngroups
, groups
) != ngroups
) {
490 for (i
=0; i
<ngroups
; i
++) {
491 if (groups
[i
] == gid
) break;
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
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
= 0;
512 struct security_token
*token
= req
->session_info
->security_token
;
514 if (pvfs_read_only(pvfs
, *access_mask
)) {
515 return NT_STATUS_ACCESS_DENIED
;
519 max_bits
|= SEC_RIGHTS_FILE_ALL
| SEC_STD_ALL
;
520 } else if (uid
== name
->st
.st_uid
|| uwrap_enabled()) {
521 /* use the IxUSR bits */
522 if ((name
->st
.st_mode
& S_IWUSR
)) {
523 max_bits
|= SEC_RIGHTS_FILE_ALL
| SEC_STD_ALL
;
524 } else if ((name
->st
.st_mode
& (S_IRUSR
| S_IXUSR
))) {
525 max_bits
|= SEC_RIGHTS_FILE_READ
| SEC_RIGHTS_FILE_EXECUTE
| SEC_STD_ALL
;
527 } else if (pvfs_group_member(pvfs
, name
->st
.st_gid
)) {
528 /* use the IxGRP bits */
529 if ((name
->st
.st_mode
& S_IWGRP
)) {
530 max_bits
|= SEC_RIGHTS_FILE_ALL
| SEC_STD_ALL
;
531 } else if ((name
->st
.st_mode
& (S_IRGRP
| S_IXGRP
))) {
532 max_bits
|= SEC_RIGHTS_FILE_READ
| SEC_RIGHTS_FILE_EXECUTE
| SEC_STD_ALL
;
535 /* use the IxOTH bits */
536 if ((name
->st
.st_mode
& S_IWOTH
)) {
537 max_bits
|= SEC_RIGHTS_FILE_ALL
| SEC_STD_ALL
;
538 } else if ((name
->st
.st_mode
& (S_IROTH
| S_IXOTH
))) {
539 max_bits
|= SEC_RIGHTS_FILE_READ
| SEC_RIGHTS_FILE_EXECUTE
| SEC_STD_ALL
;
543 if (*access_mask
& SEC_FLAG_MAXIMUM_ALLOWED
) {
544 *access_mask
|= max_bits
;
545 *access_mask
&= ~SEC_FLAG_MAXIMUM_ALLOWED
;
548 if ((*access_mask
& SEC_FLAG_SYSTEM_SECURITY
) &&
549 security_token_has_privilege(token
, SEC_PRIV_SECURITY
)) {
550 max_bits
|= SEC_FLAG_SYSTEM_SECURITY
;
553 if (((*access_mask
& ~max_bits
) & SEC_RIGHTS_PRIV_RESTORE
) &&
554 security_token_has_privilege(token
, SEC_PRIV_RESTORE
)) {
555 max_bits
|= ~(SEC_RIGHTS_PRIV_RESTORE
);
557 if (((*access_mask
& ~max_bits
) & SEC_RIGHTS_PRIV_BACKUP
) &&
558 security_token_has_privilege(token
, SEC_PRIV_BACKUP
)) {
559 max_bits
|= ~(SEC_RIGHTS_PRIV_BACKUP
);
562 if (*access_mask
& ~max_bits
) {
563 DEBUG(5,(__location__
" denied access to '%s' - wanted 0x%08x but got 0x%08x (missing 0x%08x)\n",
564 name
?name
->full_name
:"(new file)", *access_mask
, max_bits
, *access_mask
& ~max_bits
));
565 return NT_STATUS_ACCESS_DENIED
;
568 if (pvfs
->ntvfs
->ctx
->protocol
< PROTOCOL_SMB2_02
) {
569 /* on SMB, this bit is always granted, even if not
571 *access_mask
|= SEC_FILE_READ_ATTRIBUTE
;
579 check the security descriptor on a file, if any
581 *access_mask is modified with the access actually granted
583 NTSTATUS
pvfs_access_check(struct pvfs_state
*pvfs
,
584 struct ntvfs_request
*req
,
585 struct pvfs_filename
*name
,
586 uint32_t *access_mask
)
588 struct security_token
*token
= req
->session_info
->security_token
;
589 struct xattr_NTACL
*acl
;
591 struct security_descriptor
*sd
;
592 bool allow_delete
= false;
594 /* on SMB2 a blank access mask is always denied */
595 if (pvfs
->ntvfs
->ctx
->protocol
>= PROTOCOL_SMB2_02
&&
597 return NT_STATUS_ACCESS_DENIED
;
600 if (pvfs_read_only(pvfs
, *access_mask
)) {
601 return NT_STATUS_ACCESS_DENIED
;
604 if (*access_mask
& SEC_FLAG_MAXIMUM_ALLOWED
||
605 *access_mask
& SEC_STD_DELETE
) {
606 status
= pvfs_access_check_parent(pvfs
, req
,
607 name
, SEC_DIR_DELETE_CHILD
);
608 if (NT_STATUS_IS_OK(status
)) {
610 *access_mask
&= ~SEC_STD_DELETE
;
614 acl
= talloc(req
, struct xattr_NTACL
);
616 return NT_STATUS_NO_MEMORY
;
619 /* expand the generic access bits to file specific bits */
620 *access_mask
= pvfs_translate_mask(*access_mask
);
621 if (pvfs
->ntvfs
->ctx
->protocol
< PROTOCOL_SMB2_02
) {
622 *access_mask
&= ~SEC_FILE_READ_ATTRIBUTE
;
625 status
= pvfs_acl_load(pvfs
, name
, -1, acl
);
626 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_FOUND
)) {
628 status
= pvfs_access_check_unix(pvfs
, req
, name
, access_mask
);
631 if (!NT_STATUS_IS_OK(status
)) {
635 switch (acl
->version
) {
640 return NT_STATUS_INVALID_ACL
;
643 /* check the acl against the required access mask */
644 status
= se_access_check(sd
, token
, *access_mask
, access_mask
);
647 /* if we used a NT acl, then allow access override if the
648 share allows for posix permission override
650 if (NT_STATUS_IS_OK(status
)) {
651 name
->allow_override
= (pvfs
->flags
& PVFS_FLAG_PERM_OVERRIDE
) != 0;
655 if (pvfs
->ntvfs
->ctx
->protocol
< PROTOCOL_SMB2_02
) {
656 /* on SMB, this bit is always granted, even if not
658 *access_mask
|= SEC_FILE_READ_ATTRIBUTE
;
662 *access_mask
|= SEC_STD_DELETE
;
670 a simplified interface to access check, designed for calls that
671 do not take or return an access check mask
673 NTSTATUS
pvfs_access_check_simple(struct pvfs_state
*pvfs
,
674 struct ntvfs_request
*req
,
675 struct pvfs_filename
*name
,
676 uint32_t access_needed
)
678 if (access_needed
== 0) {
681 return pvfs_access_check(pvfs
, req
, name
, &access_needed
);
685 access check for creating a new file/directory
687 NTSTATUS
pvfs_access_check_create(struct pvfs_state
*pvfs
,
688 struct ntvfs_request
*req
,
689 struct pvfs_filename
*name
,
690 uint32_t *access_mask
,
692 struct security_descriptor
**sd
)
694 struct pvfs_filename
*parent
;
696 uint32_t parent_mask
;
697 bool allow_delete
= false;
699 if (pvfs_read_only(pvfs
, *access_mask
)) {
700 return NT_STATUS_ACCESS_DENIED
;
703 status
= pvfs_resolve_parent(pvfs
, req
, name
, &parent
);
704 NT_STATUS_NOT_OK_RETURN(status
);
707 parent_mask
= SEC_DIR_ADD_SUBDIR
;
709 parent_mask
= SEC_DIR_ADD_FILE
;
711 if (*access_mask
& SEC_FLAG_MAXIMUM_ALLOWED
||
712 *access_mask
& SEC_STD_DELETE
) {
713 parent_mask
|= SEC_DIR_DELETE_CHILD
;
716 status
= pvfs_access_check(pvfs
, req
, parent
, &parent_mask
);
717 if (NT_STATUS_IS_OK(status
)) {
718 if (parent_mask
& SEC_DIR_DELETE_CHILD
) {
721 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
723 * on ACCESS_DENIED we get the rejected bits
724 * remove the non critical SEC_DIR_DELETE_CHILD
725 * and check if something else was rejected.
727 parent_mask
&= ~SEC_DIR_DELETE_CHILD
;
728 if (parent_mask
!= 0) {
729 return NT_STATUS_ACCESS_DENIED
;
731 status
= NT_STATUS_OK
;
737 status
= pvfs_acl_inherited_sd(pvfs
, req
, req
, parent
, container
, sd
);
741 if (!NT_STATUS_IS_OK(status
)) {
745 /* expand the generic access bits to file specific bits */
746 *access_mask
= pvfs_translate_mask(*access_mask
);
748 if (*access_mask
& SEC_FLAG_MAXIMUM_ALLOWED
) {
749 *access_mask
|= SEC_RIGHTS_FILE_ALL
;
750 *access_mask
&= ~SEC_FLAG_MAXIMUM_ALLOWED
;
753 if (pvfs
->ntvfs
->ctx
->protocol
< PROTOCOL_SMB2_02
) {
754 /* on SMB, this bit is always granted, even if not
756 *access_mask
|= SEC_FILE_READ_ATTRIBUTE
;
760 *access_mask
|= SEC_STD_DELETE
;
767 access check for creating a new file/directory - no access mask supplied
769 NTSTATUS
pvfs_access_check_parent(struct pvfs_state
*pvfs
,
770 struct ntvfs_request
*req
,
771 struct pvfs_filename
*name
,
772 uint32_t access_mask
)
774 struct pvfs_filename
*parent
;
777 status
= pvfs_resolve_parent(pvfs
, req
, name
, &parent
);
778 if (!NT_STATUS_IS_OK(status
)) {
782 status
= pvfs_access_check_simple(pvfs
, req
, parent
, access_mask
);
783 if (NT_STATUS_IS_OK(status
) && parent
->allow_override
) {
784 name
->allow_override
= true;
791 determine if an ACE is inheritable
793 static bool pvfs_inheritable_ace(struct pvfs_state
*pvfs
,
794 const struct security_ace
*ace
,
798 return (ace
->flags
& SEC_ACE_FLAG_OBJECT_INHERIT
) != 0;
801 if (ace
->flags
& SEC_ACE_FLAG_CONTAINER_INHERIT
) {
805 if ((ace
->flags
& SEC_ACE_FLAG_OBJECT_INHERIT
) &&
806 !(ace
->flags
& SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
)) {
814 this is the core of ACL inheritance. It copies any inheritable
815 aces from the parent SD to the child SD. Note that the algorithm
816 depends on whether the child is a container or not
818 static NTSTATUS
pvfs_acl_inherit_aces(struct pvfs_state
*pvfs
,
819 struct security_descriptor
*parent_sd
,
820 struct security_descriptor
*sd
,
825 for (i
=0;i
<parent_sd
->dacl
->num_aces
;i
++) {
826 struct security_ace ace
= parent_sd
->dacl
->aces
[i
];
828 const struct dom_sid
*creator
= NULL
, *new_id
= NULL
;
831 if (!pvfs_inheritable_ace(pvfs
, &ace
, container
)) {
835 orig_flags
= ace
.flags
;
837 /* see the RAW-ACLS inheritance test for details on these rules */
841 ace
.flags
&= ~SEC_ACE_FLAG_INHERIT_ONLY
;
843 if (!(ace
.flags
& SEC_ACE_FLAG_CONTAINER_INHERIT
)) {
844 ace
.flags
|= SEC_ACE_FLAG_INHERIT_ONLY
;
846 if (ace
.flags
& SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
) {
851 /* the CREATOR sids are special when inherited */
852 if (dom_sid_equal(&ace
.trustee
, pvfs
->sid_cache
.creator_owner
)) {
853 creator
= pvfs
->sid_cache
.creator_owner
;
854 new_id
= sd
->owner_sid
;
855 } else if (dom_sid_equal(&ace
.trustee
, pvfs
->sid_cache
.creator_group
)) {
856 creator
= pvfs
->sid_cache
.creator_group
;
857 new_id
= sd
->group_sid
;
859 new_id
= &ace
.trustee
;
862 if (creator
&& container
&&
863 (ace
.flags
& SEC_ACE_FLAG_CONTAINER_INHERIT
)) {
864 uint32_t flags
= ace
.flags
;
866 ace
.trustee
= *new_id
;
868 status
= security_descriptor_dacl_add(sd
, &ace
);
869 if (!NT_STATUS_IS_OK(status
)) {
873 ace
.trustee
= *creator
;
874 ace
.flags
= flags
| SEC_ACE_FLAG_INHERIT_ONLY
;
875 status
= security_descriptor_dacl_add(sd
, &ace
);
876 } else if (container
&&
877 !(orig_flags
& SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
)) {
878 status
= security_descriptor_dacl_add(sd
, &ace
);
880 ace
.trustee
= *new_id
;
881 status
= security_descriptor_dacl_add(sd
, &ace
);
884 if (!NT_STATUS_IS_OK(status
)) {
895 calculate the ACL on a new file/directory based on the inherited ACL
896 from the parent. If there is no inherited ACL then return a NULL
897 ACL, which means the default ACL should be used
899 NTSTATUS
pvfs_acl_inherited_sd(struct pvfs_state
*pvfs
,
901 struct ntvfs_request
*req
,
902 struct pvfs_filename
*parent
,
904 struct security_descriptor
**ret_sd
)
906 struct xattr_NTACL
*acl
;
908 struct security_descriptor
*parent_sd
, *sd
;
910 struct composite_context
*ctx
;
911 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
915 acl
= talloc(req
, struct xattr_NTACL
);
916 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(acl
, tmp_ctx
);
918 status
= pvfs_acl_load(pvfs
, parent
, -1, acl
);
919 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_FOUND
)) {
920 talloc_free(tmp_ctx
);
923 NT_STATUS_NOT_OK_RETURN_AND_FREE(status
, tmp_ctx
);
925 switch (acl
->version
) {
927 parent_sd
= acl
->info
.sd
;
930 talloc_free(tmp_ctx
);
931 return NT_STATUS_INVALID_ACL
;
934 if (parent_sd
== NULL
||
935 parent_sd
->dacl
== NULL
||
936 parent_sd
->dacl
->num_aces
== 0) {
937 /* go with the default ACL */
938 talloc_free(tmp_ctx
);
942 /* create the new sd */
943 sd
= security_descriptor_initialise(req
);
944 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sd
, tmp_ctx
);
946 ids
= talloc_array(sd
, struct id_map
, 2);
947 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ids
, tmp_ctx
);
949 ids
[0].xid
.id
= geteuid();
950 ids
[0].xid
.type
= ID_TYPE_UID
;
952 ids
[0].status
= ID_UNKNOWN
;
954 ids
[1].xid
.id
= getegid();
955 ids
[1].xid
.type
= ID_TYPE_GID
;
957 ids
[1].status
= ID_UNKNOWN
;
959 ctx
= wbc_xids_to_sids_send(pvfs
->wbc_ctx
, ids
, 2, ids
);
960 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ctx
, tmp_ctx
);
962 status
= wbc_xids_to_sids_recv(ctx
, &ids
);
963 NT_STATUS_NOT_OK_RETURN_AND_FREE(status
, tmp_ctx
);
965 sd
->owner_sid
= talloc_steal(sd
, ids
[0].sid
);
966 sd
->group_sid
= talloc_steal(sd
, ids
[1].sid
);
968 sd
->type
|= SEC_DESC_DACL_PRESENT
;
970 /* fill in the aces from the parent */
971 status
= pvfs_acl_inherit_aces(pvfs
, parent_sd
, sd
, container
);
972 NT_STATUS_NOT_OK_RETURN_AND_FREE(status
, tmp_ctx
);
974 /* if there is nothing to inherit then we fallback to the
976 if (sd
->dacl
== NULL
|| sd
->dacl
->num_aces
== 0) {
977 talloc_free(tmp_ctx
);
981 *ret_sd
= talloc_steal(mem_ctx
, sd
);
983 talloc_free(tmp_ctx
);
989 setup an ACL on a new file/directory based on the inherited ACL from
990 the parent. If there is no inherited ACL then we don't set anything,
991 as the default ACL applies anyway
993 NTSTATUS
pvfs_acl_inherit(struct pvfs_state
*pvfs
,
994 struct ntvfs_request
*req
,
995 struct pvfs_filename
*name
,
998 struct xattr_NTACL acl
;
1000 struct security_descriptor
*sd
;
1001 struct pvfs_filename
*parent
;
1004 /* form the parents path */
1005 status
= pvfs_resolve_parent(pvfs
, req
, name
, &parent
);
1006 NT_STATUS_NOT_OK_RETURN(status
);
1008 container
= (name
->dos
.attrib
& FILE_ATTRIBUTE_DIRECTORY
) ? true:false;
1010 status
= pvfs_acl_inherited_sd(pvfs
, req
, req
, parent
, container
, &sd
);
1011 if (!NT_STATUS_IS_OK(status
)) {
1012 talloc_free(parent
);
1017 return NT_STATUS_OK
;
1023 status
= pvfs_acl_save(pvfs
, name
, fd
, &acl
);
1025 talloc_free(parent
);
1031 return the maximum allowed access mask
1033 NTSTATUS
pvfs_access_maximal_allowed(struct pvfs_state
*pvfs
,
1034 struct ntvfs_request
*req
,
1035 struct pvfs_filename
*name
,
1036 uint32_t *maximal_access
)
1038 *maximal_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
1039 return pvfs_access_check(pvfs
, req
, name
, maximal_access
);