xref: /original-bsd/sys/kern/kern_prot.c (revision a141c157)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)kern_prot.c	7.2 (Berkeley) 10/18/88
7  */
8 
9 /*
10  * System calls related to processes and protection
11  */
12 
13 #include "../machine/reg.h"
14 
15 #include "param.h"
16 #include "systm.h"
17 #include "dir.h"
18 #include "user.h"
19 #include "inode.h"
20 #include "proc.h"
21 #include "timeb.h"
22 #include "times.h"
23 #include "reboot.h"
24 #include "fs.h"
25 #include "buf.h"
26 #include "mount.h"
27 #include "quota.h"
28 
29 getpid()
30 {
31 
32 	u.u_r.r_val1 = u.u_procp->p_pid;
33 	u.u_r.r_val2 = u.u_procp->p_ppid;
34 }
35 
36 getpgrp()
37 {
38 	register struct a {
39 		int	pid;
40 	} *uap = (struct a *)u.u_ap;
41 	register struct proc *p;
42 
43 	if (uap->pid == 0)
44 		p = u.u_procp;
45 	else if ((p = pfind(uap->pid)) == 0) {
46 		u.u_error = ESRCH;
47 		return;
48 	}
49 	u.u_r.r_val1 = p->p_pgrp->pg_id;
50 }
51 
52 getuid()
53 {
54 
55 	u.u_r.r_val1 = u.u_ruid;
56 	u.u_r.r_val2 = u.u_uid;
57 }
58 
59 getgid()
60 {
61 
62 	u.u_r.r_val1 = u.u_rgid;
63 	u.u_r.r_val2 = u.u_gid;
64 }
65 
66 getgroups()
67 {
68 	register struct	a {
69 		u_int	gidsetsize;
70 		int	*gidset;
71 	} *uap = (struct a *)u.u_ap;
72 	register gid_t *gp;
73 	register int *lp;
74 	int groups[NGROUPS];
75 
76 	for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
77 		if (gp[-1] != NOGROUP)
78 			break;
79 	if (uap->gidsetsize < gp - u.u_groups) {
80 		u.u_error = EINVAL;
81 		return;
82 	}
83 	uap->gidsetsize = gp - u.u_groups;
84 	for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
85 		*lp++ = *gp++;
86 	u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
87 	    uap->gidsetsize * sizeof (groups[0]));
88 	if (u.u_error)
89 		return;
90 	u.u_r.r_val1 = uap->gidsetsize;
91 }
92 
93 setsid()
94 {
95 	register struct proc *p = u.u_procp;
96 
97 	if ((p->p_pgid == p->p_pid) || pgfind(p->p_pid))
98 		u.u_error = EPERM;
99 	else {
100 		pgmv(p, p->p_pid, 1);
101 		u.u_r.r_val1 = p->p_pid;
102 	}
103 	return;
104 }
105 
106 /*
107  * set process group
108  *
109  * if target pid != caller's pid
110  *	pid must be an inferior
111  *	pid must be in same session
112  *	pid can't have done an exec
113  *	there must exist a pid with pgid in same session
114  * pid must not be session leader
115  */
116 setpgrp()
117 {
118 	register struct a {
119 		int	pid;
120 		int	pgid;
121 	} *uap = (struct a *)u.u_ap;
122 	register struct proc *p;
123 	register struct pgrp *pgrp;
124 
125 	if (uap->pid == 0)
126 		p = u.u_procp;
127 	else if ((p = pfind(uap->pid)) == 0 || !inferior(p)) {
128 		u.u_error = ESRCH;
129 		return;
130 	}
131 	else if (p != u.u_procp) {
132 		if (p->p_session != u.u_procp->p_session) {
133 			u.u_error = EPERM;
134 			return;
135 		}
136 		if (p->p_flag&SEXEC) {
137 			u.u_error = EACCES;
138 			return;
139 		}
140 	}
141 	if (SESS_LEADER(p)) {
142 		u.u_error = EPERM;
143 		return;
144 	}
145 	if (uap->pgid == 0)
146 		uap->pgid = p->p_pid;
147 	else if ((uap->pgid != p->p_pid) &&
148 		(((pgrp = pgfind(uap->pgid)) == 0) ||
149 		   pgrp->pg_mem == NULL ||
150 	           pgrp->pg_session != u.u_procp->p_session)) {
151 		u.u_error = EPERM;
152 		return;
153 	}
154 	/*
155 	 * done checking, now doit
156 	 */
157 	pgmv(p, uap->pgid, 0);
158 }
159 
160 setreuid()
161 {
162 	struct a {
163 		int	ruid;
164 		int	euid;
165 	} *uap;
166 	register int ruid, euid;
167 
168 	uap = (struct a *)u.u_ap;
169 	ruid = uap->ruid;
170 	if (ruid == -1)
171 		ruid = u.u_ruid;
172 	if (u.u_ruid != ruid && u.u_uid != ruid && !suser())
173 		return;
174 	euid = uap->euid;
175 	if (euid == -1)
176 		euid = u.u_uid;
177 	if (u.u_ruid != euid && u.u_uid != euid && !suser())
178 		return;
179 	/*
180 	 * Everything's okay, do it.
181 	 */
182 #ifdef QUOTA
183 	if (u.u_quota->q_uid != ruid) {
184 		qclean();
185 		qstart(getquota((uid_t)ruid, 0, 0));
186 	}
187 #endif
188 	u.u_procp->p_uid = euid;
189 	u.u_ruid = ruid;
190 	u.u_uid = euid;
191 }
192 
193 setregid()
194 {
195 	register struct a {
196 		int	rgid;
197 		int	egid;
198 	} *uap;
199 	register int rgid, egid;
200 
201 	uap = (struct a *)u.u_ap;
202 	rgid = uap->rgid;
203 	if (rgid == -1)
204 		rgid = u.u_rgid;
205 	if (u.u_rgid != rgid && u.u_gid != rgid && !suser())
206 		return;
207 	egid = uap->egid;
208 	if (egid == -1)
209 		egid = u.u_gid;
210 	if (u.u_rgid != egid && u.u_gid != egid && !suser())
211 		return;
212 	if (u.u_rgid != rgid) {
213 		leavegroup(u.u_rgid);
214 		(void) entergroup((gid_t)rgid);
215 		u.u_rgid = rgid;
216 	}
217 	u.u_gid = egid;
218 }
219 
220 setgroups()
221 {
222 	register struct	a {
223 		u_int	gidsetsize;
224 		int	*gidset;
225 	} *uap = (struct a *)u.u_ap;
226 	register gid_t *gp;
227 	register int *lp;
228 	int groups[NGROUPS];
229 
230 	if (!suser())
231 		return;
232 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
233 		u.u_error = EINVAL;
234 		return;
235 	}
236 	u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
237 	    uap->gidsetsize * sizeof (groups[0]));
238 	if (u.u_error)
239 		return;
240 	for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
241 		*gp++ = *lp++;
242 	for ( ; gp < &u.u_groups[NGROUPS]; gp++)
243 		*gp = NOGROUP;
244 }
245 
246 /*
247  * Group utility functions.
248  */
249 
250 /*
251  * Delete gid from the group set.
252  */
253 leavegroup(gid)
254 	gid_t gid;
255 {
256 	register gid_t *gp;
257 
258 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
259 		if (*gp == gid)
260 			goto found;
261 	return;
262 found:
263 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
264 		*gp = *(gp+1);
265 	*gp = NOGROUP;
266 }
267 
268 /*
269  * Add gid to the group set.
270  */
271 entergroup(gid)
272 	gid_t gid;
273 {
274 	register gid_t *gp;
275 
276 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) {
277 		if (*gp == gid)
278 			return (0);
279 		if (*gp == NOGROUP) {
280 			*gp = gid;
281 			return (0);
282 		}
283 	}
284 	return (-1);
285 }
286 
287 /*
288  * Check if gid is a member of the group set.
289  */
290 groupmember(gid)
291 	gid_t gid;
292 {
293 	register gid_t *gp;
294 
295 	if (u.u_gid == gid)
296 		return (1);
297 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
298 		if (*gp == gid)
299 			return (1);
300 	return (0);
301 }
302