correct no-such-process error
[unix-history] / usr / src / sys / kern / kern_prot.c
index 7b1e216..005ab26 100644 (file)
@@ -1,24 +1,30 @@
-/*     kern_prot.c     5.9     82/10/17        */
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)kern_prot.c 6.8 (Berkeley) %G%
+ */
 
 /*
  * System calls related to processes and protection
  */
 
 
 /*
  * System calls related to processes and protection
  */
 
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/reg.h"
-#include "../h/inode.h"
-#include "../h/proc.h"
-#include "../h/timeb.h"
-#include "../h/times.h"
-#include "../h/reboot.h"
-#include "../h/fs.h"
-#include "../h/conf.h"
-#include "../h/buf.h"
-#include "../h/mount.h"
-#include "../h/quota.h"
+#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()
 {
 
 getpid()
 {
@@ -64,21 +70,24 @@ getgroups()
                u_int   gidsetsize;
                int     *gidset;
        } *uap = (struct a *)u.u_ap;
                u_int   gidsetsize;
                int     *gidset;
        } *uap = (struct a *)u.u_ap;
-       register int *gp;
+       register gid_t *gp;
+       register int *lp;
+       int groups[NGROUPS];
 
        for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
 
        for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
-               if (gp[-1] >= 0)
+               if (gp[-1] != NOGROUP)
                        break;
        if (uap->gidsetsize < gp - u.u_groups) {
                u.u_error = EINVAL;
                return;
        }
        uap->gidsetsize = gp - u.u_groups;
                        break;
        if (uap->gidsetsize < gp - u.u_groups) {
                u.u_error = EINVAL;
                return;
        }
        uap->gidsetsize = gp - u.u_groups;
-       if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset,
-           uap->gidsetsize * sizeof (u.u_groups[0]))) {
-               u.u_error = EFAULT;
+       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;
                return;
-       }
        u.u_r.r_val1 = uap->gidsetsize;
 }
 
        u.u_r.r_val1 = uap->gidsetsize;
 }
 
@@ -105,43 +114,64 @@ setpgrp()
        p->p_pgrp = uap->pgrp;
 }
 
        p->p_pgrp = uap->pgrp;
 }
 
-setuid()
+setreuid()
 {
 {
-       register uid;
-       register struct a {
-               int     uid;
+       struct a {
+               int     ruid;
+               int     euid;
        } *uap;
        } *uap;
+       register int ruid, euid;
 
        uap = (struct a *)u.u_ap;
 
        uap = (struct a *)u.u_ap;
-       uid = uap->uid;
-       if (u.u_ruid == uid || u.u_uid == uid || suser()) {
+       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
 #ifdef QUOTA
-               if (u.u_quota->q_uid != uid) {
-                       qclean();
-                       qstart(getquota(uid, 0, 0));
-               }
-#endif
-               u.u_uid = uid;
-               u.u_procp->p_uid = uid;
-               u.u_ruid = uid;
+       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;
 }
 
 }
 
-setgid()
+setregid()
 {
 {
-       register gid;
        register struct a {
        register struct a {
-               int     gid;
+               int     rgid;
+               int     egid;
        } *uap;
        } *uap;
+       register int rgid, egid;
 
        uap = (struct a *)u.u_ap;
 
        uap = (struct a *)u.u_ap;
-       gid = uap->gid;
-       if (u.u_rgid == gid || u.u_gid == gid || suser()) {
-               leavegroup(u.u_gid); leavegroup(u.u_rgid);
-               (void) entergroup(gid);
-               u.u_gid = gid;
-               u.u_rgid = gid;
+       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()
 }
 
 setgroups()
@@ -150,7 +180,9 @@ setgroups()
                u_int   gidsetsize;
                int     *gidset;
        } *uap = (struct a *)u.u_ap;
                u_int   gidsetsize;
                int     *gidset;
        } *uap = (struct a *)u.u_ap;
-       register int *gp;
+       register gid_t *gp;
+       register int *lp;
+       int groups[NGROUPS];
 
        if (!suser())
                return;
 
        if (!suser())
                return;
@@ -158,54 +190,27 @@ setgroups()
                u.u_error = EINVAL;
                return;
        }
                u.u_error = EINVAL;
                return;
        }
-       if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
-           uap->gidsetsize * sizeof (u.u_groups[0]))) {
-               u.u_error = EFAULT;
+       u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
+           uap->gidsetsize * sizeof (groups[0]));
+       if (u.u_error)
                return;
                return;
-       }
-       for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
-               *gp = -1;
+       for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
+               *gp++ = *lp++;
+       for ( ; gp < &u.u_groups[NGROUPS]; gp++)
+               *gp = NOGROUP;
 }
 
 /*
 }
 
 /*
- * Pid of zero implies current process.
- * Pgrp -1 is getpgrp system call returning
- * current process group.
+ * Group utility functions.
  */
  */
-osetpgrp()
-{
-       register struct proc *p;
-       register struct a {
-               int     pid;
-               int     pgrp;
-       } *uap;
-
-       uap = (struct a *)u.u_ap;
-       if (uap->pid == 0)
-               p = u.u_procp;
-       else {
-               p = pfind(uap->pid);
-               if (p == 0) {
-                       u.u_error = ESRCH;
-                       return;
-               }
-       }
-       if (uap->pgrp <= 0) {
-               u.u_r.r_val1 = p->p_pgrp;
-               return;
-       }
-       if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
-               u.u_error = EPERM;
-               return;
-       }
-       p->p_pgrp = uap->pgrp;
-}
-/* END DEFUNCT */
 
 
+/*
+ * Delete gid from the group set.
+ */
 leavegroup(gid)
 leavegroup(gid)
-       int gid;
+       gid_t gid;
 {
 {
-       register int *gp;
+       register gid_t *gp;
 
        for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
                if (*gp == gid)
 
        for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
                if (*gp == gid)
@@ -214,21 +219,40 @@ leavegroup(gid)
 found:
        for (; gp < &u.u_groups[NGROUPS-1]; gp++)
                *gp = *(gp+1);
 found:
        for (; gp < &u.u_groups[NGROUPS-1]; gp++)
                *gp = *(gp+1);
-       *gp = -1;
+       *gp = NOGROUP;
 }
 
 }
 
+/*
+ * Add gid to the group set.
+ */
 entergroup(gid)
 entergroup(gid)
-       int gid;
+       gid_t gid;
 {
 {
-       register int *gp;
+       register gid_t *gp;
 
 
-       for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
+       for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) {
                if (*gp == gid)
                        return (0);
                if (*gp == gid)
                        return (0);
-       for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
-               if (*gp < 0) {
+               if (*gp == NOGROUP) {
                        *gp = gid;
                        return (0);
                }
                        *gp = gid;
                        return (0);
                }
+       }
        return (-1);
 }
        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);
+}