3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <sys/zfs_context.h>
26 #include <sys/dmu.h>
27 #include <sys/avl.h>
28 #include <sys/zap.h>
29 #include <sys/refcount.h>
30 #include <sys/nvpair.h>
31 #ifdef _KERNEL
32 #include <sys/kidmap.h>
33 #include <sys/sid.h>
34 #include <sys/zfs_vfsops.h>
35 #include <sys/zfs_znode.h>
36 #endif
37 #include <sys/zfs_fuid.h>
38
39 /*
40 * FUID Domain table(s).
41 *
42 * The FUID table is stored as a packed nvlist of an array
672 zfs_fuid_t *zfuid;
673 zfs_fuid_domain_t *zdomain;
674
675 while ((zfuid = list_head(&fuidp->z_fuids)) != NULL) {
676 list_remove(&fuidp->z_fuids, zfuid);
677 kmem_free(zfuid, sizeof (zfs_fuid_t));
678 }
679
680 if (fuidp->z_domain_table != NULL)
681 kmem_free(fuidp->z_domain_table,
682 (sizeof (char **)) * fuidp->z_domain_cnt);
683
684 while ((zdomain = list_head(&fuidp->z_domains)) != NULL) {
685 list_remove(&fuidp->z_domains, zdomain);
686 kmem_free(zdomain, sizeof (zfs_fuid_domain_t));
687 }
688
689 kmem_free(fuidp, sizeof (zfs_fuid_info_t));
690 }
691
692 /*
693 * Check to see if id is a groupmember. If cred
694 * has ksid info then sidlist is checked first
695 * and if still not found then POSIX groups are checked
696 *
697 * Will use a straight FUID compare when possible.
698 */
699 boolean_t
700 zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
701 {
702 ksid_t *ksid = crgetsid(cr, KSID_GROUP);
703 ksidlist_t *ksidlist = crgetsidlist(cr);
704 uid_t gid;
705
706 if (ksid && ksidlist) {
707 int i;
708 ksid_t *ksid_groups;
709 uint32_t idx = FUID_INDEX(id);
710 uint32_t rid = FUID_RID(id);
711
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 #include <sys/zfs_context.h>
27 #include <sys/dmu.h>
28 #include <sys/avl.h>
29 #include <sys/zap.h>
30 #include <sys/refcount.h>
31 #include <sys/nvpair.h>
32 #ifdef _KERNEL
33 #include <sys/kidmap.h>
34 #include <sys/sid.h>
35 #include <sys/zfs_vfsops.h>
36 #include <sys/zfs_znode.h>
37 #endif
38 #include <sys/zfs_fuid.h>
39
40 /*
41 * FUID Domain table(s).
42 *
43 * The FUID table is stored as a packed nvlist of an array
673 zfs_fuid_t *zfuid;
674 zfs_fuid_domain_t *zdomain;
675
676 while ((zfuid = list_head(&fuidp->z_fuids)) != NULL) {
677 list_remove(&fuidp->z_fuids, zfuid);
678 kmem_free(zfuid, sizeof (zfs_fuid_t));
679 }
680
681 if (fuidp->z_domain_table != NULL)
682 kmem_free(fuidp->z_domain_table,
683 (sizeof (char **)) * fuidp->z_domain_cnt);
684
685 while ((zdomain = list_head(&fuidp->z_domains)) != NULL) {
686 list_remove(&fuidp->z_domains, zdomain);
687 kmem_free(zdomain, sizeof (zfs_fuid_domain_t));
688 }
689
690 kmem_free(fuidp, sizeof (zfs_fuid_info_t));
691 }
692
693 /*
694 * Check to see if user ID is in the list of SIDs in CR.
695 */
696 boolean_t
697 zfs_user_in_cred(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
698 {
699 ksid_t *ksid = crgetsid(cr, KSID_USER);
700 ksidlist_t *ksidlist = crgetsidlist(cr);
701 uid_t uid;
702
703 /* Check for match with cred->cr_uid */
704 uid = zfs_fuid_map_id(zfsvfs, id, cr, ZFS_ACE_USER);
705 if (uid != IDMAP_WK_CREATOR_OWNER_UID &&
706 uid == crgetuid(cr))
707 return (B_TRUE);
708
709 /* Check for any match in the ksidlist */
710 if (ksid && ksidlist) {
711 int i;
712 ksid_t *ksid_vec;
713 uint32_t idx = FUID_INDEX(id);
714 uint32_t rid = FUID_RID(id);
715 const char *domain;
716
717 if (idx == 0) {
718 /*
719 * The ID passed in has idx zero, which means
720 * it's just a Unix UID. That can never match
721 * anything in ksid_vec[] because those all
722 * have ksid->ks_id set to a Group ID.
723 */
724 return (B_FALSE);
725 }
726
727 domain = zfs_fuid_find_by_idx(zfsvfs, idx);
728 ASSERT(domain != NULL);
729
730 if (strcmp(domain, IDMAP_WK_CREATOR_SID_AUTHORITY) == 0)
731 return (B_FALSE);
732
733 ksid_vec = ksidlist->ksl_sids;
734 for (i = 0; i != ksidlist->ksl_nsid; i++) {
735 if ((strcmp(domain,
736 ksid_vec[i].ks_domain->kd_name) == 0) &&
737 rid == ksid_vec[i].ks_rid)
738 return (B_TRUE);
739 }
740 }
741 return (B_FALSE);
742 }
743
744 /*
745 * Check to see if id is a groupmember. If cred
746 * has ksid info then sidlist is checked first
747 * and if still not found then POSIX groups are checked
748 *
749 * Will use a straight FUID compare when possible.
750 */
751 boolean_t
752 zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
753 {
754 ksid_t *ksid = crgetsid(cr, KSID_GROUP);
755 ksidlist_t *ksidlist = crgetsidlist(cr);
756 uid_t gid;
757
758 if (ksid && ksidlist) {
759 int i;
760 ksid_t *ksid_groups;
761 uint32_t idx = FUID_INDEX(id);
762 uint32_t rid = FUID_RID(id);
763
|