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