1*9160Ssam /* kern_prot.c 5.11 82/11/13 */ 27420Sroot 37420Sroot /* 47498Sroot * System calls related to processes and protection 57420Sroot */ 67420Sroot 77420Sroot #include "../h/param.h" 87420Sroot #include "../h/systm.h" 97420Sroot #include "../h/dir.h" 107420Sroot #include "../h/user.h" 117420Sroot #include "../h/reg.h" 127420Sroot #include "../h/inode.h" 137420Sroot #include "../h/proc.h" 147420Sroot #include "../h/timeb.h" 157420Sroot #include "../h/times.h" 167420Sroot #include "../h/reboot.h" 177420Sroot #include "../h/fs.h" 187420Sroot #include "../h/conf.h" 197420Sroot #include "../h/buf.h" 207420Sroot #include "../h/mount.h" 217489Skre #include "../h/quota.h" 227420Sroot 237498Sroot getpid() 247498Sroot { 257498Sroot 267498Sroot u.u_r.r_val1 = u.u_procp->p_pid; 277498Sroot u.u_r.r_val2 = u.u_procp->p_ppid; 287498Sroot } 297498Sroot 307498Sroot getpgrp() 317498Sroot { 327498Sroot register struct a { 337498Sroot int pid; 347498Sroot } *uap = (struct a *)u.u_ap; 357498Sroot register struct proc *p; 367498Sroot 377498Sroot if (uap->pid == 0) 387498Sroot uap->pid = u.u_procp->p_pid; 397498Sroot p = pfind(uap->pid); 407498Sroot if (p == 0) { 417498Sroot u.u_error = ESRCH; 427498Sroot return; 437498Sroot } 447498Sroot u.u_r.r_val1 = p->p_pgrp; 457498Sroot } 467498Sroot 477420Sroot getuid() 487420Sroot { 497420Sroot 507420Sroot u.u_r.r_val1 = u.u_ruid; 517420Sroot u.u_r.r_val2 = u.u_uid; 527420Sroot } 537420Sroot 547498Sroot getgid() 557498Sroot { 567498Sroot 577498Sroot u.u_r.r_val1 = u.u_rgid; 587498Sroot u.u_r.r_val2 = u.u_gid; 597498Sroot } 607498Sroot 617866Sroot getgroups() 627498Sroot { 637498Sroot register struct a { 648624Sroot u_int gidsetsize; 657498Sroot int *gidset; 667498Sroot } *uap = (struct a *)u.u_ap; 677866Sroot register int *gp; 687498Sroot 697866Sroot for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--) 707866Sroot if (gp[-1] >= 0) 717866Sroot break; 727866Sroot if (uap->gidsetsize < gp - u.u_groups) { 737866Sroot u.u_error = EINVAL; 747866Sroot return; 757866Sroot } 767866Sroot uap->gidsetsize = gp - u.u_groups; 777866Sroot if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset, 787866Sroot uap->gidsetsize * sizeof (u.u_groups[0]))) { 797498Sroot u.u_error = EFAULT; 807498Sroot return; 817498Sroot } 827866Sroot u.u_r.r_val1 = uap->gidsetsize; 837498Sroot } 847498Sroot 857498Sroot setpgrp() 867498Sroot { 877498Sroot register struct proc *p; 887498Sroot register struct a { 897498Sroot int pid; 907498Sroot int pgrp; 917498Sroot } *uap = (struct a *)u.u_ap; 927498Sroot 937498Sroot if (uap->pid == 0) 947498Sroot uap->pid = u.u_procp->p_pid; 957498Sroot p = pfind(uap->pid); 967498Sroot if (p == 0) { 977498Sroot u.u_error = ESRCH; 987498Sroot return; 997498Sroot } 1007866Sroot /* need better control mechanisms for process groups */ 1017498Sroot if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 1027498Sroot u.u_error = EPERM; 1037498Sroot return; 1047498Sroot } 1057498Sroot p->p_pgrp = uap->pgrp; 1067498Sroot } 1077498Sroot 108*9160Ssam setreuid() 1097420Sroot { 110*9160Ssam struct a { 111*9160Ssam int ruid; 112*9160Ssam int euid; 113*9160Ssam } *uap; 114*9160Ssam register int ruid, euid; 115*9160Ssam 116*9160Ssam uap = (struct a *)u.u_ap; 117*9160Ssam ruid = uap->ruid; 118*9160Ssam if (ruid == -1) 119*9160Ssam ruid = u.u_ruid; 120*9160Ssam if (u.u_ruid != ruid && u.u_uid != ruid && !suser()) 121*9160Ssam return; 122*9160Ssam euid = uap->euid; 123*9160Ssam if (euid == -1) 124*9160Ssam euid = u.u_uid; 125*9160Ssam if (u.u_ruid != euid && u.u_uid != euid && !suser()) 126*9160Ssam return; 127*9160Ssam /* 128*9160Ssam * Everything's okay, do it. 129*9160Ssam */ 130*9160Ssam if (ruid != u.u_ruid) { 131*9160Ssam #ifdef QUOTA 132*9160Ssam if (u.u_quota->q_uid != ruid) { 133*9160Ssam qclean(); 134*9160Ssam qstart(getquota(ruid, 0, 0)); 135*9160Ssam } 136*9160Ssam #endif 137*9160Ssam u.u_procp->p_uid = ruid; 138*9160Ssam u.u_ruid = ruid; 139*9160Ssam } 140*9160Ssam u.u_uid = euid; 141*9160Ssam } 142*9160Ssam 143*9160Ssam #ifndef NOCOMPAT 144*9160Ssam osetuid() 145*9160Ssam { 1467420Sroot register uid; 1477420Sroot register struct a { 1487420Sroot int uid; 1497420Sroot } *uap; 1507420Sroot 1517420Sroot uap = (struct a *)u.u_ap; 1527420Sroot uid = uap->uid; 1537420Sroot if (u.u_ruid == uid || u.u_uid == uid || suser()) { 1547489Skre #ifdef QUOTA 1557489Skre if (u.u_quota->q_uid != uid) { 1567489Skre qclean(); 1577489Skre qstart(getquota(uid, 0, 0)); 1587489Skre } 1597489Skre #endif 1607420Sroot u.u_uid = uid; 1617420Sroot u.u_procp->p_uid = uid; 1627420Sroot u.u_ruid = uid; 1637420Sroot } 1647420Sroot } 165*9160Ssam #endif 1667420Sroot 167*9160Ssam setregid() 1687420Sroot { 169*9160Ssam register struct a { 170*9160Ssam int rgid; 171*9160Ssam int egid; 172*9160Ssam } *uap; 173*9160Ssam register int rgid, egid; 174*9160Ssam 175*9160Ssam uap = (struct a *)u.u_ap; 176*9160Ssam rgid = uap->rgid; 177*9160Ssam if (rgid == -1) 178*9160Ssam rgid = u.u_rgid; 179*9160Ssam if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) 180*9160Ssam return; 181*9160Ssam egid = uap->egid; 182*9160Ssam if (egid == -1) 183*9160Ssam egid = u.u_gid; 184*9160Ssam if (u.u_rgid != egid && u.u_gid != egid && !suser()) 185*9160Ssam return; 186*9160Ssam if (u.u_rgid != rgid) { 187*9160Ssam leavegroup(u.u_rgid); 188*9160Ssam (void) entergroup(u.u_rgid); 189*9160Ssam u.u_rgid = rgid; 190*9160Ssam } 191*9160Ssam if (u.u_gid != egid) { 192*9160Ssam leavegroup(u.u_gid); 193*9160Ssam (void) entergroup(egid); 194*9160Ssam u.u_gid = egid; 195*9160Ssam } 196*9160Ssam } 197*9160Ssam 198*9160Ssam #ifndef NOCOMPAT 199*9160Ssam osetgid() 200*9160Ssam { 2017420Sroot register gid; 2027420Sroot register struct a { 2037420Sroot int gid; 2047420Sroot } *uap; 2057420Sroot 2067420Sroot uap = (struct a *)u.u_ap; 2077420Sroot gid = uap->gid; 2087420Sroot if (u.u_rgid == gid || u.u_gid == gid || suser()) { 2097866Sroot leavegroup(u.u_gid); leavegroup(u.u_rgid); 2107866Sroot (void) entergroup(gid); 2117420Sroot u.u_gid = gid; 2127420Sroot u.u_rgid = gid; 2137420Sroot } 2147420Sroot } 2157498Sroot 2167866Sroot setgroups() 2177498Sroot { 2187498Sroot register struct a { 2198624Sroot u_int gidsetsize; 2207498Sroot int *gidset; 2217498Sroot } *uap = (struct a *)u.u_ap; 2227866Sroot register int *gp; 2237498Sroot 2248100Sroot if (!suser()) 2257498Sroot return; 2267866Sroot if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 2277866Sroot u.u_error = EINVAL; 2287498Sroot return; 2297498Sroot } 2307866Sroot if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups, 2317866Sroot uap->gidsetsize * sizeof (u.u_groups[0]))) { 2327498Sroot u.u_error = EFAULT; 2337498Sroot return; 2347498Sroot } 2357866Sroot for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++) 2367866Sroot *gp = -1; 2377498Sroot } 2387498Sroot 2397498Sroot /* 2407498Sroot * Pid of zero implies current process. 2417498Sroot * Pgrp -1 is getpgrp system call returning 2427498Sroot * current process group. 2437498Sroot */ 2447498Sroot osetpgrp() 2457498Sroot { 2467498Sroot register struct proc *p; 2477498Sroot register struct a { 2487498Sroot int pid; 2497498Sroot int pgrp; 2507498Sroot } *uap; 2517498Sroot 2527498Sroot uap = (struct a *)u.u_ap; 2537498Sroot if (uap->pid == 0) 2547498Sroot p = u.u_procp; 2557498Sroot else { 2567498Sroot p = pfind(uap->pid); 2577498Sroot if (p == 0) { 2587498Sroot u.u_error = ESRCH; 2597498Sroot return; 2607498Sroot } 2617498Sroot } 2627498Sroot if (uap->pgrp <= 0) { 2637498Sroot u.u_r.r_val1 = p->p_pgrp; 2647498Sroot return; 2657498Sroot } 2667498Sroot if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 2677498Sroot u.u_error = EPERM; 2687498Sroot return; 2697498Sroot } 2707498Sroot p->p_pgrp = uap->pgrp; 2717498Sroot } 2727498Sroot /* END DEFUNCT */ 2737866Sroot 2747866Sroot leavegroup(gid) 2757866Sroot int gid; 2767866Sroot { 2777866Sroot register int *gp; 2787866Sroot 2797866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2807866Sroot if (*gp == gid) 2817866Sroot goto found; 2827866Sroot return; 2837866Sroot found: 2847866Sroot for (; gp < &u.u_groups[NGROUPS-1]; gp++) 2857866Sroot *gp = *(gp+1); 2867879Sroot *gp = -1; 2877866Sroot } 2887866Sroot 2897866Sroot entergroup(gid) 2907866Sroot int gid; 2917866Sroot { 2927866Sroot register int *gp; 2937866Sroot 2947866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2957866Sroot if (*gp == gid) 2967866Sroot return (0); 2977866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2987866Sroot if (*gp < 0) { 2997866Sroot *gp = gid; 3007866Sroot return (0); 3017866Sroot } 3027866Sroot return (-1); 3037866Sroot } 304