1*11810Ssam /* kern_prot.c 5.16 83/03/31 */ 27420Sroot 37420Sroot /* 47498Sroot * System calls related to processes and protection 57420Sroot */ 67420Sroot 79754Ssam #include "../machine/reg.h" 89754Ssam 97420Sroot #include "../h/param.h" 107420Sroot #include "../h/systm.h" 117420Sroot #include "../h/dir.h" 127420Sroot #include "../h/user.h" 137420Sroot #include "../h/inode.h" 147420Sroot #include "../h/proc.h" 157420Sroot #include "../h/timeb.h" 167420Sroot #include "../h/times.h" 177420Sroot #include "../h/reboot.h" 187420Sroot #include "../h/fs.h" 197420Sroot #include "../h/conf.h" 207420Sroot #include "../h/buf.h" 217420Sroot #include "../h/mount.h" 227489Skre #include "../h/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 #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); 18611164Ssam (void) entergroup(rgid); 1879160Ssam u.u_rgid = rgid; 1889160Ssam } 18911164Ssam u.u_gid = egid; 1909160Ssam } 1919160Ssam 1929160Ssam #ifndef NOCOMPAT 1939160Ssam osetgid() 1949160Ssam { 1957420Sroot register gid; 1967420Sroot register struct a { 1977420Sroot int gid; 1987420Sroot } *uap; 1997420Sroot 2007420Sroot uap = (struct a *)u.u_ap; 2017420Sroot gid = uap->gid; 2027420Sroot if (u.u_rgid == gid || u.u_gid == gid || suser()) { 20311164Ssam leavegroup(u.u_rgid); 2047866Sroot (void) entergroup(gid); 2057420Sroot u.u_gid = gid; 2067420Sroot u.u_rgid = gid; 2077420Sroot } 2087420Sroot } 2097498Sroot 2107866Sroot setgroups() 2117498Sroot { 2127498Sroot register struct a { 2138624Sroot u_int gidsetsize; 2147498Sroot int *gidset; 2157498Sroot } *uap = (struct a *)u.u_ap; 2167866Sroot register int *gp; 2177498Sroot 2188100Sroot if (!suser()) 2197498Sroot return; 2207866Sroot if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { 2217866Sroot u.u_error = EINVAL; 2227498Sroot return; 2237498Sroot } 2249997Ssam u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups, 2259997Ssam uap->gidsetsize * sizeof (u.u_groups[0])); 2269997Ssam if (u.u_error) 2277498Sroot return; 2287866Sroot for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++) 229*11810Ssam *gp = NOGROUP; 2307498Sroot } 2317498Sroot 2327498Sroot /* 2337498Sroot * Pid of zero implies current process. 2347498Sroot * Pgrp -1 is getpgrp system call returning 2357498Sroot * current process group. 2367498Sroot */ 2377498Sroot osetpgrp() 2387498Sroot { 2397498Sroot register struct proc *p; 2407498Sroot register struct a { 2417498Sroot int pid; 2427498Sroot int pgrp; 2437498Sroot } *uap; 2447498Sroot 2457498Sroot uap = (struct a *)u.u_ap; 2467498Sroot if (uap->pid == 0) 2477498Sroot p = u.u_procp; 2487498Sroot else { 2497498Sroot p = pfind(uap->pid); 2507498Sroot if (p == 0) { 2517498Sroot u.u_error = ESRCH; 2527498Sroot return; 2537498Sroot } 2547498Sroot } 2557498Sroot if (uap->pgrp <= 0) { 2567498Sroot u.u_r.r_val1 = p->p_pgrp; 2577498Sroot return; 2587498Sroot } 2597498Sroot if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { 2607498Sroot u.u_error = EPERM; 2617498Sroot return; 2627498Sroot } 2637498Sroot p->p_pgrp = uap->pgrp; 2647498Sroot } 2657498Sroot /* END DEFUNCT */ 2667866Sroot 267*11810Ssam /* 268*11810Ssam * Group utility functions. 269*11810Ssam */ 270*11810Ssam 271*11810Ssam /* 272*11810Ssam * Delete gid from the group set. 273*11810Ssam */ 2747866Sroot leavegroup(gid) 2757866Sroot int gid; 2767866Sroot { 2777866Sroot register int *gp; 2787866Sroot 2797866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2807866Sroot if (*gp == gid) 2817866Sroot goto found; 2827866Sroot return; 2837866Sroot found: 2847866Sroot for (; gp < &u.u_groups[NGROUPS-1]; gp++) 2857866Sroot *gp = *(gp+1); 286*11810Ssam *gp = NOGROUP; 2877866Sroot } 2887866Sroot 289*11810Ssam /* 290*11810Ssam * Add gid to the group set. 291*11810Ssam */ 2927866Sroot entergroup(gid) 2937866Sroot int gid; 2947866Sroot { 2957866Sroot register int *gp; 2967866Sroot 2977866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 2987866Sroot if (*gp == gid) 2997866Sroot return (0); 3007866Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 3017866Sroot if (*gp < 0) { 3027866Sroot *gp = gid; 3037866Sroot return (0); 3047866Sroot } 3057866Sroot return (-1); 3067866Sroot } 307*11810Ssam 308*11810Ssam /* 309*11810Ssam * Check if gid is a member of the group set. 310*11810Ssam */ 311*11810Ssam groupmember(gid) 312*11810Ssam int gid; 313*11810Ssam { 314*11810Ssam register int *gp; 315*11810Ssam 316*11810Ssam if (u.u_gid == gid) 317*11810Ssam return (1); 318*11810Ssam for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) 319*11810Ssam if (*gp == gid) 320*11810Ssam return (1); 321*11810Ssam return (0); 322*11810Ssam } 323