xref: /original-bsd/sys/kern/kern_prot.c (revision f0fd5f8a)
1 /*	kern_prot.c	5.13	82/12/17	*/
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 	if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset,
79 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
80 		u.u_error = EFAULT;
81 		return;
82 	}
83 	u.u_r.r_val1 = uap->gidsetsize;
84 }
85 
86 setpgrp()
87 {
88 	register struct proc *p;
89 	register struct a {
90 		int	pid;
91 		int	pgrp;
92 	} *uap = (struct a *)u.u_ap;
93 
94 	if (uap->pid == 0)
95 		uap->pid = u.u_procp->p_pid;
96 	p = pfind(uap->pid);
97 	if (p == 0) {
98 		u.u_error = ESRCH;
99 		return;
100 	}
101 /* need better control mechanisms for process groups */
102 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
103 		u.u_error = EPERM;
104 		return;
105 	}
106 	p->p_pgrp = uap->pgrp;
107 }
108 
109 setreuid()
110 {
111 	struct a {
112 		int	ruid;
113 		int	euid;
114 	} *uap;
115 	register int ruid, euid;
116 
117 	uap = (struct a *)u.u_ap;
118 	ruid = uap->ruid;
119 	if (ruid == -1)
120 		ruid = u.u_ruid;
121 	if (u.u_ruid != ruid && u.u_uid != ruid && !suser())
122 		return;
123 	euid = uap->euid;
124 	if (euid == -1)
125 		euid = u.u_uid;
126 	if (u.u_ruid != euid && u.u_uid != euid && !suser())
127 		return;
128 	/*
129 	 * Everything's okay, do it.
130 	 */
131 #ifdef QUOTA
132 	if (u.u_quota->q_uid != ruid) {
133 		qclean();
134 		qstart(getquota(ruid, 0, 0));
135 	}
136 #endif
137 	u.u_procp->p_uid = ruid;
138 	u.u_ruid = ruid;
139 	u.u_uid = euid;
140 }
141 
142 #ifndef NOCOMPAT
143 osetuid()
144 {
145 	register uid;
146 	register struct a {
147 		int	uid;
148 	} *uap;
149 
150 	uap = (struct a *)u.u_ap;
151 	uid = uap->uid;
152 	if (u.u_ruid == uid || u.u_uid == uid || suser()) {
153 #ifdef QUOTA
154 		if (u.u_quota->q_uid != uid) {
155 			qclean();
156 			qstart(getquota(uid, 0, 0));
157 		}
158 #endif
159 		u.u_uid = uid;
160 		u.u_procp->p_uid = uid;
161 		u.u_ruid = uid;
162 	}
163 }
164 #endif
165 
166 setregid()
167 {
168 	register struct a {
169 		int	rgid;
170 		int	egid;
171 	} *uap;
172 	register int rgid, egid;
173 
174 	uap = (struct a *)u.u_ap;
175 	rgid = uap->rgid;
176 	if (rgid == -1)
177 		rgid = u.u_rgid;
178 	if (u.u_rgid != rgid && u.u_gid != rgid && !suser())
179 		return;
180 	egid = uap->egid;
181 	if (egid == -1)
182 		egid = u.u_gid;
183 	if (u.u_rgid != egid && u.u_gid != egid && !suser())
184 		return;
185 	if (u.u_rgid != rgid) {
186 		leavegroup(u.u_rgid);
187 		(void) entergroup(u.u_rgid);
188 		u.u_rgid = rgid;
189 	}
190 	if (u.u_gid != egid) {
191 		leavegroup(u.u_gid);
192 		(void) entergroup(egid);
193 		u.u_gid = egid;
194 	}
195 }
196 
197 #ifndef NOCOMPAT
198 osetgid()
199 {
200 	register gid;
201 	register struct a {
202 		int	gid;
203 	} *uap;
204 
205 	uap = (struct a *)u.u_ap;
206 	gid = uap->gid;
207 	if (u.u_rgid == gid || u.u_gid == gid || suser()) {
208 		leavegroup(u.u_gid); leavegroup(u.u_rgid);
209 		(void) entergroup(gid);
210 		u.u_gid = gid;
211 		u.u_rgid = gid;
212 	}
213 }
214 
215 setgroups()
216 {
217 	register struct	a {
218 		u_int	gidsetsize;
219 		int	*gidset;
220 	} *uap = (struct a *)u.u_ap;
221 	register int *gp;
222 
223 	if (!suser())
224 		return;
225 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
226 		u.u_error = EINVAL;
227 		return;
228 	}
229 	if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
230 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
231 		u.u_error = EFAULT;
232 		return;
233 	}
234 	for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
235 		*gp = -1;
236 }
237 
238 /*
239  * Pid of zero implies current process.
240  * Pgrp -1 is getpgrp system call returning
241  * current process group.
242  */
243 osetpgrp()
244 {
245 	register struct proc *p;
246 	register struct a {
247 		int	pid;
248 		int	pgrp;
249 	} *uap;
250 
251 	uap = (struct a *)u.u_ap;
252 	if (uap->pid == 0)
253 		p = u.u_procp;
254 	else {
255 		p = pfind(uap->pid);
256 		if (p == 0) {
257 			u.u_error = ESRCH;
258 			return;
259 		}
260 	}
261 	if (uap->pgrp <= 0) {
262 		u.u_r.r_val1 = p->p_pgrp;
263 		return;
264 	}
265 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
266 		u.u_error = EPERM;
267 		return;
268 	}
269 	p->p_pgrp = uap->pgrp;
270 }
271 /* END DEFUNCT */
272 
273 leavegroup(gid)
274 	int gid;
275 {
276 	register int *gp;
277 
278 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
279 		if (*gp == gid)
280 			goto found;
281 	return;
282 found:
283 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
284 		*gp = *(gp+1);
285 	*gp = -1;
286 }
287 
288 entergroup(gid)
289 	int gid;
290 {
291 	register int *gp;
292 
293 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
294 		if (*gp == gid)
295 			return (0);
296 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
297 		if (*gp < 0) {
298 			*gp = gid;
299 			return (0);
300 		}
301 	return (-1);
302 }
303