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.2 (Berkeley) 10/18/88 7 */ 8 9 /* 10 * System calls related to processes and protection 11 */ 12 13 #include "../machine/reg.h" 14 15 #include "param.h" 16 #include "systm.h" 17 #include "dir.h" 18 #include "user.h" 19 #include "inode.h" 20 #include "proc.h" 21 #include "timeb.h" 22 #include "times.h" 23 #include "reboot.h" 24 #include "fs.h" 25 #include "buf.h" 26 #include "mount.h" 27 #include "quota.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 && !suser()) 173 return; 174 euid = uap->euid; 175 if (euid == -1) 176 euid = u.u_uid; 177 if (u.u_ruid != euid && u.u_uid != euid && !suser()) 178 return; 179 /* 180 * Everything's okay, do it. 181 */ 182 #ifdef QUOTA 183 if (u.u_quota->q_uid != ruid) { 184 qclean(); 185 qstart(getquota((uid_t)ruid, 0, 0)); 186 } 187 #endif 188 u.u_procp->p_uid = euid; 189 u.u_ruid = ruid; 190 u.u_uid = euid; 191 } 192 193 setregid() 194 { 195 register struct a { 196 int rgid; 197 int egid; 198 } *uap; 199 register int rgid, egid; 200 201 uap = (struct a *)u.u_ap; 202 rgid = uap->rgid; 203 if (rgid == -1) 204 rgid = u.u_rgid; 205 if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) 206 return; 207 egid = uap->egid; 208 if (egid == -1) 209 egid = u.u_gid; 210 if (u.u_rgid != egid && u.u_gid != egid && !suser()) 211 return; 212 if (u.u_rgid != rgid) { 213 leavegroup(u.u_rgid); 214 (void) entergroup((gid_t)rgid); 215 u.u_rgid = rgid; 216 } 217 u.u_gid = egid; 218 } 219 220 setgroups() 221 { 222 register struct a { 223 u_int gidsetsize; 224 int *gidset; 225 } *uap = (struct a *)u.u_ap; 226 register gid_t *gp; 227 register int *lp; 228 int groups[NGROUPS]; 229 230 if (!suser()) 231 return; 232 if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 233 u.u_error = EINVAL; 234 return; 235 } 236 u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups, 237 uap->gidsetsize * sizeof (groups[0])); 238 if (u.u_error) 239 return; 240 for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 241 *gp++ = *lp++; 242 for ( ; gp < &u.u_groups[NGROUPS]; gp++) 243 *gp = NOGROUP; 244 } 245 246 /* 247 * Group utility functions. 248 */ 249 250 /* 251 * Delete gid from the group set. 252 */ 253 leavegroup(gid) 254 gid_t gid; 255 { 256 register gid_t *gp; 257 258 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 259 if (*gp == gid) 260 goto found; 261 return; 262 found: 263 for (; gp < &u.u_groups[NGROUPS-1]; gp++) 264 *gp = *(gp+1); 265 *gp = NOGROUP; 266 } 267 268 /* 269 * Add gid to the group set. 270 */ 271 entergroup(gid) 272 gid_t gid; 273 { 274 register gid_t *gp; 275 276 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) { 277 if (*gp == gid) 278 return (0); 279 if (*gp == NOGROUP) { 280 *gp = gid; 281 return (0); 282 } 283 } 284 return (-1); 285 } 286 287 /* 288 * Check if gid is a member of the group set. 289 */ 290 groupmember(gid) 291 gid_t gid; 292 { 293 register gid_t *gp; 294 295 if (u.u_gid == gid) 296 return (1); 297 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) 298 if (*gp == gid) 299 return (1); 300 return (0); 301 } 302