sun merge
[unix-history] / usr / src / sys / kern / kern_prot.c
... / ...
CommitLineData
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
24getpid()
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
31getpgrp()
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
48getuid()
49{
50
51 u.u_r.r_val1 = u.u_ruid;
52 u.u_r.r_val2 = u.u_uid;
53}
54
55getgid()
56{
57
58 u.u_r.r_val1 = u.u_rgid;
59 u.u_r.r_val2 = u.u_gid;
60}
61
62getgroups()
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
86setpgrp()
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
109setreuid()
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
143osetuid()
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
166setregid()
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
198osetgid()
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
215setgroups()
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 */
243osetpgrp()
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
273leavegroup(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;
282found:
283 for (; gp < &u.u_groups[NGROUPS-1]; gp++)
284 *gp = *(gp+1);
285 *gp = -1;
286}
287
288entergroup(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}