xref: /csrg-svn/sys/kern/kern_prot.c (revision 25627)
123372Smckusick /*
223372Smckusick  * Copyright (c) 1982 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*25627Skarels  *	@(#)kern_prot.c	6.6 (Berkeley) 12/19/85
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)
447498Sroot 		uap->pid = u.u_procp->p_pid;
457498Sroot 	p = pfind(uap->pid);
467498Sroot 	if (p == 0) {
477498Sroot 		u.u_error = ESRCH;
487498Sroot 		return;
497498Sroot 	}
507498Sroot 	u.u_r.r_val1 = p->p_pgrp;
517498Sroot }
527498Sroot 
537420Sroot getuid()
547420Sroot {
557420Sroot 
567420Sroot 	u.u_r.r_val1 = u.u_ruid;
577420Sroot 	u.u_r.r_val2 = u.u_uid;
587420Sroot }
597420Sroot 
607498Sroot getgid()
617498Sroot {
627498Sroot 
637498Sroot 	u.u_r.r_val1 = u.u_rgid;
647498Sroot 	u.u_r.r_val2 = u.u_gid;
657498Sroot }
667498Sroot 
677866Sroot getgroups()
687498Sroot {
697498Sroot 	register struct	a {
708624Sroot 		u_int	gidsetsize;
717498Sroot 		int	*gidset;
727498Sroot 	} *uap = (struct a *)u.u_ap;
7318362Skarels 	register gid_t *gp;
7418362Skarels 	register int *lp;
7518362Skarels 	int groups[NGROUPS];
767498Sroot 
777866Sroot 	for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
7818362Skarels 		if (gp[-1] != NOGROUP)
797866Sroot 			break;
807866Sroot 	if (uap->gidsetsize < gp - u.u_groups) {
817866Sroot 		u.u_error = EINVAL;
827866Sroot 		return;
837866Sroot 	}
847866Sroot 	uap->gidsetsize = gp - u.u_groups;
8518362Skarels 	for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
8618362Skarels 		*lp++ = *gp++;
8718362Skarels 	u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
8818362Skarels 	    uap->gidsetsize * sizeof (groups[0]));
899997Ssam 	if (u.u_error)
907498Sroot 		return;
917866Sroot 	u.u_r.r_val1 = uap->gidsetsize;
927498Sroot }
937498Sroot 
947498Sroot setpgrp()
957498Sroot {
967498Sroot 	register struct proc *p;
977498Sroot 	register struct a {
987498Sroot 		int	pid;
997498Sroot 		int	pgrp;
1007498Sroot 	} *uap = (struct a *)u.u_ap;
1017498Sroot 
1027498Sroot 	if (uap->pid == 0)
1037498Sroot 		uap->pid = u.u_procp->p_pid;
1047498Sroot 	p = pfind(uap->pid);
1057498Sroot 	if (p == 0) {
1067498Sroot 		u.u_error = ESRCH;
1077498Sroot 		return;
1087498Sroot 	}
1097866Sroot /* need better control mechanisms for process groups */
1107498Sroot 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
1117498Sroot 		u.u_error = EPERM;
1127498Sroot 		return;
1137498Sroot 	}
1147498Sroot 	p->p_pgrp = uap->pgrp;
1157498Sroot }
1167498Sroot 
1179160Ssam setreuid()
1187420Sroot {
1199160Ssam 	struct a {
1209160Ssam 		int	ruid;
1219160Ssam 		int	euid;
1229160Ssam 	} *uap;
1239160Ssam 	register int ruid, euid;
1249160Ssam 
1259160Ssam 	uap = (struct a *)u.u_ap;
1269160Ssam 	ruid = uap->ruid;
1279160Ssam 	if (ruid == -1)
1289160Ssam 		ruid = u.u_ruid;
1299160Ssam 	if (u.u_ruid != ruid && u.u_uid != ruid && !suser())
1309160Ssam 		return;
1319160Ssam 	euid = uap->euid;
1329160Ssam 	if (euid == -1)
1339160Ssam 		euid = u.u_uid;
1349160Ssam 	if (u.u_ruid != euid && u.u_uid != euid && !suser())
1359160Ssam 		return;
1369160Ssam 	/*
1379160Ssam 	 * Everything's okay, do it.
1389160Ssam 	 */
1399160Ssam #ifdef QUOTA
1409320Ssam 	if (u.u_quota->q_uid != ruid) {
1419320Ssam 		qclean();
1429320Ssam 		qstart(getquota(ruid, 0, 0));
1439320Ssam 	}
1449160Ssam #endif
145*25627Skarels 	u.u_procp->p_uid = euid;
1469320Ssam 	u.u_ruid = ruid;
1479160Ssam 	u.u_uid = euid;
1489160Ssam }
1499160Ssam 
1509160Ssam setregid()
1517420Sroot {
1529160Ssam 	register struct a {
1539160Ssam 		int	rgid;
1549160Ssam 		int	egid;
1559160Ssam 	} *uap;
1569160Ssam 	register int rgid, egid;
1579160Ssam 
1589160Ssam 	uap = (struct a *)u.u_ap;
1599160Ssam 	rgid = uap->rgid;
1609160Ssam 	if (rgid == -1)
1619160Ssam 		rgid = u.u_rgid;
1629160Ssam 	if (u.u_rgid != rgid && u.u_gid != rgid && !suser())
1639160Ssam 		return;
1649160Ssam 	egid = uap->egid;
1659160Ssam 	if (egid == -1)
1669160Ssam 		egid = u.u_gid;
1679160Ssam 	if (u.u_rgid != egid && u.u_gid != egid && !suser())
1689160Ssam 		return;
1699160Ssam 	if (u.u_rgid != rgid) {
1709160Ssam 		leavegroup(u.u_rgid);
17111164Ssam 		(void) entergroup(rgid);
1729160Ssam 		u.u_rgid = rgid;
1739160Ssam 	}
17411164Ssam 	u.u_gid = egid;
1759160Ssam }
1769160Ssam 
1777866Sroot setgroups()
1787498Sroot {
1797498Sroot 	register struct	a {
1808624Sroot 		u_int	gidsetsize;
1817498Sroot 		int	*gidset;
1827498Sroot 	} *uap = (struct a *)u.u_ap;
18318362Skarels 	register gid_t *gp;
18418362Skarels 	register int *lp;
18518362Skarels 	int groups[NGROUPS];
1867498Sroot 
1878100Sroot 	if (!suser())
1887498Sroot 		return;
1897866Sroot 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
1907866Sroot 		u.u_error = EINVAL;
1917498Sroot 		return;
1927498Sroot 	}
19318362Skarels 	u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
19418362Skarels 	    uap->gidsetsize * sizeof (groups[0]));
1959997Ssam 	if (u.u_error)
1967498Sroot 		return;
19718362Skarels 	for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
19818362Skarels 		*gp++ = *lp++;
19918362Skarels 	for ( ; gp < &u.u_groups[NGROUPS]; gp++)
20011810Ssam 		*gp = NOGROUP;
2017498Sroot }
2027498Sroot 
2037498Sroot /*
20411810Ssam  * Group utility functions.
20511810Ssam  */
20611810Ssam 
20711810Ssam /*
20811810Ssam  * Delete gid from the group set.
20911810Ssam  */
2107866Sroot leavegroup(gid)
2117866Sroot 	int gid;
2127866Sroot {
21318362Skarels 	register gid_t *gp;
2147866Sroot 
2157866Sroot 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
2167866Sroot 		if (*gp == gid)
2177866Sroot 			goto found;
2187866Sroot 	return;
2197866Sroot found:
2207866Sroot 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
2217866Sroot 		*gp = *(gp+1);
22211810Ssam 	*gp = NOGROUP;
2237866Sroot }
2247866Sroot 
22511810Ssam /*
22611810Ssam  * Add gid to the group set.
22711810Ssam  */
2287866Sroot entergroup(gid)
2297866Sroot 	int gid;
2307866Sroot {
23118362Skarels 	register gid_t *gp;
2327866Sroot 
23318362Skarels 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) {
2347866Sroot 		if (*gp == gid)
2357866Sroot 			return (0);
23618362Skarels 		if (*gp == NOGROUP) {
2377866Sroot 			*gp = gid;
2387866Sroot 			return (0);
2397866Sroot 		}
24018362Skarels 	}
2417866Sroot 	return (-1);
2427866Sroot }
24311810Ssam 
24411810Ssam /*
24511810Ssam  * Check if gid is a member of the group set.
24611810Ssam  */
24711810Ssam groupmember(gid)
24818362Skarels 	gid_t gid;
24911810Ssam {
25018362Skarels 	register gid_t *gp;
25111810Ssam 
25211810Ssam 	if (u.u_gid == gid)
25311810Ssam 		return (1);
25411810Ssam 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
25511810Ssam 		if (*gp == gid)
25611810Ssam 			return (1);
25711810Ssam 	return (0);
25811810Ssam }
259