]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_prot.c
xnu-517.tar.gz
[apple/xnu.git] / bsd / kern / kern_prot.c
1 /*
2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
26 /*
27 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
28 * The Regents of the University of California. All rights reserved.
29 * (c) UNIX System Laboratories, Inc.
30 * All or some portions of this file are derived from material licensed
31 * to the University of California by American Telephone and Telegraph
32 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
33 * the permission of UNIX System Laboratories, Inc.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software
44 * must display the following acknowledgement:
45 * This product includes software developed by the University of
46 * California, Berkeley and its contributors.
47 * 4. Neither the name of the University nor the names of its contributors
48 * may be used to endorse or promote products derived from this software
49 * without specific prior written permission.
50 *
51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE.
62 *
63 * @(#)kern_prot.c 8.9 (Berkeley) 2/14/95
64 */
65
66 /*
67 * System calls related to processes and protection
68 */
69
70 #include <sys/param.h>
71 #include <sys/acct.h>
72 #include <sys/systm.h>
73 #include <sys/ucred.h>
74 #include <sys/proc.h>
75 #include <sys/timeb.h>
76 #include <sys/times.h>
77 #include <sys/malloc.h>
78 #include <sys/kern_audit.h>
79
80 #include <sys/mount.h>
81 #include <mach/message.h>
82 #include <mach/host_security.h>
83
84 #include <kern/host.h>
85
86 /*
87 * setprivexec: (dis)allow this process to hold
88 * task, thread, or execption ports of processes about to exec.
89 */
90 struct setprivexec_args {
91 int flag;
92 };
93 int
94 setprivexec(p, uap, retval)
95 struct proc *p;
96 register struct setprivexec_args *uap;
97 register_t *retval;
98 {
99 *retval = p->p_debugger;
100 p->p_debugger = (uap->flag != 0);
101 return(0);
102 }
103
104 /* ARGSUSED */
105 getpid(p, uap, retval)
106 struct proc *p;
107 void *uap;
108 register_t *retval;
109 {
110
111 *retval = p->p_pid;
112 #if COMPAT_43
113 retval[1] = p->p_pptr->p_pid;
114 #endif
115 return (0);
116 }
117
118 /* ARGSUSED */
119 getppid(p, uap, retval)
120 struct proc *p;
121 void *uap;
122 register_t *retval;
123 {
124
125 *retval = p->p_pptr->p_pid;
126 return (0);
127 }
128
129 /* Get process group ID; note that POSIX getpgrp takes no parameter */
130 getpgrp(p, uap, retval)
131 struct proc *p;
132 void *uap;
133 register_t *retval;
134 {
135
136 *retval = p->p_pgrp->pg_id;
137 return (0);
138 }
139
140 /* Get an arbitary pid's process group id */
141 struct getpgid_args {
142 pid_t pid;
143 };
144
145 int
146 getpgid(p, uap, retval)
147 struct proc *p;
148 struct getpgid_args *uap;
149 register_t *retval;
150 {
151 struct proc *pt;
152
153 pt = p;
154 if (uap->pid == 0)
155 goto found;
156
157 if ((pt = pfind(uap->pid)) == 0)
158 return (ESRCH);
159 found:
160 *retval = pt->p_pgrp->pg_id;
161 return (0);
162 }
163
164 /*
165 * Get an arbitary pid's session id.
166 */
167 struct getsid_args {
168 pid_t pid;
169 };
170
171 int
172 getsid(p, uap, retval)
173 struct proc *p;
174 struct getsid_args *uap;
175 register_t *retval;
176 {
177 struct proc *pt;
178
179 pt = p;
180 if (uap->pid == 0)
181 goto found;
182
183 if ((pt = pfind(uap->pid)) == 0)
184 return (ESRCH);
185 found:
186 *retval = pt->p_session->s_sid;
187 return (0);
188 }
189
190 /* ARGSUSED */
191 getuid(p, uap, retval)
192 struct proc *p;
193 void *uap;
194 register_t *retval;
195 {
196
197 *retval = p->p_cred->p_ruid;
198 #if COMPAT_43
199 retval[1] = p->p_ucred->cr_uid;
200 #endif
201 return (0);
202 }
203
204 /* ARGSUSED */
205 geteuid(p, uap, retval)
206 struct proc *p;
207 void *uap;
208 register_t *retval;
209 {
210
211 *retval = p->p_ucred->cr_uid;
212 return (0);
213 }
214
215 /* ARGSUSED */
216 getgid(p, uap, retval)
217 struct proc *p;
218 void *uap;
219 register_t *retval;
220 {
221
222 *retval = p->p_cred->p_rgid;
223 #if COMPAT_43
224 retval[1] = p->p_ucred->cr_groups[0];
225 #endif
226 return (0);
227 }
228
229 /*
230 * Get effective group ID. The "egid" is groups[0], and could be obtained
231 * via getgroups. This syscall exists because it is somewhat painful to do
232 * correctly in a library function.
233 */
234 /* ARGSUSED */
235 getegid(p, uap, retval)
236 struct proc *p;
237 void *uap;
238 register_t *retval;
239 {
240
241 *retval = p->p_ucred->cr_groups[0];
242 return (0);
243 }
244
245 struct getgroups_args {
246 u_int gidsetsize;
247 gid_t *gidset;
248 };
249 getgroups(p, uap, retval)
250 struct proc *p;
251 register struct getgroups_args *uap;
252 register_t *retval;
253 {
254 register struct pcred *pc = p->p_cred;
255 register u_int ngrp;
256 int error;
257
258 if ((ngrp = uap->gidsetsize) == 0) {
259 *retval = pc->pc_ucred->cr_ngroups;
260 return (0);
261 }
262 if (ngrp < pc->pc_ucred->cr_ngroups)
263 return (EINVAL);
264 pcred_readlock(p);
265 ngrp = pc->pc_ucred->cr_ngroups;
266 if (error = copyout((caddr_t)pc->pc_ucred->cr_groups,
267 (caddr_t)uap->gidset, ngrp * sizeof(gid_t))) {
268 pcred_unlock(p);
269 return (error);
270 }
271 pcred_unlock(p);
272 *retval = ngrp;
273 return (0);
274 }
275
276 /* ARGSUSED */
277 setsid(p, uap, retval)
278 register struct proc *p;
279 void *uap;
280 register_t *retval;
281 {
282
283 if (p->p_pgid == p->p_pid || pgfind(p->p_pid) || p->p_flag & P_INVFORK) {
284 return (EPERM);
285 } else {
286 (void)enterpgrp(p, p->p_pid, 1);
287 *retval = p->p_pid;
288 return (0);
289 }
290 }
291
292 /*
293 * set process group (setpgid/old setpgrp)
294 *
295 * caller does setpgid(targpid, targpgid)
296 *
297 * pid must be caller or child of caller (ESRCH)
298 * if a child
299 * pid must be in same session (EPERM)
300 * pid can't have done an exec (EACCES)
301 * if pgid != pid
302 * there must exist some pid in same session having pgid (EPERM)
303 * pid must not be session leader (EPERM)
304 */
305 struct setpgid_args {
306 int pid;
307 int pgid;
308 };
309 /* ARGSUSED */
310 setpgid(curp, uap, retval)
311 struct proc *curp;
312 register struct setpgid_args *uap;
313 register_t *retval;
314 {
315 register struct proc *targp; /* target process */
316 register struct pgrp *pgrp; /* target pgrp */
317
318 if (uap->pid != 0 && uap->pid != curp->p_pid) {
319 if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
320 return (ESRCH);
321 if (targp->p_session != curp->p_session)
322 return (EPERM);
323 if (targp->p_flag & P_EXEC)
324 return (EACCES);
325 } else
326 targp = curp;
327 if (SESS_LEADER(targp))
328 return (EPERM);
329 if (uap->pgid == 0)
330 uap->pgid = targp->p_pid;
331 else if (uap->pgid != targp->p_pid)
332 if ((pgrp = pgfind(uap->pgid)) == 0 ||
333 pgrp->pg_session != curp->p_session)
334 return (EPERM);
335 return (enterpgrp(targp, uap->pgid, 0));
336 }
337
338 struct issetugid_args {
339 int dummy;
340 };
341 issetugid(p, uap, retval)
342 struct proc *p;
343 struct issetugid_args *uap;
344 register_t *retval;
345 {
346 /*
347 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
348 * we use P_SUGID because we consider changing the owners as
349 * "tainting" as well.
350 * This is significant for procs that start as root and "become"
351 * a user without an exec - programs cannot know *everything*
352 * that libc *might* have put in their data segment.
353 */
354
355 *retval = (p->p_flag & P_SUGID) ? 1 : 0;
356 return (0);
357 }
358
359 struct setuid_args {
360 uid_t uid;
361 };
362 /* ARGSUSED */
363 setuid(p, uap, retval)
364 struct proc *p;
365 struct setuid_args *uap;
366 register_t *retval;
367 {
368 register struct pcred *pc = p->p_cred;
369 register uid_t uid;
370 int error;
371
372 uid = uap->uid;
373 AUDIT_ARG(uid, uid, 0, 0, 0);
374 if (uid != pc->p_ruid &&
375 (error = suser(pc->pc_ucred, &p->p_acflag)))
376 return (error);
377 /*
378 * Everything's okay, do it.
379 * Transfer proc count to new user.
380 * Copy credentials so other references do not see our changes.
381 */
382
383 /* prepare app access profile files */
384 prepare_profile_database(uap->uid);
385 pcred_writelock(p);
386 (void)chgproccnt(pc->p_ruid, -1);
387 (void)chgproccnt(uid, 1);
388 pc->pc_ucred = crcopy(pc->pc_ucred);
389 pc->pc_ucred->cr_uid = uid;
390 pc->p_ruid = uid;
391 pc->p_svuid = uid;
392 pcred_unlock(p);
393 set_security_token(p);
394 p->p_flag |= P_SUGID;
395 return (0);
396 }
397
398 struct seteuid_args {
399 uid_t euid;
400 };
401 /* ARGSUSED */
402 seteuid(p, uap, retval)
403 struct proc *p;
404 struct seteuid_args *uap;
405 register_t *retval;
406 {
407 register struct pcred *pc = p->p_cred;
408 register uid_t euid;
409 int error;
410
411 euid = uap->euid;
412 AUDIT_ARG(uid, 0, euid, 0, 0);
413 if (euid != pc->p_ruid && euid != pc->p_svuid &&
414 (error = suser(pc->pc_ucred, &p->p_acflag)))
415 return (error);
416 /*
417 * Everything's okay, do it. Copy credentials so other references do
418 * not see our changes.
419 */
420 pcred_writelock(p);
421 pc->pc_ucred = crcopy(pc->pc_ucred);
422 pc->pc_ucred->cr_uid = euid;
423 pcred_unlock(p);
424 set_security_token(p);
425 p->p_flag |= P_SUGID;
426 return (0);
427 }
428
429 struct setgid_args {
430 gid_t gid;
431 };
432 /* ARGSUSED */
433 setgid(p, uap, retval)
434 struct proc *p;
435 struct setgid_args *uap;
436 register_t *retval;
437 {
438 register struct pcred *pc = p->p_cred;
439 register gid_t gid;
440 int error;
441
442 gid = uap->gid;
443 AUDIT_ARG(gid, gid, 0, 0, 0);
444 if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
445 return (error);
446 pcred_writelock(p);
447 pc->pc_ucred = crcopy(pc->pc_ucred);
448 pc->pc_ucred->cr_groups[0] = gid;
449 pc->p_rgid = gid;
450 pc->p_svgid = gid; /* ??? */
451 pcred_unlock(p);
452 set_security_token(p);
453 p->p_flag |= P_SUGID;
454 return (0);
455 }
456
457 struct setegid_args {
458 gid_t egid;
459 };
460 /* ARGSUSED */
461 setegid(p, uap, retval)
462 struct proc *p;
463 struct setegid_args *uap;
464 register_t *retval;
465 {
466 register struct pcred *pc = p->p_cred;
467 register gid_t egid;
468 int error;
469
470 egid = uap->egid;
471 AUDIT_ARG(gid, 0, egid, 0, 0);
472 if (egid != pc->p_rgid && egid != pc->p_svgid &&
473 (error = suser(pc->pc_ucred, &p->p_acflag)))
474 return (error);
475 pcred_writelock(p);
476 pc->pc_ucred = crcopy(pc->pc_ucred);
477 pc->pc_ucred->cr_groups[0] = egid;
478 pcred_unlock(p);
479 set_security_token(p);
480 p->p_flag |= P_SUGID;
481 return (0);
482 }
483
484 struct setgroups_args{
485 u_int gidsetsize;
486 gid_t *gidset;
487 };
488
489 /* ARGSUSED */
490 setgroups(p, uap, retval)
491 struct proc *p;
492 struct setgroups_args *uap;
493 register_t *retval;
494 {
495 register struct pcred *pc = p->p_cred;
496 struct ucred *new, *old;
497 register u_int ngrp;
498 int error;
499
500 if (error = suser(pc->pc_ucred, &p->p_acflag))
501 return (error);
502 ngrp = uap->gidsetsize;
503 if (ngrp > NGROUPS)
504 return (EINVAL);
505 new = crget();
506
507 if ( ngrp < 1 ) {
508 ngrp = 1;
509 }
510 else {
511 error = copyin((caddr_t)uap->gidset,
512 (caddr_t)new->cr_groups, ngrp * sizeof(gid_t));
513 if (error) {
514 crfree(new);
515 return (error);
516 }
517 }
518 new->cr_ngroups = ngrp;
519 AUDIT_ARG(groupset, new->cr_groups, ngrp);
520 pcred_writelock(p);
521 old = pc->pc_ucred;
522 new->cr_uid = old->cr_uid;
523 pc->pc_ucred = new;
524 pcred_unlock(p);
525 set_security_token(p);
526 p->p_flag |= P_SUGID;
527 if (old != NOCRED)
528 crfree(old);
529 return (0);
530 }
531
532 #if COMPAT_43
533 struct osetreuid_args{
534 int ruid;
535 int euid;
536 };
537 /* ARGSUSED */
538 osetreuid(p, uap, retval)
539 register struct proc *p;
540 struct osetreuid_args *uap;
541 register_t *retval;
542 {
543 struct seteuid_args seuidargs;
544 struct setuid_args suidargs;
545
546 /*
547 * There are five cases, and we attempt to emulate them in
548 * the following fashion:
549 * -1, -1: return 0. This is correct emulation.
550 * -1, N: call seteuid(N). This is correct emulation.
551 * N, -1: if we called setuid(N), our euid would be changed
552 * to N as well. the theory is that we don't want to
553 * revoke root access yet, so we call seteuid(N)
554 * instead. This is incorrect emulation, but often
555 * suffices enough for binary compatibility.
556 * N, N: call setuid(N). This is correct emulation.
557 * N, M: call setuid(N). This is close to correct emulation.
558 */
559 if (uap->ruid == (uid_t)-1) {
560 if (uap->euid == (uid_t)-1)
561 return (0); /* -1, -1 */
562 seuidargs.euid = uap->euid; /* -1, N */
563 return (seteuid(p, &seuidargs, retval));
564 }
565 if (uap->euid == (uid_t)-1) {
566 seuidargs.euid = uap->ruid; /* N, -1 */
567 return (seteuid(p, &seuidargs, retval));
568 }
569 suidargs.uid = uap->ruid; /* N, N and N, M */
570 return (setuid(p, &suidargs, retval));
571 }
572
573 struct osetregid_args {
574 int rgid;
575 int egid;
576 };
577 /* ARGSUSED */
578 osetregid(p, uap, retval)
579 register struct proc *p;
580 struct osetregid_args *uap;
581 register_t *retval;
582 {
583 struct setegid_args segidargs;
584 struct setgid_args sgidargs;
585
586 /*
587 * There are five cases, described above in osetreuid()
588 */
589 if (uap->rgid == (gid_t)-1) {
590 if (uap->egid == (gid_t)-1)
591 return (0); /* -1, -1 */
592 segidargs.egid = uap->egid; /* -1, N */
593 return (setegid(p, &segidargs, retval));
594 }
595 if (uap->egid == (gid_t)-1) {
596 segidargs.egid = uap->rgid; /* N, -1 */
597 return (setegid(p, &segidargs, retval));
598 }
599 sgidargs.gid = uap->rgid; /* N, N and N, M */
600 return (setgid(p, &sgidargs, retval));
601 }
602 #endif /* COMPAT_43 */
603
604 /*
605 * Check if gid is a member of the group set.
606 */
607 groupmember(gid, cred)
608 gid_t gid;
609 register struct ucred *cred;
610 {
611 register gid_t *gp;
612 gid_t *egp;
613
614 egp = &(cred->cr_groups[cred->cr_ngroups]);
615 for (gp = cred->cr_groups; gp < egp; gp++)
616 if (*gp == gid)
617 return (1);
618 return (0);
619 }
620
621 /*
622 * Test whether the specified credentials imply "super-user"
623 * privilege; if so, and we have accounting info, set the flag
624 * indicating use of super-powers.
625 * Returns 0 or error.
626 */
627 suser(cred, acflag)
628 struct ucred *cred;
629 u_short *acflag;
630 {
631 #if DIAGNOSTIC
632 if (cred == NOCRED || cred == FSCRED)
633 panic("suser");
634 #endif
635 if (cred->cr_uid == 0) {
636 if (acflag)
637 *acflag |= ASU;
638 return (0);
639 }
640 return (EPERM);
641 }
642
643 int
644 is_suser(void)
645 {
646 struct proc *p = current_proc();
647
648 if (!p)
649 return (0);
650
651 return (suser(p->p_ucred, &p->p_acflag) == 0);
652 }
653
654 int
655 is_suser1(void)
656 {
657 struct proc *p = current_proc();
658
659 if (!p)
660 return (0);
661
662 return (suser(p->p_ucred, &p->p_acflag) == 0 ||
663 p->p_cred->p_ruid == 0 || p->p_cred->p_svuid == 0);
664 }
665
666 /*
667 * Allocate a zeroed cred structure.
668 */
669 struct ucred *
670 crget()
671 {
672 register struct ucred *cr;
673
674 MALLOC_ZONE(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
675 bzero((caddr_t)cr, sizeof(*cr));
676 cr->cr_ref = 1;
677 return (cr);
678 }
679
680 /*
681 * Free a cred structure.
682 * Throws away space when ref count gets to 0.
683 */
684 void
685 crfree(cr)
686 struct ucred *cr;
687 {
688 #if DIAGNOSTIC
689 if (cr == NOCRED || cr == FSCRED)
690 panic("crfree");
691 #endif
692 if (--cr->cr_ref == 0)
693 FREE_ZONE((caddr_t)cr, sizeof *cr, M_CRED);
694 }
695
696 /*
697 * Copy cred structure to a new one and free the old one.
698 */
699 struct ucred *
700 crcopy(cr)
701 struct ucred *cr;
702 {
703 struct ucred *newcr;
704
705 #if DIAGNOSTIC
706 if (cr == NOCRED || cr == FSCRED)
707 panic("crcopy");
708 #endif
709 if (cr->cr_ref == 1)
710 return (cr);
711 newcr = crget();
712 *newcr = *cr;
713 crfree(cr);
714 newcr->cr_ref = 1;
715 return (newcr);
716 }
717
718 /*
719 * Dup cred struct to a new held one.
720 */
721 struct ucred *
722 crdup(cr)
723 struct ucred *cr;
724 {
725 struct ucred *newcr;
726
727 #if DIAGNOSTIC
728 if (cr == NOCRED || cr == FSCRED)
729 panic("crdup");
730 #endif
731 newcr = crget();
732 *newcr = *cr;
733 newcr->cr_ref = 1;
734 return (newcr);
735 }
736
737 /*
738 * compare two cred structs
739 */
740 int
741 crcmp(cr1, cr2)
742 struct ucred *cr1;
743 struct ucred *cr2;
744 {
745 int i;
746
747 if (cr1 == cr2)
748 return 0;
749 if (cr1 == NOCRED || cr1 == FSCRED ||
750 cr2 == NOCRED || cr2 == FSCRED)
751 return 1;
752 if (cr1->cr_uid != cr2->cr_uid)
753 return 1;
754 if (cr1->cr_ngroups != cr2->cr_ngroups)
755 return 1;
756 // XXX assumes groups will always be listed in some order
757 for (i=0; i < cr1->cr_ngroups; i++)
758 if (cr1->cr_groups[i] != cr2->cr_groups[i])
759 return 1;
760 return (0);
761 }
762
763 /*
764 * Get login name, if available.
765 */
766 struct getlogin_args {
767 char *namebuf;
768 u_int namelen;
769 };
770 /* ARGSUSED */
771 getlogin(p, uap, retval)
772 struct proc *p;
773 struct getlogin_args *uap;
774 register_t *retval;
775 {
776
777 if (uap->namelen > sizeof (p->p_pgrp->pg_session->s_login))
778 uap->namelen = sizeof (p->p_pgrp->pg_session->s_login);
779 return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
780 (caddr_t)uap->namebuf, uap->namelen));
781 }
782
783 /*
784 * Set login name.
785 */
786 struct setlogin_args {
787 char *namebuf;
788 };
789 /* ARGSUSED */
790 setlogin(p, uap, retval)
791 struct proc *p;
792 struct setlogin_args *uap;
793 register_t *retval;
794 {
795 int error;
796 int dummy=0;
797
798 if (error = suser(p->p_ucred, &p->p_acflag))
799 return (error);
800
801 error = copyinstr((caddr_t) uap->namebuf,
802 (caddr_t) p->p_pgrp->pg_session->s_login,
803 sizeof (p->p_pgrp->pg_session->s_login) - 1, (size_t *)&dummy);
804 if (error == ENAMETOOLONG)
805 error = EINVAL;
806 return (error);
807 }
808
809
810 /* Set the secrity token of the task with current euid and eguid */
811 kern_return_t
812 set_security_token(struct proc * p)
813 {
814 security_token_t sec_token;
815 audit_token_t audit_token;
816
817 sec_token.val[0] = p->p_ucred->cr_uid;
818 sec_token.val[1] = p->p_ucred->cr_gid;
819 audit_token.val[0] = p->p_au->ai_auid;
820 audit_token.val[1] = p->p_au->ai_asid;
821 /* use au_tid for now, until au_tid_addr is put to use */
822 audit_token.val[2] = p->p_au->ai_termid.port;
823 audit_token.val[3] = p->p_au->ai_termid.machine;
824 audit_token.val[4] = 0;
825 audit_token.val[5] = 0;
826 audit_token.val[6] = 0;
827 audit_token.val[7] = 0;
828 return host_security_set_task_token(host_security_self(),
829 p->task,
830 sec_token,
831 audit_token,
832 (sec_token.val[0]) ?
833 HOST_PRIV_NULL :
834 host_priv_self());
835 }
836
837
838 /*
839 * Fill in a struct xucred based on a struct ucred.
840 */
841 __private_extern__
842 void
843 cru2x(struct ucred *cr, struct xucred *xcr)
844 {
845
846 bzero(xcr, sizeof(*xcr));
847 xcr->cr_version = XUCRED_VERSION;
848 xcr->cr_uid = cr->cr_uid;
849 xcr->cr_ngroups = cr->cr_ngroups;
850 bcopy(cr->cr_groups, xcr->cr_groups, sizeof(xcr->cr_groups));
851 }