xref: /csrg-svn/sys/kern/kern_prot.c (revision 35810)
123372Smckusick /*
229092Smckusick  * Copyright (c) 1982, 1986 Regents of the University of California.
323372Smckusick  * All rights reserved.  The Berkeley software License Agreement
423372Smckusick  * specifies the terms and conditions for redistribution.
523372Smckusick  *
6*35810Smarc  *	@(#)kern_prot.c	7.2 (Berkeley) 10/18/88
723372Smckusick  */
87420Sroot 
97420Sroot /*
107498Sroot  * System calls related to processes and protection
117420Sroot  */
127420Sroot 
139754Ssam #include "../machine/reg.h"
149754Ssam 
1517092Sbloom #include "param.h"
1617092Sbloom #include "systm.h"
1717092Sbloom #include "dir.h"
1817092Sbloom #include "user.h"
1917092Sbloom #include "inode.h"
2017092Sbloom #include "proc.h"
2117092Sbloom #include "timeb.h"
2217092Sbloom #include "times.h"
2317092Sbloom #include "reboot.h"
2417092Sbloom #include "fs.h"
2517092Sbloom #include "buf.h"
2617092Sbloom #include "mount.h"
2717092Sbloom #include "quota.h"
287420Sroot 
297498Sroot getpid()
307498Sroot {
317498Sroot 
327498Sroot 	u.u_r.r_val1 = u.u_procp->p_pid;
337498Sroot 	u.u_r.r_val2 = u.u_procp->p_ppid;
347498Sroot }
357498Sroot 
367498Sroot getpgrp()
377498Sroot {
387498Sroot 	register struct a {
397498Sroot 		int	pid;
407498Sroot 	} *uap = (struct a *)u.u_ap;
417498Sroot 	register struct proc *p;
427498Sroot 
437498Sroot 	if (uap->pid == 0)
44*35810Smarc 		p = u.u_procp;
45*35810Smarc 	else if ((p = pfind(uap->pid)) == 0) {
467498Sroot 		u.u_error = ESRCH;
477498Sroot 		return;
487498Sroot 	}
49*35810Smarc 	u.u_r.r_val1 = p->p_pgrp->pg_id;
507498Sroot }
517498Sroot 
527420Sroot getuid()
537420Sroot {
547420Sroot 
557420Sroot 	u.u_r.r_val1 = u.u_ruid;
567420Sroot 	u.u_r.r_val2 = u.u_uid;
577420Sroot }
587420Sroot 
597498Sroot getgid()
607498Sroot {
617498Sroot 
627498Sroot 	u.u_r.r_val1 = u.u_rgid;
637498Sroot 	u.u_r.r_val2 = u.u_gid;
647498Sroot }
657498Sroot 
667866Sroot getgroups()
677498Sroot {
687498Sroot 	register struct	a {
698624Sroot 		u_int	gidsetsize;
707498Sroot 		int	*gidset;
717498Sroot 	} *uap = (struct a *)u.u_ap;
7218362Skarels 	register gid_t *gp;
7318362Skarels 	register int *lp;
7418362Skarels 	int groups[NGROUPS];
757498Sroot 
767866Sroot 	for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
7718362Skarels 		if (gp[-1] != NOGROUP)
787866Sroot 			break;
797866Sroot 	if (uap->gidsetsize < gp - u.u_groups) {
807866Sroot 		u.u_error = EINVAL;
817866Sroot 		return;
827866Sroot 	}
837866Sroot 	uap->gidsetsize = gp - u.u_groups;
8418362Skarels 	for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
8518362Skarels 		*lp++ = *gp++;
8618362Skarels 	u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
8718362Skarels 	    uap->gidsetsize * sizeof (groups[0]));
889997Ssam 	if (u.u_error)
897498Sroot 		return;
907866Sroot 	u.u_r.r_val1 = uap->gidsetsize;
917498Sroot }
927498Sroot 
93*35810Smarc setsid()
94*35810Smarc {
95*35810Smarc 	register struct proc *p = u.u_procp;
96*35810Smarc 
97*35810Smarc 	if ((p->p_pgid == p->p_pid) || pgfind(p->p_pid))
98*35810Smarc 		u.u_error = EPERM;
99*35810Smarc 	else {
100*35810Smarc 		pgmv(p, p->p_pid, 1);
101*35810Smarc 		u.u_r.r_val1 = p->p_pid;
102*35810Smarc 	}
103*35810Smarc 	return;
104*35810Smarc }
105*35810Smarc 
106*35810Smarc /*
107*35810Smarc  * set process group
108*35810Smarc  *
109*35810Smarc  * if target pid != caller's pid
110*35810Smarc  *	pid must be an inferior
111*35810Smarc  *	pid must be in same session
112*35810Smarc  *	pid can't have done an exec
113*35810Smarc  *	there must exist a pid with pgid in same session
114*35810Smarc  * pid must not be session leader
115*35810Smarc  */
1167498Sroot setpgrp()
1177498Sroot {
1187498Sroot 	register struct a {
1197498Sroot 		int	pid;
120*35810Smarc 		int	pgid;
1217498Sroot 	} *uap = (struct a *)u.u_ap;
122*35810Smarc 	register struct proc *p;
123*35810Smarc 	register struct pgrp *pgrp;
1247498Sroot 
1257498Sroot 	if (uap->pid == 0)
126*35810Smarc 		p = u.u_procp;
127*35810Smarc 	else if ((p = pfind(uap->pid)) == 0 || !inferior(p)) {
1287498Sroot 		u.u_error = ESRCH;
1297498Sroot 		return;
1307498Sroot 	}
131*35810Smarc 	else if (p != u.u_procp) {
132*35810Smarc 		if (p->p_session != u.u_procp->p_session) {
133*35810Smarc 			u.u_error = EPERM;
134*35810Smarc 			return;
135*35810Smarc 		}
136*35810Smarc 		if (p->p_flag&SEXEC) {
137*35810Smarc 			u.u_error = EACCES;
138*35810Smarc 			return;
139*35810Smarc 		}
140*35810Smarc 	}
141*35810Smarc 	if (SESS_LEADER(p)) {
1427498Sroot 		u.u_error = EPERM;
1437498Sroot 		return;
1447498Sroot 	}
145*35810Smarc 	if (uap->pgid == 0)
146*35810Smarc 		uap->pgid = p->p_pid;
147*35810Smarc 	else if ((uap->pgid != p->p_pid) &&
148*35810Smarc 		(((pgrp = pgfind(uap->pgid)) == 0) ||
149*35810Smarc 		   pgrp->pg_mem == NULL ||
150*35810Smarc 	           pgrp->pg_session != u.u_procp->p_session)) {
151*35810Smarc 		u.u_error = EPERM;
152*35810Smarc 		return;
153*35810Smarc 	}
154*35810Smarc 	/*
155*35810Smarc 	 * done checking, now doit
156*35810Smarc 	 */
157*35810Smarc 	pgmv(p, uap->pgid, 0);
1587498Sroot }
1597498Sroot 
1609160Ssam setreuid()
1617420Sroot {
1629160Ssam 	struct a {
1639160Ssam 		int	ruid;
1649160Ssam 		int	euid;
1659160Ssam 	} *uap;
1669160Ssam 	register int ruid, euid;
1679160Ssam 
1689160Ssam 	uap = (struct a *)u.u_ap;
1699160Ssam 	ruid = uap->ruid;
1709160Ssam 	if (ruid == -1)
1719160Ssam 		ruid = u.u_ruid;
1729160Ssam 	if (u.u_ruid != ruid && u.u_uid != ruid && !suser())
1739160Ssam 		return;
1749160Ssam 	euid = uap->euid;
1759160Ssam 	if (euid == -1)
1769160Ssam 		euid = u.u_uid;
1779160Ssam 	if (u.u_ruid != euid && u.u_uid != euid && !suser())
1789160Ssam 		return;
1799160Ssam 	/*
1809160Ssam 	 * Everything's okay, do it.
1819160Ssam 	 */
1829160Ssam #ifdef QUOTA
1839320Ssam 	if (u.u_quota->q_uid != ruid) {
1849320Ssam 		qclean();
18526354Skarels 		qstart(getquota((uid_t)ruid, 0, 0));
1869320Ssam 	}
1879160Ssam #endif
18825627Skarels 	u.u_procp->p_uid = euid;
1899320Ssam 	u.u_ruid = ruid;
1909160Ssam 	u.u_uid = euid;
1919160Ssam }
1929160Ssam 
1939160Ssam setregid()
1947420Sroot {
1959160Ssam 	register struct a {
1969160Ssam 		int	rgid;
1979160Ssam 		int	egid;
1989160Ssam 	} *uap;
1999160Ssam 	register int rgid, egid;
2009160Ssam 
2019160Ssam 	uap = (struct a *)u.u_ap;
2029160Ssam 	rgid = uap->rgid;
2039160Ssam 	if (rgid == -1)
2049160Ssam 		rgid = u.u_rgid;
2059160Ssam 	if (u.u_rgid != rgid && u.u_gid != rgid && !suser())
2069160Ssam 		return;
2079160Ssam 	egid = uap->egid;
2089160Ssam 	if (egid == -1)
2099160Ssam 		egid = u.u_gid;
2109160Ssam 	if (u.u_rgid != egid && u.u_gid != egid && !suser())
2119160Ssam 		return;
2129160Ssam 	if (u.u_rgid != rgid) {
2139160Ssam 		leavegroup(u.u_rgid);
21426275Skarels 		(void) entergroup((gid_t)rgid);
2159160Ssam 		u.u_rgid = rgid;
2169160Ssam 	}
21711164Ssam 	u.u_gid = egid;
2189160Ssam }
2199160Ssam 
2207866Sroot setgroups()
2217498Sroot {
2227498Sroot 	register struct	a {
2238624Sroot 		u_int	gidsetsize;
2247498Sroot 		int	*gidset;
2257498Sroot 	} *uap = (struct a *)u.u_ap;
22618362Skarels 	register gid_t *gp;
22718362Skarels 	register int *lp;
22818362Skarels 	int groups[NGROUPS];
2297498Sroot 
2308100Sroot 	if (!suser())
2317498Sroot 		return;
2327866Sroot 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
2337866Sroot 		u.u_error = EINVAL;
2347498Sroot 		return;
2357498Sroot 	}
23618362Skarels 	u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
23718362Skarels 	    uap->gidsetsize * sizeof (groups[0]));
2389997Ssam 	if (u.u_error)
2397498Sroot 		return;
24018362Skarels 	for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
24118362Skarels 		*gp++ = *lp++;
24218362Skarels 	for ( ; gp < &u.u_groups[NGROUPS]; gp++)
24311810Ssam 		*gp = NOGROUP;
2447498Sroot }
2457498Sroot 
2467498Sroot /*
24711810Ssam  * Group utility functions.
24811810Ssam  */
24911810Ssam 
25011810Ssam /*
25111810Ssam  * Delete gid from the group set.
25211810Ssam  */
2537866Sroot leavegroup(gid)
25426275Skarels 	gid_t gid;
2557866Sroot {
25618362Skarels 	register gid_t *gp;
2577866Sroot 
2587866Sroot 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
2597866Sroot 		if (*gp == gid)
2607866Sroot 			goto found;
2617866Sroot 	return;
2627866Sroot found:
2637866Sroot 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
2647866Sroot 		*gp = *(gp+1);
26511810Ssam 	*gp = NOGROUP;
2667866Sroot }
2677866Sroot 
26811810Ssam /*
26911810Ssam  * Add gid to the group set.
27011810Ssam  */
2717866Sroot entergroup(gid)
27226275Skarels 	gid_t gid;
2737866Sroot {
27418362Skarels 	register gid_t *gp;
2757866Sroot 
27618362Skarels 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) {
2777866Sroot 		if (*gp == gid)
2787866Sroot 			return (0);
27918362Skarels 		if (*gp == NOGROUP) {
2807866Sroot 			*gp = gid;
2817866Sroot 			return (0);
2827866Sroot 		}
28318362Skarels 	}
2847866Sroot 	return (-1);
2857866Sroot }
28611810Ssam 
28711810Ssam /*
28811810Ssam  * Check if gid is a member of the group set.
28911810Ssam  */
29011810Ssam groupmember(gid)
29118362Skarels 	gid_t gid;
29211810Ssam {
29318362Skarels 	register gid_t *gp;
29411810Ssam 
29511810Ssam 	if (u.u_gid == gid)
29611810Ssam 		return (1);
29711810Ssam 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
29811810Ssam 		if (*gp == gid)
29911810Ssam 			return (1);
30011810Ssam 	return (0);
30111810Ssam }
302