xref: /csrg-svn/sys/kern/kern_prot.c (revision 9160)
1 /*	kern_prot.c	5.11	82/11/13	*/
2 
3 /*
4  * System calls related to processes and protection
5  */
6 
7 #include "../h/param.h"
8 #include "../h/systm.h"
9 #include "../h/dir.h"
10 #include "../h/user.h"
11 #include "../h/reg.h"
12 #include "../h/inode.h"
13 #include "../h/proc.h"
14 #include "../h/timeb.h"
15 #include "../h/times.h"
16 #include "../h/reboot.h"
17 #include "../h/fs.h"
18 #include "../h/conf.h"
19 #include "../h/buf.h"
20 #include "../h/mount.h"
21 #include "../h/quota.h"
22 
23 getpid()
24 {
25 
26 	u.u_r.r_val1 = u.u_procp->p_pid;
27 	u.u_r.r_val2 = u.u_procp->p_ppid;
28 }
29 
30 getpgrp()
31 {
32 	register struct a {
33 		int	pid;
34 	} *uap = (struct a *)u.u_ap;
35 	register struct proc *p;
36 
37 	if (uap->pid == 0)
38 		uap->pid = u.u_procp->p_pid;
39 	p = pfind(uap->pid);
40 	if (p == 0) {
41 		u.u_error = ESRCH;
42 		return;
43 	}
44 	u.u_r.r_val1 = p->p_pgrp;
45 }
46 
47 getuid()
48 {
49 
50 	u.u_r.r_val1 = u.u_ruid;
51 	u.u_r.r_val2 = u.u_uid;
52 }
53 
54 getgid()
55 {
56 
57 	u.u_r.r_val1 = u.u_rgid;
58 	u.u_r.r_val2 = u.u_gid;
59 }
60 
61 getgroups()
62 {
63 	register struct	a {
64 		u_int	gidsetsize;
65 		int	*gidset;
66 	} *uap = (struct a *)u.u_ap;
67 	register int *gp;
68 
69 	for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
70 		if (gp[-1] >= 0)
71 			break;
72 	if (uap->gidsetsize < gp - u.u_groups) {
73 		u.u_error = EINVAL;
74 		return;
75 	}
76 	uap->gidsetsize = gp - u.u_groups;
77 	if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset,
78 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
79 		u.u_error = EFAULT;
80 		return;
81 	}
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 	if (ruid != u.u_ruid) {
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 	}
140 	u.u_uid = euid;
141 }
142 
143 #ifndef NOCOMPAT
144 osetuid()
145 {
146 	register uid;
147 	register struct a {
148 		int	uid;
149 	} *uap;
150 
151 	uap = (struct a *)u.u_ap;
152 	uid = uap->uid;
153 	if (u.u_ruid == uid || u.u_uid == uid || suser()) {
154 #ifdef QUOTA
155 		if (u.u_quota->q_uid != uid) {
156 			qclean();
157 			qstart(getquota(uid, 0, 0));
158 		}
159 #endif
160 		u.u_uid = uid;
161 		u.u_procp->p_uid = uid;
162 		u.u_ruid = uid;
163 	}
164 }
165 #endif
166 
167 setregid()
168 {
169 	register struct a {
170 		int	rgid;
171 		int	egid;
172 	} *uap;
173 	register int rgid, egid;
174 
175 	uap = (struct a *)u.u_ap;
176 	rgid = uap->rgid;
177 	if (rgid == -1)
178 		rgid = u.u_rgid;
179 	if (u.u_rgid != rgid && u.u_gid != rgid && !suser())
180 		return;
181 	egid = uap->egid;
182 	if (egid == -1)
183 		egid = u.u_gid;
184 	if (u.u_rgid != egid && u.u_gid != egid && !suser())
185 		return;
186 	if (u.u_rgid != rgid) {
187 		leavegroup(u.u_rgid);
188 		(void) entergroup(u.u_rgid);
189 		u.u_rgid = rgid;
190 	}
191 	if (u.u_gid != egid) {
192 		leavegroup(u.u_gid);
193 		(void) entergroup(egid);
194 		u.u_gid = egid;
195 	}
196 }
197 
198 #ifndef NOCOMPAT
199 osetgid()
200 {
201 	register gid;
202 	register struct a {
203 		int	gid;
204 	} *uap;
205 
206 	uap = (struct a *)u.u_ap;
207 	gid = uap->gid;
208 	if (u.u_rgid == gid || u.u_gid == gid || suser()) {
209 		leavegroup(u.u_gid); leavegroup(u.u_rgid);
210 		(void) entergroup(gid);
211 		u.u_gid = gid;
212 		u.u_rgid = gid;
213 	}
214 }
215 
216 setgroups()
217 {
218 	register struct	a {
219 		u_int	gidsetsize;
220 		int	*gidset;
221 	} *uap = (struct a *)u.u_ap;
222 	register int *gp;
223 
224 	if (!suser())
225 		return;
226 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
227 		u.u_error = EINVAL;
228 		return;
229 	}
230 	if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
231 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
232 		u.u_error = EFAULT;
233 		return;
234 	}
235 	for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
236 		*gp = -1;
237 }
238 
239 /*
240  * Pid of zero implies current process.
241  * Pgrp -1 is getpgrp system call returning
242  * current process group.
243  */
244 osetpgrp()
245 {
246 	register struct proc *p;
247 	register struct a {
248 		int	pid;
249 		int	pgrp;
250 	} *uap;
251 
252 	uap = (struct a *)u.u_ap;
253 	if (uap->pid == 0)
254 		p = u.u_procp;
255 	else {
256 		p = pfind(uap->pid);
257 		if (p == 0) {
258 			u.u_error = ESRCH;
259 			return;
260 		}
261 	}
262 	if (uap->pgrp <= 0) {
263 		u.u_r.r_val1 = p->p_pgrp;
264 		return;
265 	}
266 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
267 		u.u_error = EPERM;
268 		return;
269 	}
270 	p->p_pgrp = uap->pgrp;
271 }
272 /* END DEFUNCT */
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 = -1;
287 }
288 
289 entergroup(gid)
290 	int gid;
291 {
292 	register int *gp;
293 
294 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
295 		if (*gp == gid)
296 			return (0);
297 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
298 		if (*gp < 0) {
299 			*gp = gid;
300 			return (0);
301 		}
302 	return (-1);
303 }
304