123372Smckusick /* 229092Smckusick * Copyright (c) 1982, 1986 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*35810Smarc * @(#)kern_prot.c 7.2 (Berkeley) 10/18/88 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) 44*35810Smarc p = u.u_procp; 45*35810Smarc else if ((p = pfind(uap->pid)) == 0) { 467498Sroot u.u_error = ESRCH; 477498Sroot return; 487498Sroot } 49*35810Smarc u.u_r.r_val1 = p->p_pgrp->pg_id; 507498Sroot } 517498Sroot 527420Sroot getuid() 537420Sroot { 547420Sroot 557420Sroot u.u_r.r_val1 = u.u_ruid; 567420Sroot u.u_r.r_val2 = u.u_uid; 577420Sroot } 587420Sroot 597498Sroot getgid() 607498Sroot { 617498Sroot 627498Sroot u.u_r.r_val1 = u.u_rgid; 637498Sroot u.u_r.r_val2 = u.u_gid; 647498Sroot } 657498Sroot 667866Sroot getgroups() 677498Sroot { 687498Sroot register struct a { 698624Sroot u_int gidsetsize; 707498Sroot int *gidset; 717498Sroot } *uap = (struct a *)u.u_ap; 7218362Skarels register gid_t *gp; 7318362Skarels register int *lp; 7418362Skarels int groups[NGROUPS]; 757498Sroot 767866Sroot for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--) 7718362Skarels if (gp[-1] != NOGROUP) 787866Sroot break; 797866Sroot if (uap->gidsetsize < gp - u.u_groups) { 807866Sroot u.u_error = EINVAL; 817866Sroot return; 827866Sroot } 837866Sroot uap->gidsetsize = gp - u.u_groups; 8418362Skarels for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 8518362Skarels *lp++ = *gp++; 8618362Skarels u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset, 8718362Skarels uap->gidsetsize * sizeof (groups[0])); 889997Ssam if (u.u_error) 897498Sroot return; 907866Sroot u.u_r.r_val1 = uap->gidsetsize; 917498Sroot } 927498Sroot 93*35810Smarc setsid() 94*35810Smarc { 95*35810Smarc register struct proc *p = u.u_procp; 96*35810Smarc 97*35810Smarc if ((p->p_pgid == p->p_pid) || pgfind(p->p_pid)) 98*35810Smarc u.u_error = EPERM; 99*35810Smarc else { 100*35810Smarc pgmv(p, p->p_pid, 1); 101*35810Smarc u.u_r.r_val1 = p->p_pid; 102*35810Smarc } 103*35810Smarc return; 104*35810Smarc } 105*35810Smarc 106*35810Smarc /* 107*35810Smarc * set process group 108*35810Smarc * 109*35810Smarc * if target pid != caller's pid 110*35810Smarc * pid must be an inferior 111*35810Smarc * pid must be in same session 112*35810Smarc * pid can't have done an exec 113*35810Smarc * there must exist a pid with pgid in same session 114*35810Smarc * pid must not be session leader 115*35810Smarc */ 1167498Sroot setpgrp() 1177498Sroot { 1187498Sroot register struct a { 1197498Sroot int pid; 120*35810Smarc int pgid; 1217498Sroot } *uap = (struct a *)u.u_ap; 122*35810Smarc register struct proc *p; 123*35810Smarc register struct pgrp *pgrp; 1247498Sroot 1257498Sroot if (uap->pid == 0) 126*35810Smarc p = u.u_procp; 127*35810Smarc else if ((p = pfind(uap->pid)) == 0 || !inferior(p)) { 1287498Sroot u.u_error = ESRCH; 1297498Sroot return; 1307498Sroot } 131*35810Smarc else if (p != u.u_procp) { 132*35810Smarc if (p->p_session != u.u_procp->p_session) { 133*35810Smarc u.u_error = EPERM; 134*35810Smarc return; 135*35810Smarc } 136*35810Smarc if (p->p_flag&SEXEC) { 137*35810Smarc u.u_error = EACCES; 138*35810Smarc return; 139*35810Smarc } 140*35810Smarc } 141*35810Smarc if (SESS_LEADER(p)) { 1427498Sroot u.u_error = EPERM; 1437498Sroot return; 1447498Sroot } 145*35810Smarc if (uap->pgid == 0) 146*35810Smarc uap->pgid = p->p_pid; 147*35810Smarc else if ((uap->pgid != p->p_pid) && 148*35810Smarc (((pgrp = pgfind(uap->pgid)) == 0) || 149*35810Smarc pgrp->pg_mem == NULL || 150*35810Smarc pgrp->pg_session != u.u_procp->p_session)) { 151*35810Smarc u.u_error = EPERM; 152*35810Smarc return; 153*35810Smarc } 154*35810Smarc /* 155*35810Smarc * done checking, now doit 156*35810Smarc */ 157*35810Smarc pgmv(p, uap->pgid, 0); 1587498Sroot } 1597498Sroot 1609160Ssam setreuid() 1617420Sroot { 1629160Ssam struct a { 1639160Ssam int ruid; 1649160Ssam int euid; 1659160Ssam } *uap; 1669160Ssam register int ruid, euid; 1679160Ssam 1689160Ssam uap = (struct a *)u.u_ap; 1699160Ssam ruid = uap->ruid; 1709160Ssam if (ruid == -1) 1719160Ssam ruid = u.u_ruid; 1729160Ssam if (u.u_ruid != ruid && u.u_uid != ruid && !suser()) 1739160Ssam return; 1749160Ssam euid = uap->euid; 1759160Ssam if (euid == -1) 1769160Ssam euid = u.u_uid; 1779160Ssam if (u.u_ruid != euid && u.u_uid != euid && !suser()) 1789160Ssam return; 1799160Ssam /* 1809160Ssam * Everything's okay, do it. 1819160Ssam */ 1829160Ssam #ifdef QUOTA 1839320Ssam if (u.u_quota->q_uid != ruid) { 1849320Ssam qclean(); 18526354Skarels qstart(getquota((uid_t)ruid, 0, 0)); 1869320Ssam } 1879160Ssam #endif 18825627Skarels u.u_procp->p_uid = euid; 1899320Ssam u.u_ruid = ruid; 1909160Ssam u.u_uid = euid; 1919160Ssam } 1929160Ssam 1939160Ssam setregid() 1947420Sroot { 1959160Ssam register struct a { 1969160Ssam int rgid; 1979160Ssam int egid; 1989160Ssam } *uap; 1999160Ssam register int rgid, egid; 2009160Ssam 2019160Ssam uap = (struct a *)u.u_ap; 2029160Ssam rgid = uap->rgid; 2039160Ssam if (rgid == -1) 2049160Ssam rgid = u.u_rgid; 2059160Ssam if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) 2069160Ssam return; 2079160Ssam egid = uap->egid; 2089160Ssam if (egid == -1) 2099160Ssam egid = u.u_gid; 2109160Ssam if (u.u_rgid != egid && u.u_gid != egid && !suser()) 2119160Ssam return; 2129160Ssam if (u.u_rgid != rgid) { 2139160Ssam leavegroup(u.u_rgid); 21426275Skarels (void) entergroup((gid_t)rgid); 2159160Ssam u.u_rgid = rgid; 2169160Ssam } 21711164Ssam u.u_gid = egid; 2189160Ssam } 2199160Ssam 2207866Sroot setgroups() 2217498Sroot { 2227498Sroot register struct a { 2238624Sroot u_int gidsetsize; 2247498Sroot int *gidset; 2257498Sroot } *uap = (struct a *)u.u_ap; 22618362Skarels register gid_t *gp; 22718362Skarels register int *lp; 22818362Skarels int groups[NGROUPS]; 2297498Sroot 2308100Sroot if (!suser()) 2317498Sroot return; 2327866Sroot if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 2337866Sroot u.u_error = EINVAL; 2347498Sroot return; 2357498Sroot } 23618362Skarels u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups, 23718362Skarels uap->gidsetsize * sizeof (groups[0])); 2389997Ssam if (u.u_error) 2397498Sroot return; 24018362Skarels for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) 24118362Skarels *gp++ = *lp++; 24218362Skarels for ( ; gp < &u.u_groups[NGROUPS]; gp++) 24311810Ssam *gp = NOGROUP; 2447498Sroot } 2457498Sroot 2467498Sroot /* 24711810Ssam * Group utility functions. 24811810Ssam */ 24911810Ssam 25011810Ssam /* 25111810Ssam * Delete gid from the group set. 25211810Ssam */ 2537866Sroot leavegroup(gid) 25426275Skarels gid_t gid; 2557866Sroot { 25618362Skarels register gid_t *gp; 2577866Sroot 2587866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2597866Sroot if (*gp == gid) 2607866Sroot goto found; 2617866Sroot return; 2627866Sroot found: 2637866Sroot for (; gp < &u.u_groups[NGROUPS-1]; gp++) 2647866Sroot *gp = *(gp+1); 26511810Ssam *gp = NOGROUP; 2667866Sroot } 2677866Sroot 26811810Ssam /* 26911810Ssam * Add gid to the group set. 27011810Ssam */ 2717866Sroot entergroup(gid) 27226275Skarels gid_t gid; 2737866Sroot { 27418362Skarels register gid_t *gp; 2757866Sroot 27618362Skarels for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) { 2777866Sroot if (*gp == gid) 2787866Sroot return (0); 27918362Skarels if (*gp == NOGROUP) { 2807866Sroot *gp = gid; 2817866Sroot return (0); 2827866Sroot } 28318362Skarels } 2847866Sroot return (-1); 2857866Sroot } 28611810Ssam 28711810Ssam /* 28811810Ssam * Check if gid is a member of the group set. 28911810Ssam */ 29011810Ssam groupmember(gid) 29118362Skarels gid_t gid; 29211810Ssam { 29318362Skarels register gid_t *gp; 29411810Ssam 29511810Ssam if (u.u_gid == gid) 29611810Ssam return (1); 29711810Ssam for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) 29811810Ssam if (*gp == gid) 29911810Ssam return (1); 30011810Ssam return (0); 30111810Ssam } 302