sun merge
[unix-history] / usr / src / sys / kern / kern_prot.c
CommitLineData
961945a8 1/* kern_prot.c 5.13 82/12/17 */
a05af100
BJ
2
3/*
4147b3f6 4 * System calls related to processes and protection
a05af100
BJ
5 */
6
961945a8
SL
7#include "../machine/reg.h"
8
a05af100
BJ
9#include "../h/param.h"
10#include "../h/systm.h"
11#include "../h/dir.h"
12#include "../h/user.h"
a05af100
BJ
13#include "../h/inode.h"
14#include "../h/proc.h"
a05af100
BJ
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"
57e12479 22#include "../h/quota.h"
a05af100 23
4147b3f6
BJ
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
a05af100
BJ
48getuid()
49{
50
51 u.u_r.r_val1 = u.u_ruid;
52 u.u_r.r_val2 = u.u_uid;
53}
54
4147b3f6
BJ
55getgid()
56{
57
58 u.u_r.r_val1 = u.u_rgid;
59 u.u_r.r_val2 = u.u_gid;
60}
61
197da11b 62getgroups()
4147b3f6
BJ
63{
64 register struct a {
b32450f4 65 u_int gidsetsize;
4147b3f6
BJ
66 int *gidset;
67 } *uap = (struct a *)u.u_ap;
197da11b 68 register int *gp;
4147b3f6 69
197da11b
BJ
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]))) {
4147b3f6
BJ
80 u.u_error = EFAULT;
81 return;
82 }
197da11b 83 u.u_r.r_val1 = uap->gidsetsize;
4147b3f6
BJ
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 }
197da11b 101/* need better control mechanisms for process groups */
4147b3f6
BJ
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
4f083fd7
SL
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 */
4f083fd7 131#ifdef QUOTA
709593b8
SL
132 if (u.u_quota->q_uid != ruid) {
133 qclean();
134 qstart(getquota(ruid, 0, 0));
4f083fd7 135 }
709593b8
SL
136#endif
137 u.u_procp->p_uid = ruid;
138 u.u_ruid = ruid;
4f083fd7
SL
139 u.u_uid = euid;
140}
141
142#ifndef NOCOMPAT
143osetuid()
a05af100
BJ
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()) {
57e12479
RE
153#ifdef QUOTA
154 if (u.u_quota->q_uid != uid) {
155 qclean();
156 qstart(getquota(uid, 0, 0));
157 }
158#endif
a05af100
BJ
159 u.u_uid = uid;
160 u.u_procp->p_uid = uid;
161 u.u_ruid = uid;
162 }
163}
4f083fd7
SL
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}
a05af100 196
4f083fd7
SL
197#ifndef NOCOMPAT
198osetgid()
a05af100
BJ
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()) {
197da11b
BJ
208 leavegroup(u.u_gid); leavegroup(u.u_rgid);
209 (void) entergroup(gid);
a05af100
BJ
210 u.u_gid = gid;
211 u.u_rgid = gid;
212 }
213}
4147b3f6 214
197da11b 215setgroups()
4147b3f6
BJ
216{
217 register struct a {
b32450f4 218 u_int gidsetsize;
4147b3f6
BJ
219 int *gidset;
220 } *uap = (struct a *)u.u_ap;
197da11b 221 register int *gp;
4147b3f6 222
1edb1cf8 223 if (!suser())
4147b3f6 224 return;
197da11b
BJ
225 if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
226 u.u_error = EINVAL;
4147b3f6
BJ
227 return;
228 }
197da11b
BJ
229 if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
230 uap->gidsetsize * sizeof (u.u_groups[0]))) {
4147b3f6
BJ
231 u.u_error = EFAULT;
232 return;
233 }
197da11b
BJ
234 for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
235 *gp = -1;
4147b3f6
BJ
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 */
197da11b
BJ
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);
b724ad1f 285 *gp = -1;
197da11b
BJ
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}