2 * Copyright 2016 Chris Torek <torek@ixsystems.com>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/types.h>
36 #include "lib9p_impl.h"
41 typedef int econvertfn(acl_entry_t, struct l9p_ace *);
44 static struct l9p_acl *l9p_new_acl(uint32_t acetype, uint32_t aceasize);
45 static struct l9p_acl *l9p_growacl(struct l9p_acl *acl, uint32_t aceasize);
46 static int l9p_count_aces(acl_t sysacl);
47 static struct l9p_acl *l9p_sysacl_to_acl(int, acl_t, econvertfn *);
49 static bool l9p_ingroup(gid_t tid, gid_t gid, gid_t *gids, size_t ngids);
50 static int l9p_check_aces(int32_t mask, struct l9p_acl *acl, struct stat *st,
51 uid_t uid, gid_t gid, gid_t *gids, size_t ngids);
54 l9p_acl_free(struct l9p_acl *acl)
61 * Is the given group ID tid (test-id) any of the gid's in agids?
64 l9p_ingroup(gid_t tid, gid_t gid, gid_t *gids, size_t ngids)
70 for (i = 0; i < ngids; i++)
76 /* #define ACE_DEBUG */
79 * Note that NFSv4 tests are done on a "first match" basis.
80 * That is, we check each ACE sequentially until we run out
81 * of ACEs, or find something explicitly denied (DENIED!),
82 * or have cleared out all our attempt-something bits. Once
83 * we come across an ALLOW entry for the bits we're trying,
84 * we clear those from the bits we're still looking for, in
85 * the order they appear.
87 * The result is either "definitely allowed" (we cleared
88 * all the bits), "definitely denied" (we hit a deny with
89 * some or all of the bits), or "unspecified". We
90 * represent these three states as +1 (positive = yes = allow),
91 * -1 (negative = no = denied), or 0 (no strong answer).
93 * For our caller's convenience, if we are called with a
94 * mask of 0, we return 0 (no answer).
97 l9p_check_aces(int32_t mask, struct l9p_acl *acl, struct stat *st,
98 uid_t uid, gid_t gid, gid_t *gids, size_t ngids)
103 const char *acetype, *allowdeny;
112 for (i = 0; mask != 0 && i < acl->acl_nace; i++) {
113 ace = &acl->acl_aces[i];
114 switch (ace->ace_type) {
115 case L9P_ACET_ACCESS_ALLOWED:
116 case L9P_ACET_ACCESS_DENIED:
119 /* audit, alarm - ignore */
125 if (ace->ace_flags & L9P_ACEF_OWNER) {
129 match = st->st_uid == uid;
130 } else if (ace->ace_flags & L9P_ACEF_GROUP) {
134 match = l9p_ingroup(st->st_gid, gid, gids, ngids);
135 } else if (ace->ace_flags & L9P_ACEF_EVERYONE) {
137 acetype = "EVERYONE@";
141 if (ace->ace_idsize != sizeof(tid))
146 memcpy(&tid, &ace->ace_idbytes, sizeof(tid));
147 if (ace->ace_flags & L9P_ACEF_IDENTIFIER_GROUP) {
151 match = l9p_ingroup(tid, gid, gids, ngids);
160 * If this ACE applies to us, check remaining bits.
161 * If any of those bits also apply, check the type:
162 * DENY means "stop now", ALLOW means allow these bits
166 allowdeny = ace->ace_type == L9P_ACET_ACCESS_DENIED ?
169 if (match && (ace->ace_mask & (uint32_t)mask) != 0) {
173 "ACE: %s %s %d: mask 0x%x ace_mask 0x%x",
174 allowdeny, acetype, (int)tid,
175 (u_int)mask, (u_int)ace->ace_mask);
178 "ACE: %s %s: mask 0x%x ace_mask 0x%x",
180 (u_int)mask, (u_int)ace->ace_mask);
182 if (ace->ace_type == L9P_ACET_ACCESS_DENIED)
184 mask &= ~ace->ace_mask;
186 L9P_LOG(L9P_DEBUG, "clear 0x%x: now mask=0x%x",
187 (u_int)ace->ace_mask, (u_int)mask);
193 "ACE: SKIP %s %s %d: "
194 "match %d mask 0x%x ace_mask 0x%x",
195 allowdeny, acetype, (int)tid,
196 (int)match, (u_int)mask,
197 (u_int)ace->ace_mask);
201 "match %d mask 0x%x ace_mask 0x%x",
203 (int)match, (u_int)mask,
204 (u_int)ace->ace_mask);
209 /* Return 1 if access definitely granted. */
211 L9P_LOG(L9P_DEBUG, "ACE: end of ACEs, mask now 0x%x: %s",
212 mask, mask ? "no-definitive-answer" : "ALLOW");
214 return (mask == 0 ? 1 : 0);
220 * The return value is normally 0 (access allowed) or EPERM
221 * (access denied), so it could just be a boolean....
223 * For "make new dir in dir" and "remove dir in dir", you must
224 * set the mask to test the directory permissions (not ADD_FILE but
225 * ADD_SUBDIRECTORY, and DELETE_CHILD). For "make new file in dir"
226 * you must set the opmask to test file ADD_FILE.
228 * The L9P_ACE_DELETE flag means "can delete this thing"; it's not
229 * clear whether it should override the parent directory's ACL if
230 * any. In our case it does not, but a caller may try
231 * L9P_ACE_DELETE_CHILD (separately, on its own) and then a
232 * (second, separate) L9P_ACE_DELETE, to make the permissions work
233 * as "or" instead of "and".
235 * Pass a NULL parent/pstat if they are not applicable, e.g.,
236 * for doing operations on an existing file, such as reading or
237 * writing data or attributes. Pass in a null child/cstat if
238 * that's not applicable, such as creating a new file/dir.
240 * NB: it's probably wise to allow the owner of any file to update
241 * the ACLs of that file, but we leave that test to the caller.
243 int l9p_acl_check_access(int32_t opmask, struct l9p_acl_check_args *args)
245 struct l9p_acl *parent, *child;
246 struct stat *pstat, *cstat;
251 int panswer, canswer;
254 parent = args->aca_parent;
255 pstat = args->aca_pstat;
256 child = args->aca_child;
257 cstat = args->aca_cstat;
260 gids = args->aca_groups;
261 ngids = args->aca_ngroups;
265 "l9p_acl_check_access: opmask=0x%x uid=%ld gid=%ld ngids=%zd",
266 (u_int)opmask, (long)uid, (long)gid, ngids);
269 * If caller said "superuser semantics", check that first.
270 * Note that we apply them regardless of ACLs.
272 if (uid == 0 && args->aca_superuser)
276 * If told to ignore ACLs and use only stat-based permissions,
277 * discard any non-NULL ACL pointers.
279 * This will need some fancying up when we support POSIX ACLs.
281 if ((args->aca_aclmode & L9P_ACM_NFS_ACL) == 0)
282 parent = child = NULL;
284 assert(parent == NULL || parent->acl_acetype == L9P_ACLTYPE_NFSv4);
285 assert(parent == NULL || pstat != NULL);
286 assert(child == NULL || child->acl_acetype == L9P_ACLTYPE_NFSv4);
287 assert(child == NULL || cstat != NULL);
288 assert(pstat != NULL || cstat != NULL);
291 * If the operation is UNLINK we should have either both ACLs
292 * or no ACLs, but we won't require that here.
294 * If a parent ACL is supplied, it's a directory by definition.
295 * Make sure we're allowed to do this there, whatever this is.
296 * If a child ACL is supplied, check it too. Note that the
297 * DELETE permission only applies in the child though, not
298 * in the parent, and the DELETE_CHILD only applies in the
302 if (parent != NULL || pstat != NULL) {
304 * Remove child-only bits from parent op and
305 * parent-only bits from child op.
307 * L9P_ACE_DELETE is child-only.
309 * L9P_ACE_DELETE_CHILD is parent-only, and three data
310 * access bits overlap with three directory access bits.
311 * We should have child==NULL && cstat==NULL, so the
312 * three data bits should be redundant, but it's
313 * both trivial and safest to remove them anyway.
315 pop &= ~L9P_ACE_DELETE;
316 cop &= ~(L9P_ACE_DELETE_CHILD | L9P_ACE_LIST_DIRECTORY |
317 L9P_ACE_ADD_FILE | L9P_ACE_ADD_SUBDIRECTORY);
320 * Remove child-only bits from parent op. We need
321 * not bother since we just found we have no parent
322 * and no pstat, and hence won't actually *use* pop.
324 * pop &= ~(L9P_ACE_READ_DATA | L9P_ACE_WRITE_DATA |
325 * L9P_ACE_APPEND_DATA);
331 panswer = l9p_check_aces(pop, parent, pstat,
332 uid, gid, gids, ngids);
334 canswer = l9p_check_aces(cop, child, cstat,
335 uid, gid, gids, ngids);
337 if (panswer || canswer) {
339 * Got a definitive answer from parent and/or
340 * child ACLs. We're not quite done yet though.
342 if (opmask == L9P_ACOP_UNLINK) {
344 * For UNLINK, we can get an allow from child
345 * and deny from parent, or vice versa. It's
346 * not 100% clear how to handle the two-answer
347 * case. ZFS says that if either says "allow",
348 * we allow, and if both definitely say "deny",
349 * we deny. This makes sense, so we do that
350 * here for all cases, even "strict".
352 if (panswer > 0 || canswer > 0)
354 if (panswer < 0 && canswer < 0)
356 /* non-definitive answer from one! move on */
359 * Have at least one definitive answer, and
360 * should have only one; obey whichever
364 return (panswer < 0 ? EPERM : 0);
365 return (canswer < 0 ? EPERM : 0);
370 * No definitive answer from ACLs alone. Check for ZFS style
371 * permissions checking and an "UNLINK" operation under ACLs.
372 * If so, find write-and-execute permission on parent.
373 * Note that WRITE overlaps with ADD_FILE -- that's ZFS's
374 * way of saying "allow write to dir" -- but EXECUTE is
375 * separate from LIST_DIRECTORY, so that's at least a little
378 * Note also that only a definitive yes (both bits are
379 * explicitly allowed) results in granting unlink, and
380 * a definitive no (at least one bit explicitly denied)
381 * results in EPERM. Only "no answer" moves on.
383 if ((args->aca_aclmode & L9P_ACM_ZFS_ACL) &&
384 opmask == L9P_ACOP_UNLINK && parent != NULL) {
385 panswer = l9p_check_aces(L9P_ACE_ADD_FILE | L9P_ACE_EXECUTE,
386 parent, pstat, uid, gid, gids, ngids);
388 return (panswer < 0 ? EPERM : 0);
392 * No definitive answer from ACLs.
394 * Try POSIX style rwx permissions if allowed. This should
395 * be rare, occurring mainly when caller supplied no ACLs
396 * or set the mode to suppress them.
398 * The stat to check is the parent's if we don't have a child
399 * (i.e., this is a dir op), or if the DELETE_CHILD bit is set
400 * (i.e., this is an unlink or similar). Otherwise it's the
403 if (args->aca_aclmode & L9P_ACM_STAT_MODE) {
407 rwx = l9p_ace_mask_to_rwx(opmask);
408 if ((st = cstat) == NULL || (opmask & L9P_ACE_DELETE_CHILD))
410 if (uid == st->st_uid)
411 bits = (st->st_mode >> 6) & 7;
412 else if (l9p_ingroup(st->st_gid, gid, gids, ngids))
413 bits = (st->st_mode >> 3) & 7;
415 bits = st->st_mode & 7;
417 * If all the desired bits are set, we're OK.
419 if ((rwx & bits) == rwx)
423 /* all methods have failed, return EPERM */
428 * Collapse fancy ACL operation mask down to simple Unix bits.
430 * Directory operations don't map that well. However, listing
431 * a directory really does require read permission, and adding
432 * or deleting files really does require write permission, so
433 * this is probably sufficient.
436 l9p_ace_mask_to_rwx(int32_t opmask)
441 (L9P_ACE_READ_DATA | L9P_ACE_READ_NAMED_ATTRS |
442 L9P_ACE_READ_ATTRIBUTES | L9P_ACE_READ_ACL))
445 (L9P_ACE_WRITE_DATA | L9P_ACE_APPEND_DATA |
446 L9P_ACE_ADD_FILE | L9P_ACE_ADD_SUBDIRECTORY |
447 L9P_ACE_DELETE | L9P_ACE_DELETE_CHILD |
448 L9P_ACE_WRITE_NAMED_ATTRS | L9P_ACE_WRITE_ATTRIBUTES |
451 if (opmask & L9P_ACE_EXECUTE)
458 * Allocate new ACL holder and ACEs.
460 static struct l9p_acl *
461 l9p_new_acl(uint32_t acetype, uint32_t aceasize)
466 asize = aceasize * sizeof(struct l9p_ace);
467 size = sizeof(struct l9p_acl) + asize;
470 ret->acl_acetype = acetype;
472 ret->acl_aceasize = aceasize;
478 * Expand ACL to accomodate more entries.
480 * Currently won't shrink, only grow, so it's a fast no-op until
481 * we hit the allocated size. After that, it's best to grow in
482 * big chunks, or this will be O(n**2).
484 static struct l9p_acl *
485 l9p_growacl(struct l9p_acl *acl, uint32_t aceasize)
490 if (acl->acl_aceasize < aceasize) {
491 asize = aceasize * sizeof(struct l9p_ace);
492 size = sizeof(struct l9p_acl) + asize;
493 tmp = realloc(acl, size);
502 * Annoyingly, there's no POSIX-standard way to count the number
503 * of ACEs in a system ACL other than to walk through them all.
504 * This is silly, but at least 2n is still O(n), and the walk is
505 * short. (If the system ACL mysteriously grows, we'll handle
506 * that OK via growacl(), too.)
509 l9p_count_aces(acl_t sysacl)
515 id = ACL_FIRST_ENTRY;
516 for (n = 0; acl_get_entry(sysacl, id, &entry) == 1; n++)
523 * Create ACL with ACEs from the given acl_t. We use the given
524 * convert function on each ACE.
526 static struct l9p_acl *
527 l9p_sysacl_to_acl(int acetype, acl_t sysacl, econvertfn *convert)
534 acl = l9p_new_acl((uint32_t)acetype, (uint32_t)l9p_count_aces(sysacl));
537 id = ACL_FIRST_ENTRY;
539 if (acl_get_entry(sysacl, id, &entry) != 1)
541 acl = l9p_growacl(acl, n + 1);
544 error = (*convert)(entry, &acl->acl_aces[n]);
554 #if defined(HAVE_POSIX_ACLS) && 0 /* not yet */
556 l9p_posix_acl_to_acl(acl_t sysacl)
561 #if defined(HAVE_FREEBSD_ACLS)
563 l9p_frombsdnfs4(acl_entry_t sysace, struct l9p_ace *ace)
565 acl_tag_t tag; /* e.g., USER_OBJ, GROUP, etc */
566 acl_entry_type_t entry_type; /* e.g., allow/deny */
567 acl_permset_t absdperm;
568 acl_flagset_t absdflag;
569 acl_perm_t bsdperm; /* e.g., READ_DATA */
570 acl_flag_t bsdflag; /* e.g., FILE_INHERIT_ACE */
571 uint32_t flags, mask;
575 error = acl_get_tag_type(sysace, &tag);
577 error = acl_get_entry_type_np(sysace, &entry_type);
579 error = acl_get_flagset_np(sysace, &absdflag);
581 error = acl_get_permset(sysace, &absdperm);
589 /* move user/group/everyone + id-is-group-id into flags */
592 flags |= L9P_ACEF_OWNER;
595 flags |= L9P_ACEF_GROUP;
598 flags |= L9P_ACEF_EVERYONE;
601 flags |= L9P_ACEF_IDENTIFIER_GROUP;
604 aid = acl_get_qualifier(sysace); /* ugh, this malloc()s */
612 return (EINVAL); /* can't happen */
615 switch (entry_type) {
617 case ACL_ENTRY_TYPE_ALLOW:
618 ace->ace_type = L9P_ACET_ACCESS_ALLOWED;
621 case ACL_ENTRY_TYPE_DENY:
622 ace->ace_type = L9P_ACET_ACCESS_DENIED;
625 case ACL_ENTRY_TYPE_AUDIT:
626 ace->ace_type = L9P_ACET_SYSTEM_AUDIT;
629 case ACL_ENTRY_TYPE_ALARM:
630 ace->ace_type = L9P_ACET_SYSTEM_ALARM;
634 return (EINVAL); /* can't happen */
637 /* transform remaining BSD flags to internal NFS-y form */
639 if (bsdflag & ACL_ENTRY_FILE_INHERIT)
640 flags |= L9P_ACEF_FILE_INHERIT_ACE;
641 if (bsdflag & ACL_ENTRY_DIRECTORY_INHERIT)
642 flags |= L9P_ACEF_DIRECTORY_INHERIT_ACE;
643 if (bsdflag & ACL_ENTRY_NO_PROPAGATE_INHERIT)
644 flags |= L9P_ACEF_NO_PROPAGATE_INHERIT_ACE;
645 if (bsdflag & ACL_ENTRY_INHERIT_ONLY)
646 flags |= L9P_ACEF_INHERIT_ONLY_ACE;
647 if (bsdflag & ACL_ENTRY_SUCCESSFUL_ACCESS)
648 flags |= L9P_ACEF_SUCCESSFUL_ACCESS_ACE_FLAG;
649 if (bsdflag & ACL_ENTRY_FAILED_ACCESS)
650 flags |= L9P_ACEF_FAILED_ACCESS_ACE_FLAG;
651 ace->ace_flags = flags;
654 * Transform BSD permissions to ace_mask. Note that directory
655 * vs file bits are the same in both sets, so we don't need
656 * to worry about that, at least.
658 * There seem to be no BSD equivalents for WRITE_RETENTION
659 * and WRITE_RETENTION_HOLD.
663 if (bsdperm & ACL_READ_DATA)
664 mask |= L9P_ACE_READ_DATA;
665 if (bsdperm & ACL_WRITE_DATA)
666 mask |= L9P_ACE_WRITE_DATA;
667 if (bsdperm & ACL_APPEND_DATA)
668 mask |= L9P_ACE_APPEND_DATA;
669 if (bsdperm & ACL_READ_NAMED_ATTRS)
670 mask |= L9P_ACE_READ_NAMED_ATTRS;
671 if (bsdperm & ACL_WRITE_NAMED_ATTRS)
672 mask |= L9P_ACE_WRITE_NAMED_ATTRS;
673 if (bsdperm & ACL_EXECUTE)
674 mask |= L9P_ACE_EXECUTE;
675 if (bsdperm & ACL_DELETE_CHILD)
676 mask |= L9P_ACE_DELETE_CHILD;
677 if (bsdperm & ACL_READ_ATTRIBUTES)
678 mask |= L9P_ACE_READ_ATTRIBUTES;
679 if (bsdperm & ACL_WRITE_ATTRIBUTES)
680 mask |= L9P_ACE_WRITE_ATTRIBUTES;
681 /* L9P_ACE_WRITE_RETENTION */
682 /* L9P_ACE_WRITE_RETENTION_HOLD */
684 if (bsdperm & ACL_DELETE)
685 mask |= L9P_ACE_DELETE;
686 if (bsdperm & ACL_READ_ACL)
687 mask |= L9P_ACE_READ_ACL;
688 if (bsdperm & ACL_WRITE_ACL)
689 mask |= L9P_ACE_WRITE_ACL;
690 if (bsdperm & ACL_WRITE_OWNER)
691 mask |= L9P_ACE_WRITE_OWNER;
692 if (bsdperm & ACL_SYNCHRONIZE)
693 mask |= L9P_ACE_SYNCHRONIZE;
694 ace->ace_mask = mask;
696 /* fill in variable-size user or group ID bytes */
700 ace->ace_idsize = sizeof(uid);
701 memcpy(&ace->ace_idbytes[0], aid, sizeof(uid));
708 l9p_freebsd_nfsv4acl_to_acl(acl_t sysacl)
711 return (l9p_sysacl_to_acl(L9P_ACLTYPE_NFSv4, sysacl, l9p_frombsdnfs4));
715 #if defined(HAVE_DARWIN_ACLS) && 0 /* not yet */
717 l9p_darwin_nfsv4acl_to_acl(acl_t sysacl)