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