1*9320Ssam /* kern_prot.c 5.12 82/11/22 */ 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 1089160Ssam setreuid() 1097420Sroot { 1109160Ssam struct a { 1119160Ssam int ruid; 1129160Ssam int euid; 1139160Ssam } *uap; 1149160Ssam register int ruid, euid; 1159160Ssam 1169160Ssam uap = (struct a *)u.u_ap; 1179160Ssam ruid = uap->ruid; 1189160Ssam if (ruid == -1) 1199160Ssam ruid = u.u_ruid; 1209160Ssam if (u.u_ruid != ruid && u.u_uid != ruid && !suser()) 1219160Ssam return; 1229160Ssam euid = uap->euid; 1239160Ssam if (euid == -1) 1249160Ssam euid = u.u_uid; 1259160Ssam if (u.u_ruid != euid && u.u_uid != euid && !suser()) 1269160Ssam return; 1279160Ssam /* 1289160Ssam * Everything's okay, do it. 1299160Ssam */ 1309160Ssam #ifdef QUOTA 131*9320Ssam if (u.u_quota->q_uid != ruid) { 132*9320Ssam qclean(); 133*9320Ssam qstart(getquota(ruid, 0, 0)); 134*9320Ssam } 1359160Ssam #endif 136*9320Ssam u.u_procp->p_uid = ruid; 137*9320Ssam u.u_ruid = ruid; 1389160Ssam u.u_uid = euid; 1399160Ssam } 1409160Ssam 1419160Ssam #ifndef NOCOMPAT 1429160Ssam osetuid() 1439160Ssam { 1447420Sroot register uid; 1457420Sroot register struct a { 1467420Sroot int uid; 1477420Sroot } *uap; 1487420Sroot 1497420Sroot uap = (struct a *)u.u_ap; 1507420Sroot uid = uap->uid; 1517420Sroot if (u.u_ruid == uid || u.u_uid == uid || suser()) { 1527489Skre #ifdef QUOTA 1537489Skre if (u.u_quota->q_uid != uid) { 1547489Skre qclean(); 1557489Skre qstart(getquota(uid, 0, 0)); 1567489Skre } 1577489Skre #endif 1587420Sroot u.u_uid = uid; 1597420Sroot u.u_procp->p_uid = uid; 1607420Sroot u.u_ruid = uid; 1617420Sroot } 1627420Sroot } 1639160Ssam #endif 1647420Sroot 1659160Ssam setregid() 1667420Sroot { 1679160Ssam register struct a { 1689160Ssam int rgid; 1699160Ssam int egid; 1709160Ssam } *uap; 1719160Ssam register int rgid, egid; 1729160Ssam 1739160Ssam uap = (struct a *)u.u_ap; 1749160Ssam rgid = uap->rgid; 1759160Ssam if (rgid == -1) 1769160Ssam rgid = u.u_rgid; 1779160Ssam if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) 1789160Ssam return; 1799160Ssam egid = uap->egid; 1809160Ssam if (egid == -1) 1819160Ssam egid = u.u_gid; 1829160Ssam if (u.u_rgid != egid && u.u_gid != egid && !suser()) 1839160Ssam return; 1849160Ssam if (u.u_rgid != rgid) { 1859160Ssam leavegroup(u.u_rgid); 1869160Ssam (void) entergroup(u.u_rgid); 1879160Ssam u.u_rgid = rgid; 1889160Ssam } 1899160Ssam if (u.u_gid != egid) { 1909160Ssam leavegroup(u.u_gid); 1919160Ssam (void) entergroup(egid); 1929160Ssam u.u_gid = egid; 1939160Ssam } 1949160Ssam } 1959160Ssam 1969160Ssam #ifndef NOCOMPAT 1979160Ssam osetgid() 1989160Ssam { 1997420Sroot register gid; 2007420Sroot register struct a { 2017420Sroot int gid; 2027420Sroot } *uap; 2037420Sroot 2047420Sroot uap = (struct a *)u.u_ap; 2057420Sroot gid = uap->gid; 2067420Sroot if (u.u_rgid == gid || u.u_gid == gid || suser()) { 2077866Sroot leavegroup(u.u_gid); leavegroup(u.u_rgid); 2087866Sroot (void) entergroup(gid); 2097420Sroot u.u_gid = gid; 2107420Sroot u.u_rgid = gid; 2117420Sroot } 2127420Sroot } 2137498Sroot 2147866Sroot setgroups() 2157498Sroot { 2167498Sroot register struct a { 2178624Sroot u_int gidsetsize; 2187498Sroot int *gidset; 2197498Sroot } *uap = (struct a *)u.u_ap; 2207866Sroot register int *gp; 2217498Sroot 2228100Sroot if (!suser()) 2237498Sroot return; 2247866Sroot if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 2257866Sroot u.u_error = EINVAL; 2267498Sroot return; 2277498Sroot } 2287866Sroot if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups, 2297866Sroot uap->gidsetsize * sizeof (u.u_groups[0]))) { 2307498Sroot u.u_error = EFAULT; 2317498Sroot return; 2327498Sroot } 2337866Sroot for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++) 2347866Sroot *gp = -1; 2357498Sroot } 2367498Sroot 2377498Sroot /* 2387498Sroot * Pid of zero implies current process. 2397498Sroot * Pgrp -1 is getpgrp system call returning 2407498Sroot * current process group. 2417498Sroot */ 2427498Sroot osetpgrp() 2437498Sroot { 2447498Sroot register struct proc *p; 2457498Sroot register struct a { 2467498Sroot int pid; 2477498Sroot int pgrp; 2487498Sroot } *uap; 2497498Sroot 2507498Sroot uap = (struct a *)u.u_ap; 2517498Sroot if (uap->pid == 0) 2527498Sroot p = u.u_procp; 2537498Sroot else { 2547498Sroot p = pfind(uap->pid); 2557498Sroot if (p == 0) { 2567498Sroot u.u_error = ESRCH; 2577498Sroot return; 2587498Sroot } 2597498Sroot } 2607498Sroot if (uap->pgrp <= 0) { 2617498Sroot u.u_r.r_val1 = p->p_pgrp; 2627498Sroot return; 2637498Sroot } 2647498Sroot if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 2657498Sroot u.u_error = EPERM; 2667498Sroot return; 2677498Sroot } 2687498Sroot p->p_pgrp = uap->pgrp; 2697498Sroot } 2707498Sroot /* END DEFUNCT */ 2717866Sroot 2727866Sroot leavegroup(gid) 2737866Sroot int gid; 2747866Sroot { 2757866Sroot register int *gp; 2767866Sroot 2777866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2787866Sroot if (*gp == gid) 2797866Sroot goto found; 2807866Sroot return; 2817866Sroot found: 2827866Sroot for (; gp < &u.u_groups[NGROUPS-1]; gp++) 2837866Sroot *gp = *(gp+1); 2847879Sroot *gp = -1; 2857866Sroot } 2867866Sroot 2877866Sroot entergroup(gid) 2887866Sroot int gid; 2897866Sroot { 2907866Sroot register int *gp; 2917866Sroot 2927866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2937866Sroot if (*gp == gid) 2947866Sroot return (0); 2957866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2967866Sroot if (*gp < 0) { 2977866Sroot *gp = gid; 2987866Sroot return (0); 2997866Sroot } 3007866Sroot return (-1); 3017866Sroot } 302