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