xref: /csrg-svn/sys/kern/kern_prot.c (revision 9160)
1*9160Ssam /*	kern_prot.c	5.11	82/11/13	*/
27420Sroot 
37420Sroot /*
47498Sroot  * System calls related to processes and protection
57420Sroot  */
67420Sroot 
77420Sroot #include "../h/param.h"
87420Sroot #include "../h/systm.h"
97420Sroot #include "../h/dir.h"
107420Sroot #include "../h/user.h"
117420Sroot #include "../h/reg.h"
127420Sroot #include "../h/inode.h"
137420Sroot #include "../h/proc.h"
147420Sroot #include "../h/timeb.h"
157420Sroot #include "../h/times.h"
167420Sroot #include "../h/reboot.h"
177420Sroot #include "../h/fs.h"
187420Sroot #include "../h/conf.h"
197420Sroot #include "../h/buf.h"
207420Sroot #include "../h/mount.h"
217489Skre #include "../h/quota.h"
227420Sroot 
237498Sroot getpid()
247498Sroot {
257498Sroot 
267498Sroot 	u.u_r.r_val1 = u.u_procp->p_pid;
277498Sroot 	u.u_r.r_val2 = u.u_procp->p_ppid;
287498Sroot }
297498Sroot 
307498Sroot getpgrp()
317498Sroot {
327498Sroot 	register struct a {
337498Sroot 		int	pid;
347498Sroot 	} *uap = (struct a *)u.u_ap;
357498Sroot 	register struct proc *p;
367498Sroot 
377498Sroot 	if (uap->pid == 0)
387498Sroot 		uap->pid = u.u_procp->p_pid;
397498Sroot 	p = pfind(uap->pid);
407498Sroot 	if (p == 0) {
417498Sroot 		u.u_error = ESRCH;
427498Sroot 		return;
437498Sroot 	}
447498Sroot 	u.u_r.r_val1 = p->p_pgrp;
457498Sroot }
467498Sroot 
477420Sroot getuid()
487420Sroot {
497420Sroot 
507420Sroot 	u.u_r.r_val1 = u.u_ruid;
517420Sroot 	u.u_r.r_val2 = u.u_uid;
527420Sroot }
537420Sroot 
547498Sroot getgid()
557498Sroot {
567498Sroot 
577498Sroot 	u.u_r.r_val1 = u.u_rgid;
587498Sroot 	u.u_r.r_val2 = u.u_gid;
597498Sroot }
607498Sroot 
617866Sroot getgroups()
627498Sroot {
637498Sroot 	register struct	a {
648624Sroot 		u_int	gidsetsize;
657498Sroot 		int	*gidset;
667498Sroot 	} *uap = (struct a *)u.u_ap;
677866Sroot 	register int *gp;
687498Sroot 
697866Sroot 	for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
707866Sroot 		if (gp[-1] >= 0)
717866Sroot 			break;
727866Sroot 	if (uap->gidsetsize < gp - u.u_groups) {
737866Sroot 		u.u_error = EINVAL;
747866Sroot 		return;
757866Sroot 	}
767866Sroot 	uap->gidsetsize = gp - u.u_groups;
777866Sroot 	if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset,
787866Sroot 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
797498Sroot 		u.u_error = EFAULT;
807498Sroot 		return;
817498Sroot 	}
827866Sroot 	u.u_r.r_val1 = uap->gidsetsize;
837498Sroot }
847498Sroot 
857498Sroot setpgrp()
867498Sroot {
877498Sroot 	register struct proc *p;
887498Sroot 	register struct a {
897498Sroot 		int	pid;
907498Sroot 		int	pgrp;
917498Sroot 	} *uap = (struct a *)u.u_ap;
927498Sroot 
937498Sroot 	if (uap->pid == 0)
947498Sroot 		uap->pid = u.u_procp->p_pid;
957498Sroot 	p = pfind(uap->pid);
967498Sroot 	if (p == 0) {
977498Sroot 		u.u_error = ESRCH;
987498Sroot 		return;
997498Sroot 	}
1007866Sroot /* need better control mechanisms for process groups */
1017498Sroot 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
1027498Sroot 		u.u_error = EPERM;
1037498Sroot 		return;
1047498Sroot 	}
1057498Sroot 	p->p_pgrp = uap->pgrp;
1067498Sroot }
1077498Sroot 
108*9160Ssam setreuid()
1097420Sroot {
110*9160Ssam 	struct a {
111*9160Ssam 		int	ruid;
112*9160Ssam 		int	euid;
113*9160Ssam 	} *uap;
114*9160Ssam 	register int ruid, euid;
115*9160Ssam 
116*9160Ssam 	uap = (struct a *)u.u_ap;
117*9160Ssam 	ruid = uap->ruid;
118*9160Ssam 	if (ruid == -1)
119*9160Ssam 		ruid = u.u_ruid;
120*9160Ssam 	if (u.u_ruid != ruid && u.u_uid != ruid && !suser())
121*9160Ssam 		return;
122*9160Ssam 	euid = uap->euid;
123*9160Ssam 	if (euid == -1)
124*9160Ssam 		euid = u.u_uid;
125*9160Ssam 	if (u.u_ruid != euid && u.u_uid != euid && !suser())
126*9160Ssam 		return;
127*9160Ssam 	/*
128*9160Ssam 	 * Everything's okay, do it.
129*9160Ssam 	 */
130*9160Ssam 	if (ruid != u.u_ruid) {
131*9160Ssam #ifdef QUOTA
132*9160Ssam 		if (u.u_quota->q_uid != ruid) {
133*9160Ssam 			qclean();
134*9160Ssam 			qstart(getquota(ruid, 0, 0));
135*9160Ssam 		}
136*9160Ssam #endif
137*9160Ssam 		u.u_procp->p_uid = ruid;
138*9160Ssam 		u.u_ruid = ruid;
139*9160Ssam 	}
140*9160Ssam 	u.u_uid = euid;
141*9160Ssam }
142*9160Ssam 
143*9160Ssam #ifndef NOCOMPAT
144*9160Ssam osetuid()
145*9160Ssam {
1467420Sroot 	register uid;
1477420Sroot 	register struct a {
1487420Sroot 		int	uid;
1497420Sroot 	} *uap;
1507420Sroot 
1517420Sroot 	uap = (struct a *)u.u_ap;
1527420Sroot 	uid = uap->uid;
1537420Sroot 	if (u.u_ruid == uid || u.u_uid == uid || suser()) {
1547489Skre #ifdef QUOTA
1557489Skre 		if (u.u_quota->q_uid != uid) {
1567489Skre 			qclean();
1577489Skre 			qstart(getquota(uid, 0, 0));
1587489Skre 		}
1597489Skre #endif
1607420Sroot 		u.u_uid = uid;
1617420Sroot 		u.u_procp->p_uid = uid;
1627420Sroot 		u.u_ruid = uid;
1637420Sroot 	}
1647420Sroot }
165*9160Ssam #endif
1667420Sroot 
167*9160Ssam setregid()
1687420Sroot {
169*9160Ssam 	register struct a {
170*9160Ssam 		int	rgid;
171*9160Ssam 		int	egid;
172*9160Ssam 	} *uap;
173*9160Ssam 	register int rgid, egid;
174*9160Ssam 
175*9160Ssam 	uap = (struct a *)u.u_ap;
176*9160Ssam 	rgid = uap->rgid;
177*9160Ssam 	if (rgid == -1)
178*9160Ssam 		rgid = u.u_rgid;
179*9160Ssam 	if (u.u_rgid != rgid && u.u_gid != rgid && !suser())
180*9160Ssam 		return;
181*9160Ssam 	egid = uap->egid;
182*9160Ssam 	if (egid == -1)
183*9160Ssam 		egid = u.u_gid;
184*9160Ssam 	if (u.u_rgid != egid && u.u_gid != egid && !suser())
185*9160Ssam 		return;
186*9160Ssam 	if (u.u_rgid != rgid) {
187*9160Ssam 		leavegroup(u.u_rgid);
188*9160Ssam 		(void) entergroup(u.u_rgid);
189*9160Ssam 		u.u_rgid = rgid;
190*9160Ssam 	}
191*9160Ssam 	if (u.u_gid != egid) {
192*9160Ssam 		leavegroup(u.u_gid);
193*9160Ssam 		(void) entergroup(egid);
194*9160Ssam 		u.u_gid = egid;
195*9160Ssam 	}
196*9160Ssam }
197*9160Ssam 
198*9160Ssam #ifndef NOCOMPAT
199*9160Ssam osetgid()
200*9160Ssam {
2017420Sroot 	register gid;
2027420Sroot 	register struct a {
2037420Sroot 		int	gid;
2047420Sroot 	} *uap;
2057420Sroot 
2067420Sroot 	uap = (struct a *)u.u_ap;
2077420Sroot 	gid = uap->gid;
2087420Sroot 	if (u.u_rgid == gid || u.u_gid == gid || suser()) {
2097866Sroot 		leavegroup(u.u_gid); leavegroup(u.u_rgid);
2107866Sroot 		(void) entergroup(gid);
2117420Sroot 		u.u_gid = gid;
2127420Sroot 		u.u_rgid = gid;
2137420Sroot 	}
2147420Sroot }
2157498Sroot 
2167866Sroot setgroups()
2177498Sroot {
2187498Sroot 	register struct	a {
2198624Sroot 		u_int	gidsetsize;
2207498Sroot 		int	*gidset;
2217498Sroot 	} *uap = (struct a *)u.u_ap;
2227866Sroot 	register int *gp;
2237498Sroot 
2248100Sroot 	if (!suser())
2257498Sroot 		return;
2267866Sroot 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
2277866Sroot 		u.u_error = EINVAL;
2287498Sroot 		return;
2297498Sroot 	}
2307866Sroot 	if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
2317866Sroot 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
2327498Sroot 		u.u_error = EFAULT;
2337498Sroot 		return;
2347498Sroot 	}
2357866Sroot 	for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
2367866Sroot 		*gp = -1;
2377498Sroot }
2387498Sroot 
2397498Sroot /*
2407498Sroot  * Pid of zero implies current process.
2417498Sroot  * Pgrp -1 is getpgrp system call returning
2427498Sroot  * current process group.
2437498Sroot  */
2447498Sroot osetpgrp()
2457498Sroot {
2467498Sroot 	register struct proc *p;
2477498Sroot 	register struct a {
2487498Sroot 		int	pid;
2497498Sroot 		int	pgrp;
2507498Sroot 	} *uap;
2517498Sroot 
2527498Sroot 	uap = (struct a *)u.u_ap;
2537498Sroot 	if (uap->pid == 0)
2547498Sroot 		p = u.u_procp;
2557498Sroot 	else {
2567498Sroot 		p = pfind(uap->pid);
2577498Sroot 		if (p == 0) {
2587498Sroot 			u.u_error = ESRCH;
2597498Sroot 			return;
2607498Sroot 		}
2617498Sroot 	}
2627498Sroot 	if (uap->pgrp <= 0) {
2637498Sroot 		u.u_r.r_val1 = p->p_pgrp;
2647498Sroot 		return;
2657498Sroot 	}
2667498Sroot 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
2677498Sroot 		u.u_error = EPERM;
2687498Sroot 		return;
2697498Sroot 	}
2707498Sroot 	p->p_pgrp = uap->pgrp;
2717498Sroot }
2727498Sroot /* END DEFUNCT */
2737866Sroot 
2747866Sroot leavegroup(gid)
2757866Sroot 	int gid;
2767866Sroot {
2777866Sroot 	register int *gp;
2787866Sroot 
2797866Sroot 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
2807866Sroot 		if (*gp == gid)
2817866Sroot 			goto found;
2827866Sroot 	return;
2837866Sroot found:
2847866Sroot 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
2857866Sroot 		*gp = *(gp+1);
2867879Sroot 	*gp = -1;
2877866Sroot }
2887866Sroot 
2897866Sroot entergroup(gid)
2907866Sroot 	int gid;
2917866Sroot {
2927866Sroot 	register int *gp;
2937866Sroot 
2947866Sroot 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
2957866Sroot 		if (*gp == gid)
2967866Sroot 			return (0);
2977866Sroot 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
2987866Sroot 		if (*gp < 0) {
2997866Sroot 			*gp = gid;
3007866Sroot 			return (0);
3017866Sroot 		}
3027866Sroot 	return (-1);
3037866Sroot }
304