xref: /csrg-svn/sys/kern/kern_prot.c (revision 7866)
1 /*	kern_prot.c	5.4	82/08/24	*/
2 
3 /*
4  * System calls related to processes and protection
5  */
6 
7 #include "../h/param.h"
8 #include "../h/systm.h"
9 #include "../h/dir.h"
10 #include "../h/user.h"
11 #include "../h/reg.h"
12 #include "../h/inode.h"
13 #include "../h/proc.h"
14 #include "../h/clock.h"
15 #include "../h/mtpr.h"
16 #include "../h/timeb.h"
17 #include "../h/times.h"
18 #include "../h/reboot.h"
19 #include "../h/fs.h"
20 #include "../h/conf.h"
21 #include "../h/buf.h"
22 #include "../h/mount.h"
23 #include "../h/quota.h"
24 
25 getpid()
26 {
27 
28 	u.u_r.r_val1 = u.u_procp->p_pid;
29 	u.u_r.r_val2 = u.u_procp->p_ppid;
30 }
31 
32 getpgrp()
33 {
34 	register struct a {
35 		int	pid;
36 	} *uap = (struct a *)u.u_ap;
37 	register struct proc *p;
38 
39 	if (uap->pid == 0)
40 		uap->pid = u.u_procp->p_pid;
41 	p = pfind(uap->pid);
42 	if (p == 0) {
43 		u.u_error = ESRCH;
44 		return;
45 	}
46 	u.u_r.r_val1 = p->p_pgrp;
47 }
48 
49 getuid()
50 {
51 
52 	u.u_r.r_val1 = u.u_ruid;
53 	u.u_r.r_val2 = u.u_uid;
54 }
55 
56 getgid()
57 {
58 
59 	u.u_r.r_val1 = u.u_rgid;
60 	u.u_r.r_val2 = u.u_gid;
61 }
62 
63 getgroups()
64 {
65 	register struct	a {
66 		int	gidsetsize;
67 		int	*gidset;
68 	} *uap = (struct a *)u.u_ap;
69 	register int *gp;
70 
71 	for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
72 		if (gp[-1] >= 0)
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 	if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset,
80 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
81 		u.u_error = EFAULT;
82 		return;
83 	}
84 	u.u_r.r_val1 = uap->gidsetsize;
85 }
86 
87 setpgrp()
88 {
89 	register struct proc *p;
90 	register struct a {
91 		int	pid;
92 		int	pgrp;
93 	} *uap = (struct a *)u.u_ap;
94 
95 	if (uap->pid == 0)
96 		uap->pid = u.u_procp->p_pid;
97 	p = pfind(uap->pid);
98 	if (p == 0) {
99 		u.u_error = ESRCH;
100 		return;
101 	}
102 /* need better control mechanisms for process groups */
103 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
104 		u.u_error = EPERM;
105 		return;
106 	}
107 	p->p_pgrp = uap->pgrp;
108 }
109 
110 setuid()
111 {
112 	register uid;
113 	register struct a {
114 		int	uid;
115 	} *uap;
116 
117 	uap = (struct a *)u.u_ap;
118 	uid = uap->uid;
119 	if (u.u_ruid == uid || u.u_uid == uid || suser()) {
120 #ifdef QUOTA
121 		if (u.u_quota->q_uid != uid) {
122 			qclean();
123 			qstart(getquota(uid, 0, 0));
124 		}
125 #endif
126 		u.u_uid = uid;
127 		u.u_procp->p_uid = uid;
128 		u.u_ruid = uid;
129 	}
130 }
131 
132 setgid()
133 {
134 	register gid;
135 	register struct a {
136 		int	gid;
137 	} *uap;
138 
139 	uap = (struct a *)u.u_ap;
140 	gid = uap->gid;
141 	if (u.u_rgid == gid || u.u_gid == gid || suser()) {
142 		leavegroup(u.u_gid); leavegroup(u.u_rgid);
143 		(void) entergroup(gid);
144 		u.u_gid = gid;
145 		u.u_rgid = gid;
146 	}
147 }
148 
149 setgroups()
150 {
151 	register struct	a {
152 		int	gidsetsize;
153 		int	*gidset;
154 	} *uap = (struct a *)u.u_ap;
155 	register int *gp;
156 
157 	if (suser())
158 		return;
159 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
160 		u.u_error = EINVAL;
161 		return;
162 	}
163 	if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
164 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
165 		u.u_error = EFAULT;
166 		return;
167 	}
168 	for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
169 		*gp = -1;
170 }
171 
172 /*
173  * Pid of zero implies current process.
174  * Pgrp -1 is getpgrp system call returning
175  * current process group.
176  */
177 osetpgrp()
178 {
179 	register struct proc *p;
180 	register struct a {
181 		int	pid;
182 		int	pgrp;
183 	} *uap;
184 
185 	uap = (struct a *)u.u_ap;
186 	if (uap->pid == 0)
187 		p = u.u_procp;
188 	else {
189 		p = pfind(uap->pid);
190 		if (p == 0) {
191 			u.u_error = ESRCH;
192 			return;
193 		}
194 	}
195 	if (uap->pgrp <= 0) {
196 		u.u_r.r_val1 = p->p_pgrp;
197 		return;
198 	}
199 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
200 		u.u_error = EPERM;
201 		return;
202 	}
203 	p->p_pgrp = uap->pgrp;
204 }
205 /* END DEFUNCT */
206 
207 leavegroup(gid)
208 	int gid;
209 {
210 	register int *gp;
211 
212 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
213 		if (*gp == gid)
214 			goto found;
215 	return;
216 found:
217 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
218 		*gp = *(gp+1);
219 	*gp = 0;
220 }
221 
222 entergroup(gid)
223 	int gid;
224 {
225 	register int *gp;
226 
227 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
228 		if (*gp == gid)
229 			return (0);
230 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
231 		if (*gp < 0) {
232 			*gp = gid;
233 			return (0);
234 		}
235 	return (-1);
236 }
237