123372Smckusick /* 223372Smckusick * Copyright (c) 1982 Regents of the University of California. 323372Smckusick * All rights reserved. The Berkeley software License Agreement 423372Smckusick * specifies the terms and conditions for redistribution. 523372Smckusick * 6*25627Skarels * @(#)kern_prot.c 6.6 (Berkeley) 12/19/85 723372Smckusick */ 87420Sroot 97420Sroot /* 107498Sroot * System calls related to processes and protection 117420Sroot */ 127420Sroot 139754Ssam #include "../machine/reg.h" 149754Ssam 1517092Sbloom #include "param.h" 1617092Sbloom #include "systm.h" 1717092Sbloom #include "dir.h" 1817092Sbloom #include "user.h" 1917092Sbloom #include "inode.h" 2017092Sbloom #include "proc.h" 2117092Sbloom #include "timeb.h" 2217092Sbloom #include "times.h" 2317092Sbloom #include "reboot.h" 2417092Sbloom #include "fs.h" 2517092Sbloom #include "buf.h" 2617092Sbloom #include "mount.h" 2717092Sbloom #include "quota.h" 287420Sroot 297498Sroot getpid() 307498Sroot { 317498Sroot 327498Sroot u.u_r.r_val1 = u.u_procp->p_pid; 337498Sroot u.u_r.r_val2 = u.u_procp->p_ppid; 347498Sroot } 357498Sroot 367498Sroot getpgrp() 377498Sroot { 387498Sroot register struct a { 397498Sroot int pid; 407498Sroot } *uap = (struct a *)u.u_ap; 417498Sroot register struct proc *p; 427498Sroot 437498Sroot if (uap->pid == 0) 447498Sroot uap->pid = u.u_procp->p_pid; 457498Sroot p = pfind(uap->pid); 467498Sroot if (p == 0) { 477498Sroot u.u_error = ESRCH; 487498Sroot return; 497498Sroot } 507498Sroot u.u_r.r_val1 = p->p_pgrp; 517498Sroot } 527498Sroot 537420Sroot getuid() 547420Sroot { 557420Sroot 567420Sroot u.u_r.r_val1 = u.u_ruid; 577420Sroot u.u_r.r_val2 = u.u_uid; 587420Sroot } 597420Sroot 607498Sroot getgid() 617498Sroot { 627498Sroot 637498Sroot u.u_r.r_val1 = u.u_rgid; 647498Sroot u.u_r.r_val2 = u.u_gid; 657498Sroot } 667498Sroot 677866Sroot getgroups() 687498Sroot { 697498Sroot register struct a { 708624Sroot u_int gidsetsize; 717498Sroot int *gidset; 727498Sroot } *uap = (struct a *)u.u_ap; 7318362Skarels register gid_t *gp; 7418362Skarels register int *lp; 7518362Skarels int groups[NGROUPS]; 767498Sroot 777866Sroot for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--) 7818362Skarels if (gp[-1] != NOGROUP) 797866Sroot break; 807866Sroot if (uap->gidsetsize < gp - u.u_groups) { 817866Sroot u.u_error = EINVAL; 827866Sroot return; 837866Sroot } 847866Sroot uap->gidsetsize = gp - u.u_groups; 8518362Skarels for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 8618362Skarels *lp++ = *gp++; 8718362Skarels u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset, 8818362Skarels uap->gidsetsize * sizeof (groups[0])); 899997Ssam if (u.u_error) 907498Sroot return; 917866Sroot u.u_r.r_val1 = uap->gidsetsize; 927498Sroot } 937498Sroot 947498Sroot setpgrp() 957498Sroot { 967498Sroot register struct proc *p; 977498Sroot register struct a { 987498Sroot int pid; 997498Sroot int pgrp; 1007498Sroot } *uap = (struct a *)u.u_ap; 1017498Sroot 1027498Sroot if (uap->pid == 0) 1037498Sroot uap->pid = u.u_procp->p_pid; 1047498Sroot p = pfind(uap->pid); 1057498Sroot if (p == 0) { 1067498Sroot u.u_error = ESRCH; 1077498Sroot return; 1087498Sroot } 1097866Sroot /* need better control mechanisms for process groups */ 1107498Sroot if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 1117498Sroot u.u_error = EPERM; 1127498Sroot return; 1137498Sroot } 1147498Sroot p->p_pgrp = uap->pgrp; 1157498Sroot } 1167498Sroot 1179160Ssam setreuid() 1187420Sroot { 1199160Ssam struct a { 1209160Ssam int ruid; 1219160Ssam int euid; 1229160Ssam } *uap; 1239160Ssam register int ruid, euid; 1249160Ssam 1259160Ssam uap = (struct a *)u.u_ap; 1269160Ssam ruid = uap->ruid; 1279160Ssam if (ruid == -1) 1289160Ssam ruid = u.u_ruid; 1299160Ssam if (u.u_ruid != ruid && u.u_uid != ruid && !suser()) 1309160Ssam return; 1319160Ssam euid = uap->euid; 1329160Ssam if (euid == -1) 1339160Ssam euid = u.u_uid; 1349160Ssam if (u.u_ruid != euid && u.u_uid != euid && !suser()) 1359160Ssam return; 1369160Ssam /* 1379160Ssam * Everything's okay, do it. 1389160Ssam */ 1399160Ssam #ifdef QUOTA 1409320Ssam if (u.u_quota->q_uid != ruid) { 1419320Ssam qclean(); 1429320Ssam qstart(getquota(ruid, 0, 0)); 1439320Ssam } 1449160Ssam #endif 145*25627Skarels u.u_procp->p_uid = euid; 1469320Ssam u.u_ruid = ruid; 1479160Ssam u.u_uid = euid; 1489160Ssam } 1499160Ssam 1509160Ssam setregid() 1517420Sroot { 1529160Ssam register struct a { 1539160Ssam int rgid; 1549160Ssam int egid; 1559160Ssam } *uap; 1569160Ssam register int rgid, egid; 1579160Ssam 1589160Ssam uap = (struct a *)u.u_ap; 1599160Ssam rgid = uap->rgid; 1609160Ssam if (rgid == -1) 1619160Ssam rgid = u.u_rgid; 1629160Ssam if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) 1639160Ssam return; 1649160Ssam egid = uap->egid; 1659160Ssam if (egid == -1) 1669160Ssam egid = u.u_gid; 1679160Ssam if (u.u_rgid != egid && u.u_gid != egid && !suser()) 1689160Ssam return; 1699160Ssam if (u.u_rgid != rgid) { 1709160Ssam leavegroup(u.u_rgid); 17111164Ssam (void) entergroup(rgid); 1729160Ssam u.u_rgid = rgid; 1739160Ssam } 17411164Ssam u.u_gid = egid; 1759160Ssam } 1769160Ssam 1777866Sroot setgroups() 1787498Sroot { 1797498Sroot register struct a { 1808624Sroot u_int gidsetsize; 1817498Sroot int *gidset; 1827498Sroot } *uap = (struct a *)u.u_ap; 18318362Skarels register gid_t *gp; 18418362Skarels register int *lp; 18518362Skarels int groups[NGROUPS]; 1867498Sroot 1878100Sroot if (!suser()) 1887498Sroot return; 1897866Sroot if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 1907866Sroot u.u_error = EINVAL; 1917498Sroot return; 1927498Sroot } 19318362Skarels u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups, 19418362Skarels uap->gidsetsize * sizeof (groups[0])); 1959997Ssam if (u.u_error) 1967498Sroot return; 19718362Skarels for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 19818362Skarels *gp++ = *lp++; 19918362Skarels for ( ; gp < &u.u_groups[NGROUPS]; gp++) 20011810Ssam *gp = NOGROUP; 2017498Sroot } 2027498Sroot 2037498Sroot /* 20411810Ssam * Group utility functions. 20511810Ssam */ 20611810Ssam 20711810Ssam /* 20811810Ssam * Delete gid from the group set. 20911810Ssam */ 2107866Sroot leavegroup(gid) 2117866Sroot int gid; 2127866Sroot { 21318362Skarels register gid_t *gp; 2147866Sroot 2157866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2167866Sroot if (*gp == gid) 2177866Sroot goto found; 2187866Sroot return; 2197866Sroot found: 2207866Sroot for (; gp < &u.u_groups[NGROUPS-1]; gp++) 2217866Sroot *gp = *(gp+1); 22211810Ssam *gp = NOGROUP; 2237866Sroot } 2247866Sroot 22511810Ssam /* 22611810Ssam * Add gid to the group set. 22711810Ssam */ 2287866Sroot entergroup(gid) 2297866Sroot int gid; 2307866Sroot { 23118362Skarels register gid_t *gp; 2327866Sroot 23318362Skarels for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) { 2347866Sroot if (*gp == gid) 2357866Sroot return (0); 23618362Skarels if (*gp == NOGROUP) { 2377866Sroot *gp = gid; 2387866Sroot return (0); 2397866Sroot } 24018362Skarels } 2417866Sroot return (-1); 2427866Sroot } 24311810Ssam 24411810Ssam /* 24511810Ssam * Check if gid is a member of the group set. 24611810Ssam */ 24711810Ssam groupmember(gid) 24818362Skarels gid_t gid; 24911810Ssam { 25018362Skarels register gid_t *gp; 25111810Ssam 25211810Ssam if (u.u_gid == gid) 25311810Ssam return (1); 25411810Ssam for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) 25511810Ssam if (*gp == gid) 25611810Ssam return (1); 25711810Ssam return (0); 25811810Ssam } 259