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