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