17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
545916cdjpk * Common Development and Distribution License (the "License").
645916cdjpk * You may not use this file except in compliance with the License.
77c478bdstevel@tonic-gate *
87c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bdstevel@tonic-gate * See the License for the specific language governing permissions
117c478bdstevel@tonic-gate * and limitations under the License.
127c478bdstevel@tonic-gate *
137c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bdstevel@tonic-gate *
197c478bdstevel@tonic-gate * CDDL HEADER END
207c478bdstevel@tonic-gate */
217257d1braf
227c478bdstevel@tonic-gate/*
237257d1braf * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
247c478bdstevel@tonic-gate * Use is subject to license terms.
257c478bdstevel@tonic-gate */
267c478bdstevel@tonic-gate
277c478bdstevel@tonic-gate
287257d1braf#pragma weak _ucred_free = ucred_free
297257d1braf#pragma weak _ucred_get = ucred_get
307257d1braf#pragma weak _ucred_getegid = ucred_getegid
317257d1braf#pragma weak _ucred_geteuid = ucred_geteuid
327257d1braf#pragma weak _ucred_getgroups = ucred_getgroups
337257d1braf#pragma weak _ucred_getpflags = ucred_getpflags
347257d1braf#pragma weak _ucred_getpid = ucred_getpid
357257d1braf#pragma weak _ucred_getzoneid = ucred_getzoneid
367257d1braf#pragma weak _ucred_getprojid = ucred_getprojid
377257d1braf#pragma weak _ucred_getprivset = ucred_getprivset
387257d1braf#pragma weak _ucred_getrgid = ucred_getrgid
397257d1braf#pragma weak _ucred_getruid = ucred_getruid
407257d1braf#pragma weak _ucred_getsgid = ucred_getsgid
417257d1braf#pragma weak _ucred_getsuid = ucred_getsuid
427257d1braf#pragma weak _ucred_getauid = ucred_getauid
437257d1braf#pragma weak _ucred_getasid = ucred_getasid
447257d1braf#pragma weak _ucred_getatid = ucred_getatid
457257d1braf#pragma weak _ucred_getlabel = ucred_getlabel
467257d1braf#pragma weak _ucred_getamask = ucred_getamask
477257d1braf#pragma weak _ucred_size = ucred_size
487257d1braf
497257d1braf#include "lint.h"
507c478bdstevel@tonic-gate
517c478bdstevel@tonic-gate#define	_STRUCTURED_PROC	1
527c478bdstevel@tonic-gate
537c478bdstevel@tonic-gate#include "priv_private.h"
547c478bdstevel@tonic-gate#include <errno.h>
557c478bdstevel@tonic-gate#include <priv.h>
567c478bdstevel@tonic-gate#include <stdarg.h>
577c478bdstevel@tonic-gate#include <stdlib.h>
587c478bdstevel@tonic-gate#include <stdio.h>
597c478bdstevel@tonic-gate#include <unistd.h>
607c478bdstevel@tonic-gate#include <ucred.h>
617c478bdstevel@tonic-gate#include <limits.h>
627c478bdstevel@tonic-gate#include <fcntl.h>
637c478bdstevel@tonic-gate#include <door.h>
647c478bdstevel@tonic-gate#include <alloca.h>
657c478bdstevel@tonic-gate#include <sys/ucred.h>
667c478bdstevel@tonic-gate#include <sys/procfs.h>
677c478bdstevel@tonic-gate#include <sys/sysmacros.h>
687c478bdstevel@tonic-gate#include <sys/zone.h>
6945916cdjpk#include <tsol/label.h>
707c478bdstevel@tonic-gate
717c478bdstevel@tonic-gateucred_t *
727c478bdstevel@tonic-gate_ucred_alloc(void)
737c478bdstevel@tonic-gate{
747c478bdstevel@tonic-gate	ucred_t *r;
757c478bdstevel@tonic-gate	size_t sz = ucred_size();
767c478bdstevel@tonic-gate
777c478bdstevel@tonic-gate	r = malloc(sz);
787c478bdstevel@tonic-gate
797c478bdstevel@tonic-gate	if (r != NULL)
807c478bdstevel@tonic-gate		r->uc_size = (uint32_t)sz;
817c478bdstevel@tonic-gate
827c478bdstevel@tonic-gate	return (r);
837c478bdstevel@tonic-gate}
847c478bdstevel@tonic-gate
857c478bdstevel@tonic-gatevoid
867c478bdstevel@tonic-gateucred_free(ucred_t *uc)
877c478bdstevel@tonic-gate{
887c478bdstevel@tonic-gate	free(uc);
897c478bdstevel@tonic-gate}
907c478bdstevel@tonic-gate
917c478bdstevel@tonic-gate
927c478bdstevel@tonic-gateucred_t *
937c478bdstevel@tonic-gateucred_get(pid_t pid)
947c478bdstevel@tonic-gate{
957c478bdstevel@tonic-gate	ucred_t *uc;
967c478bdstevel@tonic-gate
977c478bdstevel@tonic-gate	uc = _ucred_alloc();
987c478bdstevel@tonic-gate
997c478bdstevel@tonic-gate	if (uc == NULL)
1007c478bdstevel@tonic-gate		return (NULL);
1017c478bdstevel@tonic-gate
1027c478bdstevel@tonic-gate	if (syscall(SYS_ucredsys, UCREDSYS_UCREDGET, pid, uc) != 0) {
1037c478bdstevel@tonic-gate		ucred_free(uc);
1047c478bdstevel@tonic-gate		return (NULL);
1057c478bdstevel@tonic-gate	}
1067c478bdstevel@tonic-gate
1077c478bdstevel@tonic-gate	return (uc);
1087c478bdstevel@tonic-gate}
1097c478bdstevel@tonic-gate
1107c478bdstevel@tonic-gateuid_t
1117c478bdstevel@tonic-gateucred_geteuid(const ucred_t *uc)
1127c478bdstevel@tonic-gate{
1137c478bdstevel@tonic-gate	/* LINTED: alignment */
1147c478bdstevel@tonic-gate	const prcred_t *cr = UCCRED(uc);
1157c478bdstevel@tonic-gate
1167c478bdstevel@tonic-gate	if (cr == NULL) {
1177c478bdstevel@tonic-gate		errno = EINVAL;
118f48205bcasper		return ((uid_t)-1);
1197c478bdstevel@tonic-gate	}
1207c478bdstevel@tonic-gate
1217c478bdstevel@tonic-gate	return (cr->pr_euid);
1227c478bdstevel@tonic-gate}
1237c478bdstevel@tonic-gate
1247c478bdstevel@tonic-gateuid_t
1257c478bdstevel@tonic-gateucred_getruid(const ucred_t *uc)
1267c478bdstevel@tonic-gate{
1277c478bdstevel@tonic-gate	/* LINTED: alignment */
1287c478bdstevel@tonic-gate	const prcred_t *cr = UCCRED(uc);
1297c478bdstevel@tonic-gate
1307c478bdstevel@tonic-gate	if (cr == NULL) {
1317c478bdstevel@tonic-gate		errno = EINVAL;
132f48205bcasper		return ((uid_t)-1);
1337c478bdstevel@tonic-gate	}
1347c478bdstevel@tonic-gate
1357c478bdstevel@tonic-gate	return (cr->pr_ruid);
1367c478bdstevel@tonic-gate}
1377c478bdstevel@tonic-gate
1387c478bdstevel@tonic-gateuid_t
1397c478bdstevel@tonic-gateucred_getsuid(const ucred_t *uc)
1407c478bdstevel@tonic-gate{
1417c478bdstevel@tonic-gate	/* LINTED: alignment */
1427c478bdstevel@tonic-gate	const prcred_t *cr = UCCRED(uc);
1437c478bdstevel@tonic-gate
1447c478bdstevel@tonic-gate	if (cr == NULL) {
1457c478bdstevel@tonic-gate		errno = EINVAL;
146f48205bcasper		return ((uid_t)-1);
1477c478bdstevel@tonic-gate	}
1487c478bdstevel@tonic-gate
1497c478bdstevel@tonic-gate	return (cr->pr_suid);
1507c478bdstevel@tonic-gate}
1517c478bdstevel@tonic-gate
1527c478bdstevel@tonic-gategid_t
1537c478bdstevel@tonic-gateucred_getegid(const ucred_t *uc)
1547c478bdstevel@tonic-gate{
1557c478bdstevel@tonic-gate	/* LINTED: alignment */
1567c478bdstevel@tonic-gate	const prcred_t *cr = UCCRED(uc);
1577c478bdstevel@tonic-gate
1587c478bdstevel@tonic-gate	if (cr == NULL) {
1597c478bdstevel@tonic-gate		errno = EINVAL;
160f48205bcasper		return ((gid_t)-1);
1617c478bdstevel@tonic-gate	}
1627c478bdstevel@tonic-gate
1637c478bdstevel@tonic-gate	return (cr->pr_egid);
1647c478bdstevel@tonic-gate}
1657c478bdstevel@tonic-gate
1667c478bdstevel@tonic-gategid_t
1677c478bdstevel@tonic-gateucred_getrgid(const ucred_t *uc)
1687c478bdstevel@tonic-gate{
1697c478bdstevel@tonic-gate	/* LINTED: alignment */
1707c478bdstevel@tonic-gate	const prcred_t *cr = UCCRED(uc);
1717c478bdstevel@tonic-gate
1727c478bdstevel@tonic-gate	if (cr == NULL) {
1737c478bdstevel@tonic-gate		errno = EINVAL;
174f48205bcasper		return ((gid_t)-1);
1757c478bdstevel@tonic-gate	}
1767c478bdstevel@tonic-gate
1777c478bdstevel@tonic-gate	return (cr->pr_rgid);
1787c478bdstevel@tonic-gate}
1797c478bdstevel@tonic-gate
1807c478bdstevel@tonic-gategid_t
1817c478bdstevel@tonic-gateucred_getsgid(const ucred_t *uc)
1827c478bdstevel@tonic-gate{
1837c478bdstevel@tonic-gate	/* LINTED: alignment */
1847c478bdstevel@tonic-gate	const prcred_t *cr = UCCRED(uc);
1857c478bdstevel@tonic-gate
1867c478bdstevel@tonic-gate	if (cr == NULL) {
1877c478bdstevel@tonic-gate		errno = EINVAL;
188f48205bcasper		return ((gid_t)-1);
1897c478bdstevel@tonic-gate	}
1907c478bdstevel@tonic-gate
1917c478bdstevel@tonic-gate	return (cr->pr_sgid);
1927c478bdstevel@tonic-gate}
1937c478bdstevel@tonic-gate
1947c478bdstevel@tonic-gateint
1957c478bdstevel@tonic-gateucred_getgroups(const ucred_t *uc, const gid_t **grps)
1967c478bdstevel@tonic-gate{
1977c478bdstevel@tonic-gate	/* LINTED: alignment */
1987c478bdstevel@tonic-gate	const prcred_t *cr = UCCRED(uc);
1997c478bdstevel@tonic-gate
2007c478bdstevel@tonic-gate	if (cr == NULL) {
2017c478bdstevel@tonic-gate		errno = EINVAL;
2027c478bdstevel@tonic-gate		return (-1);
2037c478bdstevel@tonic-gate	}
2047c478bdstevel@tonic-gate
2057c478bdstevel@tonic-gate	if (cr->pr_ngroups > 0)
2067c478bdstevel@tonic-gate		*grps = &cr->pr_groups[0];
2077c478bdstevel@tonic-gate	else
2087c478bdstevel@tonic-gate		*grps = NULL;
2097c478bdstevel@tonic-gate
2107c478bdstevel@tonic-gate	return (cr->pr_ngroups);
2117c478bdstevel@tonic-gate}
2127c478bdstevel@tonic-gate
2137c478bdstevel@tonic-gateconst priv_set_t *
2147c478bdstevel@tonic-gateucred_getprivset(const ucred_t *uc, priv_ptype_t set)
2157c478bdstevel@tonic-gate{
2167c478bdstevel@tonic-gate	/* LINTED: alignment */
2177c478bdstevel@tonic-gate	const prpriv_t *pr = UCPRIV(uc);
2187c478bdstevel@tonic-gate	int pset = priv_getsetbyname(set);
2197c478bdstevel@tonic-gate	priv_data_t *d;
2207c478bdstevel@tonic-gate
2217c478bdstevel@tonic-gate	if (pr == NULL || pset == -1) {
2227c478bdstevel@tonic-gate		errno = EINVAL;
2237c478bdstevel@tonic-gate		return (NULL);
2247c478bdstevel@tonic-gate	}
2257c478bdstevel@tonic-gate
2267c478bdstevel@tonic-gate	LOADPRIVDATA(d);
2277c478bdstevel@tonic-gate
2287c478bdstevel@tonic-gate	return ((const priv_set_t *)
2297c478bdstevel@tonic-gate	    &pr->pr_sets[d->pd_pinfo->priv_setsize * pset]);
2307c478bdstevel@tonic-gate}
2317c478bdstevel@tonic-gate
2327c478bdstevel@tonic-gatepid_t
2337c478bdstevel@tonic-gateucred_getpid(const ucred_t *uc)
2347c478bdstevel@tonic-gate{
2357c478bdstevel@tonic-gate
2367c478bdstevel@tonic-gate	if (uc->uc_pid == -1)
2377c478bdstevel@tonic-gate		errno = EINVAL;
2387c478bdstevel@tonic-gate
2397c478bdstevel@tonic-gate	return (uc->uc_pid);
2407c478bdstevel@tonic-gate}
2417c478bdstevel@tonic-gate
2427c478bdstevel@tonic-gateprojid_t
2437c478bdstevel@tonic-gateucred_getprojid(const ucred_t *uc)
2447c478bdstevel@tonic-gate{
2457c478bdstevel@tonic-gate
2467c478bdstevel@tonic-gate	if (uc->uc_projid == -1)
2477c478bdstevel@tonic-gate		errno = EINVAL;
2487c478bdstevel@tonic-gate
2497c478bdstevel@tonic-gate	return (uc->uc_projid);
2507c478bdstevel@tonic-gate}
2517c478bdstevel@tonic-gate
2527c478bdstevel@tonic-gatezoneid_t
2537c478bdstevel@tonic-gateucred_getzoneid(const ucred_t *uc)
2547c478bdstevel@tonic-gate{
2557c478bdstevel@tonic-gate
2567c478bdstevel@tonic-gate	if (uc->uc_zoneid < MIN_ZONEID || uc->uc_zoneid > MAX_ZONEID) {
2577c478bdstevel@tonic-gate		errno = EINVAL;
2587c478bdstevel@tonic-gate		return (-1);
2597c478bdstevel@tonic-gate	}
2607c478bdstevel@tonic-gate
2617c478bdstevel@tonic-gate	return (uc->uc_zoneid);
2627c478bdstevel@tonic-gate}
2637c478bdstevel@tonic-gate
26445916cdjpkbslabel_t *
26545916cdjpkucred_getlabel(const ucred_t *uc)
26645916cdjpk{
26745916cdjpk	/* LINTED: alignment */
26845916cdjpk	bslabel_t *slabel = UCLABEL(uc);
26945916cdjpk
27045916cdjpk	if (!is_system_labeled() || slabel == NULL) {
27145916cdjpk		errno = EINVAL;
27245916cdjpk		return (NULL);
27345916cdjpk	}
27445916cdjpk
27545916cdjpk	return (slabel);
27645916cdjpk}
27745916cdjpk
2787c478bdstevel@tonic-gate/*
2797c478bdstevel@tonic-gate * For now, assume single bit flags.
2807c478bdstevel@tonic-gate */
2817c478bdstevel@tonic-gateuint_t
2827c478bdstevel@tonic-gateucred_getpflags(const ucred_t *uc, uint_t flag)
2837c478bdstevel@tonic-gate{
2847c478bdstevel@tonic-gate	/* LINTED: alignment */
2857c478bdstevel@tonic-gate	prpriv_t *pr = UCPRIV(uc);
2867c478bdstevel@tonic-gate	char *x, *end;
2877c478bdstevel@tonic-gate
2887c478bdstevel@tonic-gate	if (pr == NULL) {
2897c478bdstevel@tonic-gate		errno = EINVAL;
2907c478bdstevel@tonic-gate		return ((uint_t)-1);
2917c478bdstevel@tonic-gate	}
2927c478bdstevel@tonic-gate
2937c478bdstevel@tonic-gate	end = (char *)pr + PRIV_PRPRIV_SIZE(pr);
2947c478bdstevel@tonic-gate	x = end - pr->pr_infosize;
2957c478bdstevel@tonic-gate
2967c478bdstevel@tonic-gate	while (x < end) {
2977c478bdstevel@tonic-gate		/* LINTED: alignment */
2987c478bdstevel@tonic-gate		priv_info_t *pi = (priv_info_t *)x;
2997c478bdstevel@tonic-gate		priv_info_uint_t *pii;
3007c478bdstevel@tonic-gate
3017c478bdstevel@tonic-gate		switch (pi->priv_info_type) {
3027c478bdstevel@tonic-gate		case PRIV_INFO_FLAGS:
3037c478bdstevel@tonic-gate			/* LINTED: alignment */
3047c478bdstevel@tonic-gate			pii = (priv_info_uint_t *)x;
3057c478bdstevel@tonic-gate			return ((pii->val & flag) ? 1 : 0);
3067c478bdstevel@tonic-gate		}
3077c478bdstevel@tonic-gate		/* Forward progress */
3087c478bdstevel@tonic-gate		if (pi->priv_info_size < sizeof (priv_info_t))
3097c478bdstevel@tonic-gate			break;
3107c478bdstevel@tonic-gate		x += pi->priv_info_size;
3117c478bdstevel@tonic-gate	}
3127c478bdstevel@tonic-gate
3137c478bdstevel@tonic-gate	errno = EINVAL;
3147c478bdstevel@tonic-gate	return ((uint_t)-1);
3157c478bdstevel@tonic-gate}
3167c478bdstevel@tonic-gate
3177c478bdstevel@tonic-gateau_id_t
3187c478bdstevel@tonic-gateucred_getauid(const ucred_t *uc)
3197c478bdstevel@tonic-gate{
3207c478bdstevel@tonic-gate	/* LINTED: alignment */
3217c478bdstevel@tonic-gate	const auditinfo64_addr_t *ainfo = UCAUD(uc);
3227c478bdstevel@tonic-gate
3237c478bdstevel@tonic-gate	if (ainfo == NULL)
3247c478bdstevel@tonic-gate		return (AU_NOAUDITID);
3257c478bdstevel@tonic-gate
3267c478bdstevel@tonic-gate	return (ainfo->ai_auid);
3277c478bdstevel@tonic-gate}
3287c478bdstevel@tonic-gate
3297c478bdstevel@tonic-gateau_asid_t
3307c478bdstevel@tonic-gateucred_getasid(const ucred_t *uc)
3317c478bdstevel@tonic-gate{
3327c478bdstevel@tonic-gate	/* LINTED: alignment */
3337c478bdstevel@tonic-gate	const auditinfo64_addr_t *ainfo = UCAUD(uc);
3347c478bdstevel@tonic-gate
3357c478bdstevel@tonic-gate	if (ainfo == NULL)
336d0fa49bTony Nguyen		return ((au_asid_t)-1);
3377c478bdstevel@tonic-gate
3387c478bdstevel@tonic-gate	return (ainfo->ai_asid);
3397c478bdstevel@tonic-gate}
3407c478bdstevel@tonic-gate
3417c478bdstevel@tonic-gateconst au_tid64_addr_t *
3427c478bdstevel@tonic-gateucred_getatid(const ucred_t *uc)
3437c478bdstevel@tonic-gate{
3447c478bdstevel@tonic-gate	/* LINTED: alignment */
3457c478bdstevel@tonic-gate	const auditinfo64_addr_t *ainfo = UCAUD(uc);
3467c478bdstevel@tonic-gate
3477c478bdstevel@tonic-gate	if (ainfo == NULL) {
3487c478bdstevel@tonic-gate		errno = EINVAL;
3497c478bdstevel@tonic-gate		return (NULL);
3507c478bdstevel@tonic-gate	}
3517c478bdstevel@tonic-gate
3527c478bdstevel@tonic-gate	return (&ainfo->ai_termid);
3537c478bdstevel@tonic-gate}
3547c478bdstevel@tonic-gate
3557c478bdstevel@tonic-gateconst au_mask_t *
3567c478bdstevel@tonic-gateucred_getamask(const ucred_t *uc)
3577c478bdstevel@tonic-gate{
3587c478bdstevel@tonic-gate	/* LINTED: alignment */
3597c478bdstevel@tonic-gate	const auditinfo64_addr_t *ainfo = UCAUD(uc);
3607c478bdstevel@tonic-gate
3617c478bdstevel@tonic-gate	if (ainfo == NULL) {
3627c478bdstevel@tonic-gate		errno = EINVAL;
3637c478bdstevel@tonic-gate		return (NULL);
3647c478bdstevel@tonic-gate	}
3657c478bdstevel@tonic-gate
3667c478bdstevel@tonic-gate	return (&ainfo->ai_mask);
3677c478bdstevel@tonic-gate}
3687c478bdstevel@tonic-gate
3697c478bdstevel@tonic-gatesize_t
3707c478bdstevel@tonic-gateucred_size(void)
3717c478bdstevel@tonic-gate{
3727c478bdstevel@tonic-gate	priv_data_t *d;
3737c478bdstevel@tonic-gate
3747c478bdstevel@tonic-gate	LOADPRIVDATA(d);
3757c478bdstevel@tonic-gate
3767c478bdstevel@tonic-gate	return (d->pd_ucredsize);
3777c478bdstevel@tonic-gate}
378