1*9754Ssam /* kern_prot.c 5.13 82/12/17 */ 27420Sroot 37420Sroot /* 47498Sroot * System calls related to processes and protection 57420Sroot */ 67420Sroot 7*9754Ssam #include "../machine/reg.h" 8*9754Ssam 97420Sroot #include "../h/param.h" 107420Sroot #include "../h/systm.h" 117420Sroot #include "../h/dir.h" 127420Sroot #include "../h/user.h" 137420Sroot #include "../h/inode.h" 147420Sroot #include "../h/proc.h" 157420Sroot #include "../h/timeb.h" 167420Sroot #include "../h/times.h" 177420Sroot #include "../h/reboot.h" 187420Sroot #include "../h/fs.h" 197420Sroot #include "../h/conf.h" 207420Sroot #include "../h/buf.h" 217420Sroot #include "../h/mount.h" 227489Skre #include "../h/quota.h" 237420Sroot 247498Sroot getpid() 257498Sroot { 267498Sroot 277498Sroot u.u_r.r_val1 = u.u_procp->p_pid; 287498Sroot u.u_r.r_val2 = u.u_procp->p_ppid; 297498Sroot } 307498Sroot 317498Sroot getpgrp() 327498Sroot { 337498Sroot register struct a { 347498Sroot int pid; 357498Sroot } *uap = (struct a *)u.u_ap; 367498Sroot register struct proc *p; 377498Sroot 387498Sroot if (uap->pid == 0) 397498Sroot uap->pid = u.u_procp->p_pid; 407498Sroot p = pfind(uap->pid); 417498Sroot if (p == 0) { 427498Sroot u.u_error = ESRCH; 437498Sroot return; 447498Sroot } 457498Sroot u.u_r.r_val1 = p->p_pgrp; 467498Sroot } 477498Sroot 487420Sroot getuid() 497420Sroot { 507420Sroot 517420Sroot u.u_r.r_val1 = u.u_ruid; 527420Sroot u.u_r.r_val2 = u.u_uid; 537420Sroot } 547420Sroot 557498Sroot getgid() 567498Sroot { 577498Sroot 587498Sroot u.u_r.r_val1 = u.u_rgid; 597498Sroot u.u_r.r_val2 = u.u_gid; 607498Sroot } 617498Sroot 627866Sroot getgroups() 637498Sroot { 647498Sroot register struct a { 658624Sroot u_int gidsetsize; 667498Sroot int *gidset; 677498Sroot } *uap = (struct a *)u.u_ap; 687866Sroot register int *gp; 697498Sroot 707866Sroot for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--) 717866Sroot if (gp[-1] >= 0) 727866Sroot break; 737866Sroot if (uap->gidsetsize < gp - u.u_groups) { 747866Sroot u.u_error = EINVAL; 757866Sroot return; 767866Sroot } 777866Sroot uap->gidsetsize = gp - u.u_groups; 787866Sroot if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset, 797866Sroot uap->gidsetsize * sizeof (u.u_groups[0]))) { 807498Sroot u.u_error = EFAULT; 817498Sroot return; 827498Sroot } 837866Sroot u.u_r.r_val1 = uap->gidsetsize; 847498Sroot } 857498Sroot 867498Sroot setpgrp() 877498Sroot { 887498Sroot register struct proc *p; 897498Sroot register struct a { 907498Sroot int pid; 917498Sroot int pgrp; 927498Sroot } *uap = (struct a *)u.u_ap; 937498Sroot 947498Sroot if (uap->pid == 0) 957498Sroot uap->pid = u.u_procp->p_pid; 967498Sroot p = pfind(uap->pid); 977498Sroot if (p == 0) { 987498Sroot u.u_error = ESRCH; 997498Sroot return; 1007498Sroot } 1017866Sroot /* need better control mechanisms for process groups */ 1027498Sroot if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 1037498Sroot u.u_error = EPERM; 1047498Sroot return; 1057498Sroot } 1067498Sroot p->p_pgrp = uap->pgrp; 1077498Sroot } 1087498Sroot 1099160Ssam setreuid() 1107420Sroot { 1119160Ssam struct a { 1129160Ssam int ruid; 1139160Ssam int euid; 1149160Ssam } *uap; 1159160Ssam register int ruid, euid; 1169160Ssam 1179160Ssam uap = (struct a *)u.u_ap; 1189160Ssam ruid = uap->ruid; 1199160Ssam if (ruid == -1) 1209160Ssam ruid = u.u_ruid; 1219160Ssam if (u.u_ruid != ruid && u.u_uid != ruid && !suser()) 1229160Ssam return; 1239160Ssam euid = uap->euid; 1249160Ssam if (euid == -1) 1259160Ssam euid = u.u_uid; 1269160Ssam if (u.u_ruid != euid && u.u_uid != euid && !suser()) 1279160Ssam return; 1289160Ssam /* 1299160Ssam * Everything's okay, do it. 1309160Ssam */ 1319160Ssam #ifdef QUOTA 1329320Ssam if (u.u_quota->q_uid != ruid) { 1339320Ssam qclean(); 1349320Ssam qstart(getquota(ruid, 0, 0)); 1359320Ssam } 1369160Ssam #endif 1379320Ssam u.u_procp->p_uid = ruid; 1389320Ssam u.u_ruid = ruid; 1399160Ssam u.u_uid = euid; 1409160Ssam } 1419160Ssam 1429160Ssam #ifndef NOCOMPAT 1439160Ssam osetuid() 1449160Ssam { 1457420Sroot register uid; 1467420Sroot register struct a { 1477420Sroot int uid; 1487420Sroot } *uap; 1497420Sroot 1507420Sroot uap = (struct a *)u.u_ap; 1517420Sroot uid = uap->uid; 1527420Sroot if (u.u_ruid == uid || u.u_uid == uid || suser()) { 1537489Skre #ifdef QUOTA 1547489Skre if (u.u_quota->q_uid != uid) { 1557489Skre qclean(); 1567489Skre qstart(getquota(uid, 0, 0)); 1577489Skre } 1587489Skre #endif 1597420Sroot u.u_uid = uid; 1607420Sroot u.u_procp->p_uid = uid; 1617420Sroot u.u_ruid = uid; 1627420Sroot } 1637420Sroot } 1649160Ssam #endif 1657420Sroot 1669160Ssam setregid() 1677420Sroot { 1689160Ssam register struct a { 1699160Ssam int rgid; 1709160Ssam int egid; 1719160Ssam } *uap; 1729160Ssam register int rgid, egid; 1739160Ssam 1749160Ssam uap = (struct a *)u.u_ap; 1759160Ssam rgid = uap->rgid; 1769160Ssam if (rgid == -1) 1779160Ssam rgid = u.u_rgid; 1789160Ssam if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) 1799160Ssam return; 1809160Ssam egid = uap->egid; 1819160Ssam if (egid == -1) 1829160Ssam egid = u.u_gid; 1839160Ssam if (u.u_rgid != egid && u.u_gid != egid && !suser()) 1849160Ssam return; 1859160Ssam if (u.u_rgid != rgid) { 1869160Ssam leavegroup(u.u_rgid); 1879160Ssam (void) entergroup(u.u_rgid); 1889160Ssam u.u_rgid = rgid; 1899160Ssam } 1909160Ssam if (u.u_gid != egid) { 1919160Ssam leavegroup(u.u_gid); 1929160Ssam (void) entergroup(egid); 1939160Ssam u.u_gid = egid; 1949160Ssam } 1959160Ssam } 1969160Ssam 1979160Ssam #ifndef NOCOMPAT 1989160Ssam osetgid() 1999160Ssam { 2007420Sroot register gid; 2017420Sroot register struct a { 2027420Sroot int gid; 2037420Sroot } *uap; 2047420Sroot 2057420Sroot uap = (struct a *)u.u_ap; 2067420Sroot gid = uap->gid; 2077420Sroot if (u.u_rgid == gid || u.u_gid == gid || suser()) { 2087866Sroot leavegroup(u.u_gid); leavegroup(u.u_rgid); 2097866Sroot (void) entergroup(gid); 2107420Sroot u.u_gid = gid; 2117420Sroot u.u_rgid = gid; 2127420Sroot } 2137420Sroot } 2147498Sroot 2157866Sroot setgroups() 2167498Sroot { 2177498Sroot register struct a { 2188624Sroot u_int gidsetsize; 2197498Sroot int *gidset; 2207498Sroot } *uap = (struct a *)u.u_ap; 2217866Sroot register int *gp; 2227498Sroot 2238100Sroot if (!suser()) 2247498Sroot return; 2257866Sroot if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 2267866Sroot u.u_error = EINVAL; 2277498Sroot return; 2287498Sroot } 2297866Sroot if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups, 2307866Sroot uap->gidsetsize * sizeof (u.u_groups[0]))) { 2317498Sroot u.u_error = EFAULT; 2327498Sroot return; 2337498Sroot } 2347866Sroot for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++) 2357866Sroot *gp = -1; 2367498Sroot } 2377498Sroot 2387498Sroot /* 2397498Sroot * Pid of zero implies current process. 2407498Sroot * Pgrp -1 is getpgrp system call returning 2417498Sroot * current process group. 2427498Sroot */ 2437498Sroot osetpgrp() 2447498Sroot { 2457498Sroot register struct proc *p; 2467498Sroot register struct a { 2477498Sroot int pid; 2487498Sroot int pgrp; 2497498Sroot } *uap; 2507498Sroot 2517498Sroot uap = (struct a *)u.u_ap; 2527498Sroot if (uap->pid == 0) 2537498Sroot p = u.u_procp; 2547498Sroot else { 2557498Sroot p = pfind(uap->pid); 2567498Sroot if (p == 0) { 2577498Sroot u.u_error = ESRCH; 2587498Sroot return; 2597498Sroot } 2607498Sroot } 2617498Sroot if (uap->pgrp <= 0) { 2627498Sroot u.u_r.r_val1 = p->p_pgrp; 2637498Sroot return; 2647498Sroot } 2657498Sroot if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 2667498Sroot u.u_error = EPERM; 2677498Sroot return; 2687498Sroot } 2697498Sroot p->p_pgrp = uap->pgrp; 2707498Sroot } 2717498Sroot /* END DEFUNCT */ 2727866Sroot 2737866Sroot leavegroup(gid) 2747866Sroot int gid; 2757866Sroot { 2767866Sroot register int *gp; 2777866Sroot 2787866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2797866Sroot if (*gp == gid) 2807866Sroot goto found; 2817866Sroot return; 2827866Sroot found: 2837866Sroot for (; gp < &u.u_groups[NGROUPS-1]; gp++) 2847866Sroot *gp = *(gp+1); 2857879Sroot *gp = -1; 2867866Sroot } 2877866Sroot 2887866Sroot entergroup(gid) 2897866Sroot int gid; 2907866Sroot { 2917866Sroot register int *gp; 2927866Sroot 2937866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2947866Sroot if (*gp == gid) 2957866Sroot return (0); 2967866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2977866Sroot if (*gp < 0) { 2987866Sroot *gp = gid; 2997866Sroot return (0); 3007866Sroot } 3017866Sroot return (-1); 3027866Sroot } 303