checkpoint
[unix-history] / usr / src / sys / kern / kern_prot.c
index 70e6024..8cf9040 100644 (file)
@@ -1,4 +1,10 @@
-/*     kern_prot.c     6.2     84/08/29        */
+/*
+ * 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.2 (Berkeley) %G%
+ */
 
 /*
  * System calls related to processes and protection
 
 /*
  * System calls related to processes and protection
@@ -16,7 +22,6 @@
 #include "times.h"
 #include "reboot.h"
 #include "fs.h"
 #include "times.h"
 #include "reboot.h"
 #include "fs.h"
-#include "conf.h"
 #include "buf.h"
 #include "mount.h"
 #include "quota.h"
 #include "buf.h"
 #include "mount.h"
 #include "quota.h"
@@ -36,13 +41,12 @@ getpgrp()
        register struct proc *p;
 
        if (uap->pid == 0)
        register struct proc *p;
 
        if (uap->pid == 0)
-               uap->pid = u.u_procp->p_pid;
-       p = pfind(uap->pid);
-       if (p == 0) {
+               p = u.u_procp;
+       else if ((p = pfind(uap->pid)) == 0) {
                u.u_error = ESRCH;
                return;
        }
                u.u_error = ESRCH;
                return;
        }
-       u.u_r.r_val1 = p->p_pgrp;
+       u.u_r.r_val1 = p->p_pgrp->pg_id;
 }
 
 getuid()
 }
 
 getuid()
@@ -65,44 +69,92 @@ 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;
-       u.u_error = copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset,
-           uap->gidsetsize * sizeof (u.u_groups[0]));
+       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;
 }
 
        if (u.u_error)
                return;
        u.u_r.r_val1 = uap->gidsetsize;
 }
 
+setsid()
+{
+       register struct proc *p = u.u_procp;
+
+       if ((p->p_pgid == p->p_pid) || pgfind(p->p_pid))
+               u.u_error = EPERM;
+       else {
+               pgmv(p, p->p_pid, 1);
+               u.u_r.r_val1 = p->p_pid;
+       }
+       return;
+}
+
+/*
+ * set process group
+ *
+ * if target pid != caller's pid
+ *     pid must be an inferior
+ *     pid must be in same session
+ *     pid can't have done an exec
+ *     there must exist a pid with pgid in same session 
+ * pid must not be session leader
+ */
 setpgrp()
 {
 setpgrp()
 {
-       register struct proc *p;
        register struct a {
                int     pid;
        register struct a {
                int     pid;
-               int     pgrp;
+               int     pgid;
        } *uap = (struct a *)u.u_ap;
        } *uap = (struct a *)u.u_ap;
+       register struct proc *p;
+       register struct pgrp *pgrp;
 
        if (uap->pid == 0)
 
        if (uap->pid == 0)
-               uap->pid = u.u_procp->p_pid;
-       p = pfind(uap->pid);
-       if (p == 0) {
+               p = u.u_procp;
+       else if ((p = pfind(uap->pid)) == 0 || !inferior(p)) {
                u.u_error = ESRCH;
                return;
        }
                u.u_error = ESRCH;
                return;
        }
-/* need better control mechanisms for process groups */
-       if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
+       else if (p != u.u_procp) { 
+               if (p->p_session != u.u_procp->p_session) {
+                       u.u_error = EPERM;
+                       return;
+               }
+               if (p->p_flag&SEXEC) {
+                       u.u_error = EACCES;
+                       return;
+               }
+       }
+       if (SESS_LEADER(p)) {
+               u.u_error = EPERM;
+               return;
+       }
+       if (uap->pgid == 0)
+               uap->pgid = p->p_pid;
+       else if ((uap->pgid != p->p_pid) &&
+               (((pgrp = pgfind(uap->pgid)) == 0) || 
+                  pgrp->pg_mem == NULL ||
+                  pgrp->pg_session != u.u_procp->p_session)) {
                u.u_error = EPERM;
                return;
        }
                u.u_error = EPERM;
                return;
        }
-       p->p_pgrp = uap->pgrp;
+       /*
+        * done checking, now doit
+        */
+       pgmv(p, uap->pgid, 0);
 }
 
 setreuid()
 }
 
 setreuid()
@@ -130,10 +182,10 @@ setreuid()
 #ifdef QUOTA
        if (u.u_quota->q_uid != ruid) {
                qclean();
 #ifdef QUOTA
        if (u.u_quota->q_uid != ruid) {
                qclean();
-               qstart(getquota(ruid, 0, 0));
+               qstart(getquota((uid_t)ruid, 0, 0));
        }
 #endif
        }
 #endif
-       u.u_procp->p_uid = ruid;
+       u.u_procp->p_uid = euid;
        u.u_ruid = ruid;
        u.u_uid = euid;
 }
        u.u_ruid = ruid;
        u.u_uid = euid;
 }
@@ -159,7 +211,7 @@ setregid()
                return;
        if (u.u_rgid != rgid) {
                leavegroup(u.u_rgid);
                return;
        if (u.u_rgid != rgid) {
                leavegroup(u.u_rgid);
-               (void) entergroup(rgid);
+               (void) entergroup((gid_t)rgid);
                u.u_rgid = rgid;
        }
        u.u_gid = egid;
                u.u_rgid = rgid;
        }
        u.u_gid = egid;
@@ -171,7 +223,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;
@@ -179,11 +233,13 @@ setgroups()
                u.u_error = EINVAL;
                return;
        }
                u.u_error = EINVAL;
                return;
        }
-       u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
-           uap->gidsetsize * sizeof (u.u_groups[0]));
+       u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
+           uap->gidsetsize * sizeof (groups[0]));
        if (u.u_error)
                return;
        if (u.u_error)
                return;
-       for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
+       for (lp = groups, gp = u.u_groups; lp < &groups[uap->gidsetsize]; )
+               *gp++ = *lp++;
+       for ( ; gp < &u.u_groups[NGROUPS]; gp++)
                *gp = NOGROUP;
 }
 
                *gp = NOGROUP;
 }
 
@@ -195,9 +251,9 @@ setgroups()
  * Delete gid from the group set.
  */
 leavegroup(gid)
  * Delete gid from the group set.
  */
 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)
@@ -213,18 +269,18 @@ found:
  * Add gid to the group set.
  */
 entergroup(gid)
  * Add gid to the group set.
  */
 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);
 }
 
@@ -232,9 +288,9 @@ entergroup(gid)
  * Check if gid is a member of the group set.
  */
 groupmember(gid)
  * Check if gid is a member of the group set.
  */
 groupmember(gid)
-       int gid;
+       gid_t gid;
 {
 {
-       register int *gp;
+       register gid_t *gp;
 
        if (u.u_gid == gid)
                return (1);
 
        if (u.u_gid == gid)
                return (1);