add definition for ability to produce a backtrace
[unix-history] / usr / src / sys / kern / kern_prot.c
index e096a0e..2e4f483 100644 (file)
 /*
 /*
- * Copyright (c) 1982, 1986, 1989, 1990 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)kern_prot.c 7.17 (Berkeley) %G%
+ *     @(#)kern_prot.c 8.9 (Berkeley) %G%
  */
 
 /*
  * System calls related to processes and protection
  */
 
  */
 
 /*
  * System calls related to processes and protection
  */
 
-#include "param.h"
-#include "acct.h"
-#include "systm.h"
-#include "user.h"
-#include "proc.h"
-#include "timeb.h"
-#include "times.h"
-#include "malloc.h"
+#include <sys/param.h>
+#include <sys/acct.h>
+#include <sys/systm.h>
+#include <sys/ucred.h>
+#include <sys/proc.h>
+#include <sys/timeb.h>
+#include <sys/times.h>
+#include <sys/malloc.h>
+
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
 
 /* ARGSUSED */
 
 /* ARGSUSED */
+int
 getpid(p, uap, retval)
        struct proc *p;
        void *uap;
 getpid(p, uap, retval)
        struct proc *p;
        void *uap;
-       int *retval;
+       register_t *retval;
 {
 
        *retval = p->p_pid;
 {
 
        *retval = p->p_pid;
-#ifdef COMPAT_43
-       retval[1] = p->p_ppid;
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+       retval[1] = p->p_pptr->p_pid;
 #endif
        return (0);
 }
 
 /* ARGSUSED */
 #endif
        return (0);
 }
 
 /* ARGSUSED */
+int
 getppid(p, uap, retval)
        struct proc *p;
        void *uap;
 getppid(p, uap, retval)
        struct proc *p;
        void *uap;
-       int *retval;
+       register_t *retval;
 {
 
 {
 
-       *retval = p->p_ppid;
+       *retval = p->p_pptr->p_pid;
        return (0);
 }
 
        return (0);
 }
 
+/* Get process group ID; note that POSIX getpgrp takes no parameter */
+int
 getpgrp(p, uap, retval)
        struct proc *p;
 getpgrp(p, uap, retval)
        struct proc *p;
-       struct args {
-               int     pid;
-       } *uap;
-       int *retval;
+       void *uap;
+       register_t *retval;
 {
 
 {
 
-       if (uap->pid != 0 && (p = pfind(uap->pid)) == 0)
-               return (ESRCH);
        *retval = p->p_pgrp->pg_id;
        return (0);
 }
 
 /* ARGSUSED */
        *retval = p->p_pgrp->pg_id;
        return (0);
 }
 
 /* ARGSUSED */
+int
 getuid(p, uap, retval)
        struct proc *p;
        void *uap;
 getuid(p, uap, retval)
        struct proc *p;
        void *uap;
-       int *retval;
+       register_t *retval;
 {
 
 {
 
-       *retval = p->p_ruid;
-#ifdef COMPAT_43
-       retval[1] = u.u_cred->cr_uid;
+       *retval = p->p_cred->p_ruid;
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+       retval[1] = p->p_ucred->cr_uid;
 #endif
        return (0);
 }
 
 /* ARGSUSED */
 #endif
        return (0);
 }
 
 /* ARGSUSED */
+int
 geteuid(p, uap, retval)
        struct proc *p;
        void *uap;
 geteuid(p, uap, retval)
        struct proc *p;
        void *uap;
-       int *retval;
+       register_t *retval;
 {
 
 {
 
-       *retval = u.u_cred->cr_uid;
+       *retval = p->p_ucred->cr_uid;
        return (0);
 }
 
 /* ARGSUSED */
        return (0);
 }
 
 /* ARGSUSED */
+int
 getgid(p, uap, retval)
        struct proc *p;
        void *uap;
 getgid(p, uap, retval)
        struct proc *p;
        void *uap;
-       int *retval;
+       register_t *retval;
 {
 
 {
 
-       *retval = p->p_rgid;
-#ifdef COMPAT_43
-       retval[1] = u.u_cred->cr_groups[0];
+       *retval = p->p_cred->p_rgid;
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+       retval[1] = p->p_ucred->cr_groups[0];
 #endif
        return (0);
 }
 #endif
        return (0);
 }
@@ -104,65 +115,65 @@ getgid(p, uap, retval)
  * correctly in a library function.
  */
 /* ARGSUSED */
  * correctly in a library function.
  */
 /* ARGSUSED */
