Print this page
NEX-19350 User ACE incorrectly grants access to matching group IDs
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15035 Allow user ACE in ACL to match SID in token extra SIDs (part 2)
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-15035 Allow user ACE in ACL to match SID in token extra SIDs (part 2)
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-15035 Allow user ACE in ACL to match SID in token extra SIDs
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-15035 Allow user ACE in ACL to match SID in token extra SIDs
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>


   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