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