+int
 getegid(p, uap, retval)
        struct proc *p;
        void *uap;
 getegid(p, uap, retval)
        struct proc *p;
        void *uap;
-       int *retval;
+       register_t *retval;
 {
 {
-       *retval = u.u_cred->cr_groups[0];
+
+       *retval = p->p_ucred->cr_groups[0];
        return (0);
 }
 
        return (0);
 }
 
+int
 getgroups(p, uap, retval)
        struct proc *p;
 getgroups(p, uap, retval)
        struct proc *p;
-       register struct arg {
-               u_int   gidsetsize;
-               int     *gidset;                /* XXX not yet POSIX */
-       } *uap;
-       int *retval;
+       register struct getgroups_args /* {
+               syscallarg(u_int) gidsetsize;
+               syscallarg(gid_t *) gidset;
+       } */ *uap;
+       register_t *retval;
 {
 {
-       register gid_t *gp;
-       register int *lp;
+       register struct pcred *pc = p->p_cred;
        register u_int ngrp;
        register u_int ngrp;
-       int groups[NGROUPS];
        int error;
 
        int error;
 
-       if ((ngrp = uap->gidsetsize) == 0) {
-               *retval = u.u_cred->cr_ngroups;
+       if ((ngrp = SCARG(uap, gidsetsize)) == 0) {
+               *retval = pc->pc_ucred->cr_ngroups;
                return (0);
        }
                return (0);
        }
-       if (ngrp < u.u_cred->cr_ngroups)
+       if (ngrp < pc->pc_ucred->cr_ngroups)
                return (EINVAL);
                return (EINVAL);
-       ngrp = u.u_cred->cr_ngroups;
-       for (gp = u.u_cred->cr_groups, lp = groups; lp < &groups[ngrp]; )
-               *lp++ = *gp++;
-       if (error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
-           ngrp * sizeof (groups[0])))
+       ngrp = pc->pc_ucred->cr_ngroups;
+       if (error = copyout((caddr_t)pc->pc_ucred->cr_groups,
+           (caddr_t)SCARG(uap, gidset), ngrp * sizeof(gid_t)))
                return (error);
        *retval = ngrp;
        return (0);
 }
 
 /* ARGSUSED */
                return (error);
        *retval = ngrp;
        return (0);
 }
 
 /* ARGSUSED */
+int
 setsid(p, uap, retval)
 setsid(p, uap, retval)
-       struct proc *p;
+       register struct proc *p;
        void *uap;
        void *uap;
-       int *retval;
+       register_t *retval;
 {
 
        if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
                return (EPERM);
        } else {
 {
 
        if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
                return (EPERM);
        } else {
-               pgmv(p, p->p_pid, 1);
+               (void)enterpgrp(p, p->p_pid, 1);
                *retval = p->p_pid;
                return (0);
        }
 }
 
 /*
                *retval = p->p_pid;
                return (0);
        }
 }
 
 /*
- * set process group (setpgrp/setpgid)
+ * set process group (setpgid/old setpgrp)
  *
  *
- * caller does setpgrp(pid, pgid)
+ * caller does setpgid(targpid, targpgid)
  *
  * pid must be caller or child of caller (ESRCH)
  * if a child
  *
  * pid must be caller or child of caller (ESRCH)
  * if a child
@@ -173,218 +184,256 @@ setsid(p, uap, retval)
  * pid must not be session leader (EPERM)
  */
 /* ARGSUSED */
  * pid must not be session leader (EPERM)
  */
 /* ARGSUSED */
