10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*1676Sjpk * Common Development and Distribution License (the "License"). 6*1676Sjpk * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*1676Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate #pragma weak ucred_free = _ucred_free 290Sstevel@tonic-gate #pragma weak ucred_get = _ucred_get 300Sstevel@tonic-gate #pragma weak ucred_getegid = _ucred_getegid 310Sstevel@tonic-gate #pragma weak ucred_geteuid = _ucred_geteuid 320Sstevel@tonic-gate #pragma weak ucred_getgroups = _ucred_getgroups 330Sstevel@tonic-gate #pragma weak ucred_getpflags = _ucred_getpflags 340Sstevel@tonic-gate #pragma weak ucred_getpid = _ucred_getpid 350Sstevel@tonic-gate #pragma weak ucred_getzoneid = _ucred_getzoneid 360Sstevel@tonic-gate #pragma weak ucred_getprojid = _ucred_getprojid 370Sstevel@tonic-gate #pragma weak ucred_getprivset = _ucred_getprivset 380Sstevel@tonic-gate #pragma weak ucred_getrgid = _ucred_getrgid 390Sstevel@tonic-gate #pragma weak ucred_getruid = _ucred_getruid 400Sstevel@tonic-gate #pragma weak ucred_getsgid = _ucred_getsgid 410Sstevel@tonic-gate #pragma weak ucred_getsuid = _ucred_getsuid 420Sstevel@tonic-gate #pragma weak ucred_getauid = _ucred_getauid 430Sstevel@tonic-gate #pragma weak ucred_getasid = _ucred_getasid 440Sstevel@tonic-gate #pragma weak ucred_getatid = _ucred_getatid 45*1676Sjpk #pragma weak ucred_getlabel = _ucred_getlabel 460Sstevel@tonic-gate #pragma weak ucred_getamask = _ucred_getamask 470Sstevel@tonic-gate #pragma weak ucred_size = _ucred_size 480Sstevel@tonic-gate 490Sstevel@tonic-gate #include "synonyms.h" 500Sstevel@tonic-gate 510Sstevel@tonic-gate #define _STRUCTURED_PROC 1 520Sstevel@tonic-gate 530Sstevel@tonic-gate #include "priv_private.h" 540Sstevel@tonic-gate #include <errno.h> 550Sstevel@tonic-gate #include <priv.h> 560Sstevel@tonic-gate #include <stdarg.h> 570Sstevel@tonic-gate #include <stdlib.h> 580Sstevel@tonic-gate #include <stdio.h> 590Sstevel@tonic-gate #include <unistd.h> 600Sstevel@tonic-gate #include <ucred.h> 610Sstevel@tonic-gate #include <limits.h> 620Sstevel@tonic-gate #include <fcntl.h> 630Sstevel@tonic-gate #include <door.h> 640Sstevel@tonic-gate #include <alloca.h> 650Sstevel@tonic-gate #include <sys/ucred.h> 660Sstevel@tonic-gate #include <sys/procfs.h> 670Sstevel@tonic-gate #include <sys/sysmacros.h> 680Sstevel@tonic-gate #include <sys/zone.h> 69*1676Sjpk #include <tsol/label.h> 700Sstevel@tonic-gate 710Sstevel@tonic-gate ucred_t * 720Sstevel@tonic-gate _ucred_alloc(void) 730Sstevel@tonic-gate { 740Sstevel@tonic-gate ucred_t *r; 750Sstevel@tonic-gate size_t sz = ucred_size(); 760Sstevel@tonic-gate 770Sstevel@tonic-gate r = malloc(sz); 780Sstevel@tonic-gate 790Sstevel@tonic-gate if (r != NULL) 800Sstevel@tonic-gate r->uc_size = (uint32_t)sz; 810Sstevel@tonic-gate 820Sstevel@tonic-gate return (r); 830Sstevel@tonic-gate } 840Sstevel@tonic-gate 850Sstevel@tonic-gate void 860Sstevel@tonic-gate ucred_free(ucred_t *uc) 870Sstevel@tonic-gate { 880Sstevel@tonic-gate free(uc); 890Sstevel@tonic-gate } 900Sstevel@tonic-gate 910Sstevel@tonic-gate 920Sstevel@tonic-gate ucred_t * 930Sstevel@tonic-gate ucred_get(pid_t pid) 940Sstevel@tonic-gate { 950Sstevel@tonic-gate ucred_t *uc; 960Sstevel@tonic-gate 970Sstevel@tonic-gate uc = _ucred_alloc(); 980Sstevel@tonic-gate 990Sstevel@tonic-gate if (uc == NULL) 1000Sstevel@tonic-gate return (NULL); 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate if (syscall(SYS_ucredsys, UCREDSYS_UCREDGET, pid, uc) != 0) { 1030Sstevel@tonic-gate ucred_free(uc); 1040Sstevel@tonic-gate return (NULL); 1050Sstevel@tonic-gate } 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate return (uc); 1080Sstevel@tonic-gate } 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate uid_t 1110Sstevel@tonic-gate ucred_geteuid(const ucred_t *uc) 1120Sstevel@tonic-gate { 1130Sstevel@tonic-gate /* LINTED: alignment */ 1140Sstevel@tonic-gate const prcred_t *cr = UCCRED(uc); 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate if (cr == NULL) { 1170Sstevel@tonic-gate errno = EINVAL; 1180Sstevel@tonic-gate return (-1); 1190Sstevel@tonic-gate } 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate return (cr->pr_euid); 1220Sstevel@tonic-gate } 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate uid_t 1250Sstevel@tonic-gate ucred_getruid(const ucred_t *uc) 1260Sstevel@tonic-gate { 1270Sstevel@tonic-gate /* LINTED: alignment */ 1280Sstevel@tonic-gate const prcred_t *cr = UCCRED(uc); 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate if (cr == NULL) { 1310Sstevel@tonic-gate errno = EINVAL; 1320Sstevel@tonic-gate return (-1); 1330Sstevel@tonic-gate } 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate return (cr->pr_ruid); 1360Sstevel@tonic-gate } 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate uid_t 1390Sstevel@tonic-gate ucred_getsuid(const ucred_t *uc) 1400Sstevel@tonic-gate { 1410Sstevel@tonic-gate /* LINTED: alignment */ 1420Sstevel@tonic-gate const prcred_t *cr = UCCRED(uc); 1430Sstevel@tonic-gate 1440Sstevel@tonic-gate if (cr == NULL) { 1450Sstevel@tonic-gate errno = EINVAL; 1460Sstevel@tonic-gate return (-1); 1470Sstevel@tonic-gate } 1480Sstevel@tonic-gate 1490Sstevel@tonic-gate return (cr->pr_suid); 1500Sstevel@tonic-gate } 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate gid_t 1530Sstevel@tonic-gate ucred_getegid(const ucred_t *uc) 1540Sstevel@tonic-gate { 1550Sstevel@tonic-gate /* LINTED: alignment */ 1560Sstevel@tonic-gate const prcred_t *cr = UCCRED(uc); 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate if (cr == NULL) { 1590Sstevel@tonic-gate errno = EINVAL; 1600Sstevel@tonic-gate return (-1); 1610Sstevel@tonic-gate } 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate return (cr->pr_egid); 1640Sstevel@tonic-gate } 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate gid_t 1670Sstevel@tonic-gate ucred_getrgid(const ucred_t *uc) 1680Sstevel@tonic-gate { 1690Sstevel@tonic-gate /* LINTED: alignment */ 1700Sstevel@tonic-gate const prcred_t *cr = UCCRED(uc); 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate if (cr == NULL) { 1730Sstevel@tonic-gate errno = EINVAL; 1740Sstevel@tonic-gate return (-1); 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate return (cr->pr_rgid); 1780Sstevel@tonic-gate } 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate gid_t 1810Sstevel@tonic-gate ucred_getsgid(const ucred_t *uc) 1820Sstevel@tonic-gate { 1830Sstevel@tonic-gate /* LINTED: alignment */ 1840Sstevel@tonic-gate const prcred_t *cr = UCCRED(uc); 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate if (cr == NULL) { 1870Sstevel@tonic-gate errno = EINVAL; 1880Sstevel@tonic-gate return (-1); 1890Sstevel@tonic-gate } 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate return (cr->pr_sgid); 1920Sstevel@tonic-gate } 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate int 1950Sstevel@tonic-gate ucred_getgroups(const ucred_t *uc, const gid_t **grps) 1960Sstevel@tonic-gate { 1970Sstevel@tonic-gate /* LINTED: alignment */ 1980Sstevel@tonic-gate const prcred_t *cr = UCCRED(uc); 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate if (cr == NULL) { 2010Sstevel@tonic-gate errno = EINVAL; 2020Sstevel@tonic-gate return (-1); 2030Sstevel@tonic-gate } 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate if (cr->pr_ngroups > 0) 2060Sstevel@tonic-gate *grps = &cr->pr_groups[0]; 2070Sstevel@tonic-gate else 2080Sstevel@tonic-gate *grps = NULL; 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate return (cr->pr_ngroups); 2110Sstevel@tonic-gate } 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate const priv_set_t * 2140Sstevel@tonic-gate ucred_getprivset(const ucred_t *uc, priv_ptype_t set) 2150Sstevel@tonic-gate { 2160Sstevel@tonic-gate /* LINTED: alignment */ 2170Sstevel@tonic-gate const prpriv_t *pr = UCPRIV(uc); 2180Sstevel@tonic-gate int pset = priv_getsetbyname(set); 2190Sstevel@tonic-gate priv_data_t *d; 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate if (pr == NULL || pset == -1) { 2220Sstevel@tonic-gate errno = EINVAL; 2230Sstevel@tonic-gate return (NULL); 2240Sstevel@tonic-gate } 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate LOADPRIVDATA(d); 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate return ((const priv_set_t *) 2290Sstevel@tonic-gate &pr->pr_sets[d->pd_pinfo->priv_setsize * pset]); 2300Sstevel@tonic-gate } 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate pid_t 2330Sstevel@tonic-gate ucred_getpid(const ucred_t *uc) 2340Sstevel@tonic-gate { 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate if (uc->uc_pid == -1) 2370Sstevel@tonic-gate errno = EINVAL; 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate return (uc->uc_pid); 2400Sstevel@tonic-gate } 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate projid_t 2430Sstevel@tonic-gate ucred_getprojid(const ucred_t *uc) 2440Sstevel@tonic-gate { 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate if (uc->uc_projid == -1) 2470Sstevel@tonic-gate errno = EINVAL; 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate return (uc->uc_projid); 2500Sstevel@tonic-gate } 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate zoneid_t 2530Sstevel@tonic-gate ucred_getzoneid(const ucred_t *uc) 2540Sstevel@tonic-gate { 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate if (uc->uc_zoneid < MIN_ZONEID || uc->uc_zoneid > MAX_ZONEID) { 2570Sstevel@tonic-gate errno = EINVAL; 2580Sstevel@tonic-gate return (-1); 2590Sstevel@tonic-gate } 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate return (uc->uc_zoneid); 2620Sstevel@tonic-gate } 2630Sstevel@tonic-gate 264*1676Sjpk bslabel_t * 265*1676Sjpk ucred_getlabel(const ucred_t *uc) 266*1676Sjpk { 267*1676Sjpk /* LINTED: alignment */ 268*1676Sjpk bslabel_t *slabel = UCLABEL(uc); 269*1676Sjpk 270*1676Sjpk if (!is_system_labeled() || slabel == NULL) { 271*1676Sjpk errno = EINVAL; 272*1676Sjpk return (NULL); 273*1676Sjpk } 274*1676Sjpk 275*1676Sjpk return (slabel); 276*1676Sjpk } 277*1676Sjpk 2780Sstevel@tonic-gate /* 2790Sstevel@tonic-gate * For now, assume single bit flags. 2800Sstevel@tonic-gate */ 2810Sstevel@tonic-gate uint_t 2820Sstevel@tonic-gate ucred_getpflags(const ucred_t *uc, uint_t flag) 2830Sstevel@tonic-gate { 2840Sstevel@tonic-gate /* LINTED: alignment */ 2850Sstevel@tonic-gate prpriv_t *pr = UCPRIV(uc); 2860Sstevel@tonic-gate char *x, *end; 2870Sstevel@tonic-gate 2880Sstevel@tonic-gate if (pr == NULL) { 2890Sstevel@tonic-gate errno = EINVAL; 2900Sstevel@tonic-gate return ((uint_t)-1); 2910Sstevel@tonic-gate } 2920Sstevel@tonic-gate 2930Sstevel@tonic-gate end = (char *)pr + PRIV_PRPRIV_SIZE(pr); 2940Sstevel@tonic-gate x = end - pr->pr_infosize; 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate while (x < end) { 2970Sstevel@tonic-gate /* LINTED: alignment */ 2980Sstevel@tonic-gate priv_info_t *pi = (priv_info_t *)x; 2990Sstevel@tonic-gate priv_info_uint_t *pii; 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate switch (pi->priv_info_type) { 3020Sstevel@tonic-gate case PRIV_INFO_FLAGS: 3030Sstevel@tonic-gate /* LINTED: alignment */ 3040Sstevel@tonic-gate pii = (priv_info_uint_t *)x; 3050Sstevel@tonic-gate return ((pii->val & flag) ? 1 : 0); 3060Sstevel@tonic-gate } 3070Sstevel@tonic-gate /* Forward progress */ 3080Sstevel@tonic-gate if (pi->priv_info_size < sizeof (priv_info_t)) 3090Sstevel@tonic-gate break; 3100Sstevel@tonic-gate x += pi->priv_info_size; 3110Sstevel@tonic-gate } 3120Sstevel@tonic-gate 3130Sstevel@tonic-gate errno = EINVAL; 3140Sstevel@tonic-gate return ((uint_t)-1); 3150Sstevel@tonic-gate } 3160Sstevel@tonic-gate 3170Sstevel@tonic-gate au_id_t 3180Sstevel@tonic-gate ucred_getauid(const ucred_t *uc) 3190Sstevel@tonic-gate { 3200Sstevel@tonic-gate /* LINTED: alignment */ 3210Sstevel@tonic-gate const auditinfo64_addr_t *ainfo = UCAUD(uc); 3220Sstevel@tonic-gate 3230Sstevel@tonic-gate if (ainfo == NULL) 3240Sstevel@tonic-gate return (AU_NOAUDITID); 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate return (ainfo->ai_auid); 3270Sstevel@tonic-gate } 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate au_asid_t 3300Sstevel@tonic-gate ucred_getasid(const ucred_t *uc) 3310Sstevel@tonic-gate { 3320Sstevel@tonic-gate /* LINTED: alignment */ 3330Sstevel@tonic-gate const auditinfo64_addr_t *ainfo = UCAUD(uc); 3340Sstevel@tonic-gate 3350Sstevel@tonic-gate if (ainfo == NULL) 3360Sstevel@tonic-gate return (-1); 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate return (ainfo->ai_asid); 3390Sstevel@tonic-gate } 3400Sstevel@tonic-gate 3410Sstevel@tonic-gate const au_tid64_addr_t * 3420Sstevel@tonic-gate ucred_getatid(const ucred_t *uc) 3430Sstevel@tonic-gate { 3440Sstevel@tonic-gate /* LINTED: alignment */ 3450Sstevel@tonic-gate const auditinfo64_addr_t *ainfo = UCAUD(uc); 3460Sstevel@tonic-gate 3470Sstevel@tonic-gate if (ainfo == NULL) { 3480Sstevel@tonic-gate errno = EINVAL; 3490Sstevel@tonic-gate return (NULL); 3500Sstevel@tonic-gate } 3510Sstevel@tonic-gate 3520Sstevel@tonic-gate return (&ainfo->ai_termid); 3530Sstevel@tonic-gate } 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate const au_mask_t * 3560Sstevel@tonic-gate ucred_getamask(const ucred_t *uc) 3570Sstevel@tonic-gate { 3580Sstevel@tonic-gate /* LINTED: alignment */ 3590Sstevel@tonic-gate const auditinfo64_addr_t *ainfo = UCAUD(uc); 3600Sstevel@tonic-gate 3610Sstevel@tonic-gate if (ainfo == NULL) { 3620Sstevel@tonic-gate errno = EINVAL; 3630Sstevel@tonic-gate return (NULL); 3640Sstevel@tonic-gate } 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate return (&ainfo->ai_mask); 3670Sstevel@tonic-gate } 3680Sstevel@tonic-gate 3690Sstevel@tonic-gate size_t 3700Sstevel@tonic-gate ucred_size(void) 3710Sstevel@tonic-gate { 3720Sstevel@tonic-gate priv_data_t *d; 3730Sstevel@tonic-gate 3740Sstevel@tonic-gate LOADPRIVDATA(d); 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate return (d->pd_ucredsize); 3770Sstevel@tonic-gate } 378