1*17092Sbloom /* kern_prot.c 6.2 84/08/29 */ 27420Sroot 37420Sroot /* 47498Sroot * System calls related to processes and protection 57420Sroot */ 67420Sroot 79754Ssam #include "../machine/reg.h" 89754Ssam 9*17092Sbloom #include "param.h" 10*17092Sbloom #include "systm.h" 11*17092Sbloom #include "dir.h" 12*17092Sbloom #include "user.h" 13*17092Sbloom #include "inode.h" 14*17092Sbloom #include "proc.h" 15*17092Sbloom #include "timeb.h" 16*17092Sbloom #include "times.h" 17*17092Sbloom #include "reboot.h" 18*17092Sbloom #include "fs.h" 19*17092Sbloom #include "conf.h" 20*17092Sbloom #include "buf.h" 21*17092Sbloom #include "mount.h" 22*17092Sbloom #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; 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; 789997Ssam u.u_error = copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset, 799997Ssam uap->gidsetsize * sizeof (u.u_groups[0])); 809997Ssam if (u.u_error) 817498Sroot return; 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 1319320Ssam if (u.u_quota->q_uid != ruid) { 1329320Ssam qclean(); 1339320Ssam qstart(getquota(ruid, 0, 0)); 1349320Ssam } 1359160Ssam #endif 1369320Ssam u.u_procp->p_uid = ruid; 1379320Ssam u.u_ruid = ruid; 1389160Ssam u.u_uid = euid; 1399160Ssam } 1409160Ssam 1419160Ssam setregid() 1427420Sroot { 1439160Ssam register struct a { 1449160Ssam int rgid; 1459160Ssam int egid; 1469160Ssam } *uap; 1479160Ssam register int rgid, egid; 1489160Ssam 1499160Ssam uap = (struct a *)u.u_ap; 1509160Ssam rgid = uap->rgid; 1519160Ssam if (rgid == -1) 1529160Ssam rgid = u.u_rgid; 1539160Ssam if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) 1549160Ssam return; 1559160Ssam egid = uap->egid; 1569160Ssam if (egid == -1) 1579160Ssam egid = u.u_gid; 1589160Ssam if (u.u_rgid != egid && u.u_gid != egid && !suser()) 1599160Ssam return; 1609160Ssam if (u.u_rgid != rgid) { 1619160Ssam leavegroup(u.u_rgid); 16211164Ssam (void) entergroup(rgid); 1639160Ssam u.u_rgid = rgid; 1649160Ssam } 16511164Ssam u.u_gid = egid; 1669160Ssam } 1679160Ssam 1687866Sroot setgroups() 1697498Sroot { 1707498Sroot register struct a { 1718624Sroot u_int gidsetsize; 1727498Sroot int *gidset; 1737498Sroot } *uap = (struct a *)u.u_ap; 1747866Sroot register int *gp; 1757498Sroot 1768100Sroot if (!suser()) 1777498Sroot return; 1787866Sroot if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 1797866Sroot u.u_error = EINVAL; 1807498Sroot return; 1817498Sroot } 1829997Ssam u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups, 1839997Ssam uap->gidsetsize * sizeof (u.u_groups[0])); 1849997Ssam if (u.u_error) 1857498Sroot return; 1867866Sroot for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++) 18711810Ssam *gp = NOGROUP; 1887498Sroot } 1897498Sroot 1907498Sroot /* 19111810Ssam * Group utility functions. 19211810Ssam */ 19311810Ssam 19411810Ssam /* 19511810Ssam * Delete gid from the group set. 19611810Ssam */ 1977866Sroot leavegroup(gid) 1987866Sroot int gid; 1997866Sroot { 2007866Sroot register int *gp; 2017866Sroot 2027866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2037866Sroot if (*gp == gid) 2047866Sroot goto found; 2057866Sroot return; 2067866Sroot found: 2077866Sroot for (; gp < &u.u_groups[NGROUPS-1]; gp++) 2087866Sroot *gp = *(gp+1); 20911810Ssam *gp = NOGROUP; 2107866Sroot } 2117866Sroot 21211810Ssam /* 21311810Ssam * Add gid to the group set. 21411810Ssam */ 2157866Sroot entergroup(gid) 2167866Sroot int gid; 2177866Sroot { 2187866Sroot register int *gp; 2197866Sroot 2207866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2217866Sroot if (*gp == gid) 2227866Sroot return (0); 2237866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2247866Sroot if (*gp < 0) { 2257866Sroot *gp = gid; 2267866Sroot return (0); 2277866Sroot } 2287866Sroot return (-1); 2297866Sroot } 23011810Ssam 23111810Ssam /* 23211810Ssam * Check if gid is a member of the group set. 23311810Ssam */ 23411810Ssam groupmember(gid) 23511810Ssam int gid; 23611810Ssam { 23711810Ssam register int *gp; 23811810Ssam 23911810Ssam if (u.u_gid == gid) 24011810Ssam return (1); 24111810Ssam for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) 24211810Ssam if (*gp == gid) 24311810Ssam return (1); 24411810Ssam return (0); 24511810Ssam } 246