/* * Copyright (c) 1982, 1986 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * * @(#)kern_prot.c 7.1 (Berkeley) 6/5/86 */ /* * System calls related to processes and protection */ #include "../machine/reg.h" #include "param.h" #include "systm.h" #include "dir.h" #include "user.h" #include "inode.h" #include "proc.h" #include "timeb.h" #include "times.h" #include "reboot.h" #include "fs.h" #include "buf.h" #include "mount.h" #include "quota.h" getpid() { u.u_r.r_val1 = u.u_procp->p_pid; u.u_r.r_val2 = u.u_procp->p_ppid; } getpgrp() { register struct a { int pid; } *uap = (struct a *)u.u_ap; register struct proc *p; if (uap->pid == 0) uap->pid = u.u_procp->p_pid; p = pfind(uap->pid); if (p == 0) { u.u_error = ESRCH; return; } u.u_r.r_val1 = p->p_pgrp; } getuid() { u.u_r.r_val1 = u.u_ruid; u.u_r.r_val2 = u.u_uid; } getgid() { u.u_r.r_val1 = u.u_rgid; u.u_r.r_val2 = u.u_gid; } getgroups() { register struct a { u_int gidsetsize; int *gidset; } *uap = (struct a *)u.u_ap; register gid_t *gp; register int *lp; int groups[NGROUPS]; for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--) if (gp[-1] != NOGROUP) break; if (uap->gidsetsize < gp - u.u_groups) { u.u_error = EINVAL; return; } uap->gidsetsize = gp - u.u_groups; for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) *lp++ = *gp++; u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset, uap->gidsetsize * sizeof (groups[0])); if (u.u_error) return; u.u_r.r_val1 = uap->gidsetsize; } setpgrp() { register struct proc *p; register struct a { int pid; int pgrp; } *uap = (struct a *)u.u_ap; if (uap->pid == 0) uap->pid = u.u_procp->p_pid; p = pfind(uap->pid); if (p == 0) { u.u_error = ESRCH; return; } /* need better control mechanisms for process groups */ if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) { u.u_error = EPERM; return; } p->p_pgrp = uap->pgrp; } setreuid() { struct a { int ruid; int euid; } *uap; register int ruid, euid; uap = (struct a *)u.u_ap; ruid = uap->ruid; if (ruid == -1) ruid = u.u_ruid; if (u.u_ruid != ruid && u.u_uid != ruid && !suser()) return; euid = uap->euid; if (euid == -1) euid = u.u_uid; if (u.u_ruid != euid && u.u_uid != euid && !suser()) return; /* * Everything's okay, do it. */ #ifdef QUOTA if (u.u_quota->q_uid != ruid) { qclean(); qstart(getquota((uid_t)ruid, 0, 0)); } #endif u.u_procp->p_uid = euid; u.u_ruid = ruid; u.u_uid = euid; } setregid() { register struct a { int rgid; int egid; } *uap; register int rgid, egid; uap = (struct a *)u.u_ap; rgid = uap->rgid; if (rgid == -1) rgid = u.u_rgid; if (u.u_rgid != rgid && u.u_gid != rgid && !suser()) return; egid = uap->egid; if (egid == -1) egid = u.u_gid; if (u.u_rgid != egid && u.u_gid != egid && !suser()) return; if (u.u_rgid != rgid) { leavegroup(u.u_rgid); (void) entergroup((gid_t)rgid); u.u_rgid = rgid; } u.u_gid = egid; } setgroups() { register struct a { u_int gidsetsize; int *gidset; } *uap = (struct a *)u.u_ap; register gid_t *gp; register int *lp; int groups[NGROUPS]; if (!suser()) return; if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) { u.u_error = EINVAL; return; } u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups, uap->gidsetsize * sizeof (groups[0])); if (u.u_error) return; for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; ) *gp++ = *lp++; for ( ; gp < &u.u_groups[NGROUPS]; gp++) *gp = NOGROUP; } /* * Group utility functions. */ /* * Delete gid from the group set. */ leavegroup(gid) gid_t gid; { register gid_t *gp; for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) if (*gp == gid) goto found; return; found: for (; gp < &u.u_groups[NGROUPS-1]; gp++) *gp = *(gp+1); *gp = NOGROUP; } /* * Add gid to the group set. */ entergroup(gid) gid_t gid; { register gid_t *gp; for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) { if (*gp == gid) return (0); if (*gp == NOGROUP) { *gp = gid; return (0); } } return (-1); } /* * Check if gid is a member of the group set. */ groupmember(gid) gid_t gid; { register gid_t *gp; if (u.u_gid == gid) return (1); for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) if (*gp == gid) return (1); return (0); }