1 /* kern_prot.c 5.16 83/03/31 */ 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(rgid); 187 u.u_rgid = rgid; 188 } 189 u.u_gid = egid; 190 } 191 192 #ifndef NOCOMPAT 193 osetgid() 194 { 195 register gid; 196 register struct a { 197 int gid; 198 } *uap; 199 200 uap = (struct a *)u.u_ap; 201 gid = uap->gid; 202 if (u.u_rgid == gid || u.u_gid == gid || suser()) { 203 leavegroup(u.u_rgid); 204 (void) entergroup(gid); 205 u.u_gid = gid; 206 u.u_rgid = gid; 207 } 208 } 209 210 setgroups() 211 { 212 register struct a { 213 u_int gidsetsize; 214 int *gidset; 215 } *uap = (struct a *)u.u_ap; 216 register int *gp; 217 218 if (!suser()) 219 return; 220 if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 221 u.u_error = EINVAL; 222 return; 223 } 224 u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups, 225 uap->gidsetsize * sizeof (u.u_groups[0])); 226 if (u.u_error) 227 return; 228 for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++) 229 *gp = NOGROUP; 230 } 231 232 /* 233 * Pid of zero implies current process. 234 * Pgrp -1 is getpgrp system call returning 235 * current process group. 236 */ 237 osetpgrp() 238 { 239 register struct proc *p; 240 register struct a { 241 int pid; 242 int pgrp; 243 } *uap; 244 245 uap = (struct a *)u.u_ap; 246 if (uap->pid == 0) 247 p = u.u_procp; 248 else { 249 p = pfind(uap->pid); 250 if (p == 0) { 251 u.u_error = ESRCH; 252 return; 253 } 254 } 255 if (uap->pgrp <= 0) { 256 u.u_r.r_val1 = p->p_pgrp; 257 return; 258 } 259 if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 260 u.u_error = EPERM; 261 return; 262 } 263 p->p_pgrp = uap->pgrp; 264 } 265 /* END DEFUNCT */ 266 267 /* 268 * Group utility functions. 269 */ 270 271 /* 272 * Delete gid from the group set. 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 = NOGROUP; 287 } 288 289 /* 290 * Add gid to the group set. 291 */ 292 entergroup(gid) 293 int gid; 294 { 295 register int *gp; 296 297 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 298 if (*gp == gid) 299 return (0); 300 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 301 if (*gp < 0) { 302 *gp = gid; 303 return (0); 304 } 305 return (-1); 306 } 307 308 /* 309 * Check if gid is a member of the group set. 310 */ 311 groupmember(gid) 312 int gid; 313 { 314 register int *gp; 315 316 if (u.u_gid == gid) 317 return (1); 318 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) 319 if (*gp == gid) 320 return (1); 321 return (0); 322 } 323