xref: /csrg-svn/sys/kern/kern_prot.c (revision 23372)
1 /*
2  * Copyright (c) 1982 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)kern_prot.c	6.5 (Berkeley) 06/08/85
7  */
8 
9 /*
10  * System calls related to processes and protection
11  */
12 
13 #include "../machine/reg.h"
14 
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"
25 #include "buf.h"
26 #include "mount.h"
27 #include "quota.h"
28 
29 getpid()
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 
36 getpgrp()
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 
53 getuid()
54 {
55 
56 	u.u_r.r_val1 = u.u_ruid;
57 	u.u_r.r_val2 = u.u_uid;
58 }
59 
60 getgid()
61 {
62 
63 	u.u_r.r_val1 = u.u_rgid;
64 	u.u_r.r_val2 = u.u_gid;
65 }
66 
67 getgroups()
68 {
69 	register struct	a {
70 		u_int	gidsetsize;
71 		int	*gidset;
72 	} *uap = (struct a *)u.u_ap;
73 	register gid_t *gp;
74 	register int *lp;
75 	int groups[NGROUPS];
76 
77 	for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
78 		if (gp[-1] != NOGROUP)
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;
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]));
89 	if (u.u_error)
90 		return;
91 	u.u_r.r_val1 = uap->gidsetsize;
92 }
93 
94 setpgrp()
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 	}
109 /* need better control mechanisms for process groups */
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 
117 setreuid()
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 	 */
139 #ifdef QUOTA
140 	if (u.u_quota->q_uid != ruid) {
141 		qclean();
142 		qstart(getquota(ruid, 0, 0));
143 	}
144 #endif
145 	u.u_procp->p_uid = ruid;
146 	u.u_ruid = ruid;
147 	u.u_uid = euid;
148 }
149 
150 setregid()
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);
171 		(void) entergroup(rgid);
172 		u.u_rgid = rgid;
173 	}
174 	u.u_gid = egid;
175 }
176 
177 setgroups()
178 {
179 	register struct	a {
180 		u_int	gidsetsize;
181 		int	*gidset;
182 	} *uap = (struct a *)u.u_ap;
183 	register gid_t *gp;
184 	register int *lp;
185 	int groups[NGROUPS];
186 
187 	if (!suser())
188 		return;
189 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
190 		u.u_error = EINVAL;
191 		return;
192 	}
193 	u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
194 	    uap->gidsetsize * sizeof (groups[0]));
195 	if (u.u_error)
196 		return;
197 	for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
198 		*gp++ = *lp++;
199 	for ( ; gp < &u.u_groups[NGROUPS]; gp++)
200 		*gp = NOGROUP;
201 }
202 
203 /*
204  * Group utility functions.
205  */
206 
207 /*
208  * Delete gid from the group set.
209  */
210 leavegroup(gid)
211 	int gid;
212 {
213 	register gid_t *gp;
214 
215 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
216 		if (*gp == gid)
217 			goto found;
218 	return;
219 found:
220 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
221 		*gp = *(gp+1);
222 	*gp = NOGROUP;
223 }
224 
225 /*
226  * Add gid to the group set.
227  */
228 entergroup(gid)
229 	int gid;
230 {
231 	register gid_t *gp;
232 
233 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) {
234 		if (*gp == gid)
235 			return (0);
236 		if (*gp == NOGROUP) {
237 			*gp = gid;
238 			return (0);
239 		}
240 	}
241 	return (-1);
242 }
243 
244 /*
245  * Check if gid is a member of the group set.
246  */
247 groupmember(gid)
248 	gid_t gid;
249 {
250 	register gid_t *gp;
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 }
259