-setpgrp(cp, uap, retval)
-       struct proc *cp;
-       register struct args {
-               int     pid;
-               int     pgid;
-       } *uap;
-       int *retval;
+int
+setpgid(curp, uap, retval)
+       struct proc *curp;
+       register struct setpgid_args /* {
+               syscallarg(int) pid;
+               syscallarg(int) pgid;
+       } */ *uap;
+       register_t *retval;
 {
 {
-       register struct proc *p;
-       register struct pgrp *pgrp;
+       register struct proc *targp;            /* target process */
+       register struct pgrp *pgrp;             /* target pgrp */
 
 
-       if (uap->pid != 0) {
-               if ((p = pfind(uap->pid)) == 0 || !inferior(p))
+       if (SCARG(uap, pid) != 0 && SCARG(uap, pid) != curp->p_pid) {
+               if ((targp = pfind(SCARG(uap, pid))) == 0 || !inferior(targp))
                        return (ESRCH);
                        return (ESRCH);
-               if (p->p_session != cp->p_session)
+               if (targp->p_session != curp->p_session)
                        return (EPERM);
                        return (EPERM);
-               if (p->p_flag&SEXEC)
+               if (targp->p_flag & P_EXEC)
                        return (EACCES);
        } else
                        return (EACCES);
        } else
-               p = cp;
-       if (SESS_LEADER(p))
+               targp = curp;
+       if (SESS_LEADER(targp))
                return (EPERM);
                return (EPERM);
-       if (uap->pgid == 0)
-               uap->pgid = p->p_pid;
-       else if (uap->pgid != p->p_pid)
-               if ((pgrp = pgfind(uap->pgid)) == 0 ||
-                   pgrp->pg_mem == NULL ||
-                   pgrp->pg_session != cp->p_session)
+       if (SCARG(uap, pgid) == 0)
+               SCARG(uap, pgid) = targp->p_pid;
+       else if (SCARG(uap, pgid) != targp->p_pid)
+               if ((pgrp = pgfind(SCARG(uap, pgid))) == 0 ||
+                   pgrp->pg_session != curp->p_session)
                        return (EPERM);
                        return (EPERM);
-       pgmv(p, uap->pgid, 0);
-       return (0);
+       return (enterpgrp(targp, SCARG(uap, pgid), 0));
 }
 
 /* ARGSUSED */
 }
 
 /* ARGSUSED */
+int
 setuid(p, uap, retval)
 setuid(p, uap, retval)
-       register struct proc *p;
-       struct args {
-               int     uid;
-       } *uap;
-       int *retval;
+       struct proc *p;
+       struct setuid_args /* {
+               syscallarg(uid_t) uid;
+       } */ *uap;
+       register_t *retval;
 {
 {
+       register struct pcred *pc = p->p_cred;
        register uid_t uid;
        int error;
 
        register uid_t uid;
        int error;
 
-       uid = uap->uid;
-       if (uid != p->p_ruid && (error = suser(u.u_cred, &u.u_acflag)))
+       uid = SCARG(uap, uid);
+       if (uid != pc->p_ruid &&
+           (error = suser(pc->pc_ucred, &p->p_acflag)))
                return (error);
        /*
                return (error);
        /*
-        * Everything's okay, do it.  Copy credentials so other references do
-        * not see our changes.
+        * Everything's okay, do it.
+        * Transfer proc count to new user.
+        * Copy credentials so other references do not see our changes.
         */
         */
-       u.u_cred = crcopy(u.u_cred);
-       u.u_cred->cr_uid = uid;
-       p->p_uid = uid;
-       p->p_ruid = uid;
-       p->p_svuid = uid;
+       (void)chgproccnt(pc->p_ruid, -1);
+       (void)chgproccnt(uid, 1);
+       pc->pc_ucred = crcopy(pc->pc_ucred);
+       pc->pc_ucred->cr_uid = uid;
+       pc->p_ruid = uid;
+       pc->p_svuid = uid;
+       p->p_flag |= P_SUGID;
        return (0);
 }
 
 /* ARGSUSED */
        return (0);
 }
 
 /* ARGSUSED */
+int
 seteuid(p, uap, retval)
 seteuid(p, uap, retval)
-       register struct proc *p;
-       struct args {
-               int     euid;
-       } *uap;
-       int *retval;
+       struct proc *p;
+       struct seteuid_args /* {
+               syscallarg(uid_t) euid;
+       } */ *uap;
+       register_t *retval;
 {
 {
+       register struct pcred *pc = p->p_cred;
        register uid_t euid;
        int error;
 
        register uid_t euid;
        int error;
 
-       euid = uap->euid;
-       if (euid != p->p_ruid && euid != p->p_svuid &&
-           (error = suser(u.u_cred, &u.u_acflag)))
+       euid = SCARG(uap, euid);
+       if (euid != pc->p_ruid && euid != pc->p_svuid &&
+           (error = suser(pc->pc_ucred, &p->p_acflag)))
                return (error);
        /*
         * Everything's okay, do it.  Copy credentials so other references do
         * not see our changes.
         */
                return (error);
        /*
         * Everything's okay, do it.  Copy credentials so other references do
         * not see our changes.
         */
-       u.u_cred = crcopy(u.u_cred);
-       u.u_cred->cr_uid = euid;
-       p->p_uid = euid;
+       pc->pc_ucred = crcopy(pc->pc_ucred);
+       pc->pc_ucred->cr_uid = euid;
+       p->p_flag |= P_SUGID;
        return (0);
 }
 
 /* ARGSUSED */
        return (0);
 }
 
 /* ARGSUSED */
