kern_prot.c revision 75632
1/*
2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed by the University of
21 *	California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 *	@(#)kern_prot.c	8.6 (Berkeley) 1/21/94
39 * $FreeBSD: head/sys/kern/kern_prot.c 75632 2001-04-17 20:50:43Z alfred $
40 */
41
42/*
43 * System calls related to processes and protection
44 */
45
46#include "opt_compat.h"
47#include "opt_global.h"
48
49#include <sys/param.h>
50#include <sys/acct.h>
51#include <sys/systm.h>
52#include <sys/sysproto.h>
53#include <sys/kernel.h>
54#include <sys/lock.h>
55#include <sys/proc.h>
56#include <sys/malloc.h>
57#include <sys/pioctl.h>
58#include <sys/resourcevar.h>
59#include <sys/sysctl.h>
60#include <sys/jail.h>
61
62static MALLOC_DEFINE(M_CRED, "cred", "credentials");
63
64#ifndef _SYS_SYSPROTO_H_
65struct getpid_args {
66	int	dummy;
67};
68#endif
69
70/*
71 * getpid - MP SAFE
72 */
73
74/* ARGSUSED */
75int
76getpid(p, uap)
77	struct proc *p;
78	struct getpid_args *uap;
79{
80
81	p->p_retval[0] = p->p_pid;
82#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
83	PROC_LOCK(p);
84	p->p_retval[1] = p->p_pptr->p_pid;
85	PROC_UNLOCK(p);
86#endif
87	return (0);
88}
89
90/*
91 * getppid - MP SAFE
92 */
93
94#ifndef _SYS_SYSPROTO_H_
95struct getppid_args {
96        int     dummy;
97};
98#endif
99/* ARGSUSED */
100int
101getppid(p, uap)
102	struct proc *p;
103	struct getppid_args *uap;
104{
105
106	PROC_LOCK(p);
107	p->p_retval[0] = p->p_pptr->p_pid;
108	PROC_UNLOCK(p);
109	return (0);
110}
111
112/*
113 * Get process group ID; note that POSIX getpgrp takes no parameter
114 *
115 * MP SAFE
116 */
117#ifndef _SYS_SYSPROTO_H_
118struct getpgrp_args {
119        int     dummy;
120};
121#endif
122
123int
124getpgrp(p, uap)
125	struct proc *p;
126	struct getpgrp_args *uap;
127{
128
129	p->p_retval[0] = p->p_pgrp->pg_id;
130	return (0);
131}
132
133/* Get an arbitary pid's process group id */
134#ifndef _SYS_SYSPROTO_H_
135struct getpgid_args {
136	pid_t	pid;
137};
138#endif
139
140int
141getpgid(p, uap)
142	struct proc *p;
143	struct getpgid_args *uap;
144{
145	struct proc *pt;
146	int error;
147
148	pt = p;
149	if (uap->pid == 0)
150		goto found;
151
152	if ((pt = pfind(uap->pid)) == 0)
153		return ESRCH;
154	if ((error = p_can(p, pt, P_CAN_SEE, NULL)))
155		return (error);
156found:
157	p->p_retval[0] = pt->p_pgrp->pg_id;
158	return 0;
159}
160
161/*
162 * Get an arbitary pid's session id.
163 */
164#ifndef _SYS_SYSPROTO_H_
165struct getsid_args {
166	pid_t	pid;
167};
168#endif
169
170int
171getsid(p, uap)
172	struct proc *p;
173	struct getsid_args *uap;
174{
175	struct proc *pt;
176	int error;
177
178	pt = p;
179	if (uap->pid == 0)
180		goto found;
181
182	if ((pt = pfind(uap->pid)) == 0)
183		return ESRCH;
184	if ((error = p_can(p, pt, P_CAN_SEE, NULL)))
185		return (error);
186found:
187	p->p_retval[0] = pt->p_session->s_sid;
188	return 0;
189}
190
191
192/*
193 * getuid() - MP SAFE
194 */
195#ifndef _SYS_SYSPROTO_H_
196struct getuid_args {
197        int     dummy;
198};
199#endif
200
201/* ARGSUSED */
202int
203getuid(p, uap)
204	struct proc *p;
205	struct getuid_args *uap;
206{
207
208	p->p_retval[0] = p->p_cred->p_ruid;
209#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
210	p->p_retval[1] = p->p_ucred->cr_uid;
211#endif
212	return (0);
213}
214
215/*
216 * geteuid() - MP SAFE
217 */
218#ifndef _SYS_SYSPROTO_H_
219struct geteuid_args {
220        int     dummy;
221};
222#endif
223
224/* ARGSUSED */
225int
226geteuid(p, uap)
227	struct proc *p;
228	struct geteuid_args *uap;
229{
230
231	p->p_retval[0] = p->p_ucred->cr_uid;
232	return (0);
233}
234
235/*
236 * getgid() - MP SAFE
237 */
238#ifndef _SYS_SYSPROTO_H_
239struct getgid_args {
240        int     dummy;
241};
242#endif
243
244/* ARGSUSED */
245int
246getgid(p, uap)
247	struct proc *p;
248	struct getgid_args *uap;
249{
250
251	p->p_retval[0] = p->p_cred->p_rgid;
252#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
253	p->p_retval[1] = p->p_ucred->cr_groups[0];
254#endif
255	return (0);
256}
257
258/*
259 * Get effective group ID.  The "egid" is groups[0], and could be obtained
260 * via getgroups.  This syscall exists because it is somewhat painful to do
261 * correctly in a library function.
262 */
263#ifndef _SYS_SYSPROTO_H_
264struct getegid_args {
265        int     dummy;
266};
267#endif
268
269/* ARGSUSED */
270int
271getegid(p, uap)
272	struct proc *p;
273	struct getegid_args *uap;
274{
275
276	p->p_retval[0] = p->p_ucred->cr_groups[0];
277	return (0);
278}
279
280#ifndef _SYS_SYSPROTO_H_
281struct getgroups_args {
282	u_int	gidsetsize;
283	gid_t	*gidset;
284};
285#endif
286int
287getgroups(p, uap)
288	struct proc *p;
289	register struct	getgroups_args *uap;
290{
291	register struct pcred *pc = p->p_cred;
292	register u_int ngrp;
293	int error;
294
295	if ((ngrp = uap->gidsetsize) == 0) {
296		p->p_retval[0] = pc->pc_ucred->cr_ngroups;
297		return (0);
298	}
299	if (ngrp < pc->pc_ucred->cr_ngroups)
300		return (EINVAL);
301	ngrp = pc->pc_ucred->cr_ngroups;
302	if ((error = copyout((caddr_t)pc->pc_ucred->cr_groups,
303	    (caddr_t)uap->gidset, ngrp * sizeof(gid_t))))
304		return (error);
305	p->p_retval[0] = ngrp;
306	return (0);
307}
308
309#ifndef _SYS_SYSPROTO_H_
310struct setsid_args {
311        int     dummy;
312};
313#endif
314
315/* ARGSUSED */
316int
317setsid(p, uap)
318	register struct proc *p;
319	struct setsid_args *uap;
320{
321
322	if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
323		return (EPERM);
324	} else {
325		(void)enterpgrp(p, p->p_pid, 1);
326		p->p_retval[0] = p->p_pid;
327		return (0);
328	}
329}
330
331/*
332 * set process group (setpgid/old setpgrp)
333 *
334 * caller does setpgid(targpid, targpgid)
335 *
336 * pid must be caller or child of caller (ESRCH)
337 * if a child
338 *	pid must be in same session (EPERM)
339 *	pid can't have done an exec (EACCES)
340 * if pgid != pid
341 * 	there must exist some pid in same session having pgid (EPERM)
342 * pid must not be session leader (EPERM)
343 */
344#ifndef _SYS_SYSPROTO_H_
345struct setpgid_args {
346	int	pid;	/* target process id */
347	int	pgid;	/* target pgrp id */
348};
349#endif
350/* ARGSUSED */
351int
352setpgid(curp, uap)
353	struct proc *curp;
354	register struct setpgid_args *uap;
355{
356	register struct proc *targp;		/* target process */
357	register struct pgrp *pgrp;		/* target pgrp */
358	int error;
359
360	if (uap->pgid < 0)
361		return (EINVAL);
362	if (uap->pid != 0 && uap->pid != curp->p_pid) {
363		if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
364			return (ESRCH);
365		if ((error = p_can(curproc, targp, P_CAN_SEE, NULL)))
366			return (error);
367		if (targp->p_pgrp == NULL ||  targp->p_session != curp->p_session)
368			return (EPERM);
369		if (targp->p_flag & P_EXEC)
370			return (EACCES);
371	} else
372		targp = curp;
373	if (SESS_LEADER(targp))
374		return (EPERM);
375	if (uap->pgid == 0)
376		uap->pgid = targp->p_pid;
377	else if (uap->pgid != targp->p_pid)
378		if ((pgrp = pgfind(uap->pgid)) == 0 ||
379	            pgrp->pg_session != curp->p_session)
380			return (EPERM);
381	return (enterpgrp(targp, uap->pgid, 0));
382}
383
384/*
385 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD
386 * compatible.  It says that setting the uid/gid to euid/egid is a special
387 * case of "appropriate privilege".  Once the rules are expanded out, this
388 * basically means that setuid(nnn) sets all three id's, in all permitted
389 * cases unless _POSIX_SAVED_IDS is enabled.  In that case, setuid(getuid())
390 * does not set the saved id - this is dangerous for traditional BSD
391 * programs.  For this reason, we *really* do not want to set
392 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2.
393 */
394#define POSIX_APPENDIX_B_4_2_2
395
396#ifndef _SYS_SYSPROTO_H_
397struct setuid_args {
398	uid_t	uid;
399};
400#endif
401/* ARGSUSED */
402int
403setuid(p, uap)
404	struct proc *p;
405	struct setuid_args *uap;
406{
407	register struct pcred *pc = p->p_cred;
408	register uid_t uid;
409	int error;
410
411	/*
412	 * See if we have "permission" by POSIX 1003.1 rules.
413	 *
414	 * Note that setuid(geteuid()) is a special case of
415	 * "appropriate privileges" in appendix B.4.2.2.  We need
416	 * to use this clause to be compatible with traditional BSD
417	 * semantics.  Basically, it means that "setuid(xx)" sets all
418	 * three id's (assuming you have privs).
419	 *
420	 * Notes on the logic.  We do things in three steps.
421	 * 1: We determine if the euid is going to change, and do EPERM
422	 *    right away.  We unconditionally change the euid later if this
423	 *    test is satisfied, simplifying that part of the logic.
424	 * 2: We determine if the real and/or saved uid's are going to
425	 *    change.  Determined by compile options.
426	 * 3: Change euid last. (after tests in #2 for "appropriate privs")
427	 */
428	uid = uap->uid;
429	if (uid != pc->p_ruid &&		/* allow setuid(getuid()) */
430#ifdef _POSIX_SAVED_IDS
431	    uid != pc->p_svuid &&		/* allow setuid(saved gid) */
432#endif
433#ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
434	    uid != pc->pc_ucred->cr_uid &&	/* allow setuid(geteuid()) */
435#endif
436	    (error = suser_xxx(0, p, PRISON_ROOT)))
437		return (error);
438
439#ifdef _POSIX_SAVED_IDS
440	/*
441	 * Do we have "appropriate privileges" (are we root or uid == euid)
442	 * If so, we are changing the real uid and/or saved uid.
443	 */
444	if (
445#ifdef POSIX_APPENDIX_B_4_2_2	/* Use the clause from B.4.2.2 */
446	    uid == pc->pc_ucred->cr_uid ||
447#endif
448	    suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */
449#endif
450	{
451		/*
452		 * Set the real uid and transfer proc count to new user.
453		 */
454		if (uid != pc->p_ruid) {
455			change_ruid(p, uid);
456			setsugid(p);
457		}
458		/*
459		 * Set saved uid
460		 *
461		 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as
462		 * the security of seteuid() depends on it.  B.4.2.2 says it
463		 * is important that we should do this.
464		 */
465		if (pc->p_svuid != uid) {
466			pc->p_svuid = uid;
467			setsugid(p);
468		}
469	}
470
471	/*
472	 * In all permitted cases, we are changing the euid.
473	 * Copy credentials so other references do not see our changes.
474	 */
475	if (pc->pc_ucred->cr_uid != uid) {
476		change_euid(p, uid);
477		setsugid(p);
478	}
479	return (0);
480}
481
482#ifndef _SYS_SYSPROTO_H_
483struct seteuid_args {
484	uid_t	euid;
485};
486#endif
487/* ARGSUSED */
488int
489seteuid(p, uap)
490	struct proc *p;
491	struct seteuid_args *uap;
492{
493	register struct pcred *pc = p->p_cred;
494	register uid_t euid;
495	int error;
496
497	euid = uap->euid;
498	if (euid != pc->p_ruid &&		/* allow seteuid(getuid()) */
499	    euid != pc->p_svuid &&		/* allow seteuid(saved uid) */
500	    (error = suser_xxx(0, p, PRISON_ROOT)))
501		return (error);
502	/*
503	 * Everything's okay, do it.  Copy credentials so other references do
504	 * not see our changes.
505	 */
506	if (pc->pc_ucred->cr_uid != euid) {
507		change_euid(p, euid);
508		setsugid(p);
509	}
510	return (0);
511}
512
513#ifndef _SYS_SYSPROTO_H_
514struct setgid_args {
515	gid_t	gid;
516};
517#endif
518/* ARGSUSED */
519int
520setgid(p, uap)
521	struct proc *p;
522	struct setgid_args *uap;
523{
524	register struct pcred *pc = p->p_cred;
525	register gid_t gid;
526	int error;
527
528	/*
529	 * See if we have "permission" by POSIX 1003.1 rules.
530	 *
531	 * Note that setgid(getegid()) is a special case of
532	 * "appropriate privileges" in appendix B.4.2.2.  We need
533	 * to use this clause to be compatible with traditional BSD
534	 * semantics.  Basically, it means that "setgid(xx)" sets all
535	 * three id's (assuming you have privs).
536	 *
537	 * For notes on the logic here, see setuid() above.
538	 */
539	gid = uap->gid;
540	if (gid != pc->p_rgid &&		/* allow setgid(getgid()) */
541#ifdef _POSIX_SAVED_IDS
542	    gid != pc->p_svgid &&		/* allow setgid(saved gid) */
543#endif
544#ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
545	    gid != pc->pc_ucred->cr_groups[0] && /* allow setgid(getegid()) */
546#endif
547	    (error = suser_xxx(0, p, PRISON_ROOT)))
548		return (error);
549
550#ifdef _POSIX_SAVED_IDS
551	/*
552	 * Do we have "appropriate privileges" (are we root or gid == egid)
553	 * If so, we are changing the real uid and saved gid.
554	 */
555	if (
556#ifdef POSIX_APPENDIX_B_4_2_2	/* use the clause from B.4.2.2 */
557	    gid == pc->pc_ucred->cr_groups[0] ||
558#endif
559	    suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */
560#endif
561	{
562		/*
563		 * Set real gid
564		 */
565		if (pc->p_rgid != gid) {
566			pc->p_rgid = gid;
567			setsugid(p);
568		}
569		/*
570		 * Set saved gid
571		 *
572		 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as
573		 * the security of setegid() depends on it.  B.4.2.2 says it
574		 * is important that we should do this.
575		 */
576		if (pc->p_svgid != gid) {
577			pc->p_svgid = gid;
578			setsugid(p);
579		}
580	}
581	/*
582	 * In all cases permitted cases, we are changing the egid.
583	 * Copy credentials so other references do not see our changes.
584	 */
585	if (pc->pc_ucred->cr_groups[0] != gid) {
586		pc->pc_ucred = crcopy(pc->pc_ucred);
587		pc->pc_ucred->cr_groups[0] = gid;
588		setsugid(p);
589	}
590	return (0);
591}
592
593#ifndef _SYS_SYSPROTO_H_
594struct setegid_args {
595	gid_t	egid;
596};
597#endif
598/* ARGSUSED */
599int
600setegid(p, uap)
601	struct proc *p;
602	struct setegid_args *uap;
603{
604	register struct pcred *pc = p->p_cred;
605	register gid_t egid;
606	int error;
607
608	egid = uap->egid;
609	if (egid != pc->p_rgid &&		/* allow setegid(getgid()) */
610	    egid != pc->p_svgid &&		/* allow setegid(saved gid) */
611	    (error = suser_xxx(0, p, PRISON_ROOT)))
612		return (error);
613	if (pc->pc_ucred->cr_groups[0] != egid) {
614		pc->pc_ucred = crcopy(pc->pc_ucred);
615		pc->pc_ucred->cr_groups[0] = egid;
616		setsugid(p);
617	}
618	return (0);
619}
620
621#ifndef _SYS_SYSPROTO_H_
622struct setgroups_args {
623	u_int	gidsetsize;
624	gid_t	*gidset;
625};
626#endif
627/* ARGSUSED */
628int
629setgroups(p, uap)
630	struct proc *p;
631	struct setgroups_args *uap;
632{
633	register struct pcred *pc = p->p_cred;
634	register u_int ngrp;
635	int error;
636
637	if ((error = suser_xxx(0, p, PRISON_ROOT)))
638		return (error);
639	ngrp = uap->gidsetsize;
640	if (ngrp > NGROUPS)
641		return (EINVAL);
642	/*
643	 * XXX A little bit lazy here.  We could test if anything has
644	 * changed before crcopy() and setting P_SUGID.
645	 */
646	pc->pc_ucred = crcopy(pc->pc_ucred);
647	if (ngrp < 1) {
648		/*
649		 * setgroups(0, NULL) is a legitimate way of clearing the
650		 * groups vector on non-BSD systems (which generally do not
651		 * have the egid in the groups[0]).  We risk security holes
652		 * when running non-BSD software if we do not do the same.
653		 */
654		pc->pc_ucred->cr_ngroups = 1;
655	} else {
656		if ((error = copyin((caddr_t)uap->gidset,
657		    (caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t))))
658			return (error);
659		pc->pc_ucred->cr_ngroups = ngrp;
660	}
661	setsugid(p);
662	return (0);
663}
664
665#ifndef _SYS_SYSPROTO_H_
666struct setreuid_args {
667	uid_t	ruid;
668	uid_t	euid;
669};
670#endif
671/* ARGSUSED */
672int
673setreuid(p, uap)
674	register struct proc *p;
675	struct setreuid_args *uap;
676{
677	register struct pcred *pc = p->p_cred;
678	register uid_t ruid, euid;
679	int error;
680
681	ruid = uap->ruid;
682	euid = uap->euid;
683	if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid) ||
684	     (euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid &&
685	     euid != pc->p_ruid && euid != pc->p_svuid)) &&
686	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
687		return (error);
688
689	if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) {
690		change_euid(p, euid);
691		setsugid(p);
692	}
693	if (ruid != (uid_t)-1 && pc->p_ruid != ruid) {
694		change_ruid(p, ruid);
695		setsugid(p);
696	}
697	if ((ruid != (uid_t)-1 || pc->pc_ucred->cr_uid != pc->p_ruid) &&
698	    pc->p_svuid != pc->pc_ucred->cr_uid) {
699		pc->p_svuid = pc->pc_ucred->cr_uid;
700		setsugid(p);
701	}
702	return (0);
703}
704
705#ifndef _SYS_SYSPROTO_H_
706struct setregid_args {
707	gid_t	rgid;
708	gid_t	egid;
709};
710#endif
711/* ARGSUSED */
712int
713setregid(p, uap)
714	register struct proc *p;
715	struct setregid_args *uap;
716{
717	register struct pcred *pc = p->p_cred;
718	register gid_t rgid, egid;
719	int error;
720
721	rgid = uap->rgid;
722	egid = uap->egid;
723	if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid) ||
724	     (egid != (gid_t)-1 && egid != pc->pc_ucred->cr_groups[0] &&
725	     egid != pc->p_rgid && egid != pc->p_svgid)) &&
726	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
727		return (error);
728
729	if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) {
730		pc->pc_ucred = crcopy(pc->pc_ucred);
731		pc->pc_ucred->cr_groups[0] = egid;
732		setsugid(p);
733	}
734	if (rgid != (gid_t)-1 && pc->p_rgid != rgid) {
735		pc->p_rgid = rgid;
736		setsugid(p);
737	}
738	if ((rgid != (gid_t)-1 || pc->pc_ucred->cr_groups[0] != pc->p_rgid) &&
739	    pc->p_svgid != pc->pc_ucred->cr_groups[0]) {
740		pc->p_svgid = pc->pc_ucred->cr_groups[0];
741		setsugid(p);
742	}
743	return (0);
744}
745
746/*
747 * setresuid(ruid, euid, suid) is like setreuid except control over the
748 * saved uid is explicit.
749 */
750
751#ifndef _SYS_SYSPROTO_H_
752struct setresuid_args {
753	uid_t	ruid;
754	uid_t	euid;
755	uid_t	suid;
756};
757#endif
758/* ARGSUSED */
759int
760setresuid(p, uap)
761	register struct proc *p;
762	struct setresuid_args *uap;
763{
764	register struct pcred *pc = p->p_cred;
765	register uid_t ruid, euid, suid;
766	int error;
767
768	ruid = uap->ruid;
769	euid = uap->euid;
770	suid = uap->suid;
771	if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid &&
772	      ruid != pc->pc_ucred->cr_uid) ||
773	     (euid != (uid_t)-1 && euid != pc->p_ruid && euid != pc->p_svuid &&
774	      euid != pc->pc_ucred->cr_uid) ||
775	     (suid != (uid_t)-1 && suid != pc->p_ruid && suid != pc->p_svuid &&
776	      suid != pc->pc_ucred->cr_uid)) &&
777	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
778		return (error);
779	if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) {
780		change_euid(p, euid);
781		setsugid(p);
782	}
783	if (ruid != (uid_t)-1 && pc->p_ruid != ruid) {
784		change_ruid(p, ruid);
785		setsugid(p);
786	}
787	if (suid != (uid_t)-1 && pc->p_svuid != suid) {
788		pc->p_svuid = suid;
789		setsugid(p);
790	}
791	return (0);
792}
793
794/*
795 * setresgid(rgid, egid, sgid) is like setregid except control over the
796 * saved gid is explicit.
797 */
798
799#ifndef _SYS_SYSPROTO_H_
800struct setresgid_args {
801	gid_t	rgid;
802	gid_t	egid;
803	gid_t	sgid;
804};
805#endif
806/* ARGSUSED */
807int
808setresgid(p, uap)
809	register struct proc *p;
810	struct setresgid_args *uap;
811{
812	register struct pcred *pc = p->p_cred;
813	register gid_t rgid, egid, sgid;
814	int error;
815
816	rgid = uap->rgid;
817	egid = uap->egid;
818	sgid = uap->sgid;
819	if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid &&
820	      rgid != pc->pc_ucred->cr_groups[0]) ||
821	     (egid != (gid_t)-1 && egid != pc->p_rgid && egid != pc->p_svgid &&
822	      egid != pc->pc_ucred->cr_groups[0]) ||
823	     (sgid != (gid_t)-1 && sgid != pc->p_rgid && sgid != pc->p_svgid &&
824	      sgid != pc->pc_ucred->cr_groups[0])) &&
825	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
826		return (error);
827
828	if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) {
829		pc->pc_ucred = crcopy(pc->pc_ucred);
830		pc->pc_ucred->cr_groups[0] = egid;
831		setsugid(p);
832	}
833	if (rgid != (gid_t)-1 && pc->p_rgid != rgid) {
834		pc->p_rgid = rgid;
835		setsugid(p);
836	}
837	if (sgid != (gid_t)-1 && pc->p_svgid != sgid) {
838		pc->p_svgid = sgid;
839		setsugid(p);
840	}
841	return (0);
842}
843
844#ifndef _SYS_SYSPROTO_H_
845struct getresuid_args {
846	uid_t	*ruid;
847	uid_t	*euid;
848	uid_t	*suid;
849};
850#endif
851/* ARGSUSED */
852int
853getresuid(p, uap)
854	register struct proc *p;
855	struct getresuid_args *uap;
856{
857	struct pcred *pc = p->p_cred;
858	int error1 = 0, error2 = 0, error3 = 0;
859
860	if (uap->ruid)
861		error1 = copyout((caddr_t)&pc->p_ruid,
862		    (caddr_t)uap->ruid, sizeof(pc->p_ruid));
863	if (uap->euid)
864		error2 = copyout((caddr_t)&pc->pc_ucred->cr_uid,
865		    (caddr_t)uap->euid, sizeof(pc->pc_ucred->cr_uid));
866	if (uap->suid)
867		error3 = copyout((caddr_t)&pc->p_svuid,
868		    (caddr_t)uap->suid, sizeof(pc->p_svuid));
869	return error1 ? error1 : (error2 ? error2 : error3);
870}
871
872#ifndef _SYS_SYSPROTO_H_
873struct getresgid_args {
874	gid_t	*rgid;
875	gid_t	*egid;
876	gid_t	*sgid;
877};
878#endif
879/* ARGSUSED */
880int
881getresgid(p, uap)
882	register struct proc *p;
883	struct getresgid_args *uap;
884{
885	struct pcred *pc = p->p_cred;
886	int error1 = 0, error2 = 0, error3 = 0;
887
888	if (uap->rgid)
889		error1 = copyout((caddr_t)&pc->p_rgid,
890		    (caddr_t)uap->rgid, sizeof(pc->p_rgid));
891	if (uap->egid)
892		error2 = copyout((caddr_t)&pc->pc_ucred->cr_groups[0],
893		    (caddr_t)uap->egid, sizeof(pc->pc_ucred->cr_groups[0]));
894	if (uap->sgid)
895		error3 = copyout((caddr_t)&pc->p_svgid,
896		    (caddr_t)uap->sgid, sizeof(pc->p_svgid));
897	return error1 ? error1 : (error2 ? error2 : error3);
898}
899
900
901#ifndef _SYS_SYSPROTO_H_
902struct issetugid_args {
903	int dummy;
904};
905#endif
906/* ARGSUSED */
907int
908issetugid(p, uap)
909	register struct proc *p;
910	struct issetugid_args *uap;
911{
912	/*
913	 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
914	 * we use P_SUGID because we consider changing the owners as
915	 * "tainting" as well.
916	 * This is significant for procs that start as root and "become"
917	 * a user without an exec - programs cannot know *everything*
918	 * that libc *might* have put in their data segment.
919	 */
920	p->p_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0;
921	return (0);
922}
923
924int
925__setugid(p, uap)
926	struct proc *p;
927	struct __setugid_args *uap;
928{
929
930#ifdef REGRESSION
931	switch (uap->flag) {
932	case 0:
933		p->p_flag &= ~P_SUGID;
934		return (0);
935	case 1:
936		p->p_flag |= P_SUGID;
937		return (0);
938	default:
939		return (EINVAL);
940	}
941#else /* !REGRESSION */
942	return (ENOSYS);
943#endif /* !REGRESSION */
944}
945
946/*
947 * Check if gid is a member of the group set.
948 */
949int
950groupmember(gid, cred)
951	gid_t gid;
952	register struct ucred *cred;
953{
954	register gid_t *gp;
955	gid_t *egp;
956
957	egp = &(cred->cr_groups[cred->cr_ngroups]);
958	for (gp = cred->cr_groups; gp < egp; gp++)
959		if (*gp == gid)
960			return (1);
961	return (0);
962}
963
964static int suser_permitted = 1;
965
966SYSCTL_INT(_kern, OID_AUTO, suser_permitted, CTLFLAG_RW, &suser_permitted, 0,
967    "processes with uid 0 have privilege");
968
969/*
970 * Test whether the specified credentials imply "super-user"
971 * privilege; if so, and we have accounting info, set the flag
972 * indicating use of super-powers.
973 * Returns 0 or error.
974 */
975int
976suser(p)
977	struct proc *p;
978{
979	return suser_xxx(0, p, 0);
980}
981
982int
983suser_xxx(cred, proc, flag)
984	struct ucred *cred;
985	struct proc *proc;
986	int flag;
987{
988	if (!suser_permitted)
989		return (EPERM);
990	if (!cred && !proc) {
991		printf("suser_xxx(): THINK!\n");
992		return (EPERM);
993	}
994	if (!cred)
995		cred = proc->p_ucred;
996	if (cred->cr_uid != 0)
997		return (EPERM);
998	if (jailed(cred) && !(flag & PRISON_ROOT))
999		return (EPERM);
1000	return (0);
1001}
1002
1003/*
1004 * u_cansee(u1, u2): determine if u1 "can see" the subject specified by u2
1005 * Arguments: imutable credentials u1, u2
1006 * Returns: 0 for permitted, an errno value otherwise
1007 * Locks: none
1008 * References: u1 and u2 must be valid for the lifetime of the call
1009 *             u1 may equal u2, in which case only one reference is required
1010 */
1011int
1012u_cansee(struct ucred *u1, struct ucred *u2)
1013{
1014	int error;
1015
1016	if ((error = prison_check(u1, u2)))
1017		return (error);
1018	if (!ps_showallprocs && u1->cr_uid != u2->cr_uid) {
1019		if (suser_xxx(u1, NULL, PRISON_ROOT) != 0)
1020			return (ESRCH);
1021	}
1022	return (0);
1023}
1024
1025static int
1026p_cansee(struct proc *p1, struct proc *p2, int *privused)
1027{
1028
1029	/* XXX: privused is going away, so don't do that here. */
1030	if (privused != NULL)
1031		*privused = 0;
1032	/* Wrap u_cansee() for all functionality. */
1033	return (u_cansee(p1->p_ucred, p2->p_ucred));
1034}
1035
1036/*
1037 * Can process p1 send the signal signum to process p2?
1038 */
1039int
1040p_cansignal(struct proc *p1, struct proc *p2, int signum)
1041{
1042	int	error;
1043
1044	if (p1 == p2)
1045		return (0);
1046
1047	/*
1048	 * Jail semantics limit the scope of signalling to p2 in the same
1049	 * jail as p1, if p1 is in jail.
1050	 */
1051	if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
1052		return (error);
1053
1054	/*
1055	 * UNIX signalling semantics require that processes in the same
1056	 * session always be able to deliver SIGCONT to one another,
1057	 * overriding the remaining protections.
1058	 */
1059	if (signum == SIGCONT && p1->p_session == p2->p_session)
1060		return (0);
1061
1062	/*
1063	 * UNIX uid semantics depend on the status of the P_SUGID
1064	 * bit on the target process.  If the bit is set, then more
1065	 * restricted signal sets are permitted.
1066	 */
1067	if (p2->p_flag & P_SUGID) {
1068		switch (signum) {
1069		case 0:
1070		case SIGKILL:
1071		case SIGINT:
1072		case SIGTERM:
1073		case SIGSTOP:
1074		case SIGTTIN:
1075		case SIGTTOU:
1076		case SIGTSTP:
1077		case SIGHUP:
1078		case SIGUSR1:
1079		case SIGUSR2:
1080			break;
1081		default:
1082			/* Not permitted, try privilege. */
1083			error = suser_xxx(NULL, p1, PRISON_ROOT);
1084			if (error)
1085				return (error);
1086		}
1087	}
1088
1089	/*
1090	 * Generally, the object credential's ruid or svuid must match the
1091	 * subject credential's ruid or euid.
1092	 */
1093	if (p1->p_cred->p_ruid != p2->p_cred->p_ruid &&
1094	    p1->p_cred->p_ruid != p2->p_cred->p_svuid &&
1095	    p1->p_ucred->cr_uid != p2->p_cred->p_ruid &&
1096	    p1->p_ucred->cr_uid != p2->p_cred->p_svuid) {
1097		/* Not permitted, try privilege. */
1098		error = suser_xxx(NULL, p1, PRISON_ROOT);
1099		if (error)
1100			return (error);
1101	}
1102
1103        return (0);
1104}
1105
1106static int
1107p_cansched(struct proc *p1, struct proc *p2, int *privused)
1108{
1109	int error;
1110
1111	if (privused != NULL)
1112		*privused = 0;
1113
1114	if (p1 == p2)
1115		return (0);
1116
1117	if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
1118		return (error);
1119
1120	if (p1->p_cred->p_ruid == p2->p_cred->p_ruid)
1121		return (0);
1122	if (p1->p_ucred->cr_uid == p2->p_cred->p_ruid)
1123		return (0);
1124#if 0
1125	/*
1126	 * XXX should a process be able to affect another process
1127	 * acting as the same uid (i.e., sendmail delivery, lpd,
1128	 * et al?)
1129	 */
1130	if (p1->p_cred->p_ruid == p2->p_ucred->cr_uid)
1131		return (0);
1132	if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid)
1133		return (0);
1134#endif /* 0 */
1135
1136	if (!suser_xxx(0, p1, PRISON_ROOT)) {
1137		if (privused != NULL)
1138			*privused = 1;
1139		return (0);
1140	}
1141
1142#ifdef CAPABILITIES
1143	if (!cap_check_xxx(0, p1, CAP_SYS_NICE, PRISON_ROOT)) {
1144		if (privused != NULL)
1145			*privused = 1;
1146		return (0);
1147	}
1148#endif
1149
1150	return (EPERM);
1151}
1152
1153static int
1154p_candebug(struct proc *p1, struct proc *p2, int *privused)
1155{
1156	int error;
1157
1158	if (privused != NULL)
1159		*privused = 0;
1160
1161	/* XXX it is authorized, but semantics don't permit it */
1162	if (p1 == p2)
1163		return (0);
1164
1165	if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
1166		return (error);
1167
1168	/* not owned by you, has done setuid (unless you're root) */
1169	/* add a CAP_SYS_PTRACE here? */
1170	if (p1->p_cred->pc_ucred->cr_uid != p2->p_cred->p_ruid ||
1171	    p1->p_cred->p_ruid != p2->p_cred->p_ruid ||
1172	    p1->p_cred->p_svuid != p2->p_cred->p_ruid ||
1173	    p2->p_flag & P_SUGID) {
1174		if ((error = suser_xxx(0, p1, PRISON_ROOT)))
1175			return (error);
1176		if (privused != NULL)
1177			*privused = 1;
1178	}
1179
1180	/* can't trace init when securelevel > 0 */
1181	if (securelevel > 0 && p2->p_pid == 1)
1182		return (EPERM);
1183
1184	return (0);
1185}
1186
1187int
1188p_can(struct proc *p1, struct proc *p2, int operation,
1189    int *privused)
1190{
1191
1192	switch(operation) {
1193	case P_CAN_SEE:
1194		return (p_cansee(p1, p2, privused));
1195
1196	case P_CAN_SCHED:
1197		return (p_cansched(p1, p2, privused));
1198
1199	case P_CAN_DEBUG:
1200		return (p_candebug(p1, p2, privused));
1201
1202	default:
1203		panic("p_can: invalid operation");
1204	}
1205}
1206
1207
1208/*
1209 * Allocate a zeroed cred structure.
1210 */
1211struct ucred *
1212crget()
1213{
1214	register struct ucred *cr;
1215
1216	MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK|M_ZERO);
1217	cr->cr_ref = 1;
1218	mtx_init(&cr->cr_mtx, "ucred", MTX_DEF);
1219	return (cr);
1220}
1221
1222/*
1223 * Claim another reference to a ucred structure
1224 */
1225void
1226crhold(cr)
1227	struct ucred *cr;
1228{
1229
1230	mtx_lock(&cr->cr_mtx);
1231	cr->cr_ref++;
1232	mtx_unlock(&(cr)->cr_mtx);
1233}
1234
1235
1236/*
1237 * Free a cred structure.
1238 * Throws away space when ref count gets to 0.
1239 */
1240void
1241crfree(cr)
1242	struct ucred *cr;
1243{
1244
1245	mtx_lock(&cr->cr_mtx);
1246	KASSERT(cr->cr_ref > 0, ("bad ucred refcount: %d", cr->cr_ref));
1247	if (--cr->cr_ref == 0) {
1248		mtx_destroy(&cr->cr_mtx);
1249		/*
1250		 * Some callers of crget(), such as nfs_statfs(),
1251		 * allocate a temporary credential, but don't
1252		 * allocate a uidinfo structure.
1253		 */
1254		if (cr->cr_uidinfo != NULL)
1255			uifree(cr->cr_uidinfo);
1256		/*
1257		 * Free a prison, if any.
1258		 */
1259		if (jailed(cr))
1260			prison_free(cr->cr_prison);
1261		FREE((caddr_t)cr, M_CRED);
1262	} else {
1263		mtx_unlock(&cr->cr_mtx);
1264	}
1265}
1266
1267/*
1268 * Copy cred structure to a new one and free the old one.
1269 */
1270struct ucred *
1271crcopy(cr)
1272	struct ucred *cr;
1273{
1274	struct ucred *newcr;
1275
1276	mtx_lock(&cr->cr_mtx);
1277	if (cr->cr_ref == 1) {
1278		mtx_unlock(&cr->cr_mtx);
1279		return (cr);
1280	}
1281	mtx_unlock(&cr->cr_mtx);
1282	newcr = crdup(cr);
1283	crfree(cr);
1284	return (newcr);
1285}
1286
1287/*
1288 * Dup cred struct to a new held one.
1289 */
1290struct ucred *
1291crdup(cr)
1292	struct ucred *cr;
1293{
1294	struct ucred *newcr;
1295
1296	MALLOC(newcr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
1297	*newcr = *cr;
1298	mtx_init(&newcr->cr_mtx, "ucred", MTX_DEF);
1299	uihold(newcr->cr_uidinfo);
1300	if (jailed(newcr))
1301		prison_hold(newcr->cr_prison);
1302	newcr->cr_ref = 1;
1303	return (newcr);
1304}
1305
1306/*
1307 * Get login name, if available.
1308 */
1309#ifndef _SYS_SYSPROTO_H_
1310struct getlogin_args {
1311	char	*namebuf;
1312	u_int	namelen;
1313};
1314#endif
1315/* ARGSUSED */
1316int
1317getlogin(p, uap)
1318	struct proc *p;
1319	struct getlogin_args *uap;
1320{
1321
1322	if (uap->namelen > MAXLOGNAME)
1323		uap->namelen = MAXLOGNAME;
1324	return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
1325	    (caddr_t) uap->namebuf, uap->namelen));
1326}
1327
1328/*
1329 * Set login name.
1330 */
1331#ifndef _SYS_SYSPROTO_H_
1332struct setlogin_args {
1333	char	*namebuf;
1334};
1335#endif
1336/* ARGSUSED */
1337int
1338setlogin(p, uap)
1339	struct proc *p;
1340	struct setlogin_args *uap;
1341{
1342	int error;
1343	char logintmp[MAXLOGNAME];
1344
1345	if ((error = suser_xxx(0, p, PRISON_ROOT)))
1346		return (error);
1347	error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp,
1348	    sizeof(logintmp), (size_t *)0);
1349	if (error == ENAMETOOLONG)
1350		error = EINVAL;
1351	else if (!error)
1352		(void) memcpy(p->p_pgrp->pg_session->s_login, logintmp,
1353		    sizeof(logintmp));
1354	return (error);
1355}
1356
1357void
1358setsugid(p)
1359	struct proc *p;
1360{
1361	p->p_flag |= P_SUGID;
1362	if (!(p->p_pfsflags & PF_ISUGID))
1363		p->p_stops = 0;
1364}
1365
1366/*
1367 * Helper function to change the effective uid of a process
1368 */
1369void
1370change_euid(p, euid)
1371	struct	proc *p;
1372	uid_t	euid;
1373{
1374	struct	pcred *pc;
1375	struct	uidinfo *uip;
1376
1377	pc = p->p_cred;
1378	/*
1379	 * crcopy is essentially a NOP if ucred has a reference count
1380	 * of 1, which is true if it has already been copied.
1381	 */
1382	pc->pc_ucred = crcopy(pc->pc_ucred);
1383	uip = pc->pc_ucred->cr_uidinfo;
1384	pc->pc_ucred->cr_uid = euid;
1385	pc->pc_ucred->cr_uidinfo = uifind(euid);
1386	uifree(uip);
1387}
1388
1389/*
1390 * Helper function to change the real uid of a process
1391 *
1392 * The per-uid process count for this process is transfered from
1393 * the old uid to the new uid.
1394 */
1395void
1396change_ruid(p, ruid)
1397	struct	proc *p;
1398	uid_t	ruid;
1399{
1400	struct	pcred *pc;
1401	struct	uidinfo *uip;
1402
1403	pc = p->p_cred;
1404	(void)chgproccnt(pc->p_uidinfo, -1, 0);
1405	uip = pc->p_uidinfo;
1406	/* It is assumed that pcred is not shared between processes */
1407	pc->p_ruid = ruid;
1408	pc->p_uidinfo = uifind(ruid);
1409	(void)chgproccnt(pc->p_uidinfo, 1, 0);
1410	uifree(uip);
1411}
1412