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