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