xref: /illumos-gate/usr/src/lib/libc/port/gen/ucred.c (revision 8eea8e29)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 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_getamask = _ucred_getamask
47 #pragma weak ucred_size	 = _ucred_size
48 
49 #include "synonyms.h"
50 
51 #define	_STRUCTURED_PROC	1
52 
53 #include "priv_private.h"
54 #include <errno.h>
55 #include <priv.h>
56 #include <stdarg.h>
57 #include <stdlib.h>
58 #include <stdio.h>
59 #include <unistd.h>
60 #include <ucred.h>
61 #include <limits.h>
62 #include <fcntl.h>
63 #include <door.h>
64 #include <alloca.h>
65 #include <sys/ucred.h>
66 #include <sys/procfs.h>
67 #include <sys/sysmacros.h>
68 #include <sys/zone.h>
69 
70 ucred_t *
71 _ucred_alloc(void)
72 {
73 	ucred_t *r;
74 	size_t sz = ucred_size();
75 
76 	r = malloc(sz);
77 
78 	if (r != NULL)
79 		r->uc_size = (uint32_t)sz;
80 
81 	return (r);
82 }
83 
84 void
85 ucred_free(ucred_t *uc)
86 {
87 	free(uc);
88 }
89 
90 
91 ucred_t *
92 ucred_get(pid_t pid)
93 {
94 	ucred_t *uc;
95 
96 	uc = _ucred_alloc();
97 
98 	if (uc == NULL)
99 		return (NULL);
100 
101 	if (syscall(SYS_ucredsys, UCREDSYS_UCREDGET, pid, uc) != 0) {
102 		ucred_free(uc);
103 		return (NULL);
104 	}
105 
106 	return (uc);
107 }
108 
109 uid_t
110 ucred_geteuid(const ucred_t *uc)
111 {
112 	/* LINTED: alignment */
113 	const prcred_t *cr = UCCRED(uc);
114 
115 	if (cr == NULL) {
116 		errno = EINVAL;
117 		return (-1);
118 	}
119 
120 	return (cr->pr_euid);
121 }
122 
123 uid_t
124 ucred_getruid(const ucred_t *uc)
125 {
126 	/* LINTED: alignment */
127 	const prcred_t *cr = UCCRED(uc);
128 
129 	if (cr == NULL) {
130 		errno = EINVAL;
131 		return (-1);
132 	}
133 
134 	return (cr->pr_ruid);
135 }
136 
137 uid_t
138 ucred_getsuid(const ucred_t *uc)
139 {
140 	/* LINTED: alignment */
141 	const prcred_t *cr = UCCRED(uc);
142 
143 	if (cr == NULL) {
144 		errno = EINVAL;
145 		return (-1);
146 	}
147 
148 	return (cr->pr_suid);
149 }
150 
151 gid_t
152 ucred_getegid(const ucred_t *uc)
153 {
154 	/* LINTED: alignment */
155 	const prcred_t *cr = UCCRED(uc);
156 
157 	if (cr == NULL) {
158 		errno = EINVAL;
159 		return (-1);
160 	}
161 
162 	return (cr->pr_egid);
163 }
164 
165 gid_t
166 ucred_getrgid(const ucred_t *uc)
167 {
168 	/* LINTED: alignment */
169 	const prcred_t *cr = UCCRED(uc);
170 
171 	if (cr == NULL) {
172 		errno = EINVAL;
173 		return (-1);
174 	}
175 
176 	return (cr->pr_rgid);
177 }
178 
179 gid_t
180 ucred_getsgid(const ucred_t *uc)
181 {
182 	/* LINTED: alignment */
183 	const prcred_t *cr = UCCRED(uc);
184 
185 	if (cr == NULL) {
186 		errno = EINVAL;
187 		return (-1);
188 	}
189 
190 	return (cr->pr_sgid);
191 }
192 
193 int
194 ucred_getgroups(const ucred_t *uc, const gid_t **grps)
195 {
196 	/* LINTED: alignment */
197 	const prcred_t *cr = UCCRED(uc);
198 
199 	if (cr == NULL) {
200 		errno = EINVAL;
201 		return (-1);
202 	}
203 
204 	if (cr->pr_ngroups > 0)
205 		*grps = &cr->pr_groups[0];
206 	else
207 		*grps = NULL;
208 
209 	return (cr->pr_ngroups);
210 }
211 
212 const priv_set_t *
213 ucred_getprivset(const ucred_t *uc, priv_ptype_t set)
214 {
215 	/* LINTED: alignment */
216 	const prpriv_t *pr = UCPRIV(uc);
217 	int pset = priv_getsetbyname(set);
218 	priv_data_t *d;
219 
220 	if (pr == NULL || pset == -1) {
221 		errno = EINVAL;
222 		return (NULL);
223 	}
224 
225 	LOADPRIVDATA(d);
226 
227 	return ((const priv_set_t *)
228 	    &pr->pr_sets[d->pd_pinfo->priv_setsize * pset]);
229 }
230 
231 pid_t
232 ucred_getpid(const ucred_t *uc)
233 {
234 
235 	if (uc->uc_pid == -1)
236 		errno = EINVAL;
237 
238 	return (uc->uc_pid);
239 }
240 
241 projid_t
242 ucred_getprojid(const ucred_t *uc)
243 {
244 
245 	if (uc->uc_projid == -1)
246 		errno = EINVAL;
247 
248 	return (uc->uc_projid);
249 }
250 
251 zoneid_t
252 ucred_getzoneid(const ucred_t *uc)
253 {
254 
255 	if (uc->uc_zoneid < MIN_ZONEID || uc->uc_zoneid > MAX_ZONEID) {
256 		errno = EINVAL;
257 		return (-1);
258 	}
259 
260 	return (uc->uc_zoneid);
261 }
262 
263 /*
264  * For now, assume single bit flags.
265  */
266 uint_t
267 ucred_getpflags(const ucred_t *uc, uint_t flag)
268 {
269 	/* LINTED: alignment */
270 	prpriv_t *pr = UCPRIV(uc);
271 	char *x, *end;
272 
273 	if (pr == NULL) {
274 		errno = EINVAL;
275 		return ((uint_t)-1);
276 	}
277 
278 	end = (char *)pr + PRIV_PRPRIV_SIZE(pr);
279 	x = end - pr->pr_infosize;
280 
281 	while (x < end) {
282 		/* LINTED: alignment */
283 		priv_info_t *pi = (priv_info_t *)x;
284 		priv_info_uint_t *pii;
285 
286 		switch (pi->priv_info_type) {
287 		case PRIV_INFO_FLAGS:
288 			/* LINTED: alignment */
289 			pii = (priv_info_uint_t *)x;
290 			return ((pii->val & flag) ? 1 : 0);
291 		}
292 		/* Forward progress */
293 		if (pi->priv_info_size < sizeof (priv_info_t))
294 			break;
295 		x += pi->priv_info_size;
296 	}
297 
298 	errno = EINVAL;
299 	return ((uint_t)-1);
300 }
301 
302 au_id_t
303 ucred_getauid(const ucred_t *uc)
304 {
305 	/* LINTED: alignment */
306 	const auditinfo64_addr_t *ainfo = UCAUD(uc);
307 
308 	if (ainfo == NULL)
309 		return (AU_NOAUDITID);
310 
311 	return (ainfo->ai_auid);
312 }
313 
314 au_asid_t
315 ucred_getasid(const ucred_t *uc)
316 {
317 	/* LINTED: alignment */
318 	const auditinfo64_addr_t *ainfo = UCAUD(uc);
319 
320 	if (ainfo == NULL)
321 		return (-1);
322 
323 	return (ainfo->ai_asid);
324 }
325 
326 const au_tid64_addr_t *
327 ucred_getatid(const ucred_t *uc)
328 {
329 	/* LINTED: alignment */
330 	const auditinfo64_addr_t *ainfo = UCAUD(uc);
331 
332 	if (ainfo == NULL) {
333 		errno = EINVAL;
334 		return (NULL);
335 	}
336 
337 	return (&ainfo->ai_termid);
338 }
339 
340 const au_mask_t *
341 ucred_getamask(const ucred_t *uc)
342 {
343 	/* LINTED: alignment */
344 	const auditinfo64_addr_t *ainfo = UCAUD(uc);
345 
346 	if (ainfo == NULL) {
347 		errno = EINVAL;
348 		return (NULL);
349 	}
350 
351 	return (&ainfo->ai_mask);
352 }
353 
354 size_t
355 ucred_size(void)
356 {
357 	priv_data_t *d;
358 
359 	LOADPRIVDATA(d);
360 
361 	return (d->pd_ucredsize);
362 }
363