1 /* kern_prot.c 6.4 85/03/19 */ 2 3 /* 4 * System calls related to processes and protection 5 */ 6 7 #include "../machine/reg.h" 8 9 #include "param.h" 10 #include "systm.h" 11 #include "dir.h" 12 #include "user.h" 13 #include "inode.h" 14 #include "proc.h" 15 #include "timeb.h" 16 #include "times.h" 17 #include "reboot.h" 18 #include "fs.h" 19 #include "buf.h" 20 #include "mount.h" 21 #include "quota.h" 22 23 getpid() 24 { 25 26 u.u_r.r_val1 = u.u_procp->p_pid; 27 u.u_r.r_val2 = u.u_procp->p_ppid; 28 } 29 30 getpgrp() 31 { 32 register struct a { 33 int pid; 34 } *uap = (struct a *)u.u_ap; 35 register struct proc *p; 36 37 if (uap->pid == 0) 38 uap->pid = u.u_procp->p_pid; 39 p = pfind(uap->pid); 40 if (p == 0) { 41 u.u_error = ESRCH; 42 return; 43 } 44 u.u_r.r_val1 = p->p_pgrp; 45 } 46 47 getuid() 48 { 49 50 u.u_r.r_val1 = u.u_ruid; 51 u.u_r.r_val2 = u.u_uid; 52 } 53 54 getgid() 55 { 56 57 u.u_r.r_val1 = u.u_rgid; 58 u.u_r.r_val2 = u.u_gid; 59 } 60 61 getgroups() 62 { 63 register struct a { 64 u_int gidsetsize; 65 int *gidset; 66 } *uap = (struct a *)u.u_ap; 67 register gid_t *gp; 68 register int *lp; 69 int groups[NGROUPS]; 70 71 for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--) 72 if (gp[-1] != NOGROUP) 73 break; 74 if (uap->gidsetsize < gp - u.u_groups) { 75 u.u_error = EINVAL; 76 return; 77 } 78 uap->gidsetsize = gp - u.u_groups; 79 for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 80 *lp++ = *gp++; 81 u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset, 82 uap->gidsetsize * sizeof (groups[0])); 83 if (u.u_error) 84 return; 85 u.u_r.r_val1 = uap->gidsetsize; 86 } 87 88 setpgrp() 89 { 90 register struct proc *p; 91 register struct a { 92 int pid; 93 int pgrp; 94 } *uap = (struct a *)u.u_ap; 95 96 if (uap->pid == 0) 97 uap->pid = u.u_procp->p_pid; 98 p = pfind(uap->pid); 99 if (p == 0) { 100 u.u_error = ESRCH; 101 return; 102 } 103 /* need better control mechanisms for process groups */ 104 if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 105 u.u_error = EPERM; 106 return; 107 } 108 p->p_pgrp = uap->pgrp; 109 } 110 111 setreuid() 112 { 113 struct a { 114 int ruid; 115 int euid; 116 } *uap; 117 register int ruid, euid; 118 119 uap = (struct a *)u.u_ap; 120 ruid = uap->ruid; 121 if (ruid == -1) 122 ruid = u.u_ruid; 123 if (u.u_ruid != ruid && u.u_uid != ruid && !suser()) 124 return; 125 euid = uap->euid; 126 if (euid == -1) 127 euid = u.u_uid; 128 if (u.u_ruid != euid && u.u_uid != euid && !suser()) 129 return; 130 /* 131 * Everything's okay, do it. 132 */ 133 #ifdef QUOTA 134 if (u.u_quota->q_uid != ruid) { 135 qclean(); 136 qstart(getquota(ruid, 0, 0)); 137 } 138 #endif 139 u.u_procp->p_uid = ruid; 140 u.u_ruid = ruid; 141 u.u_uid = euid; 142 } 143 144 setregid() 145 { 146 register struct a { 147 int rgid; 148 int egid; 149 } *uap; 150 register int rgid, egid; 151 152 uap = (struct a *)u.u_ap; 153 rgid = uap->rgid; 154 if (rgid == -1) 155 rgid = u.u_rgid; 156 if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) 157 return; 158 egid = uap->egid; 159 if (egid == -1) 160 egid = u.u_gid; 161 if (u.u_rgid != egid && u.u_gid != egid && !suser()) 162 return; 163 if (u.u_rgid != rgid) { 164 leavegroup(u.u_rgid); 165 (void) entergroup(rgid); 166 u.u_rgid = rgid; 167 } 168 u.u_gid = egid; 169 } 170 171 setgroups() 172 { 173 register struct a { 174 u_int gidsetsize; 175 int *gidset; 176 } *uap = (struct a *)u.u_ap; 177 register gid_t *gp; 178 register int *lp; 179 int groups[NGROUPS]; 180 181 if (!suser()) 182 return; 183 if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 184 u.u_error = EINVAL; 185 return; 186 } 187 u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups, 188 uap->gidsetsize * sizeof (groups[0])); 189 if (u.u_error) 190 return; 191 for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 192 *gp++ = *lp++; 193 for ( ; gp < &u.u_groups[NGROUPS]; gp++) 194 *gp = NOGROUP; 195 } 196 197 /* 198 * Group utility functions. 199 */ 200 201 /* 202 * Delete gid from the group set. 203 */ 204 leavegroup(gid) 205 int gid; 206 { 207 register gid_t *gp; 208 209 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 210 if (*gp == gid) 211 goto found; 212 return; 213 found: 214 for (; gp < &u.u_groups[NGROUPS-1]; gp++) 215 *gp = *(gp+1); 216 *gp = NOGROUP; 217 } 218 219 /* 220 * Add gid to the group set. 221 */ 222 entergroup(gid) 223 int gid; 224 { 225 register gid_t *gp; 226 227 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) { 228 if (*gp == gid) 229 return (0); 230 if (*gp == NOGROUP) { 231 *gp = gid; 232 return (0); 233 } 234 } 235 return (-1); 236 } 237 238 /* 239 * Check if gid is a member of the group set. 240 */ 241 groupmember(gid) 242 gid_t gid; 243 { 244 register gid_t *gp; 245 246 if (u.u_gid == gid) 247 return (1); 248 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) 249 if (*gp == gid) 250 return (1); 251 return (0); 252 } 253