1 /* 2 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC. 3 * Copyright (C) 2007 The Regents of the University of California. 4 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). 5 * Written by Brian Behlendorf <behlendorf1@llnl.gov>. 6 * UCRL-CODE-235197 7 * 8 * This file is part of the SPL, Solaris Porting Layer. 9 * 10 * The SPL is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the 12 * Free Software Foundation; either version 2 of the License, or (at your 13 * option) any later version. 14 * 15 * The SPL is distributed in the hope that it will be useful, but WITHOUT 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18 * for more details. 19 * 20 * You should have received a copy of the GNU General Public License along 21 * with the SPL. If not, see <http://www.gnu.org/licenses/>. 22 * 23 * Solaris Porting Layer (SPL) Credential Implementation. 24 */ 25 26 #include <sys/cred.h> 27 28 static int 29 cr_groups_search(const struct group_info *group_info, kgid_t grp) 30 { 31 unsigned int left, right, mid; 32 int cmp; 33 34 if (!group_info) 35 return (0); 36 37 left = 0; 38 right = group_info->ngroups; 39 while (left < right) { 40 mid = (left + right) / 2; 41 cmp = KGID_TO_SGID(grp) - 42 KGID_TO_SGID(GROUP_AT(group_info, mid)); 43 44 if (cmp > 0) 45 left = mid + 1; 46 else if (cmp < 0) 47 right = mid; 48 else 49 return (1); 50 } 51 return (0); 52 } 53 54 /* Hold a reference on the credential */ 55 void 56 crhold(cred_t *cr) 57 { 58 (void) get_cred((const cred_t *)cr); 59 } 60 61 /* Free a reference on the credential */ 62 void 63 crfree(cred_t *cr) 64 { 65 put_cred((const cred_t *)cr); 66 } 67 68 /* Return the number of supplemental groups */ 69 int 70 crgetngroups(const cred_t *cr) 71 { 72 struct group_info *gi; 73 int rc; 74 75 gi = cr->group_info; 76 rc = gi->ngroups; 77 78 return (rc); 79 } 80 81 /* 82 * Return an array of supplemental gids. The returned address is safe 83 * to use as long as the caller has taken a reference with crhold(). 84 */ 85 gid_t * 86 crgetgroups(const cred_t *cr) 87 { 88 struct group_info *gi; 89 gid_t *gids = NULL; 90 91 gi = cr->group_info; 92 gids = KGIDP_TO_SGIDP(gi->gid); 93 94 return (gids); 95 } 96 97 /* Check if the passed gid is available in supplied credential. */ 98 int 99 groupmember(gid_t gid, const cred_t *cr) 100 { 101 struct group_info *gi; 102 int rc; 103 104 gi = cr->group_info; 105 rc = cr_groups_search(gi, SGID_TO_KGID(gid)); 106 107 return (rc); 108 } 109 110 /* Return the effective user id */ 111 uid_t 112 crgetuid(const cred_t *cr) 113 { 114 return (KUID_TO_SUID(cr->fsuid)); 115 } 116 117 /* Return the real user id */ 118 uid_t 119 crgetruid(const cred_t *cr) 120 { 121 return (KUID_TO_SUID(cr->uid)); 122 } 123 124 /* Return the effective group id */ 125 gid_t 126 crgetgid(const cred_t *cr) 127 { 128 return (KGID_TO_SGID(cr->fsgid)); 129 } 130 131 /* Return the initial user ns or nop_mnt_idmap */ 132 zidmap_t * 133 zfs_get_init_idmap(void) 134 { 135 #ifdef HAVE_IOPS_CREATE_IDMAP 136 return ((zidmap_t *)&nop_mnt_idmap); 137 #else 138 return ((zidmap_t *)&init_user_ns); 139 #endif 140 } 141 142 EXPORT_SYMBOL(zfs_get_init_idmap); 143 EXPORT_SYMBOL(crhold); 144 EXPORT_SYMBOL(crfree); 145 EXPORT_SYMBOL(crgetuid); 146 EXPORT_SYMBOL(crgetruid); 147 EXPORT_SYMBOL(crgetgid); 148 EXPORT_SYMBOL(crgetngroups); 149 EXPORT_SYMBOL(crgetgroups); 150 EXPORT_SYMBOL(groupmember); 151