+int
 setgid(p, uap, retval)
        struct proc *p;
 setgid(p, uap, retval)
        struct proc *p;
-       struct args {
-               int     gid;
-       } *uap;
-       int *retval;
+       struct setgid_args /* {
+               syscallarg(gid_t) gid;
+       } */ *uap;
+       register_t *retval;
 {
 {
+       register struct pcred *pc = p->p_cred;
        register gid_t gid;
        int error;
 
        register gid_t gid;
        int error;
 
-       gid = uap->gid;
-       if (gid != p->p_rgid && (error = suser(u.u_cred, &u.u_acflag)))
+       gid = SCARG(uap, gid);
+       if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
                return (error);
                return (error);
-       u.u_cred = crcopy(u.u_cred);
-       p->p_rgid = gid;
-       u.u_cred->cr_groups[0] = gid;
-       p->p_svgid = gid;               /* ??? */
+       pc->pc_ucred = crcopy(pc->pc_ucred);
+       pc->pc_ucred->cr_groups[0] = gid;
+       pc->p_rgid = gid;
+       pc->p_svgid = gid;              /* ??? */
+       p->p_flag |= P_SUGID;
        return (0);
 }
 
 /* ARGSUSED */
        return (0);
 }
 
 /* ARGSUSED */
+int
 setegid(p, uap, retval)
        struct proc *p;
 setegid(p, uap, retval)
        struct proc *p;
-       struct args {
-               int     egid;
-       } *uap;
-       int *retval;
+       struct setegid_args /* {
+               syscallarg(gid_t) egid;
+       } */ *uap;
+       register_t *retval;
 {
 {
+       register struct pcred *pc = p->p_cred;
        register gid_t egid;
        int error;
 
        register gid_t egid;
        int error;
 
-       egid = uap->egid;
-       if (egid != p->p_rgid && egid != p->p_svgid &&
-           (error = suser(u.u_cred, &u.u_acflag)))
+       egid = SCARG(uap, egid);
+       if (egid != pc->p_rgid && egid != pc->p_svgid &&
+           (error = suser(pc->pc_ucred, &p->p_acflag)))
                return (error);
                return (error);
-       u.u_cred = crcopy(u.u_cred);
-       u.u_cred->cr_groups[0] = egid;
+       pc->pc_ucred = crcopy(pc->pc_ucred);
+       pc->pc_ucred->cr_groups[0] = egid;
+       p->p_flag |= P_SUGID;
        return (0);
 }
 
        return (0);
 }
 
-#ifdef COMPAT_43
 /* ARGSUSED */
 /* ARGSUSED */
-osetreuid(p, uap, retval)
-       register struct proc *p;
-       struct args {
-               int     ruid;
-               int     euid;
-       } *uap;
-       int *retval;
+int
+setgroups(p, uap, retval)
+       struct proc *p;
+       struct setgroups_args /* {
+               syscallarg(u_int) gidsetsize;
+               syscallarg(gid_t *) gidset;
+       } */ *uap;
+       register_t *retval;
 {
 {
-       register uid_t ruid, euid;
+       register struct pcred *pc = p->p_cred;
+       register u_int ngrp;
        int error;
 
        int error;
 
-       if (uap->ruid == -1)
-           (error = suser(u.u_cred, &u.u_acflag)))
+       if (error = suser(pc->pc_ucred, &p->p_acflag))
                return (error);
                return (error);
-       if (uap->euid == -1)
-           euid != p->p_svuid && (error = suser(u.u_cred, &u.u_acflag)))
+       ngrp = SCARG(uap, gidsetsize);
+       if (ngrp < 1 || ngrp > NGROUPS)
+               return (EINVAL);
+       pc->pc_ucred = crcopy(pc->pc_ucred);
+       if (error = copyin((caddr_t)SCARG(uap, gidset),
+           (caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t)))
                return (error);
                return (error);
-       /*
-        * Everything's okay, do it.  Copy credentials so other references do
-        * not see our changes.
-        */
-       u.u_cred = crcopy(u.u_cred);
-       u.u_cred->cr_uid = euid;
-       p->p_uid = euid;
-       p->p_ruid = ruid;
+       pc->pc_ucred->cr_ngroups = ngrp;
+       p->p_flag |= P_SUGID;
        return (0);
 }
 
        return (0);
 }
 
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
 /* ARGSUSED */
 /* ARGSUSED */
