xref: /illumos-gate/usr/src/lib/libc/port/gen/ucred.c (revision b87f3af36bb994656da117319f5129ddfd05ed21)
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