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