copyin & copyout now return EFAULT and all callers uniformly
[unix-history] / usr / src / sys / kern / kern_prot.c
CommitLineData
127f7d76 1/* kern_prot.c 5.14 82/12/28 */
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;
127f7d76
SL
78 u.u_error = copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset,
79 uap->gidsetsize * sizeof (u.u_groups[0]));
80 if (u.u_error)
4147b3f6 81 return;
197da11b 82 u.u_r.r_val1 = uap->gidsetsize;
4147b3f6
BJ
83}
84
85setpgrp()
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 }
197da11b 100/* need better control mechanisms for process groups */
4147b3f6
BJ
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
4f083fd7
SL
108setreuid()
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 */
4f083fd7 130#ifdef QUOTA
709593b8
SL
131 if (u.u_quota->q_uid != ruid) {
132 qclean();
133 qstart(getquota(ruid, 0, 0));
4f083fd7 134 }
709593b8
SL
135#endif
136 u.u_procp->p_uid = ruid;
137 u.u_ruid = ruid;
4f083fd7
SL
138 u.u_uid = euid;
139}
140
141#ifndef NOCOMPAT
142osetuid()
a05af100
BJ
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()) {
57e12479
RE
152#ifdef QUOTA
153 if (u.u_quota->q_uid != uid) {
154 qclean();
155 qstart(getquota(uid, 0, 0));
156 }
157#endif
a05af100
BJ
158 u.u_uid = uid;
159 u.u_procp->p_uid = uid;
160 u.u_ruid = uid;
161 }
162}
4f083fd7
SL
163#endif
164
165setregid()
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}
a05af100 195
4f083fd7
SL
196#ifndef NOCOMPAT
197osetgid()
a05af100
BJ
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()) {
197da11b
BJ
207 leavegroup(u.u_gid); leavegroup(u.u_rgid);
208 (void) entergroup(gid);
a05af100
BJ
209 u.u_gid = gid;
210 u.u_rgid = gid;
211 }
212}
4147b3f6 213
197da11b 214setgroups()
4147b3f6
BJ
215{
216 register struct a {
b32450f4 217 u_int gidsetsize;
4147b3f6
BJ
218 int *gidset;
219 } *uap = (struct a *)u.u_ap;
197da11b 220 register int *gp;
4147b3f6 221
1edb1cf8 222 if (!suser())
4147b3f6 223 return;
197da11b
BJ
224 if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
225 u.u_error = EINVAL;
4147b3f6
BJ
226 return;
227 }
127f7d76
SL
228 u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
229 uap->gidsetsize * sizeof (u.u_groups[0]));
230 if (u.u_error)
4147b3f6 231 return;
197da11b
BJ
232 for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
233 *gp = -1;
4147b3f6
BJ
234}
235
236/*
237 * Pid of zero implies current process.
238 * Pgrp -1 is getpgrp system call returning
239 * current process group.
240 */
241osetpgrp()
242{
243 register struct proc *p;
244 register struct a {
245 int pid;
246 int pgrp;
247 } *uap;
248
249 uap = (struct a *)u.u_ap;
250 if (uap->pid == 0)
251 p = u.u_procp;
252 else {
253 p = pfind(uap->pid);
254 if (p == 0) {
255 u.u_error = ESRCH;
256 return;
257 }
258 }
259 if (uap->pgrp <= 0) {
260 u.u_r.r_val1 = p->p_pgrp;
261 return;
262 }
263 if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
264 u.u_error = EPERM;
265 return;
266 }
267 p->p_pgrp = uap->pgrp;
268}
269/* END DEFUNCT */
197da11b
BJ
270
271leavegroup(gid)
272 int gid;
273{
274 register int *gp;
275
276 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
277 if (*gp == gid)
278 goto found;
279 return;
280found:
281 for (; gp < &u.u_groups[NGROUPS-1]; gp++)
282 *gp = *(gp+1);
b724ad1f 283 *gp = -1;
197da11b
BJ
284}
285
286entergroup(gid)
287 int gid;
288{
289 register int *gp;
290
291 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
292 if (*gp == gid)
293 return (0);
294 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
295 if (*gp < 0) {
296 *gp = gid;
297 return (0);
298 }
299 return (-1);
300}