print errno when init can't be executed
[unix-history] / usr / src / sys / kern / kern_prot.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
0880b18e 6 * @(#)kern_prot.c 7.1 (Berkeley) %G%
da7c5cc6 7 */
a05af100
BJ
8
9/*
4147b3f6 10 * System calls related to processes and protection
a05af100
BJ
11 */
12
961945a8
SL
13#include "../machine/reg.h"
14
94368568
JB
15#include "param.h"
16#include "systm.h"
17#include "dir.h"
18#include "user.h"
19#include "inode.h"
20#include "proc.h"
21#include "timeb.h"
22#include "times.h"
23#include "reboot.h"
24#include "fs.h"
94368568
JB
25#include "buf.h"
26#include "mount.h"
27#include "quota.h"
a05af100 28
4147b3f6
BJ
29getpid()
30{
31
32 u.u_r.r_val1 = u.u_procp->p_pid;
33 u.u_r.r_val2 = u.u_procp->p_ppid;
34}
35
36getpgrp()
37{
38 register struct a {
39 int pid;
40 } *uap = (struct a *)u.u_ap;
41 register struct proc *p;
42
43 if (uap->pid == 0)
44 uap->pid = u.u_procp->p_pid;
45 p = pfind(uap->pid);
46 if (p == 0) {
47 u.u_error = ESRCH;
48 return;
49 }
50 u.u_r.r_val1 = p->p_pgrp;
51}
52
a05af100
BJ
53getuid()
54{
55
56 u.u_r.r_val1 = u.u_ruid;
57 u.u_r.r_val2 = u.u_uid;
58}
59
4147b3f6
BJ
60getgid()
61{
62
63 u.u_r.r_val1 = u.u_rgid;
64 u.u_r.r_val2 = u.u_gid;
65}
66
197da11b 67getgroups()
4147b3f6
BJ
68{
69 register struct a {
b32450f4 70 u_int gidsetsize;
4147b3f6
BJ
71 int *gidset;
72 } *uap = (struct a *)u.u_ap;
38b6104c
MK
73 register gid_t *gp;
74 register int *lp;
75 int groups[NGROUPS];
4147b3f6 76
197da11b 77 for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
38b6104c 78 if (gp[-1] != NOGROUP)
197da11b
BJ
79 break;
80 if (uap->gidsetsize < gp - u.u_groups) {
81 u.u_error = EINVAL;
82 return;
83 }
84 uap->gidsetsize = gp - u.u_groups;
38b6104c
MK
85 for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
86 *lp++ = *gp++;
87 u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
88 uap->gidsetsize * sizeof (groups[0]));
127f7d76 89 if (u.u_error)
4147b3f6 90 return;
197da11b 91 u.u_r.r_val1 = uap->gidsetsize;
4147b3f6
BJ
92}
93
94setpgrp()
95{
96 register struct proc *p;
97 register struct a {
98 int pid;
99 int pgrp;
100 } *uap = (struct a *)u.u_ap;
101
102 if (uap->pid == 0)
103 uap->pid = u.u_procp->p_pid;
104 p = pfind(uap->pid);
105 if (p == 0) {
106 u.u_error = ESRCH;
107 return;
108 }
197da11b 109/* need better control mechanisms for process groups */
4147b3f6
BJ
110 if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
111 u.u_error = EPERM;
112 return;
113 }
114 p->p_pgrp = uap->pgrp;
115}
116
4f083fd7
SL
117setreuid()
118{
119 struct a {
120 int ruid;
121 int euid;
122 } *uap;
123 register int ruid, euid;
124
125 uap = (struct a *)u.u_ap;
126 ruid = uap->ruid;
127 if (ruid == -1)
128 ruid = u.u_ruid;
129 if (u.u_ruid != ruid && u.u_uid != ruid && !suser())
130 return;
131 euid = uap->euid;
132 if (euid == -1)
133 euid = u.u_uid;
134 if (u.u_ruid != euid && u.u_uid != euid && !suser())
135 return;
136 /*
137 * Everything's okay, do it.
138 */
4f083fd7 139#ifdef QUOTA
709593b8
SL
140 if (u.u_quota->q_uid != ruid) {
141 qclean();
8011f5df 142 qstart(getquota((uid_t)ruid, 0, 0));
4f083fd7 143 }
709593b8 144#endif
d3e64b9b 145 u.u_procp->p_uid = euid;
709593b8 146 u.u_ruid = ruid;
4f083fd7
SL
147 u.u_uid = euid;
148}
149
4f083fd7
SL
150setregid()
151{
152 register struct a {
153 int rgid;
154 int egid;
155 } *uap;
156 register int rgid, egid;
157
158 uap = (struct a *)u.u_ap;
159 rgid = uap->rgid;
160 if (rgid == -1)
161 rgid = u.u_rgid;
162 if (u.u_rgid != rgid && u.u_gid != rgid && !suser())
163 return;
164 egid = uap->egid;
165 if (egid == -1)
166 egid = u.u_gid;
167 if (u.u_rgid != egid && u.u_gid != egid && !suser())
168 return;
169 if (u.u_rgid != rgid) {
170 leavegroup(u.u_rgid);
90731a34 171 (void) entergroup((gid_t)rgid);
4f083fd7
SL
172 u.u_rgid = rgid;
173 }
955b5346 174 u.u_gid = egid;
4f083fd7 175}
a05af100 176
197da11b 177setgroups()
4147b3f6
BJ
178{
179 register struct a {
b32450f4 180 u_int gidsetsize;
4147b3f6
BJ
181 int *gidset;
182 } *uap = (struct a *)u.u_ap;
38b6104c
MK
183 register gid_t *gp;
184 register int *lp;
185 int groups[NGROUPS];
4147b3f6 186
1edb1cf8 187 if (!suser())
4147b3f6 188 return;
197da11b
BJ
189 if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
190 u.u_error = EINVAL;
4147b3f6
BJ
191 return;
192 }
38b6104c
MK
193 u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
194 uap->gidsetsize * sizeof (groups[0]));
127f7d76 195 if (u.u_error)
4147b3f6 196 return;
38b6104c
MK
197 for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
198 *gp++ = *lp++;
199 for ( ; gp < &u.u_groups[NGROUPS]; gp++)
f926daf9 200 *gp = NOGROUP;
4147b3f6
BJ
201}
202
f926daf9
SL
203/*
204 * Group utility functions.
205 */
206
207/*
208 * Delete gid from the group set.
209 */
197da11b 210leavegroup(gid)
90731a34 211 gid_t gid;
197da11b 212{
38b6104c 213 register gid_t *gp;
197da11b
BJ
214
215 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
216 if (*gp == gid)
217 goto found;
218 return;
219found:
220 for (; gp < &u.u_groups[NGROUPS-1]; gp++)
221 *gp = *(gp+1);
f926daf9 222 *gp = NOGROUP;
197da11b
BJ
223}
224
f926daf9
SL
225/*
226 * Add gid to the group set.
227 */
197da11b 228entergroup(gid)
90731a34 229 gid_t gid;
197da11b 230{
38b6104c 231 register gid_t *gp;
197da11b 232
38b6104c 233 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) {
197da11b
BJ
234 if (*gp == gid)
235 return (0);
38b6104c 236 if (*gp == NOGROUP) {
197da11b
BJ
237 *gp = gid;
238 return (0);
239 }
38b6104c 240 }
197da11b
BJ
241 return (-1);
242}
f926daf9
SL
243
244/*
245 * Check if gid is a member of the group set.
246 */
247groupmember(gid)
38b6104c 248 gid_t gid;
f926daf9 249{
38b6104c 250 register gid_t *gp;
f926daf9
SL
251
252 if (u.u_gid == gid)
253 return (1);
254 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
255 if (*gp == gid)
256 return (1);
257 return (0);
258}