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 *
_ucred_alloc(void)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
ucred_free(ucred_t * uc)86 ucred_free(ucred_t *uc)
87 {
88 free(uc);
89 }
90
91
92 ucred_t *
ucred_get(pid_t pid)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
ucred_geteuid(const ucred_t * uc)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
ucred_getruid(const ucred_t * uc)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
ucred_getsuid(const ucred_t * uc)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
ucred_getegid(const ucred_t * uc)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
ucred_getrgid(const ucred_t * uc)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
ucred_getsgid(const ucred_t * uc)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
ucred_getgroups(const ucred_t * uc,const gid_t ** grps)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 *
ucred_getprivset(const ucred_t * uc,priv_ptype_t set)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
ucred_getpid(const ucred_t * uc)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
ucred_getprojid(const ucred_t * uc)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
ucred_getzoneid(const ucred_t * uc)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 *
ucred_getlabel(const ucred_t * uc)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
ucred_getpflags(const ucred_t * uc,uint_t flag)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
ucred_getauid(const ucred_t * uc)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
ucred_getasid(const ucred_t * uc)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 *
ucred_getatid(const ucred_t * uc)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 *
ucred_getamask(const ucred_t * uc)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
ucred_size(void)370 ucred_size(void)
371 {
372 priv_data_t *d;
373
374 LOADPRIVDATA(d);
375
376 return (d->pd_ucredsize);
377 }
378