1 /* kern_prot.c 5.14 82/12/28 */ 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 u.u_error = copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset, 79 uap->gidsetsize * sizeof (u.u_groups[0])); 80 if (u.u_error) 81 return; 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 u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups, 229 uap->gidsetsize * sizeof (u.u_groups[0])); 230 if (u.u_error) 231 return; 232 for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++) 233 *gp = -1; 234 } 235 236 /* 237 * Pid of zero implies current process. 238 * Pgrp -1 is getpgrp system call returning 239 * current process group. 240 */ 241 osetpgrp() 242 { 243 register struct proc *p; 244 register struct a { 245 int pid; 246 int pgrp; 247 } *uap; 248 249 uap = (struct a *)u.u_ap; 250 if (uap->pid == 0) 251 p = u.u_procp; 252 else { 253 p = pfind(uap->pid); 254 if (p == 0) { 255 u.u_error = ESRCH; 256 return; 257 } 258 } 259 if (uap->pgrp <= 0) { 260 u.u_r.r_val1 = p->p_pgrp; 261 return; 262 } 263 if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 264 u.u_error = EPERM; 265 return; 266 } 267 p->p_pgrp = uap->pgrp; 268 } 269 /* END DEFUNCT */ 270 271 leavegroup(gid) 272 int gid; 273 { 274 register int *gp; 275 276 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 277 if (*gp == gid) 278 goto found; 279 return; 280 found: 281 for (; gp < &u.u_groups[NGROUPS-1]; gp++) 282 *gp = *(gp+1); 283 *gp = -1; 284 } 285 286 entergroup(gid) 287 int gid; 288 { 289 register int *gp; 290 291 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 292 if (*gp == gid) 293 return (0); 294 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 295 if (*gp < 0) { 296 *gp = gid; 297 return (0); 298 } 299 return (-1); 300 } 301