xref: /original-bsd/sys/kern/kern_prot.c (revision 0eaa7944)
1 /*	kern_prot.c	6.4	85/03/19	*/
2 
3 /*
4  * System calls related to processes and protection
5  */
6 
7 #include "../machine/reg.h"
8 
9 #include "param.h"
10 #include "systm.h"
11 #include "dir.h"
12 #include "user.h"
13 #include "inode.h"
14 #include "proc.h"
15 #include "timeb.h"
16 #include "times.h"
17 #include "reboot.h"
18 #include "fs.h"
19 #include "buf.h"
20 #include "mount.h"
21 #include "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 gid_t *gp;
68 	register int *lp;
69 	int groups[NGROUPS];
70 
71 	for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
72 		if (gp[-1] != NOGROUP)
73 			break;
74 	if (uap->gidsetsize < gp - u.u_groups) {
75 		u.u_error = EINVAL;
76 		return;
77 	}
78 	uap->gidsetsize = gp - u.u_groups;
79 	for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
80 		*lp++ = *gp++;
81 	u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
82 	    uap->gidsetsize * sizeof (groups[0]));
83 	if (u.u_error)
84 		return;
85 	u.u_r.r_val1 = uap->gidsetsize;
86 }
87 
88 setpgrp()
89 {
90 	register struct proc *p;
91 	register struct a {
92 		int	pid;
93 		int	pgrp;
94 	} *uap = (struct a *)u.u_ap;
95 
96 	if (uap->pid == 0)
97 		uap->pid = u.u_procp->p_pid;
98 	p = pfind(uap->pid);
99 	if (p == 0) {
100 		u.u_error = ESRCH;
101 		return;
102 	}
103 /* need better control mechanisms for process groups */
104 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
105 		u.u_error = EPERM;
106 		return;
107 	}
108 	p->p_pgrp = uap->pgrp;
109 }
110 
111 setreuid()
112 {
113 	struct a {
114 		int	ruid;
115 		int	euid;
116 	} *uap;
117 	register int ruid, euid;
118 
119 	uap = (struct a *)u.u_ap;
120 	ruid = uap->ruid;
121 	if (ruid == -1)
122 		ruid = u.u_ruid;
123 	if (u.u_ruid != ruid && u.u_uid != ruid && !suser())
124 		return;
125 	euid = uap->euid;
126 	if (euid == -1)
127 		euid = u.u_uid;
128 	if (u.u_ruid != euid && u.u_uid != euid && !suser())
129 		return;
130 	/*
131 	 * Everything's okay, do it.
132 	 */
133 #ifdef QUOTA
134 	if (u.u_quota->q_uid != ruid) {
135 		qclean();
136 		qstart(getquota(ruid, 0, 0));
137 	}
138 #endif
139 	u.u_procp->p_uid = ruid;
140 	u.u_ruid = ruid;
141 	u.u_uid = euid;
142 }
143 
144 setregid()
145 {
146 	register struct a {
147 		int	rgid;
148 		int	egid;
149 	} *uap;
150 	register int rgid, egid;
151 
152 	uap = (struct a *)u.u_ap;
153 	rgid = uap->rgid;
154 	if (rgid == -1)
155 		rgid = u.u_rgid;
156 	if (u.u_rgid != rgid && u.u_gid != rgid && !suser())
157 		return;
158 	egid = uap->egid;
159 	if (egid == -1)
160 		egid = u.u_gid;
161 	if (u.u_rgid != egid && u.u_gid != egid && !suser())
162 		return;
163 	if (u.u_rgid != rgid) {
164 		leavegroup(u.u_rgid);
165 		(void) entergroup(rgid);
166 		u.u_rgid = rgid;
167 	}
168 	u.u_gid = egid;
169 }
170 
171 setgroups()
172 {
173 	register struct	a {
174 		u_int	gidsetsize;
175 		int	*gidset;
176 	} *uap = (struct a *)u.u_ap;
177 	register gid_t *gp;
178 	register int *lp;
179 	int groups[NGROUPS];
180 
181 	if (!suser())
182 		return;
183 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
184 		u.u_error = EINVAL;
185 		return;
186 	}
187 	u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
188 	    uap->gidsetsize * sizeof (groups[0]));
189 	if (u.u_error)
190 		return;
191 	for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
192 		*gp++ = *lp++;
193 	for ( ; gp < &u.u_groups[NGROUPS]; gp++)
194 		*gp = NOGROUP;
195 }
196 
197 /*
198  * Group utility functions.
199  */
200 
201 /*
202  * Delete gid from the group set.
203  */
204 leavegroup(gid)
205 	int gid;
206 {
207 	register gid_t *gp;
208 
209 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
210 		if (*gp == gid)
211 			goto found;
212 	return;
213 found:
214 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
215 		*gp = *(gp+1);
216 	*gp = NOGROUP;
217 }
218 
219 /*
220  * Add gid to the group set.
221  */
222 entergroup(gid)
223 	int gid;
224 {
225 	register gid_t *gp;
226 
227 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) {
228 		if (*gp == gid)
229 			return (0);
230 		if (*gp == NOGROUP) {
231 			*gp = gid;
232 			return (0);
233 		}
234 	}
235 	return (-1);
236 }
237 
238 /*
239  * Check if gid is a member of the group set.
240  */
241 groupmember(gid)
242 	gid_t gid;
243 {
244 	register gid_t *gp;
245 
246 	if (u.u_gid == gid)
247 		return (1);
248 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
249 		if (*gp == gid)
250 			return (1);
251 	return (0);
252 }
253