Split execve(). This required some interesting changes to the shell
[dragonfly.git] / sys / kern / kern_prot.c
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  *      @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
39  * $FreeBSD: src/sys/kern/kern_prot.c,v 1.53.2.9 2002/03/09 05:20:26 dd Exp $
40  * $DragonFly: src/sys/kern/kern_prot.c,v 1.12 2003/11/05 20:24:37 dillon Exp $
41  */
42
43 /*
44  * System calls related to processes and protection
45  */
46
47 #include "opt_compat.h"
48
49 #include <sys/param.h>
50 #include <sys/acct.h>
51 #include <sys/systm.h>
52 #include <sys/sysproto.h>
53 #include <sys/kernel.h>
54 #include <sys/proc.h>
55 #include <sys/malloc.h>
56 #include <sys/pioctl.h>
57 #include <sys/resourcevar.h>
58 #include <sys/thread2.h>
59 #include <sys/jail.h>
60
61 static MALLOC_DEFINE(M_CRED, "cred", "credentials");
62
63 /*
64  * NOT MP SAFE due to p_pptr access
65  */
66 /* ARGSUSED */
67 int
68 getpid(struct getpid_args *uap)
69 {
70         struct proc *p = curproc;
71
72         uap->sysmsg_fds[0] = p->p_pid;
73 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
74         uap->sysmsg_fds[1] = p->p_pptr->p_pid;
75 #endif
76         return (0);
77 }
78
79 /* ARGSUSED */
80 int
81 getppid(struct getppid_args *uap)
82 {
83         struct proc *p = curproc;
84
85         uap->sysmsg_result = p->p_pptr->p_pid;
86         return (0);
87 }
88
89 /* 
90  * Get process group ID; note that POSIX getpgrp takes no parameter 
91  *
92  * MP SAFE
93  */
94 int
95 getpgrp(struct getpgrp_args *uap)
96 {
97         struct proc *p = curproc;
98
99         uap->sysmsg_result = p->p_pgrp->pg_id;
100         return (0);
101 }
102
103 /*
104  * Get an arbitary pid's process group id 
105  */
106 int
107 getpgid(struct getpgid_args *uap)
108 {
109         struct proc *p = curproc;
110         struct proc *pt;
111
112         pt = p;
113         if (uap->pid == 0)
114                 goto found;
115
116         if ((pt = pfind(uap->pid)) == 0)
117                 return ESRCH;
118 found:
119         uap->sysmsg_result = pt->p_pgrp->pg_id;
120         return 0;
121 }
122
123 /*
124  * Get an arbitary pid's session id.
125  */
126 int
127 getsid(struct getsid_args *uap)
128 {
129         struct proc *p = curproc;
130         struct proc *pt;
131
132         pt = p;
133         if (uap->pid == 0)
134                 goto found;
135
136         if ((pt = pfind(uap->pid)) == 0)
137                 return ESRCH;
138 found:
139         uap->sysmsg_result = pt->p_session->s_sid;
140         return 0;
141 }
142
143
144 /*
145  * getuid() - MP SAFE
146  */
147 /* ARGSUSED */
148 int
149 getuid(struct getuid_args *uap)
150 {
151         struct proc *p = curproc;
152
153         uap->sysmsg_fds[0] = p->p_ucred->cr_ruid;
154 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
155         uap->sysmsg_fds[1] = p->p_ucred->cr_uid;
156 #endif
157         return (0);
158 }
159
160 /*
161  * geteuid() - MP SAFE
162  */
163 /* ARGSUSED */
164 int
165 geteuid(struct geteuid_args *uap)
166 {
167         struct proc *p = curproc;
168
169         uap->sysmsg_result = p->p_ucred->cr_uid;
170         return (0);
171 }
172
173 /*
174  * getgid() - MP SAFE
175  */
176 /* ARGSUSED */
177 int
178 getgid(struct getgid_args *uap)
179 {
180         struct proc *p = curproc;
181
182         uap->sysmsg_fds[0] = p->p_ucred->cr_rgid;
183 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
184         uap->sysmsg_fds[1] = p->p_ucred->cr_groups[0];
185 #endif
186         return (0);
187 }
188
189 /*
190  * Get effective group ID.  The "egid" is groups[0], and could be obtained
191  * via getgroups.  This syscall exists because it is somewhat painful to do
192  * correctly in a library function.
193  */
194 /* ARGSUSED */
195 int
196 getegid(struct getegid_args *uap)
197 {
198         struct proc *p = curproc;
199
200         uap->sysmsg_result = p->p_ucred->cr_groups[0];
201         return (0);
202 }
203
204 int
205 getgroups(struct getgroups_args *uap)
206 {
207         struct proc *p = curproc;
208         struct ucred *cr;
209         u_int ngrp;
210         int error;
211
212         if (p == NULL)                          /* API enforcement */
213                 return(EPERM);
214         cr = p->p_ucred;
215
216         if ((ngrp = uap->gidsetsize) == 0) {
217                 uap->sysmsg_result = cr->cr_ngroups;
218                 return (0);
219         }
220         if (ngrp < cr->cr_ngroups)
221                 return (EINVAL);
222         ngrp = cr->cr_ngroups;
223         if ((error = copyout((caddr_t)cr->cr_groups,
224             (caddr_t)uap->gidset, ngrp * sizeof(gid_t))))
225                 return (error);
226         uap->sysmsg_result = ngrp;
227         return (0);
228 }
229
230 /* ARGSUSED */
231 int
232 setsid(struct setsid_args *uap)
233 {
234         struct proc *p = curproc;
235
236         if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
237                 return (EPERM);
238         } else {
239                 (void)enterpgrp(p, p->p_pid, 1);
240                 uap->sysmsg_result = p->p_pid;
241                 return (0);
242         }
243 }
244
245 /*
246  * set process group (setpgid/old setpgrp)
247  *
248  * caller does setpgid(targpid, targpgid)
249  *
250  * pid must be caller or child of caller (ESRCH)
251  * if a child
252  *      pid must be in same session (EPERM)
253  *      pid can't have done an exec (EACCES)
254  * if pgid != pid
255  *      there must exist some pid in same session having pgid (EPERM)
256  * pid must not be session leader (EPERM)
257  */
258 /* ARGSUSED */
259 int
260 setpgid(struct setpgid_args *uap)
261 {
262         struct proc *curp = curproc;
263         struct proc *targp;             /* target process */
264         struct pgrp *pgrp;              /* target pgrp */
265
266         if (uap->pgid < 0)
267                 return (EINVAL);
268         if (uap->pid != 0 && uap->pid != curp->p_pid) {
269                 if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
270                         return (ESRCH);
271                 if (targp->p_pgrp == NULL ||  targp->p_session != curp->p_session)
272                         return (EPERM);
273                 if (targp->p_flag & P_EXEC)
274                         return (EACCES);
275         } else
276                 targp = curp;
277         if (SESS_LEADER(targp))
278                 return (EPERM);
279         if (uap->pgid == 0)
280                 uap->pgid = targp->p_pid;
281         else if (uap->pgid != targp->p_pid)
282                 if ((pgrp = pgfind(uap->pgid)) == 0 ||
283                     pgrp->pg_session != curp->p_session)
284                         return (EPERM);
285         return (enterpgrp(targp, uap->pgid, 0));
286 }
287
288 /*
289  * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD
290  * compatable.  It says that setting the uid/gid to euid/egid is a special
291  * case of "appropriate privilege".  Once the rules are expanded out, this
292  * basically means that setuid(nnn) sets all three id's, in all permitted
293  * cases unless _POSIX_SAVED_IDS is enabled.  In that case, setuid(getuid())
294  * does not set the saved id - this is dangerous for traditional BSD
295  * programs.  For this reason, we *really* do not want to set
296  * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2.
297  */
298 #define POSIX_APPENDIX_B_4_2_2
299
300 /* ARGSUSED */
301 int
302 setuid(struct setuid_args *uap)
303 {
304         struct proc *p = curproc;
305         struct ucred *cr;
306         uid_t uid;
307         int error;
308
309         if (p == NULL)                          /* API enforcement */
310                 return(EPERM);
311         cr = p->p_ucred;
312
313         /*
314          * See if we have "permission" by POSIX 1003.1 rules.
315          *
316          * Note that setuid(geteuid()) is a special case of 
317          * "appropriate privileges" in appendix B.4.2.2.  We need
318          * to use this clause to be compatable with traditional BSD
319          * semantics.  Basically, it means that "setuid(xx)" sets all
320          * three id's (assuming you have privs).
321          *
322          * Notes on the logic.  We do things in three steps.
323          * 1: We determine if the euid is going to change, and do EPERM
324          *    right away.  We unconditionally change the euid later if this
325          *    test is satisfied, simplifying that part of the logic.
326          * 2: We determine if the real and/or saved uid's are going to
327          *    change.  Determined by compile options.
328          * 3: Change euid last. (after tests in #2 for "appropriate privs")
329          */
330         uid = uap->uid;
331         if (uid != cr->cr_ruid &&               /* allow setuid(getuid()) */
332 #ifdef _POSIX_SAVED_IDS
333             uid != crc->cr_svuid &&             /* allow setuid(saved gid) */
334 #endif
335 #ifdef POSIX_APPENDIX_B_4_2_2   /* Use BSD-compat clause from B.4.2.2 */
336             uid != cr->cr_uid &&        /* allow setuid(geteuid()) */
337 #endif
338             (error = suser_cred(cr, PRISON_ROOT)))
339                 return (error);
340
341 #ifdef _POSIX_SAVED_IDS
342         /*
343          * Do we have "appropriate privileges" (are we root or uid == euid)
344          * If so, we are changing the real uid and/or saved uid.
345          */
346         if (
347 #ifdef POSIX_APPENDIX_B_4_2_2   /* Use the clause from B.4.2.2 */
348             uid == cr->cr_uid ||
349 #endif
350             suser_cred(cr, PRISON_ROOT) == 0) /* we are using privs */
351 #endif
352         {
353                 /*
354                  * Set the real uid and transfer proc count to new user.
355                  */
356                 if (uid != cr->cr_ruid) {
357                         change_ruid(uid);
358                         setsugid();
359                 }
360                 /*
361                  * Set saved uid
362                  *
363                  * XXX always set saved uid even if not _POSIX_SAVED_IDS, as
364                  * the security of seteuid() depends on it.  B.4.2.2 says it
365                  * is important that we should do this.
366                  */
367                 if (cr->cr_svuid != uid) {
368                         cr = cratom(&p->p_ucred);
369                         cr->cr_svuid = uid;
370                         setsugid();
371                 }
372         }
373
374         /*
375          * In all permitted cases, we are changing the euid.
376          * Copy credentials so other references do not see our changes.
377          */
378         if (cr->cr_uid != uid) {
379                 change_euid(uid);
380                 setsugid();
381         }
382         return (0);
383 }
384
385 /* ARGSUSED */
386 int
387 seteuid(struct seteuid_args *uap)
388 {
389         struct proc *p = curproc;
390         struct ucred *cr;
391         uid_t euid;
392         int error;
393
394         if (p == NULL)                          /* API enforcement */
395                 return(EPERM);
396
397         cr = p->p_ucred;
398         euid = uap->euid;
399         if (euid != cr->cr_ruid &&              /* allow seteuid(getuid()) */
400             euid != cr->cr_svuid &&             /* allow seteuid(saved uid) */
401             (error = suser_cred(cr, PRISON_ROOT)))
402                 return (error);
403         /*
404          * Everything's okay, do it.  Copy credentials so other references do
405          * not see our changes.
406          */
407         if (cr->cr_uid != euid) {
408                 change_euid(euid);
409                 setsugid();
410         }
411         return (0);
412 }
413
414 /* ARGSUSED */
415 int
416 setgid(struct setgid_args *uap)
417 {
418         struct proc *p = curproc;
419         struct ucred *cr;
420         gid_t gid;
421         int error;
422
423         if (p == NULL)                          /* API enforcement */
424                 return(EPERM);
425         cr = p->p_ucred;
426
427         /*
428          * See if we have "permission" by POSIX 1003.1 rules.
429          *
430          * Note that setgid(getegid()) is a special case of
431          * "appropriate privileges" in appendix B.4.2.2.  We need
432          * to use this clause to be compatable with traditional BSD
433          * semantics.  Basically, it means that "setgid(xx)" sets all
434          * three id's (assuming you have privs).
435          *
436          * For notes on the logic here, see setuid() above.
437          */
438         gid = uap->gid;
439         if (gid != cr->cr_rgid &&               /* allow setgid(getgid()) */
440 #ifdef _POSIX_SAVED_IDS
441             gid != cr->cr_svgid &&              /* allow setgid(saved gid) */
442 #endif
443 #ifdef POSIX_APPENDIX_B_4_2_2   /* Use BSD-compat clause from B.4.2.2 */
444             gid != cr->cr_groups[0] && /* allow setgid(getegid()) */
445 #endif
446             (error = suser_cred(cr, PRISON_ROOT)))
447                 return (error);
448
449 #ifdef _POSIX_SAVED_IDS
450         /*
451          * Do we have "appropriate privileges" (are we root or gid == egid)
452          * If so, we are changing the real uid and saved gid.
453          */
454         if (
455 #ifdef POSIX_APPENDIX_B_4_2_2   /* use the clause from B.4.2.2 */
456             gid == cr->cr_groups[0] ||
457 #endif
458             suser_cred(cr, PRISON_ROOT) == 0) /* we are using privs */
459 #endif
460         {
461                 /*
462                  * Set real gid
463                  */
464                 if (cr->cr_rgid != gid) {
465                         cr = cratom(&p->p_ucred);
466                         cr->cr_rgid = gid;
467                         setsugid();
468                 }
469                 /*
470                  * Set saved gid
471                  *
472                  * XXX always set saved gid even if not _POSIX_SAVED_IDS, as
473                  * the security of setegid() depends on it.  B.4.2.2 says it
474                  * is important that we should do this.
475                  */
476                 if (cr->cr_svgid != gid) {
477                         cr = cratom(&p->p_ucred);
478                         cr->cr_svgid = gid;
479                         setsugid();
480                 }
481         }
482         /*
483          * In all cases permitted cases, we are changing the egid.
484          * Copy credentials so other references do not see our changes.
485          */
486         if (cr->cr_groups[0] != gid) {
487                 cr = cratom(&p->p_ucred);
488                 cr->cr_groups[0] = gid;
489                 setsugid();
490         }
491         return (0);
492 }
493
494 /* ARGSUSED */
495 int
496 setegid(struct setegid_args *uap)
497 {
498         struct proc *p = curproc;
499         struct ucred *cr;
500         gid_t egid;
501         int error;
502
503         if (p == NULL)                          /* API enforcement */
504                 return(EPERM);
505         cr = p->p_ucred;
506
507         egid = uap->egid;
508         if (egid != cr->cr_rgid &&              /* allow setegid(getgid()) */
509             egid != cr->cr_svgid &&             /* allow setegid(saved gid) */
510             (error = suser_cred(cr, PRISON_ROOT)))
511                 return (error);
512         if (cr->cr_groups[0] != egid) {
513                 cr = cratom(&p->p_ucred);
514                 cr->cr_groups[0] = egid;
515                 setsugid();
516         }
517         return (0);
518 }
519
520 /* ARGSUSED */
521 int
522 setgroups(struct setgroups_args *uap)
523 {
524         struct proc *p = curproc;
525         struct ucred *cr;
526         u_int ngrp;
527         int error;
528
529         if (p == NULL)                          /* API enforcement */
530                 return(EPERM);
531         cr = p->p_ucred;
532
533         if ((error = suser_cred(cr, PRISON_ROOT)))
534                 return (error);
535         ngrp = uap->gidsetsize;
536         if (ngrp > NGROUPS)
537                 return (EINVAL);
538         /*
539          * XXX A little bit lazy here.  We could test if anything has
540          * changed before cratom() and setting P_SUGID.
541          */
542         cr = cratom(&p->p_ucred);
543         if (ngrp < 1) {
544                 /*
545                  * setgroups(0, NULL) is a legitimate way of clearing the
546                  * groups vector on non-BSD systems (which generally do not
547                  * have the egid in the groups[0]).  We risk security holes
548                  * when running non-BSD software if we do not do the same.
549                  */
550                 cr->cr_ngroups = 1;
551         } else {
552                 if ((error = copyin((caddr_t)uap->gidset,
553                     (caddr_t)cr->cr_groups, ngrp * sizeof(gid_t))))
554                         return (error);
555                 cr->cr_ngroups = ngrp;
556         }
557         setsugid();
558         return (0);
559 }
560
561 /* ARGSUSED */
562 int
563 setreuid(struct setreuid_args *uap)
564 {
565         struct proc *p = curproc;
566         struct ucred *cr;
567         uid_t ruid, euid;
568         int error;
569
570         if (p == NULL)                          /* API enforcement */
571                 return(EPERM);
572         cr = p->p_ucred;
573
574         ruid = uap->ruid;
575         euid = uap->euid;
576         if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && ruid != cr->cr_svuid) ||
577              (euid != (uid_t)-1 && euid != cr->cr_uid &&
578              euid != cr->cr_ruid && euid != cr->cr_svuid)) &&
579             (error = suser_cred(cr, PRISON_ROOT)) != 0)
580                 return (error);
581
582         if (euid != (uid_t)-1 && cr->cr_uid != euid) {
583                 change_euid(euid);
584                 setsugid();
585         }
586         if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) {
587                 change_ruid(ruid);
588                 setsugid();
589         }
590         if ((ruid != (uid_t)-1 || cr->cr_uid != cr->cr_ruid) &&
591             cr->cr_svuid != cr->cr_uid) {
592                 cr = cratom(&p->p_ucred);
593                 cr->cr_svuid = cr->cr_uid;
594                 setsugid();
595         }
596         return (0);
597 }
598
599 /* ARGSUSED */
600 int
601 setregid(struct setregid_args *uap)
602 {
603         struct proc *p = curproc;
604         struct ucred *cr;
605         gid_t rgid, egid;
606         int error;
607
608         if (p == NULL)                          /* API enforcement */
609                 return(EPERM);
610         cr = p->p_ucred;
611
612         rgid = uap->rgid;
613         egid = uap->egid;
614         if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && rgid != cr->cr_svgid) ||
615              (egid != (gid_t)-1 && egid != cr->cr_groups[0] &&
616              egid != cr->cr_rgid && egid != cr->cr_svgid)) &&
617             (error = suser_cred(cr, PRISON_ROOT)) != 0)
618                 return (error);
619
620         if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) {
621                 cr = cratom(&p->p_ucred);
622                 cr->cr_groups[0] = egid;
623                 setsugid();
624         }
625         if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) {
626                 cr = cratom(&p->p_ucred);
627                 cr->cr_rgid = rgid;
628                 setsugid();
629         }
630         if ((rgid != (gid_t)-1 || cr->cr_groups[0] != cr->cr_rgid) &&
631             cr->cr_svgid != cr->cr_groups[0]) {
632                 cr = cratom(&p->p_ucred);
633                 cr->cr_svgid = cr->cr_groups[0];
634                 setsugid();
635         }
636         return (0);
637 }
638
639 /*
640  * setresuid(ruid, euid, suid) is like setreuid except control over the
641  * saved uid is explicit.
642  */
643
644 /* ARGSUSED */
645 int
646 setresuid(struct setresuid_args *uap)
647 {
648         struct proc *p = curproc;
649         struct ucred *cr;
650         uid_t ruid, euid, suid;
651         int error;
652
653         cr = p->p_ucred;
654         ruid = uap->ruid;
655         euid = uap->euid;
656         suid = uap->suid;
657         if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && ruid != cr->cr_svuid &&
658               ruid != cr->cr_uid) ||
659              (euid != (uid_t)-1 && euid != cr->cr_ruid && euid != cr->cr_svuid &&
660               euid != cr->cr_uid) ||
661              (suid != (uid_t)-1 && suid != cr->cr_ruid && suid != cr->cr_svuid &&
662               suid != cr->cr_uid)) &&
663             (error = suser_cred(cr, PRISON_ROOT)) != 0)
664                 return (error);
665         if (euid != (uid_t)-1 && cr->cr_uid != euid) {
666                 change_euid(euid);
667                 setsugid();
668         }
669         if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) {
670                 change_ruid(ruid);
671                 setsugid();
672         }
673         if (suid != (uid_t)-1 && cr->cr_svuid != suid) {
674                 cr = cratom(&p->p_ucred);
675                 cr->cr_svuid = suid;
676                 setsugid();
677         }
678         return (0);
679 }
680
681 /*
682  * setresgid(rgid, egid, sgid) is like setregid except control over the
683  * saved gid is explicit.
684  */
685
686 /* ARGSUSED */
687 int
688 setresgid(struct setresgid_args *uap)
689 {
690         struct proc *p = curproc;
691         struct ucred *cr;
692         gid_t rgid, egid, sgid;
693         int error;
694
695         cr = p->p_ucred;
696         rgid = uap->rgid;
697         egid = uap->egid;
698         sgid = uap->sgid;
699         if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && rgid != cr->cr_svgid &&
700               rgid != cr->cr_groups[0]) ||
701              (egid != (gid_t)-1 && egid != cr->cr_rgid && egid != cr->cr_svgid &&
702               egid != cr->cr_groups[0]) ||
703              (sgid != (gid_t)-1 && sgid != cr->cr_rgid && sgid != cr->cr_svgid &&
704               sgid != cr->cr_groups[0])) &&
705             (error = suser_cred(cr, PRISON_ROOT)) != 0)
706                 return (error);
707
708         if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) {
709                 cr = cratom(&p->p_ucred);
710                 cr->cr_groups[0] = egid;
711                 setsugid();
712         }
713         if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) {
714                 cr = cratom(&p->p_ucred);
715                 cr->cr_rgid = rgid;
716                 setsugid();
717         }
718         if (sgid != (gid_t)-1 && cr->cr_svgid != sgid) {
719                 cr = cratom(&p->p_ucred);
720                 cr->cr_svgid = sgid;
721                 setsugid();
722         }
723         return (0);
724 }
725
726 /* ARGSUSED */
727 int
728 getresuid(struct getresuid_args *uap)
729 {
730         struct proc *p = curproc;
731         struct ucred *cr = p->p_ucred;
732         int error1 = 0, error2 = 0, error3 = 0;
733
734         if (uap->ruid)
735                 error1 = copyout((caddr_t)&cr->cr_ruid,
736                     (caddr_t)uap->ruid, sizeof(cr->cr_ruid));
737         if (uap->euid)
738                 error2 = copyout((caddr_t)&cr->cr_uid,
739                     (caddr_t)uap->euid, sizeof(cr->cr_uid));
740         if (uap->suid)
741                 error3 = copyout((caddr_t)&cr->cr_svuid,
742                     (caddr_t)uap->suid, sizeof(cr->cr_svuid));
743         return error1 ? error1 : (error2 ? error2 : error3);
744 }
745
746 /* ARGSUSED */
747 int
748 getresgid(struct getresgid_args *uap)
749 {
750         struct proc *p = curproc;
751         struct ucred *cr = p->p_ucred;
752         int error1 = 0, error2 = 0, error3 = 0;
753
754         if (uap->rgid)
755                 error1 = copyout((caddr_t)&cr->cr_rgid,
756                     (caddr_t)uap->rgid, sizeof(cr->cr_rgid));
757         if (uap->egid)
758                 error2 = copyout((caddr_t)&cr->cr_groups[0],
759                     (caddr_t)uap->egid, sizeof(cr->cr_groups[0]));
760         if (uap->sgid)
761                 error3 = copyout((caddr_t)&cr->cr_svgid,
762                     (caddr_t)uap->sgid, sizeof(cr->cr_svgid));
763         return error1 ? error1 : (error2 ? error2 : error3);
764 }
765
766
767 /* ARGSUSED */
768 int
769 issetugid(struct issetugid_args *uap)
770 {
771         struct proc *p = curproc;
772         /*
773          * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
774          * we use P_SUGID because we consider changing the owners as
775          * "tainting" as well.
776          * This is significant for procs that start as root and "become"
777          * a user without an exec - programs cannot know *everything*
778          * that libc *might* have put in their data segment.
779          */
780         uap->sysmsg_result = (p->p_flag & P_SUGID) ? 1 : 0;
781         return (0);
782 }
783
784 /*
785  * Check if gid is a member of the group set.
786  */
787 int
788 groupmember(gid_t gid, struct ucred *cred)
789 {
790         gid_t *gp;
791         gid_t *egp;
792
793         egp = &(cred->cr_groups[cred->cr_ngroups]);
794         for (gp = cred->cr_groups; gp < egp; gp++)
795                 if (*gp == gid)
796                         return (1);
797         return (0);
798 }
799
800 /*
801  * Test whether the specified credentials imply "super-user"
802  * privilege; if so, and we have accounting info, set the flag
803  * indicating use of super-powers.  A kernel thread without a process
804  * context is assumed to have super user capabilities.  In situations
805  * where the caller always expect a cred to exist, the cred should be
806  * passed separately and suser_cred()should be used instead of suser().
807  *
808  * Returns 0 or error.
809  */
810 int
811 suser(struct thread *td)
812 {
813         struct proc *p = td->td_proc;
814
815         if (p != NULL) {
816                 return suser_cred(p->p_ucred, 0);
817         } else {
818                 return (0);
819         }
820 }
821
822 int
823 suser_cred(struct ucred *cred, int flag)
824 {
825         KASSERT(cred != NULL, ("suser_cred: NULL cred!"));
826
827         if (cred->cr_uid != 0) 
828                 return (EPERM);
829         if (cred->cr_prison && !(flag & PRISON_ROOT))
830                 return (EPERM);
831         /* NOTE: accounting for suser access (p_acflag/ASU) removed */
832         return (0);
833 }
834
835 /*
836  * Return zero if p1 can fondle p2, return errno (EPERM/ESRCH) otherwise.
837  */
838 int
839 p_trespass(struct ucred *cr1, struct ucred *cr2)
840 {
841         if (cr1 == cr2)
842                 return (0);
843         if (!PRISON_CHECK(cr1, cr2))
844                 return (ESRCH);
845         if (cr1->cr_ruid == cr2->cr_ruid)
846                 return (0);
847         if (cr1->cr_uid == cr2->cr_ruid)
848                 return (0);
849         if (cr1->cr_ruid == cr2->cr_uid)
850                 return (0);
851         if (cr1->cr_uid == cr2->cr_uid)
852                 return (0);
853         if (suser_cred(cr1, PRISON_ROOT) == 0)
854                 return (0);
855         return (EPERM);
856 }
857
858 /*
859  * Allocate a zeroed cred structure.
860  */
861 struct ucred *
862 crget()
863 {
864         struct ucred *cr;
865
866         MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
867         bzero((caddr_t)cr, sizeof(*cr));
868         cr->cr_ref = 1;
869         return (cr);
870 }
871
872 /*
873  * Claim another reference to a ucred structure.  Can be used with special
874  * creds.
875  */
876 struct ucred *
877 crhold(struct ucred *cr)
878 {
879         if (cr != NOCRED && cr != FSCRED)
880                 cr->cr_ref++;
881         return(cr);
882 }
883
884 /*
885  * Free a cred structure.
886  * Throws away space when ref count gets to 0.
887  * MPSAFE
888  */
889 void
890 crfree(struct ucred *cr)
891 {
892         /* Protect crfree() as a critical section as there
893          * appears to be a crfree race  which can occur on
894          * SMP systems.
895          */
896         crit_enter();
897         if (cr->cr_ref == 0)
898                 panic("Freeing already free credential! %p", cr);
899         
900         if (--cr->cr_ref == 0) {
901                 /*
902                  * Some callers of crget(), such as nfs_statfs(),
903                  * allocate a temporary credential, but don't
904                  * allocate a uidinfo structure.
905                  */
906                 if (cr->cr_uidinfo != NULL) {
907                         uidrop(cr->cr_uidinfo);
908                         cr->cr_uidinfo = NULL;
909                 }
910                 if (cr->cr_ruidinfo != NULL) {
911                         uidrop(cr->cr_ruidinfo);
912                         cr->cr_ruidinfo = NULL;
913                 }
914
915                 /*
916                  * Destroy empty prisons
917                  */
918                 if (cr->cr_prison && !--cr->cr_prison->pr_ref) {
919                         if (cr->cr_prison->pr_linux != NULL)
920                                 FREE(cr->cr_prison->pr_linux, M_PRISON);
921                         FREE(cr->cr_prison, M_PRISON);
922                 }
923                 cr->cr_prison = NULL;   /* safety */
924
925                 FREE((caddr_t)cr, M_CRED);
926         }
927         crit_exit();
928 }
929
930 /*
931  * Atomize a cred structure so it can be modified without polluting
932  * other references to it.
933  */
934 struct ucred *
935 cratom(struct ucred **pcr)
936 {
937         struct ucred *oldcr;
938         struct ucred *newcr;
939
940         oldcr = *pcr;
941         if (oldcr->cr_ref == 1)
942                 return (oldcr);
943         newcr = crget();
944         *newcr = *oldcr;
945         if (newcr->cr_uidinfo)
946                 uihold(newcr->cr_uidinfo);
947         if (newcr->cr_ruidinfo)
948                 uihold(newcr->cr_ruidinfo);
949         if (newcr->cr_prison)
950                 ++newcr->cr_prison->pr_ref;
951         newcr->cr_ref = 1;
952         crfree(oldcr);
953         *pcr = newcr;
954         return (newcr);
955 }
956
957 #if 0   /* no longer used but keep around for a little while */
958 /*
959  * Copy cred structure to a new one and free the old one.
960  */
961 struct ucred *
962 crcopy(struct ucred *cr)
963 {
964         struct ucred *newcr;
965
966         if (cr->cr_ref == 1)
967                 return (cr);
968         newcr = crget();
969         *newcr = *cr;
970         if (newcr->cr_uidinfo)
971                 uihold(newcr->cr_uidinfo);
972         if (newcr->cr_ruidinfo)
973                 uihold(newcr->cr_ruidinfo);
974         if (newcr->cr_prison)
975                 ++newcr->cr_prison->pr_ref;
976         newcr->cr_ref = 1;
977         crfree(cr);
978         return (newcr);
979 }
980 #endif
981
982 /*
983  * Dup cred struct to a new held one.
984  */
985 struct ucred *
986 crdup(cr)
987         struct ucred *cr;
988 {
989         struct ucred *newcr;
990
991         newcr = crget();
992         *newcr = *cr;
993         if (newcr->cr_uidinfo)
994                 uihold(newcr->cr_uidinfo);
995         if (newcr->cr_ruidinfo)
996                 uihold(newcr->cr_ruidinfo);
997         if (newcr->cr_prison)
998                 ++newcr->cr_prison->pr_ref;
999         newcr->cr_ref = 1;
1000         return (newcr);
1001 }
1002
1003 /*
1004  * Fill in a struct xucred based on a struct ucred.
1005  */
1006 void
1007 cru2x(cr, xcr)
1008         struct ucred *cr;
1009         struct xucred *xcr;
1010 {
1011
1012         bzero(xcr, sizeof(*xcr));
1013         xcr->cr_version = XUCRED_VERSION;
1014         xcr->cr_uid = cr->cr_uid;
1015         xcr->cr_ngroups = cr->cr_ngroups;
1016         bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups));
1017 }
1018
1019 /*
1020  * Get login name, if available.
1021  */
1022 /* ARGSUSED */
1023 int
1024 getlogin(struct getlogin_args *uap)
1025 {
1026         struct proc *p = curproc;
1027
1028         if (uap->namelen > MAXLOGNAME)
1029                 uap->namelen = MAXLOGNAME;
1030         return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
1031             (caddr_t) uap->namebuf, uap->namelen));
1032 }
1033
1034 /*
1035  * Set login name.
1036  */
1037 /* ARGSUSED */
1038 int
1039 setlogin(struct setlogin_args *uap)
1040 {
1041         struct proc *p = curproc;
1042         int error;
1043         char logintmp[MAXLOGNAME];
1044
1045         KKASSERT(p != NULL);
1046         if ((error = suser_cred(p->p_ucred, PRISON_ROOT)))
1047                 return (error);
1048         error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp,
1049             sizeof(logintmp), (size_t *)0);
1050         if (error == ENAMETOOLONG)
1051                 error = EINVAL;
1052         else if (!error)
1053                 (void) memcpy(p->p_pgrp->pg_session->s_login, logintmp,
1054                     sizeof(logintmp));
1055         return (error);
1056 }
1057
1058 void
1059 setsugid()
1060 {
1061         struct proc *p = curproc;
1062
1063         KKASSERT(p != NULL);
1064         p->p_flag |= P_SUGID;
1065         if (!(p->p_pfsflags & PF_ISUGID))
1066                 p->p_stops = 0;
1067 }
1068
1069 /*
1070  * Helper function to change the effective uid of a process
1071  */
1072 void
1073 change_euid(uid_t euid)
1074 {
1075         struct  proc *p = curproc;
1076         struct  ucred *cr;
1077
1078         KKASSERT(p != NULL);
1079         cr = cratom(&p->p_ucred);
1080         cr->cr_uid = euid;
1081         uireplace(&cr->cr_uidinfo, uifind(euid));
1082 }
1083
1084 /*
1085  * Helper function to change the real uid of a process
1086  *
1087  * The per-uid process count for this process is transfered from
1088  * the old uid to the new uid.
1089  */
1090 void
1091 change_ruid(uid_t ruid)
1092 {
1093         struct  proc *p = curproc;
1094         struct  ucred *cr;
1095
1096         KKASSERT(p != NULL);
1097
1098         cr = cratom(&p->p_ucred);
1099         (void)chgproccnt(cr->cr_ruidinfo, -1, 0);
1100         /* It is assumed that pcred is not shared between processes */
1101         cr->cr_ruid = ruid;
1102         uireplace(&cr->cr_ruidinfo, uifind(ruid));
1103         (void)chgproccnt(cr->cr_ruidinfo, 1, 0);
1104 }