xref: /csrg-svn/sys/kern/kern_prot.c (revision 8100)
1 /*	kern_prot.c	5.6	82/09/06	*/
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 printf("gidsetsize %d, gidset %x\n", uap->gidsetsize, uap->gidset);
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 printf("copied in %d %d ... \n", u.u_groups[0], u.u_groups[1]);
169 	for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
170 		*gp = -1;
171 }
172 
173 /*
174  * Pid of zero implies current process.
175  * Pgrp -1 is getpgrp system call returning
176  * current process group.
177  */
178 osetpgrp()
179 {
180 	register struct proc *p;
181 	register struct a {
182 		int	pid;
183 		int	pgrp;
184 	} *uap;
185 
186 	uap = (struct a *)u.u_ap;
187 	if (uap->pid == 0)
188 		p = u.u_procp;
189 	else {
190 		p = pfind(uap->pid);
191 		if (p == 0) {
192 			u.u_error = ESRCH;
193 			return;
194 		}
195 	}
196 	if (uap->pgrp <= 0) {
197 		u.u_r.r_val1 = p->p_pgrp;
198 		return;
199 	}
200 	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
201 		u.u_error = EPERM;
202 		return;
203 	}
204 	p->p_pgrp = uap->pgrp;
205 }
206 /* END DEFUNCT */
207 
208 leavegroup(gid)
209 	int gid;
210 {
211 	register int *gp;
212 
213 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
214 		if (*gp == gid)
215 			goto found;
216 	return;
217 found:
218 	for (; gp < &u.u_groups[NGROUPS-1]; gp++)
219 		*gp = *(gp+1);
220 	*gp = -1;
221 }
222 
223 entergroup(gid)
224 	int gid;
225 {
226 	register int *gp;
227 
228 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
229 		if (*gp == gid)
230 			return (0);
231 	for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
232 		if (*gp < 0) {
233 			*gp = gid;
234 			return (0);
235 		}
236 	return (-1);
237 }
238