1 /* kern_prot.c 5.13 82/12/17 */ 2 3 /* 4 * System calls related to processes and protection 5 */ 6 7 #include "../machine/reg.h" 8 9 #include "../h/param.h" 10 #include "../h/systm.h" 11 #include "../h/dir.h" 12 #include "../h/user.h" 13 #include "../h/inode.h" 14 #include "../h/proc.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 u_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 setreuid() 110 { 111 struct a { 112 int ruid; 113 int euid; 114 } *uap; 115 register int ruid, euid; 116 117 uap = (struct a *)u.u_ap; 118 ruid = uap->ruid; 119 if (ruid == -1) 120 ruid = u.u_ruid; 121 if (u.u_ruid != ruid && u.u_uid != ruid && !suser()) 122 return; 123 euid = uap->euid; 124 if (euid == -1) 125 euid = u.u_uid; 126 if (u.u_ruid != euid && u.u_uid != euid && !suser()) 127 return; 128 /* 129 * Everything's okay, do it. 130 */ 131 #ifdef QUOTA 132 if (u.u_quota->q_uid != ruid) { 133 qclean(); 134 qstart(getquota(ruid, 0, 0)); 135 } 136 #endif 137 u.u_procp->p_uid = ruid; 138 u.u_ruid = ruid; 139 u.u_uid = euid; 140 } 141 142 #ifndef NOCOMPAT 143 osetuid() 144 { 145 register uid; 146 register struct a { 147 int uid; 148 } *uap; 149 150 uap = (struct a *)u.u_ap; 151 uid = uap->uid; 152 if (u.u_ruid == uid || u.u_uid == uid || suser()) { 153 #ifdef QUOTA 154 if (u.u_quota->q_uid != uid) { 155 qclean(); 156 qstart(getquota(uid, 0, 0)); 157 } 158 #endif 159 u.u_uid = uid; 160 u.u_procp->p_uid = uid; 161 u.u_ruid = uid; 162 } 163 } 164 #endif 165 166 setregid() 167 { 168 register struct a { 169 int rgid; 170 int egid; 171 } *uap; 172 register int rgid, egid; 173 174 uap = (struct a *)u.u_ap; 175 rgid = uap->rgid; 176 if (rgid == -1) 177 rgid = u.u_rgid; 178 if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) 179 return; 180 egid = uap->egid; 181 if (egid == -1) 182 egid = u.u_gid; 183 if (u.u_rgid != egid && u.u_gid != egid && !suser()) 184 return; 185 if (u.u_rgid != rgid) { 186 leavegroup(u.u_rgid); 187 (void) entergroup(u.u_rgid); 188 u.u_rgid = rgid; 189 } 190 if (u.u_gid != egid) { 191 leavegroup(u.u_gid); 192 (void) entergroup(egid); 193 u.u_gid = egid; 194 } 195 } 196 197 #ifndef NOCOMPAT 198 osetgid() 199 { 200 register gid; 201 register struct a { 202 int gid; 203 } *uap; 204 205 uap = (struct a *)u.u_ap; 206 gid = uap->gid; 207 if (u.u_rgid == gid || u.u_gid == gid || suser()) { 208 leavegroup(u.u_gid); leavegroup(u.u_rgid); 209 (void) entergroup(gid); 210 u.u_gid = gid; 211 u.u_rgid = gid; 212 } 213 } 214 215 setgroups() 216 { 217 register struct a { 218 u_int gidsetsize; 219 int *gidset; 220 } *uap = (struct a *)u.u_ap; 221 register int *gp; 222 223 if (!suser()) 224 return; 225 if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 226 u.u_error = EINVAL; 227 return; 228 } 229 if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups, 230 uap->gidsetsize * sizeof (u.u_groups[0]))) { 231 u.u_error = EFAULT; 232 return; 233 } 234 for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++) 235 *gp = -1; 236 } 237 238 /* 239 * Pid of zero implies current process. 240 * Pgrp -1 is getpgrp system call returning 241 * current process group. 242 */ 243 osetpgrp() 244 { 245 register struct proc *p; 246 register struct a { 247 int pid; 248 int pgrp; 249 } *uap; 250 251 uap = (struct a *)u.u_ap; 252 if (uap->pid == 0) 253 p = u.u_procp; 254 else { 255 p = pfind(uap->pid); 256 if (p == 0) { 257 u.u_error = ESRCH; 258 return; 259 } 260 } 261 if (uap->pgrp <= 0) { 262 u.u_r.r_val1 = p->p_pgrp; 263 return; 264 } 265 if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 266 u.u_error = EPERM; 267 return; 268 } 269 p->p_pgrp = uap->pgrp; 270 } 271 /* END DEFUNCT */ 272 273 leavegroup(gid) 274 int gid; 275 { 276 register int *gp; 277 278 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 279 if (*gp == gid) 280 goto found; 281 return; 282 found: 283 for (; gp < &u.u_groups[NGROUPS-1]; gp++) 284 *gp = *(gp+1); 285 *gp = -1; 286 } 287 288 entergroup(gid) 289 int gid; 290 { 291 register int *gp; 292 293 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 294 if (*gp == gid) 295 return (0); 296 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 297 if (*gp < 0) { 298 *gp = gid; 299 return (0); 300 } 301 return (-1); 302 } 303