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