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