xref: /csrg-svn/sys/kern/kern_prot.c (revision 18362)
1*18362Skarels /*	kern_prot.c	6.3	85/03/18	*/
27420Sroot 
37420Sroot /*
47498Sroot  * System calls related to processes and protection
57420Sroot  */
67420Sroot 
79754Ssam #include "../machine/reg.h"
89754Ssam 
917092Sbloom #include "param.h"
1017092Sbloom #include "systm.h"
1117092Sbloom #include "dir.h"
1217092Sbloom #include "user.h"
1317092Sbloom #include "inode.h"
1417092Sbloom #include "proc.h"
1517092Sbloom #include "timeb.h"
1617092Sbloom #include "times.h"
1717092Sbloom #include "reboot.h"
1817092Sbloom #include "fs.h"
1917092Sbloom #include "conf.h"
2017092Sbloom #include "buf.h"
2117092Sbloom #include "mount.h"
2217092Sbloom #include "quota.h"
237420Sroot 
247498Sroot getpid()
257498Sroot {
267498Sroot 
277498Sroot 	u.u_r.r_val1 = u.u_procp->p_pid;
287498Sroot 	u.u_r.r_val2 = u.u_procp->p_ppid;
297498Sroot }
307498Sroot 
317498Sroot getpgrp()
327498Sroot {
337498Sroot 	register struct a {
347498Sroot 		int	pid;
357498Sroot 	} *uap = (struct a *)u.u_ap;
367498Sroot 	register struct proc *p;
377498Sroot 
387498Sroot 	if (uap->pid == 0)
397498Sroot 		uap->pid = u.u_procp->p_pid;
407498Sroot 	p = pfind(uap->pid);
417498Sroot 	if (p == 0) {
427498Sroot 		u.u_error = ESRCH;
437498Sroot 		return;
447498Sroot 	}
457498Sroot 	u.u_r.r_val1 = p->p_pgrp;
467498Sroot }
477498Sroot 
487420Sroot getuid()
497420Sroot {
507420Sroot 
517420Sroot 	u.u_r.r_val1 = u.u_ruid;
527420Sroot 	u.u_r.r_val2 = u.u_uid;
537420Sroot }
547420Sroot 
557498Sroot getgid()
567498Sroot {
577498Sroot 
587498Sroot 	u.u_r.r_val1 = u.u_rgid;
597498Sroot 	u.u_r.r_val2 = u.u_gid;
607498Sroot }
617498Sroot 
627866Sroot getgroups()
637498Sroot {
647498Sroot 	register struct	a {
658624Sroot 		u_int	gidsetsize;
667498Sroot 		int	*gidset;
677498Sroot 	} *uap = (struct a *)u.u_ap;
68*18362Skarels 	register gid_t *gp;
69*18362Skarels 	register int *lp;
70*18362Skarels 	int groups[NGROUPS];
717498Sroot 
727866Sroot 	for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
73*18362Skarels 		if (gp[-1] != NOGROUP)
747866Sroot 			break;
757866Sroot 	if (uap->gidsetsize < gp - u.u_groups) {
767866Sroot 		u.u_error = EINVAL;
777866Sroot 		return;
787866Sroot 	}
797866Sroot 	uap->gidsetsize = gp - u.u_groups;
80*18362Skarels 	for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
81*18362Skarels 		*lp++ = *gp++;
82*18362Skarels 	u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
83*18362Skarels 	    uap->gidsetsize * sizeof (groups[0]));
849997Ssam 	if (u.u_error)
857498Sroot 		return;
867866Sroot 	u.u_r.r_val1 = uap->gidsetsize;
877498Sroot }
887498Sroot 
897498Sroot setpgrp()
907498Sroot {
917498Sroot 	register struct proc *p;
927498Sroot 	register struct a {
937498Sroot 		int	pid;
947498Sroot 		int	pgrp;
957498Sroot 	} *uap = (struct a *)u.u_ap;
967498Sroot 
977498Sroot 	if (uap->pid == 0)
987498Sroot 		uap->pid = u.u_procp->p_pid;
997498Sroot 	p = pfind(uap->pid);
1007498Sroot 	if (p == 0) {
1017498Sroot 		u.u_error = ESRCH;
1027498Sroot 		return;
1037498Sroot 	}
1047866Sroot /* need better control mechanisms for process groups */
1057498Sroot 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
1067498Sroot 		u.u_error = EPERM;
1077498Sroot 		return;
1087498Sroot 	}
1097498Sroot 	p->p_pgrp = uap->pgrp;
1107498Sroot }
1117498Sroot 
1129160Ssam setreuid()
1137420Sroot {
1149160Ssam 	struct a {
1159160Ssam 		int	ruid;
1169160Ssam 		int	euid;
1179160Ssam 	} *uap;
1189160Ssam 	register int ruid, euid;
1199160Ssam 
1209160Ssam 	uap = (struct a *)u.u_ap;
1219160Ssam 	ruid = uap->ruid;
1229160Ssam 	if (ruid == -1)
1239160Ssam 		ruid = u.u_ruid;
1249160Ssam 	if (u.u_ruid != ruid && u.u_uid != ruid && !suser())
1259160Ssam 		return;
1269160Ssam 	euid = uap->euid;
1279160Ssam 	if (euid == -1)
1289160Ssam 		euid = u.u_uid;
1299160Ssam 	if (u.u_ruid != euid && u.u_uid != euid && !suser())
1309160Ssam 		return;
1319160Ssam 	/*
1329160Ssam 	 * Everything's okay, do it.
1339160Ssam 	 */
1349160Ssam #ifdef QUOTA
1359320Ssam 	if (u.u_quota->q_uid != ruid) {
1369320Ssam 		qclean();
1379320Ssam 		qstart(getquota(ruid, 0, 0));
1389320Ssam 	}
1399160Ssam #endif
1409320Ssam 	u.u_procp->p_uid = ruid;
1419320Ssam 	u.u_ruid = ruid;
1429160Ssam 	u.u_uid = euid;
1439160Ssam }
1449160Ssam 
1459160Ssam setregid()
1467420Sroot {
1479160Ssam 	register struct a {
1489160Ssam 		int	rgid;
1499160Ssam 		int	egid;
1509160Ssam 	} *uap;
1519160Ssam 	register int rgid, egid;
1529160Ssam 
1539160Ssam 	uap = (struct a *)u.u_ap;
1549160Ssam 	rgid = uap->rgid;
1559160Ssam 	if (rgid == -1)
1569160Ssam 		rgid = u.u_rgid;
1579160Ssam 	if (u.u_rgid != rgid && u.u_gid != rgid && !suser())
1589160Ssam 		return;
1599160Ssam 	egid = uap->egid;
1609160Ssam 	if (egid == -1)
1619160Ssam 		egid = u.u_gid;
1629160Ssam 	if (u.u_rgid != egid && u.u_gid != egid && !suser())
1639160Ssam 		return;
1649160Ssam 	if (u.u_rgid != rgid) {
1659160Ssam 		leavegroup(u.u_rgid);
16611164Ssam 		(void) entergroup(rgid);
1679160Ssam 		u.u_rgid = rgid;
1689160Ssam 	}
16911164Ssam 	u.u_gid = egid;
1709160Ssam }
1719160Ssam 
1727866Sroot setgroups()
1737498Sroot {
1747498Sroot 	register struct	a {
1758624Sroot 		u_int	gidsetsize;
1767498Sroot 		int	*gidset;
1777498Sroot 	} *uap = (struct a *)u.u_ap;
178*18362Skarels 	register gid_t *gp;
179*18362Skarels 	register int *lp;
180*18362Skarels 	int groups[NGROUPS];
1817498Sroot 
1828100Sroot 	if (!suser())
1837498Sroot 		return;
1847866Sroot 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
1857866Sroot 		u.u_error = EINVAL;
1867498Sroot 		return;
1877498Sroot 	}
188*18362Skarels 	u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
189*18362Skarels 	    uap->gidsetsize * sizeof (groups[0]));
1909997Ssam 	if (u.u_error)
1917498Sroot 		return;
192*18362Skarels 	for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
193*18362Skarels 		*gp++ = *lp++;
194*18362Skarels 	for ( ; gp < &u.u_groups[NGROUPS]; gp++)
19511810Ssam 		*gp = NOGROUP;
1967498Sroot }
1977498Sroot 
1987498Sroot /*
19911810Ssam  * Group utility functions.
20011810Ssam  */
20111810Ssam 
20211810Ssam /*
20311810Ssam  * Delete gid from the group set.
20411810Ssam  */
2057866Sroot leavegroup(gid)
2067866Sroot 	int gid;
2077866Sroot {
208*18362Skarels 	register gid_t *gp;
2097866Sroot 
2107866Sroot 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
2117866Sroot 		if (*gp == gid)
2127866Sroot 			goto found;
2137866Sroot 	return;
2147866Sroot found:
2157866Sroot 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
2167866Sroot 		*gp = *(gp+1);
21711810Ssam 	*gp = NOGROUP;
2187866Sroot }
2197866Sroot 
22011810Ssam /*
22111810Ssam  * Add gid to the group set.
22211810Ssam  */
2237866Sroot entergroup(gid)
2247866Sroot 	int gid;
2257866Sroot {
226*18362Skarels 	register gid_t *gp;
2277866Sroot 
228*18362Skarels 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) {
2297866Sroot 		if (*gp == gid)
2307866Sroot 			return (0);
231*18362Skarels 		if (*gp == NOGROUP) {
2327866Sroot 			*gp = gid;
2337866Sroot 			return (0);
2347866Sroot 		}
235*18362Skarels 	}
2367866Sroot 	return (-1);
2377866Sroot }
23811810Ssam 
23911810Ssam /*
24011810Ssam  * Check if gid is a member of the group set.
24111810Ssam  */
24211810Ssam groupmember(gid)
243*18362Skarels 	gid_t gid;
24411810Ssam {
245*18362Skarels 	register gid_t *gp;
24611810Ssam 
24711810Ssam 	if (u.u_gid == gid)
24811810Ssam 		return (1);
24911810Ssam 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
25011810Ssam 		if (*gp == gid)
25111810Ssam 			return (1);
25211810Ssam 	return (0);
25311810Ssam }
254