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