xref: /csrg-svn/sys/kern/kern_prot.c (revision 9320)
1 /*	kern_prot.c	5.12	82/11/22	*/
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 #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(u.u_rgid);
187 		u.u_rgid = rgid;
188 	}
189 	if (u.u_gid != egid) {
190 		leavegroup(u.u_gid);
191 		(void) entergroup(egid);
192 		u.u_gid = egid;
193 	}
194 }
195 
196 #ifndef NOCOMPAT
197 osetgid()
198 {
199 	register gid;
200 	register struct a {
201 		int	gid;
202 	} *uap;
203 
204 	uap = (struct a *)u.u_ap;
205 	gid = uap->gid;
206 	if (u.u_rgid == gid || u.u_gid == gid || suser()) {
207 		leavegroup(u.u_gid); leavegroup(u.u_rgid);
208 		(void) entergroup(gid);
209 		u.u_gid = gid;
210 		u.u_rgid = gid;
211 	}
212 }
213 
214 setgroups()
215 {
216 	register struct	a {
217 		u_int	gidsetsize;
218 		int	*gidset;
219 	} *uap = (struct a *)u.u_ap;
220 	register int *gp;
221 
222 	if (!suser())
223 		return;
224 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
225 		u.u_error = EINVAL;
226 		return;
227 	}
228 	if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
229 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
230 		u.u_error = EFAULT;
231 		return;
232 	}
233 	for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
234 		*gp = -1;
235 }
236 
237 /*
238  * Pid of zero implies current process.
239  * Pgrp -1 is getpgrp system call returning
240  * current process group.
241  */
242 osetpgrp()
243 {
244 	register struct proc *p;
245 	register struct a {
246 		int	pid;
247 		int	pgrp;
248 	} *uap;
249 
250 	uap = (struct a *)u.u_ap;
251 	if (uap->pid == 0)
252 		p = u.u_procp;
253 	else {
254 		p = pfind(uap->pid);
255 		if (p == 0) {
256 			u.u_error = ESRCH;
257 			return;
258 		}
259 	}
260 	if (uap->pgrp <= 0) {
261 		u.u_r.r_val1 = p->p_pgrp;
262 		return;
263 	}
264 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
265 		u.u_error = EPERM;
266 		return;
267 	}
268 	p->p_pgrp = uap->pgrp;
269 }
270 /* END DEFUNCT */
271 
272 leavegroup(gid)
273 	int gid;
274 {
275 	register int *gp;
276 
277 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
278 		if (*gp == gid)
279 			goto found;
280 	return;
281 found:
282 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
283 		*gp = *(gp+1);
284 	*gp = -1;
285 }
286 
287 entergroup(gid)
288 	int gid;
289 {
290 	register int *gp;
291 
292 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
293 		if (*gp == gid)
294 			return (0);
295 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
296 		if (*gp < 0) {
297 			*gp = gid;
298 			return (0);
299 		}
300 	return (-1);
301 }
302