1 /* 2 * CDDL HEADER START 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 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #pragma weak _ucred_free = ucred_free 30 #pragma weak _ucred_get = ucred_get 31 #pragma weak _ucred_getegid = ucred_getegid 32 #pragma weak _ucred_geteuid = ucred_geteuid 33 #pragma weak _ucred_getgroups = ucred_getgroups 34 #pragma weak _ucred_getpflags = ucred_getpflags 35 #pragma weak _ucred_getpid = ucred_getpid 36 #pragma weak _ucred_getzoneid = ucred_getzoneid 37 #pragma weak _ucred_getprojid = ucred_getprojid 38 #pragma weak _ucred_getprivset = ucred_getprivset 39 #pragma weak _ucred_getrgid = ucred_getrgid 40 #pragma weak _ucred_getruid = ucred_getruid 41 #pragma weak _ucred_getsgid = ucred_getsgid 42 #pragma weak _ucred_getsuid = ucred_getsuid 43 #pragma weak _ucred_getauid = ucred_getauid 44 #pragma weak _ucred_getasid = ucred_getasid 45 #pragma weak _ucred_getatid = ucred_getatid 46 #pragma weak _ucred_getlabel = ucred_getlabel 47 #pragma weak _ucred_getamask = ucred_getamask 48 #pragma weak _ucred_size = ucred_size 49 50 #include "lint.h" 51 52 #define _STRUCTURED_PROC 1 53 54 #include "priv_private.h" 55 #include <errno.h> 56 #include <priv.h> 57 #include <stdarg.h> 58 #include <stdlib.h> 59 #include <stdio.h> 60 #include <unistd.h> 61 #include <ucred.h> 62 #include <limits.h> 63 #include <fcntl.h> 64 #include <door.h> 65 #include <alloca.h> 66 #include <sys/ucred.h> 67 #include <sys/procfs.h> 68 #include <sys/sysmacros.h> 69 #include <sys/zone.h> 70 #include <tsol/label.h> 71 72 ucred_t * 73 _ucred_alloc(void) 74 { 75 ucred_t *r; 76 size_t sz = ucred_size(); 77 78 r = malloc(sz); 79 80 if (r != NULL) 81 r->uc_size = (uint32_t)sz; 82 83 return (r); 84 } 85 86 void 87 ucred_free(ucred_t *uc) 88 { 89 free(uc); 90 } 91 92 93 ucred_t * 94 ucred_get(pid_t pid) 95 { 96 ucred_t *uc; 97 98 uc = _ucred_alloc(); 99 100 if (uc == NULL) 101 return (NULL); 102 103 if (syscall(SYS_ucredsys, UCREDSYS_UCREDGET, pid, uc) != 0) { 104 ucred_free(uc); 105 return (NULL); 106 } 107 108 return (uc); 109 } 110 111 uid_t 112 ucred_geteuid(const ucred_t *uc) 113 { 114 /* LINTED: alignment */ 115 const prcred_t *cr = UCCRED(uc); 116 117 if (cr == NULL) { 118 errno = EINVAL; 119 return ((uid_t)-1); 120 } 121 122 return (cr->pr_euid); 123 } 124 125 uid_t 126 ucred_getruid(const ucred_t *uc) 127 { 128 /* LINTED: alignment */ 129 const prcred_t *cr = UCCRED(uc); 130 131 if (cr == NULL) { 132 errno = EINVAL; 133 return ((uid_t)-1); 134 } 135 136 return (cr->pr_ruid); 137 } 138 139 uid_t 140 ucred_getsuid(const ucred_t *uc) 141 { 142 /* LINTED: alignment */ 143 const prcred_t *cr = UCCRED(uc); 144 145 if (cr == NULL) { 146 errno = EINVAL; 147 return ((uid_t)-1); 148 } 149 150 return (cr->pr_suid); 151 } 152 153 gid_t 154 ucred_getegid(const ucred_t *uc) 155 { 156 /* LINTED: alignment */ 157 const prcred_t *cr = UCCRED(uc); 158 159 if (cr == NULL) { 160 errno = EINVAL; 161 return ((gid_t)-1); 162 } 163 164 return (cr->pr_egid); 165 } 166 167 gid_t 168 ucred_getrgid(const ucred_t *uc) 169 { 170 /* LINTED: alignment */ 171 const prcred_t *cr = UCCRED(uc); 172 173 if (cr == NULL) { 174 errno = EINVAL; 175 return ((gid_t)-1); 176 } 177 178 return (cr->pr_rgid); 179 } 180 181 gid_t 182 ucred_getsgid(const ucred_t *uc) 183 { 184 /* LINTED: alignment */ 185 const prcred_t *cr = UCCRED(uc); 186 187 if (cr == NULL) { 188 errno = EINVAL; 189 return ((gid_t)-1); 190 } 191 192 return (cr->pr_sgid); 193 } 194 195 int 196 ucred_getgroups(const ucred_t *uc, const gid_t **grps) 197 { 198 /* LINTED: alignment */ 199 const prcred_t *cr = UCCRED(uc); 200 201 if (cr == NULL) { 202 errno = EINVAL; 203 return (-1); 204 } 205 206 if (cr->pr_ngroups > 0) 207 *grps = &cr->pr_groups[0]; 208 else 209 *grps = NULL; 210 211 return (cr->pr_ngroups); 212 } 213 214 const priv_set_t * 215 ucred_getprivset(const ucred_t *uc, priv_ptype_t set) 216 { 217 /* LINTED: alignment */ 218 const prpriv_t *pr = UCPRIV(uc); 219 int pset = priv_getsetbyname(set); 220 priv_data_t *d; 221 222 if (pr == NULL || pset == -1) { 223 errno = EINVAL; 224 return (NULL); 225 } 226 227 LOADPRIVDATA(d); 228 229 return ((const priv_set_t *) 230 &pr->pr_sets[d->pd_pinfo->priv_setsize * pset]); 231 } 232 233 pid_t 234 ucred_getpid(const ucred_t *uc) 235 { 236 237 if (uc->uc_pid == -1) 238 errno = EINVAL; 239 240 return (uc->uc_pid); 241 } 242 243 projid_t 244 ucred_getprojid(const ucred_t *uc) 245 { 246 247 if (uc->uc_projid == -1) 248 errno = EINVAL; 249 250 return (uc->uc_projid); 251 } 252 253 zoneid_t 254 ucred_getzoneid(const ucred_t *uc) 255 { 256 257 if (uc->uc_zoneid < MIN_ZONEID || uc->uc_zoneid > MAX_ZONEID) { 258 errno = EINVAL; 259 return (-1); 260 } 261 262 return (uc->uc_zoneid); 263 } 264 265 bslabel_t * 266 ucred_getlabel(const ucred_t *uc) 267 { 268 /* LINTED: alignment */ 269 bslabel_t *slabel = UCLABEL(uc); 270 271 if (!is_system_labeled() || slabel == NULL) { 272 errno = EINVAL; 273 return (NULL); 274 } 275 276 return (slabel); 277 } 278 279 /* 280 * For now, assume single bit flags. 281 */ 282 uint_t 283 ucred_getpflags(const ucred_t *uc, uint_t flag) 284 { 285 /* LINTED: alignment */ 286 prpriv_t *pr = UCPRIV(uc); 287 char *x, *end; 288 289 if (pr == NULL) { 290 errno = EINVAL; 291 return ((uint_t)-1); 292 } 293 294 end = (char *)pr + PRIV_PRPRIV_SIZE(pr); 295 x = end - pr->pr_infosize; 296 297 while (x < end) { 298 /* LINTED: alignment */ 299 priv_info_t *pi = (priv_info_t *)x; 300 priv_info_uint_t *pii; 301 302 switch (pi->priv_info_type) { 303 case PRIV_INFO_FLAGS: 304 /* LINTED: alignment */ 305 pii = (priv_info_uint_t *)x; 306 return ((pii->val & flag) ? 1 : 0); 307 } 308 /* Forward progress */ 309 if (pi->priv_info_size < sizeof (priv_info_t)) 310 break; 311 x += pi->priv_info_size; 312 } 313 314 errno = EINVAL; 315 return ((uint_t)-1); 316 } 317 318 au_id_t 319 ucred_getauid(const ucred_t *uc) 320 { 321 /* LINTED: alignment */ 322 const auditinfo64_addr_t *ainfo = UCAUD(uc); 323 324 if (ainfo == NULL) 325 return (AU_NOAUDITID); 326 327 return (ainfo->ai_auid); 328 } 329 330 au_asid_t 331 ucred_getasid(const ucred_t *uc) 332 { 333 /* LINTED: alignment */ 334 const auditinfo64_addr_t *ainfo = UCAUD(uc); 335 336 if (ainfo == NULL) 337 return (-1); 338 339 return (ainfo->ai_asid); 340 } 341 342 const au_tid64_addr_t * 343 ucred_getatid(const ucred_t *uc) 344 { 345 /* LINTED: alignment */ 346 const auditinfo64_addr_t *ainfo = UCAUD(uc); 347 348 if (ainfo == NULL) { 349 errno = EINVAL; 350 return (NULL); 351 } 352 353 return (&ainfo->ai_termid); 354 } 355 356 const au_mask_t * 357 ucred_getamask(const ucred_t *uc) 358 { 359 /* LINTED: alignment */ 360 const auditinfo64_addr_t *ainfo = UCAUD(uc); 361 362 if (ainfo == NULL) { 363 errno = EINVAL; 364 return (NULL); 365 } 366 367 return (&ainfo->ai_mask); 368 } 369 370 size_t 371 ucred_size(void) 372 { 373 priv_data_t *d; 374 375 LOADPRIVDATA(d); 376 377 return (d->pd_ucredsize); 378 } 379