1 /* 2 * Copyright (c) 1982 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 6.7 (Berkeley) 02/20/86 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 uap->pid = u.u_procp->p_pid; 45 p = pfind(uap->pid); 46 if (p == 0) { 47 u.u_error = ESRCH; 48 return; 49 } 50 u.u_r.r_val1 = p->p_pgrp; 51 } 52 53 getuid() 54 { 55 56 u.u_r.r_val1 = u.u_ruid; 57 u.u_r.r_val2 = u.u_uid; 58 } 59 60 getgid() 61 { 62 63 u.u_r.r_val1 = u.u_rgid; 64 u.u_r.r_val2 = u.u_gid; 65 } 66 67 getgroups() 68 { 69 register struct a { 70 u_int gidsetsize; 71 int *gidset; 72 } *uap = (struct a *)u.u_ap; 73 register gid_t *gp; 74 register int *lp; 75 int groups[NGROUPS]; 76 77 for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--) 78 if (gp[-1] != NOGROUP) 79 break; 80 if (uap->gidsetsize < gp - u.u_groups) { 81 u.u_error = EINVAL; 82 return; 83 } 84 uap->gidsetsize = gp - u.u_groups; 85 for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 86 *lp++ = *gp++; 87 u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset, 88 uap->gidsetsize * sizeof (groups[0])); 89 if (u.u_error) 90 return; 91 u.u_r.r_val1 = uap->gidsetsize; 92 } 93 94 setpgrp() 95 { 96 register struct proc *p; 97 register struct a { 98 int pid; 99 int pgrp; 100 } *uap = (struct a *)u.u_ap; 101 102 if (uap->pid == 0) 103 uap->pid = u.u_procp->p_pid; 104 p = pfind(uap->pid); 105 if (p == 0) { 106 u.u_error = ESRCH; 107 return; 108 } 109 /* need better control mechanisms for process groups */ 110 if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 111 u.u_error = EPERM; 112 return; 113 } 114 p->p_pgrp = uap->pgrp; 115 } 116 117 setreuid() 118 { 119 struct a { 120 int ruid; 121 int euid; 122 } *uap; 123 register int ruid, euid; 124 125 uap = (struct a *)u.u_ap; 126 ruid = uap->ruid; 127 if (ruid == -1) 128 ruid = u.u_ruid; 129 if (u.u_ruid != ruid && u.u_uid != ruid && !suser()) 130 return; 131 euid = uap->euid; 132 if (euid == -1) 133 euid = u.u_uid; 134 if (u.u_ruid != euid && u.u_uid != euid && !suser()) 135 return; 136 /* 137 * Everything's okay, do it. 138 */ 139 #ifdef QUOTA 140 if (u.u_quota->q_uid != ruid) { 141 qclean(); 142 qstart(getquota(ruid, 0, 0)); 143 } 144 #endif 145 u.u_procp->p_uid = euid; 146 u.u_ruid = ruid; 147 u.u_uid = euid; 148 } 149 150 setregid() 151 { 152 register struct a { 153 int rgid; 154 int egid; 155 } *uap; 156 register int rgid, egid; 157 158 uap = (struct a *)u.u_ap; 159 rgid = uap->rgid; 160 if (rgid == -1) 161 rgid = u.u_rgid; 162 if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) 163 return; 164 egid = uap->egid; 165 if (egid == -1) 166 egid = u.u_gid; 167 if (u.u_rgid != egid && u.u_gid != egid && !suser()) 168 return; 169 if (u.u_rgid != rgid) { 170 leavegroup(u.u_rgid); 171 (void) entergroup((gid_t)rgid); 172 u.u_rgid = rgid; 173 } 174 u.u_gid = egid; 175 } 176 177 setgroups() 178 { 179 register struct a { 180 u_int gidsetsize; 181 int *gidset; 182 } *uap = (struct a *)u.u_ap; 183 register gid_t *gp; 184 register int *lp; 185 int groups[NGROUPS]; 186 187 if (!suser()) 188 return; 189 if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 190 u.u_error = EINVAL; 191 return; 192 } 193 u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups, 194 uap->gidsetsize * sizeof (groups[0])); 195 if (u.u_error) 196 return; 197 for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 198 *gp++ = *lp++; 199 for ( ; gp < &u.u_groups[NGROUPS]; gp++) 200 *gp = NOGROUP; 201 } 202 203 /* 204 * Group utility functions. 205 */ 206 207 /* 208 * Delete gid from the group set. 209 */ 210 leavegroup(gid) 211 gid_t gid; 212 { 213 register gid_t *gp; 214 215 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 216 if (*gp == gid) 217 goto found; 218 return; 219 found: 220 for (; gp < &u.u_groups[NGROUPS-1]; gp++) 221 *gp = *(gp+1); 222 *gp = NOGROUP; 223 } 224 225 /* 226 * Add gid to the group set. 227 */ 228 entergroup(gid) 229 gid_t gid; 230 { 231 register gid_t *gp; 232 233 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) { 234 if (*gp == gid) 235 return (0); 236 if (*gp == NOGROUP) { 237 *gp = gid; 238 return (0); 239 } 240 } 241 return (-1); 242 } 243 244 /* 245 * Check if gid is a member of the group set. 246 */ 247 groupmember(gid) 248 gid_t gid; 249 { 250 register gid_t *gp; 251 252 if (u.u_gid == gid) 253 return (1); 254 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) 255 if (*gp == gid) 256 return (1); 257 return (0); 258 } 259