1*18362Skarels /* kern_prot.c 6.3 85/03/18 */ 27420Sroot 37420Sroot /* 47498Sroot * System calls related to processes and protection 57420Sroot */ 67420Sroot 79754Ssam #include "../machine/reg.h" 89754Ssam 917092Sbloom #include "param.h" 1017092Sbloom #include "systm.h" 1117092Sbloom #include "dir.h" 1217092Sbloom #include "user.h" 1317092Sbloom #include "inode.h" 1417092Sbloom #include "proc.h" 1517092Sbloom #include "timeb.h" 1617092Sbloom #include "times.h" 1717092Sbloom #include "reboot.h" 1817092Sbloom #include "fs.h" 1917092Sbloom #include "conf.h" 2017092Sbloom #include "buf.h" 2117092Sbloom #include "mount.h" 2217092Sbloom #include "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; 68*18362Skarels register gid_t *gp; 69*18362Skarels register int *lp; 70*18362Skarels int groups[NGROUPS]; 717498Sroot 727866Sroot for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--) 73*18362Skarels if (gp[-1] != NOGROUP) 747866Sroot break; 757866Sroot if (uap->gidsetsize < gp - u.u_groups) { 767866Sroot u.u_error = EINVAL; 777866Sroot return; 787866Sroot } 797866Sroot uap->gidsetsize = gp - u.u_groups; 80*18362Skarels for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 81*18362Skarels *lp++ = *gp++; 82*18362Skarels u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset, 83*18362Skarels uap->gidsetsize * sizeof (groups[0])); 849997Ssam if (u.u_error) 857498Sroot return; 867866Sroot u.u_r.r_val1 = uap->gidsetsize; 877498Sroot } 887498Sroot 897498Sroot setpgrp() 907498Sroot { 917498Sroot register struct proc *p; 927498Sroot register struct a { 937498Sroot int pid; 947498Sroot int pgrp; 957498Sroot } *uap = (struct a *)u.u_ap; 967498Sroot 977498Sroot if (uap->pid == 0) 987498Sroot uap->pid = u.u_procp->p_pid; 997498Sroot p = pfind(uap->pid); 1007498Sroot if (p == 0) { 1017498Sroot u.u_error = ESRCH; 1027498Sroot return; 1037498Sroot } 1047866Sroot /* need better control mechanisms for process groups */ 1057498Sroot if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 1067498Sroot u.u_error = EPERM; 1077498Sroot return; 1087498Sroot } 1097498Sroot p->p_pgrp = uap->pgrp; 1107498Sroot } 1117498Sroot 1129160Ssam setreuid() 1137420Sroot { 1149160Ssam struct a { 1159160Ssam int ruid; 1169160Ssam int euid; 1179160Ssam } *uap; 1189160Ssam register int ruid, euid; 1199160Ssam 1209160Ssam uap = (struct a *)u.u_ap; 1219160Ssam ruid = uap->ruid; 1229160Ssam if (ruid == -1) 1239160Ssam ruid = u.u_ruid; 1249160Ssam if (u.u_ruid != ruid && u.u_uid != ruid && !suser()) 1259160Ssam return; 1269160Ssam euid = uap->euid; 1279160Ssam if (euid == -1) 1289160Ssam euid = u.u_uid; 1299160Ssam if (u.u_ruid != euid && u.u_uid != euid && !suser()) 1309160Ssam return; 1319160Ssam /* 1329160Ssam * Everything's okay, do it. 1339160Ssam */ 1349160Ssam #ifdef QUOTA 1359320Ssam if (u.u_quota->q_uid != ruid) { 1369320Ssam qclean(); 1379320Ssam qstart(getquota(ruid, 0, 0)); 1389320Ssam } 1399160Ssam #endif 1409320Ssam u.u_procp->p_uid = ruid; 1419320Ssam u.u_ruid = ruid; 1429160Ssam u.u_uid = euid; 1439160Ssam } 1449160Ssam 1459160Ssam setregid() 1467420Sroot { 1479160Ssam register struct a { 1489160Ssam int rgid; 1499160Ssam int egid; 1509160Ssam } *uap; 1519160Ssam register int rgid, egid; 1529160Ssam 1539160Ssam uap = (struct a *)u.u_ap; 1549160Ssam rgid = uap->rgid; 1559160Ssam if (rgid == -1) 1569160Ssam rgid = u.u_rgid; 1579160Ssam if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) 1589160Ssam return; 1599160Ssam egid = uap->egid; 1609160Ssam if (egid == -1) 1619160Ssam egid = u.u_gid; 1629160Ssam if (u.u_rgid != egid && u.u_gid != egid && !suser()) 1639160Ssam return; 1649160Ssam if (u.u_rgid != rgid) { 1659160Ssam leavegroup(u.u_rgid); 16611164Ssam (void) entergroup(rgid); 1679160Ssam u.u_rgid = rgid; 1689160Ssam } 16911164Ssam u.u_gid = egid; 1709160Ssam } 1719160Ssam 1727866Sroot setgroups() 1737498Sroot { 1747498Sroot register struct a { 1758624Sroot u_int gidsetsize; 1767498Sroot int *gidset; 1777498Sroot } *uap = (struct a *)u.u_ap; 178*18362Skarels register gid_t *gp; 179*18362Skarels register int *lp; 180*18362Skarels int groups[NGROUPS]; 1817498Sroot 1828100Sroot if (!suser()) 1837498Sroot return; 1847866Sroot if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 1857866Sroot u.u_error = EINVAL; 1867498Sroot return; 1877498Sroot } 188*18362Skarels u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups, 189*18362Skarels uap->gidsetsize * sizeof (groups[0])); 1909997Ssam if (u.u_error) 1917498Sroot return; 192*18362Skarels for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 193*18362Skarels *gp++ = *lp++; 194*18362Skarels for ( ; gp < &u.u_groups[NGROUPS]; gp++) 19511810Ssam *gp = NOGROUP; 1967498Sroot } 1977498Sroot 1987498Sroot /* 19911810Ssam * Group utility functions. 20011810Ssam */ 20111810Ssam 20211810Ssam /* 20311810Ssam * Delete gid from the group set. 20411810Ssam */ 2057866Sroot leavegroup(gid) 2067866Sroot int gid; 2077866Sroot { 208*18362Skarels register gid_t *gp; 2097866Sroot 2107866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2117866Sroot if (*gp == gid) 2127866Sroot goto found; 2137866Sroot return; 2147866Sroot found: 2157866Sroot for (; gp < &u.u_groups[NGROUPS-1]; gp++) 2167866Sroot *gp = *(gp+1); 21711810Ssam *gp = NOGROUP; 2187866Sroot } 2197866Sroot 22011810Ssam /* 22111810Ssam * Add gid to the group set. 22211810Ssam */ 2237866Sroot entergroup(gid) 2247866Sroot int gid; 2257866Sroot { 226*18362Skarels register gid_t *gp; 2277866Sroot 228*18362Skarels for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) { 2297866Sroot if (*gp == gid) 2307866Sroot return (0); 231*18362Skarels if (*gp == NOGROUP) { 2327866Sroot *gp = gid; 2337866Sroot return (0); 2347866Sroot } 235*18362Skarels } 2367866Sroot return (-1); 2377866Sroot } 23811810Ssam 23911810Ssam /* 24011810Ssam * Check if gid is a member of the group set. 24111810Ssam */ 24211810Ssam groupmember(gid) 243*18362Skarels gid_t gid; 24411810Ssam { 245*18362Skarels register gid_t *gp; 24611810Ssam 24711810Ssam if (u.u_gid == gid) 24811810Ssam return (1); 24911810Ssam for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) 25011810Ssam if (*gp == gid) 25111810Ssam return (1); 25211810Ssam return (0); 25311810Ssam } 254