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