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