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>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/zfs_fuid.c
          +++ new/usr/src/uts/common/fs/zfs/zfs_fuid.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  23   24   */
  24   25  
  25   26  #include <sys/zfs_context.h>
  26   27  #include <sys/dmu.h>
  27   28  #include <sys/avl.h>
  28   29  #include <sys/zap.h>
  29   30  #include <sys/refcount.h>
  30   31  #include <sys/nvpair.h>
  31   32  #ifdef _KERNEL
  32   33  #include <sys/kidmap.h>
↓ open down ↓ 457 lines elided ↑ open up ↑
 490  491   * is used unless it's an ephemeral ID in which case KSID_GROUP will
 491  492   * be used if it exists.
 492  493   */
 493  494  uint64_t
 494  495  zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
 495  496      cred_t *cr, zfs_fuid_info_t **fuidp)
 496  497  {
 497  498          uint64_t        idx;
 498  499          ksid_t          *ksid;
 499  500          uint32_t        rid;
 500      -        char            *kdomain;
      501 +        char            *kdomain;
 501  502          const char      *domain;
 502  503          uid_t           id;
 503  504  
 504  505          VERIFY(type == ZFS_OWNER || type == ZFS_GROUP);
 505  506  
 506  507          ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP);
 507  508  
 508  509          if (!zfsvfs->z_use_fuids || (ksid == NULL)) {
 509  510                  id = (type == ZFS_OWNER) ? crgetuid(cr) : crgetgid(cr);
 510  511  
↓ open down ↓ 172 lines elided ↑ open up ↑
 683  684  
 684  685          while ((zdomain = list_head(&fuidp->z_domains)) != NULL) {
 685  686                  list_remove(&fuidp->z_domains, zdomain);
 686  687                  kmem_free(zdomain, sizeof (zfs_fuid_domain_t));
 687  688          }
 688  689  
 689  690          kmem_free(fuidp, sizeof (zfs_fuid_info_t));
 690  691  }
 691  692  
 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 +/*
 693  745   * Check to see if id is a groupmember.  If cred
 694  746   * has ksid info then sidlist is checked first
 695  747   * and if still not found then POSIX groups are checked
 696  748   *
 697  749   * Will use a straight FUID compare when possible.
 698  750   */
 699  751  boolean_t
 700  752  zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
 701  753  {
 702  754          ksid_t          *ksid = crgetsid(cr, KSID_GROUP);
 703  755          ksidlist_t      *ksidlist = crgetsidlist(cr);
 704  756          uid_t           gid;
 705  757  
 706  758          if (ksid && ksidlist) {
 707      -                int             i;
      759 +                int             i;
 708  760                  ksid_t          *ksid_groups;
 709  761                  uint32_t        idx = FUID_INDEX(id);
 710  762                  uint32_t        rid = FUID_RID(id);
 711  763  
 712  764                  ksid_groups = ksidlist->ksl_sids;
 713  765  
 714  766                  for (i = 0; i != ksidlist->ksl_nsid; i++) {
 715  767                          if (idx == 0) {
 716  768                                  if (id != IDMAP_WK_CREATOR_GROUP_GID &&
 717  769                                      id == ksid_groups[i].ks_id) {
↓ open down ↓ 42 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX