xref: /csrg-svn/sys/kern/kern_prot.c (revision 9754)
1*9754Ssam /*	kern_prot.c	5.13	82/12/17	*/
27420Sroot 
37420Sroot /*
47498Sroot  * System calls related to processes and protection
57420Sroot  */
67420Sroot 
7*9754Ssam #include "../machine/reg.h"
8*9754Ssam 
97420Sroot #include "../h/param.h"
107420Sroot #include "../h/systm.h"
117420Sroot #include "../h/dir.h"
127420Sroot #include "../h/user.h"
137420Sroot #include "../h/inode.h"
147420Sroot #include "../h/proc.h"
157420Sroot #include "../h/timeb.h"
167420Sroot #include "../h/times.h"
177420Sroot #include "../h/reboot.h"
187420Sroot #include "../h/fs.h"
197420Sroot #include "../h/conf.h"
207420Sroot #include "../h/buf.h"
217420Sroot #include "../h/mount.h"
227489Skre #include "../h/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;
687866Sroot 	register int *gp;
697498Sroot 
707866Sroot 	for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
717866Sroot 		if (gp[-1] >= 0)
727866Sroot 			break;
737866Sroot 	if (uap->gidsetsize < gp - u.u_groups) {
747866Sroot 		u.u_error = EINVAL;
757866Sroot 		return;
767866Sroot 	}
777866Sroot 	uap->gidsetsize = gp - u.u_groups;
787866Sroot 	if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset,
797866Sroot 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
807498Sroot 		u.u_error = EFAULT;
817498Sroot 		return;
827498Sroot 	}
837866Sroot 	u.u_r.r_val1 = uap->gidsetsize;
847498Sroot }
857498Sroot 
867498Sroot setpgrp()
877498Sroot {
887498Sroot 	register struct proc *p;
897498Sroot 	register struct a {
907498Sroot 		int	pid;
917498Sroot 		int	pgrp;
927498Sroot 	} *uap = (struct a *)u.u_ap;
937498Sroot 
947498Sroot 	if (uap->pid == 0)
957498Sroot 		uap->pid = u.u_procp->p_pid;
967498Sroot 	p = pfind(uap->pid);
977498Sroot 	if (p == 0) {
987498Sroot 		u.u_error = ESRCH;
997498Sroot 		return;
1007498Sroot 	}
1017866Sroot /* need better control mechanisms for process groups */
1027498Sroot 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
1037498Sroot 		u.u_error = EPERM;
1047498Sroot 		return;
1057498Sroot 	}
1067498Sroot 	p->p_pgrp = uap->pgrp;
1077498Sroot }
1087498Sroot 
1099160Ssam setreuid()
1107420Sroot {
1119160Ssam 	struct a {
1129160Ssam 		int	ruid;
1139160Ssam 		int	euid;
1149160Ssam 	} *uap;
1159160Ssam 	register int ruid, euid;
1169160Ssam 
1179160Ssam 	uap = (struct a *)u.u_ap;
1189160Ssam 	ruid = uap->ruid;
1199160Ssam 	if (ruid == -1)
1209160Ssam 		ruid = u.u_ruid;
1219160Ssam 	if (u.u_ruid != ruid && u.u_uid != ruid && !suser())
1229160Ssam 		return;
1239160Ssam 	euid = uap->euid;
1249160Ssam 	if (euid == -1)
1259160Ssam 		euid = u.u_uid;
1269160Ssam 	if (u.u_ruid != euid && u.u_uid != euid && !suser())
1279160Ssam 		return;
1289160Ssam 	/*
1299160Ssam 	 * Everything's okay, do it.
1309160Ssam 	 */
1319160Ssam #ifdef QUOTA
1329320Ssam 	if (u.u_quota->q_uid != ruid) {
1339320Ssam 		qclean();
1349320Ssam 		qstart(getquota(ruid, 0, 0));
1359320Ssam 	}
1369160Ssam #endif
1379320Ssam 	u.u_procp->p_uid = ruid;
1389320Ssam 	u.u_ruid = ruid;
1399160Ssam 	u.u_uid = euid;
1409160Ssam }
1419160Ssam 
1429160Ssam #ifndef NOCOMPAT
1439160Ssam osetuid()
1449160Ssam {
1457420Sroot 	register uid;
1467420Sroot 	register struct a {
1477420Sroot 		int	uid;
1487420Sroot 	} *uap;
1497420Sroot 
1507420Sroot 	uap = (struct a *)u.u_ap;
1517420Sroot 	uid = uap->uid;
1527420Sroot 	if (u.u_ruid == uid || u.u_uid == uid || suser()) {
1537489Skre #ifdef QUOTA
1547489Skre 		if (u.u_quota->q_uid != uid) {
1557489Skre 			qclean();
1567489Skre 			qstart(getquota(uid, 0, 0));
1577489Skre 		}
1587489Skre #endif
1597420Sroot 		u.u_uid = uid;
1607420Sroot 		u.u_procp->p_uid = uid;
1617420Sroot 		u.u_ruid = uid;
1627420Sroot 	}
1637420Sroot }
1649160Ssam #endif
1657420Sroot 
1669160Ssam setregid()
1677420Sroot {
1689160Ssam 	register struct a {
1699160Ssam 		int	rgid;
1709160Ssam 		int	egid;
1719160Ssam 	} *uap;
1729160Ssam 	register int rgid, egid;
1739160Ssam 
1749160Ssam 	uap = (struct a *)u.u_ap;
1759160Ssam 	rgid = uap->rgid;
1769160Ssam 	if (rgid == -1)
1779160Ssam 		rgid = u.u_rgid;
1789160Ssam 	if (u.u_rgid != rgid && u.u_gid != rgid && !suser())
1799160Ssam 		return;
1809160Ssam 	egid = uap->egid;
1819160Ssam 	if (egid == -1)
1829160Ssam 		egid = u.u_gid;
1839160Ssam 	if (u.u_rgid != egid && u.u_gid != egid && !suser())
1849160Ssam 		return;
1859160Ssam 	if (u.u_rgid != rgid) {
1869160Ssam 		leavegroup(u.u_rgid);
1879160Ssam 		(void) entergroup(u.u_rgid);
1889160Ssam 		u.u_rgid = rgid;
1899160Ssam 	}
1909160Ssam 	if (u.u_gid != egid) {
1919160Ssam 		leavegroup(u.u_gid);
1929160Ssam 		(void) entergroup(egid);
1939160Ssam 		u.u_gid = egid;
1949160Ssam 	}
1959160Ssam }
1969160Ssam 
1979160Ssam #ifndef NOCOMPAT
1989160Ssam osetgid()
1999160Ssam {
2007420Sroot 	register gid;
2017420Sroot 	register struct a {
2027420Sroot 		int	gid;
2037420Sroot 	} *uap;
2047420Sroot 
2057420Sroot 	uap = (struct a *)u.u_ap;
2067420Sroot 	gid = uap->gid;
2077420Sroot 	if (u.u_rgid == gid || u.u_gid == gid || suser()) {
2087866Sroot 		leavegroup(u.u_gid); leavegroup(u.u_rgid);
2097866Sroot 		(void) entergroup(gid);
2107420Sroot 		u.u_gid = gid;
2117420Sroot 		u.u_rgid = gid;
2127420Sroot 	}
2137420Sroot }
2147498Sroot 
2157866Sroot setgroups()
2167498Sroot {
2177498Sroot 	register struct	a {
2188624Sroot 		u_int	gidsetsize;
2197498Sroot 		int	*gidset;
2207498Sroot 	} *uap = (struct a *)u.u_ap;
2217866Sroot 	register int *gp;
2227498Sroot 
2238100Sroot 	if (!suser())
2247498Sroot 		return;
2257866Sroot 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
2267866Sroot 		u.u_error = EINVAL;
2277498Sroot 		return;
2287498Sroot 	}
2297866Sroot 	if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
2307866Sroot 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
2317498Sroot 		u.u_error = EFAULT;
2327498Sroot 		return;
2337498Sroot 	}
2347866Sroot 	for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
2357866Sroot 		*gp = -1;
2367498Sroot }
2377498Sroot 
2387498Sroot /*
2397498Sroot  * Pid of zero implies current process.
2407498Sroot  * Pgrp -1 is getpgrp system call returning
2417498Sroot  * current process group.
2427498Sroot  */
2437498Sroot osetpgrp()
2447498Sroot {
2457498Sroot 	register struct proc *p;
2467498Sroot 	register struct a {
2477498Sroot 		int	pid;
2487498Sroot 		int	pgrp;
2497498Sroot 	} *uap;
2507498Sroot 
2517498Sroot 	uap = (struct a *)u.u_ap;
2527498Sroot 	if (uap->pid == 0)
2537498Sroot 		p = u.u_procp;
2547498Sroot 	else {
2557498Sroot 		p = pfind(uap->pid);
2567498Sroot 		if (p == 0) {
2577498Sroot 			u.u_error = ESRCH;
2587498Sroot 			return;
2597498Sroot 		}
2607498Sroot 	}
2617498Sroot 	if (uap->pgrp <= 0) {
2627498Sroot 		u.u_r.r_val1 = p->p_pgrp;
2637498Sroot 		return;
2647498Sroot 	}
2657498Sroot 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
2667498Sroot 		u.u_error = EPERM;
2677498Sroot 		return;
2687498Sroot 	}
2697498Sroot 	p->p_pgrp = uap->pgrp;
2707498Sroot }
2717498Sroot /* END DEFUNCT */
2727866Sroot 
2737866Sroot leavegroup(gid)
2747866Sroot 	int gid;
2757866Sroot {
2767866Sroot 	register int *gp;
2777866Sroot 
2787866Sroot 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
2797866Sroot 		if (*gp == gid)
2807866Sroot 			goto found;
2817866Sroot 	return;
2827866Sroot found:
2837866Sroot 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
2847866Sroot 		*gp = *(gp+1);
2857879Sroot 	*gp = -1;
2867866Sroot }
2877866Sroot 
2887866Sroot entergroup(gid)
2897866Sroot 	int gid;
2907866Sroot {
2917866Sroot 	register int *gp;
2927866Sroot 
2937866Sroot 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
2947866Sroot 		if (*gp == gid)
2957866Sroot 			return (0);
2967866Sroot 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
2977866Sroot 		if (*gp < 0) {
2987866Sroot 			*gp = gid;
2997866Sroot 			return (0);
3007866Sroot 		}
3017866Sroot 	return (-1);
3027866Sroot }
303