-osetregid(p, uap, retval)
-       struct proc *p;
-       struct args {
-               int     rgid;
-               int     egid;
-       } *uap;
-       int *retval;
+int
+compat_43_setreuid(p, uap, retval)
+       register struct proc *p;
+       struct compat_43_setreuid_args /* {
+               syscallarg(int) ruid;
+               syscallarg(int) euid;
+       } */ *uap;
+       register_t *retval;
 {
 {
-       register gid_t rgid, egid;
-       int error;
+       register struct pcred *pc = p->p_cred;
+       union {
+               struct setuid_args sa;
+               struct seteuid_args ea;
+       } args;
 
 
-       if (uap->rgid == -1)
-           (error = suser(u.u_cred, &u.u_acflag)))
-               return (error);
-       if (uap->egid == -1)
-           egid != p->p_svgid && (error = suser(u.u_cred, &u.u_acflag)))
-               return (error);
-       u.u_cred = crcopy(u.u_cred);
-       p->p_rgid = rgid;
-       u.u_cred->cr_groups[0] = egid;
-       return (0);
+       /*
+        * If ruid == euid then setreuid is being used to emulate setuid,
+        * just do it.
+        */
+       if (SCARG(uap, ruid) != -1 && SCARG(uap, ruid) == SCARG(uap, euid)) {
+               SCARG(&args.sa, uid) = SCARG(uap, ruid);
+               return (setuid(p, &args.sa, retval));
+       }
+       /*
+        * Otherwise we assume that the intent of setting ruid is to be
+        * able to get back ruid priviledge (i.e. swapping ruid and euid).
+        * So we make sure that we will be able to do so, but do not
+        * actually set the ruid.
+        */
+       if (SCARG(uap, ruid) != (uid_t)-1 && SCARG(uap, ruid) != pc->p_ruid &&
+           SCARG(uap, ruid) != pc->p_svuid)
+               return (EPERM);
+       if (SCARG(uap, euid) == (uid_t)-1)
+               return (0);
+       SCARG(&args.ea, euid) = SCARG(uap, euid);
+       return (seteuid(p, &args.ea, retval));
 }
 }
-#endif
 
 /* ARGSUSED */
 
 /* ARGSUSED */
-setgroups(p, uap, retval)
-       struct proc *p;
-       struct args {
-               u_int   gidsetsize;
-               int     *gidset;
-       } *uap;
-       int *retval;
+int
+compat_43_setregid(p, uap, retval)
+       register struct proc *p;
+       struct compat_43_setregid_args /* {
+               syscallarg(int) rgid;
+               syscallarg(int) egid;
+       } */ *uap;
+       register_t *retval;
 {
 {
-       register gid_t *gp;
-       register u_int ngrp;
-       register int *lp;
-       int error, groups[NGROUPS];
+       register struct pcred *pc = p->p_cred;
+       union {
+               struct setgid_args sa;
+               struct setegid_args ea;
+       } args;
 
 
-       if (error = suser(u.u_cred, &u.u_acflag))
-               return (error);
-       if ((ngrp = uap->gidsetsize) > NGROUPS)
-               return (EINVAL);
-       if (error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
-           ngrp * sizeof (groups[0])))
-               return (error);
-       u.u_cred = crcopy(u.u_cred);
-       u.u_cred->cr_ngroups = ngrp;
-       /* convert from int's to gid_t's */
-       for (gp = u.u_cred->cr_groups, lp = groups; ngrp--; )
-               *gp++ = *lp++;
-       return (0);
+       /*
+        * If rgid == egid then setreuid is being used to emulate setgid,
+        * just do it.
+        */
+       if (SCARG(uap, rgid) != -1 && SCARG(uap, rgid) == SCARG(uap, egid)) {
+               SCARG(&args.sa, gid) = SCARG(uap, rgid);
+               return (setgid(p, &args.sa, retval));
+       }
+       /*
+        * Otherwise we assume that the intent of setting rgid is to be
+        * able to get back rgid priviledge (i.e. swapping rgid and egid).
+        * So we make sure that we will be able to do so, but do not
+        * actually set the rgid.
+        */
+       if (SCARG(uap, rgid) != (gid_t)-1 && SCARG(uap, rgid) != pc->p_rgid &&
+           SCARG(uap, rgid) != pc->p_svgid)
+               return (EPERM);
+       if (SCARG(uap, egid) == (gid_t)-1)
+               return (0);
+       SCARG(&args.ea, egid) = SCARG(uap, egid);
+       return (setegid(p, &args.ea, retval));
 }
 }
