xref: /csrg-svn/sys/kern/kern_prot.c (revision 8152)
1 /*	kern_prot.c	5.7	82/09/12	*/
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/mtpr.h"
15 #include "../h/timeb.h"
16 #include "../h/times.h"
17 #include "../h/reboot.h"
18 #include "../h/fs.h"
19 #include "../h/conf.h"
20 #include "../h/buf.h"
21 #include "../h/mount.h"
22 #include "../h/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 		int	gidsetsize;
66 		int	*gidset;
67 	} *uap = (struct a *)u.u_ap;
68 	register int *gp;
69 
70 	for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
71 		if (gp[-1] >= 0)
72 			break;
73 	if (uap->gidsetsize < gp - u.u_groups) {
74 		u.u_error = EINVAL;
75 		return;
76 	}
77 	uap->gidsetsize = gp - u.u_groups;
78 	if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset,
79 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
80 		u.u_error = EFAULT;
81 		return;
82 	}
83 	u.u_r.r_val1 = uap->gidsetsize;
84 }
85 
86 setpgrp()
87 {
88 	register struct proc *p;
89 	register struct a {
90 		int	pid;
91 		int	pgrp;
92 	} *uap = (struct a *)u.u_ap;
93 
94 	if (uap->pid == 0)
95 		uap->pid = u.u_procp->p_pid;
96 	p = pfind(uap->pid);
97 	if (p == 0) {
98 		u.u_error = ESRCH;
99 		return;
100 	}
101 /* need better control mechanisms for process groups */
102 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
103 		u.u_error = EPERM;
104 		return;
105 	}
106 	p->p_pgrp = uap->pgrp;
107 }
108 
109 setuid()
110 {
111 	register uid;
112 	register struct a {
113 		int	uid;
114 	} *uap;
115 
116 	uap = (struct a *)u.u_ap;
117 	uid = uap->uid;
118 	if (u.u_ruid == uid || u.u_uid == uid || suser()) {
119 #ifdef QUOTA
120 		if (u.u_quota->q_uid != uid) {
121 			qclean();
122 			qstart(getquota(uid, 0, 0));
123 		}
124 #endif
125 		u.u_uid = uid;
126 		u.u_procp->p_uid = uid;
127 		u.u_ruid = uid;
128 	}
129 }
130 
131 setgid()
132 {
133 	register gid;
134 	register struct a {
135 		int	gid;
136 	} *uap;
137 
138 	uap = (struct a *)u.u_ap;
139 	gid = uap->gid;
140 	if (u.u_rgid == gid || u.u_gid == gid || suser()) {
141 		leavegroup(u.u_gid); leavegroup(u.u_rgid);
142 		(void) entergroup(gid);
143 		u.u_gid = gid;
144 		u.u_rgid = gid;
145 	}
146 }
147 
148 setgroups()
149 {
150 	register struct	a {
151 		int	gidsetsize;
152 		int	*gidset;
153 	} *uap = (struct a *)u.u_ap;
154 	register int *gp;
155 
156 	if (!suser())
157 		return;
158 	if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
159 		u.u_error = EINVAL;
160 		return;
161 	}
162 	if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
163 	    uap->gidsetsize * sizeof (u.u_groups[0]))) {
164 		u.u_error = EFAULT;
165 		return;
166 	}
167 	for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
168 		*gp = -1;
169 }
170 
171 /*
172  * Pid of zero implies current process.
173  * Pgrp -1 is getpgrp system call returning
174  * current process group.
175  */
176 osetpgrp()
177 {
178 	register struct proc *p;
179 	register struct a {
180 		int	pid;
181 		int	pgrp;
182 	} *uap;
183 
184 	uap = (struct a *)u.u_ap;
185 	if (uap->pid == 0)
186 		p = u.u_procp;
187 	else {
188 		p = pfind(uap->pid);
189 		if (p == 0) {
190 			u.u_error = ESRCH;
191 			return;
192 		}
193 	}
194 	if (uap->pgrp <= 0) {
195 		u.u_r.r_val1 = p->p_pgrp;
196 		return;
197 	}
198 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
199 		u.u_error = EPERM;
200 		return;
201 	}
202 	p->p_pgrp = uap->pgrp;
203 }
204 /* END DEFUNCT */
205 
206 leavegroup(gid)
207 	int gid;
208 {
209 	register int *gp;
210 
211 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
212 		if (*gp == gid)
213 			goto found;
214 	return;
215 found:
216 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
217 		*gp = *(gp+1);
218 	*gp = -1;
219 }
220 
221 entergroup(gid)
222 	int gid;
223 {
224 	register int *gp;
225 
226 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
227 		if (*gp == gid)
228 			return (0);
229 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
230 		if (*gp < 0) {
231 			*gp = gid;
232 			return (0);
233 		}
234 	return (-1);
235 }
236