1 /* kern_prot.c 5.7 82/09/12 */ 2 3 /* 4 * System calls related to processes and protection 5 */ 6 7 #include "../h/param.h" 8 #include "../h/systm.h" 9 #include "../h/dir.h" 10 #include "../h/user.h" 11 #include "../h/reg.h" 12 #include "../h/inode.h" 13 #include "../h/proc.h" 14 #include "../h/mtpr.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 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 if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset, 79 uap->gidsetsize * sizeof (u.u_groups[0]))) { 80 u.u_error = EFAULT; 81 return; 82 } 83 u.u_r.r_val1 = uap->gidsetsize; 84 } 85 86 setpgrp() 87 { 88 register struct proc *p; 89 register struct a { 90 int pid; 91 int pgrp; 92 } *uap = (struct a *)u.u_ap; 93 94 if (uap->pid == 0) 95 uap->pid = u.u_procp->p_pid; 96 p = pfind(uap->pid); 97 if (p == 0) { 98 u.u_error = ESRCH; 99 return; 100 } 101 /* need better control mechanisms for process groups */ 102 if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 103 u.u_error = EPERM; 104 return; 105 } 106 p->p_pgrp = uap->pgrp; 107 } 108 109 setuid() 110 { 111 register uid; 112 register struct a { 113 int uid; 114 } *uap; 115 116 uap = (struct a *)u.u_ap; 117 uid = uap->uid; 118 if (u.u_ruid == uid || u.u_uid == uid || suser()) { 119 #ifdef QUOTA 120 if (u.u_quota->q_uid != uid) { 121 qclean(); 122 qstart(getquota(uid, 0, 0)); 123 } 124 #endif 125 u.u_uid = uid; 126 u.u_procp->p_uid = uid; 127 u.u_ruid = uid; 128 } 129 } 130 131 setgid() 132 { 133 register gid; 134 register struct a { 135 int gid; 136 } *uap; 137 138 uap = (struct a *)u.u_ap; 139 gid = uap->gid; 140 if (u.u_rgid == gid || u.u_gid == gid || suser()) { 141 leavegroup(u.u_gid); leavegroup(u.u_rgid); 142 (void) entergroup(gid); 143 u.u_gid = gid; 144 u.u_rgid = gid; 145 } 146 } 147 148 setgroups() 149 { 150 register struct a { 151 int gidsetsize; 152 int *gidset; 153 } *uap = (struct a *)u.u_ap; 154 register int *gp; 155 156 if (!suser()) 157 return; 158 if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 159 u.u_error = EINVAL; 160 return; 161 } 162 if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups, 163 uap->gidsetsize * sizeof (u.u_groups[0]))) { 164 u.u_error = EFAULT; 165 return; 166 } 167 for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++) 168 *gp = -1; 169 } 170 171 /* 172 * Pid of zero implies current process. 173 * Pgrp -1 is getpgrp system call returning 174 * current process group. 175 */ 176 osetpgrp() 177 { 178 register struct proc *p; 179 register struct a { 180 int pid; 181 int pgrp; 182 } *uap; 183 184 uap = (struct a *)u.u_ap; 185 if (uap->pid == 0) 186 p = u.u_procp; 187 else { 188 p = pfind(uap->pid); 189 if (p == 0) { 190 u.u_error = ESRCH; 191 return; 192 } 193 } 194 if (uap->pgrp <= 0) { 195 u.u_r.r_val1 = p->p_pgrp; 196 return; 197 } 198 if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 199 u.u_error = EPERM; 200 return; 201 } 202 p->p_pgrp = uap->pgrp; 203 } 204 /* END DEFUNCT */ 205 206 leavegroup(gid) 207 int gid; 208 { 209 register int *gp; 210 211 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 212 if (*gp == gid) 213 goto found; 214 return; 215 found: 216 for (; gp < &u.u_groups[NGROUPS-1]; gp++) 217 *gp = *(gp+1); 218 *gp = -1; 219 } 220 221 entergroup(gid) 222 int gid; 223 { 224 register int *gp; 225 226 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 227 if (*gp == gid) 228 return (0); 229 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 230 if (*gp < 0) { 231 *gp = gid; 232 return (0); 233 } 234 return (-1); 235 } 236