+#endif /* defined(COMPAT_43) || defined(COMPAT_SUNOS) */
 
 /*
  * Check if gid is a member of the group set.
  */
 
 /*
  * Check if gid is a member of the group set.
  */
+int
 groupmember(gid, cred)
        gid_t gid;
        register struct ucred *cred;
 groupmember(gid, cred)
        gid_t gid;
        register struct ucred *cred;
@@ -400,11 +449,15 @@ groupmember(gid, cred)
 }
 
 /*
 }
 
 /*
- * Test if the current user is the super user.
+ * Test whether the specified credentials imply "super-user"
+ * privilege; if so, and we have accounting info, set the flag
+ * indicating use of super-powers.
+ * Returns 0 or error.
  */
  */
+int
 suser(cred, acflag)
        struct ucred *cred;
 suser(cred, acflag)
        struct ucred *cred;
-       short *acflag;
+       u_short *acflag;
 {
        if (cred->cr_uid == 0) {
                if (acflag)
 {
        if (cred->cr_uid == 0) {
                if (acflag)
@@ -432,16 +485,15 @@ crget()
  * Free a cred structure.
  * Throws away space when ref count gets to 0.
  */
  * Free a cred structure.
  * Throws away space when ref count gets to 0.
  */
+void
 crfree(cr)
        struct ucred *cr;
 {
 crfree(cr)
        struct ucred *cr;
 {
-       int s = splimp();
+       int s;
 
 
-       if (--cr->cr_ref != 0) {
-               (void) splx(s);
-               return;
-       }
-       FREE((caddr_t)cr, M_CRED);
+       s = splimp();                           /* ??? */
+       if (--cr->cr_ref == 0)
+               FREE((caddr_t)cr, M_CRED);
        (void) splx(s);
 }
 
        (void) splx(s);
 }
 
@@ -482,39 +534,42 @@ crdup(cr)
  * Get login name, if available.
  */
 /* ARGSUSED */
  * Get login name, if available.
  */
 /* ARGSUSED */
+int
 getlogin(p, uap, retval)
        struct proc *p;
 getlogin(p, uap, retval)
        struct proc *p;
-       struct args {
-               char    *namebuf;
-               u_int   namelen;
-       } *uap;
-       int *retval;
+       struct getlogin_args /* {
+               syscallarg(char *) namebuf;
+               syscallarg(u_int) namelen;
+       } */ *uap;
+       register_t *retval;
 {
 
 {
 
-       if (uap->namelen > sizeof (p->p_logname))
-               uap->namelen = sizeof (p->p_logname);
-       return (copyout((caddr_t)p->p_logname, (caddr_t)uap->namebuf,
-           uap->namelen));
+       if (SCARG(uap, namelen) > sizeof (p->p_pgrp->pg_session->s_login))
+               SCARG(uap, namelen) = sizeof (p->p_pgrp->pg_session->s_login);
+       return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
+           (caddr_t) SCARG(uap, namebuf), SCARG(uap, namelen)));
 }
 
 /*
  * Set login name.
  */
 /* ARGSUSED */
 }
 
 /*
  * Set login name.
  */
 /* ARGSUSED */
+int
 setlogin(p, uap, retval)
        struct proc *p;
 setlogin(p, uap, retval)
        struct proc *p;
-       struct args {
-               char    *namebuf;
-       } *uap;
-       int *retval;
+       struct setlogin_args /* {
+               syscallarg(char *) namebuf;
+       } */ *uap;
+       register_t *retval;
 {
        int error;
 
 {
        int error;
 
-       if (error = suser(u.u_cred, &u.u_acflag))
+       if (error = suser(p->p_ucred, &p->p_acflag))
                return (error);
                return (error);
-       error = copyinstr((caddr_t)uap->namebuf, (caddr_t)p->p_logname,
-           sizeof (p->p_logname) - 1, (u_int *)0);
-       if (error == ENAMETOOLONG)              /* name too long */
+       error = copyinstr((caddr_t) SCARG(uap, namebuf),
+           (caddr_t) p->p_pgrp->pg_session->s_login,
+           sizeof (p->p_pgrp->pg_session->s_login) - 1, (u_int *)0);
+       if (error == ENAMETOOLONG)
                error = EINVAL;
        return (error);
 }
                error = EINVAL;
        return (error);
 }