1 /* 2 * Copyright (c) 1982, 1986 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)kern_prot.c 7.5 (Berkeley) 04/26/89 7 */ 8 9 /* 10 * System calls related to processes and protection 11 */ 12 13 #include "param.h" 14 #include "systm.h" 15 #include "dir.h" 16 #include "user.h" 17 #include "inode.h" 18 #include "proc.h" 19 #include "timeb.h" 20 #include "times.h" 21 #include "reboot.h" 22 #include "fs.h" 23 #include "buf.h" 24 #include "mount.h" 25 #include "quota.h" 26 27 #include "machine/reg.h" 28 29 getpid() 30 { 31 32 u.u_r.r_val1 = u.u_procp->p_pid; 33 u.u_r.r_val2 = u.u_procp->p_ppid; 34 } 35 36 getpgrp() 37 { 38 register struct a { 39 int pid; 40 } *uap = (struct a *)u.u_ap; 41 register struct proc *p; 42 43 if (uap->pid == 0) 44 p = u.u_procp; 45 else if ((p = pfind(uap->pid)) == 0) { 46 u.u_error = ESRCH; 47 return; 48 } 49 u.u_r.r_val1 = p->p_pgrp->pg_id; 50 } 51 52 getuid() 53 { 54 55 u.u_r.r_val1 = u.u_ruid; 56 u.u_r.r_val2 = u.u_uid; 57 } 58 59 getgid() 60 { 61 62 u.u_r.r_val1 = u.u_rgid; 63 u.u_r.r_val2 = u.u_gid; 64 } 65 66 getgroups() 67 { 68 register struct a { 69 u_int gidsetsize; 70 int *gidset; 71 } *uap = (struct a *)u.u_ap; 72 register gid_t *gp; 73 register int *lp; 74 int groups[NGROUPS]; 75 76 for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--) 77 if (gp[-1] != NOGROUP) 78 break; 79 if (uap->gidsetsize < gp - u.u_groups) { 80 u.u_error = EINVAL; 81 return; 82 } 83 uap->gidsetsize = gp - u.u_groups; 84 for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 85 *lp++ = *gp++; 86 u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset, 87 uap->gidsetsize * sizeof (groups[0])); 88 if (u.u_error) 89 return; 90 u.u_r.r_val1 = uap->gidsetsize; 91 } 92 93 setsid() 94 { 95 register struct proc *p = u.u_procp; 96 97 if ((p->p_pgid == p->p_pid) || pgfind(p->p_pid)) 98 u.u_error = EPERM; 99 else { 100 pgmv(p, p->p_pid, 1); 101 u.u_r.r_val1 = p->p_pid; 102 } 103 return; 104 } 105 106 /* 107 * set process group 108 * 109 * if target pid != caller's pid 110 * pid must be an inferior 111 * pid must be in same session 112 * pid can't have done an exec 113 * there must exist a pid with pgid in same session 114 * pid must not be session leader 115 */ 116 setpgrp() 117 { 118 register struct a { 119 int pid; 120 int pgid; 121 } *uap = (struct a *)u.u_ap; 122 register struct proc *p; 123 register struct pgrp *pgrp; 124 125 if (uap->pid == 0) 126 p = u.u_procp; 127 else if ((p = pfind(uap->pid)) == 0 || !inferior(p)) { 128 u.u_error = ESRCH; 129 return; 130 } 131 else if (p != u.u_procp) { 132 if (p->p_session != u.u_procp->p_session) { 133 u.u_error = EPERM; 134 return; 135 } 136 if (p->p_flag&SEXEC) { 137 u.u_error = EACCES; 138 return; 139 } 140 } 141 if (SESS_LEADER(p)) { 142 u.u_error = EPERM; 143 return; 144 } 145 if (uap->pgid == 0) 146 uap->pgid = p->p_pid; 147 else if ((uap->pgid != p->p_pid) && 148 (((pgrp = pgfind(uap->pgid)) == 0) || 149 pgrp->pg_mem == NULL || 150 pgrp->pg_session != u.u_procp->p_session)) { 151 u.u_error = EPERM; 152 return; 153 } 154 /* 155 * done checking, now doit 156 */ 157 pgmv(p, uap->pgid, 0); 158 } 159 160 setreuid() 161 { 162 struct a { 163 int ruid; 164 int euid; 165 } *uap; 166 register int ruid, euid; 167 168 uap = (struct a *)u.u_ap; 169 ruid = uap->ruid; 170 if (ruid == -1) 171 ruid = u.u_ruid; 172 if (u.u_ruid != ruid && u.u_uid != ruid && 173 (u.u_error = suser(u.u_cred, &u.u_acflag))) 174 return; 175 euid = uap->euid; 176 if (euid == -1) 177 euid = u.u_uid; 178 if (u.u_ruid != euid && u.u_uid != euid && 179 (u.u_error = suser(u.u_cred, &u.u_acflag))) 180 return; 181 /* 182 * Everything's okay, do it. 183 */ 184 #ifdef QUOTA 185 if (u.u_quota->q_uid != ruid) { 186 qclean(); 187 qstart(getquota((uid_t)ruid, 0, 0)); 188 } 189 #endif 190 u.u_procp->p_uid = euid; 191 u.u_ruid = ruid; 192 u.u_uid = euid; 193 } 194 195 setregid() 196 { 197 register struct a { 198 int rgid; 199 int egid; 200 } *uap; 201 register int rgid, egid; 202 203 uap = (struct a *)u.u_ap; 204 rgid = uap->rgid; 205 if (rgid == -1) 206 rgid = u.u_rgid; 207 if (u.u_rgid != rgid && u.u_gid != rgid && 208 (u.u_error = suser(u.u_cred, &u.u_acflag))) 209 return; 210 egid = uap->egid; 211 if (egid == -1) 212 egid = u.u_gid; 213 if (u.u_rgid != egid && u.u_gid != egid && 214 (u.u_error = suser(u.u_cred, &u.u_acflag))) 215 return; 216 if (u.u_rgid != rgid) { 217 leavegroup(u.u_rgid); 218 (void) entergroup((gid_t)rgid); 219 u.u_rgid = rgid; 220 } 221 u.u_gid = egid; 222 } 223 224 setgroups() 225 { 226 register struct a { 227 u_int gidsetsize; 228 int *gidset; 229 } *uap = (struct a *)u.u_ap; 230 register gid_t *gp; 231 register int *lp; 232 int groups[NGROUPS]; 233 234 if (u.u_error = suser(u.u_cred, &u.u_acflag)) 235 return; 236 if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 237 u.u_error = EINVAL; 238 return; 239 } 240 u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups, 241 uap->gidsetsize * sizeof (groups[0])); 242 if (u.u_error) 243 return; 244 for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 245 *gp++ = *lp++; 246 for ( ; gp < &u.u_groups[NGROUPS]; gp++) 247 *gp = NOGROUP; 248 } 249 250 /* 251 * Group utility functions. 252 */ 253 254 /* 255 * Delete gid from the group set. 256 */ 257 leavegroup(gid) 258 gid_t gid; 259 { 260 register gid_t *gp; 261 262 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 263 if (*gp == gid) 264 goto found; 265 return; 266 found: 267 for (; gp < &u.u_groups[NGROUPS-1]; gp++) 268 *gp = *(gp+1); 269 *gp = NOGROUP; 270 } 271 272 /* 273 * Add gid to the group set. 274 */ 275 entergroup(gid) 276 gid_t gid; 277 { 278 register gid_t *gp; 279 280 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) { 281 if (*gp == gid) 282 return (0); 283 if (*gp == NOGROUP) { 284 *gp = gid; 285 return (0); 286 } 287 } 288 return (-1); 289 } 290 291 /* 292 * Check if gid is a member of the group set. 293 */ 294 groupmember(gid) 295 gid_t gid; 296 { 297 register gid_t *gp; 298 299 if (u.u_gid == gid) 300 return (1); 301 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) 302 if (*gp == gid) 303 return (1); 304 return (0); 305 } 306 307 /* 308 * Get login name of process owner, if available 309 */ 310 311 getlogname() 312 { 313 struct a { 314 char *namebuf; 315 u_int namelen; 316 } *uap = (struct a *)u.u_ap; 317 318 if (uap->namelen > sizeof (u.u_logname)) 319 uap->namelen = sizeof (u.u_logname); 320 u.u_error = copyout((caddr_t)u.u_logname, (caddr_t)uap->namebuf, 321 uap->namelen); 322 } 323 324 /* 325 * Set login name of process owner 326 */ 327 328 setlogname() 329 { 330 struct a { 331 char *namebuf; 332 u_int namelen; 333 } *uap = (struct a *)u.u_ap; 334 335 if (u.u_error = suser(u.u_cred, &u.u_acflag)) 336 return; 337 if (uap->namelen > sizeof (u.u_logname) - 1) 338 u.u_error = EINVAL; 339 else 340 u.u_error = copyin((caddr_t)uap->namebuf, 341 (caddr_t)u.u_logname, uap->namelen); 342 } 343