update to lite

This commit is contained in:
cgd 1994-05-19 05:57:44 +00:00
parent 31f076d805
commit 540aa31a08
4 changed files with 225 additions and 196 deletions

View File

@ -1 +1 @@
revision 1.22 intentionally removed revision 1.23 intentionally removed

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. * Copyright (c) 1982, 1986, 1989, 1991, 1993
* All rights reserved. * The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc. * (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed * All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph * to the University of California by American Telephone and Telegraph
@ -35,12 +35,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)kern_fork.c 7.29 (Berkeley) 5/15/91 * from: @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
* $Id: kern_fork.c,v 1.16 1994/05/17 04:21:54 cgd Exp $ * $Id: kern_fork.c,v 1.17 1994/05/19 05:57:48 cgd Exp $
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/map.h>
#include <sys/filedesc.h> #include <sys/filedesc.h>
#include <sys/kernel.h> #include <sys/kernel.h>
#include <sys/malloc.h> #include <sys/malloc.h>
@ -51,13 +52,7 @@
#include <sys/acct.h> #include <sys/acct.h>
#include <sys/ktrace.h> #include <sys/ktrace.h>
#include <vm/vm.h>
/* would be static, except for symbol-sharing considerations in ddb, etc */
int fork1(struct proc *p1, int isvfork, int retval[]);
/* ARGSUSED */ /* ARGSUSED */
int
fork(p, uap, retval) fork(p, uap, retval)
struct proc *p; struct proc *p;
void *uap; void *uap;
@ -68,7 +63,6 @@ fork(p, uap, retval)
} }
/* ARGSUSED */ /* ARGSUSED */
int
vfork(p, uap, retval) vfork(p, uap, retval)
struct proc *p; struct proc *p;
void *uap; void *uap;
@ -80,42 +74,45 @@ vfork(p, uap, retval)
int nprocs = 1; /* process 0 */ int nprocs = 1; /* process 0 */
int
fork1(p1, isvfork, retval) fork1(p1, isvfork, retval)
register struct proc *p1; register struct proc *p1;
int isvfork, retval[]; int isvfork, retval[];
{ {
register struct proc *p2; register struct proc *p2;
register int count, uid; register uid_t uid;
struct proc *newproc;
struct proc **hash;
int count;
static int nextpid, pidchecked = 0; static int nextpid, pidchecked = 0;
count = 0;
if ((uid = p1->p_ucred->cr_uid) != 0) {
for (p2 = (struct proc *)allproc; p2; p2 = p2->p_next)
if (p2->p_ucred->cr_uid == uid)
count++;
for (p2 = zombproc; p2; p2 = p2->p_next)
if (p2->p_ucred->cr_uid == uid)
count++;
}
/* /*
* Although process entries are dynamically entries, we still keep * Although process entries are dynamically created, we still keep
* a global limit on the maximum number we will create. Don't allow * a global limit on the maximum number we will create. Don't allow
* a nonprivileged user to use the last process; don't let root * a nonprivileged user to use the last process; don't let root
* exceed the limit. The variable nprocs is the current number of * exceed the limit. The variable nprocs is the current number of
* processes, maxproc is the limit. * processes, maxproc is the limit.
*/ */
uid = p1->p_cred->p_ruid;
if ((nprocs >= maxproc - 1 && uid != 0) || nprocs >= maxproc) { if ((nprocs >= maxproc - 1 && uid != 0) || nprocs >= maxproc) {
tablefull("proc"); tablefull("proc");
return (EAGAIN); return (EAGAIN);
} }
if (count > p1->p_rlimit[RLIMIT_NPROC].rlim_cur) /*
* Increment the count of procs running with this uid. Don't allow
* a nonprivileged user to exceed their current limit.
*/
count = chgproccnt(uid, 1);
if (uid != 0 && count > p1->p_rlimit[RLIMIT_NPROC].rlim_cur) {
(void)chgproccnt(uid, -1);
return (EAGAIN); return (EAGAIN);
}
/* Allocate new proc. */
MALLOC(newproc, struct proc *, sizeof(struct proc), M_PROC, M_WAITOK);
/* /*
* Find an unused process ID. * Find an unused process ID. We remember a range of unused IDs
* We remember a range of unused IDs ready to use * ready to use (from nextpid+1 through pidchecked-1).
* (from nextpid+1 through pidchecked-1).
*/ */
nextpid++; nextpid++;
retry: retry:
@ -161,15 +158,16 @@ again:
/* /*
* Allocate new proc.
* Link onto allproc (this should probably be delayed). * Link onto allproc (this should probably be delayed).
* Heavy use of volatile here to prevent the compiler from
* rearranging code. Yes, it *is* terribly ugly, but at least
* it works.
*/ */
MALLOC(p2, struct proc *, sizeof(struct proc), M_PROC, M_WAITOK);
nprocs++; nprocs++;
#define Vp2 ((volatile struct proc *)p2) p2 = newproc;
Vp2->p_stat = SIDL; /* protect from others */ #define Vp2 ((volatile struct proc *)p2)
Vp2->p_stat = SIDL; /* protect against others */
Vp2->p_pid = nextpid; Vp2->p_pid = nextpid;
/* /*
* This is really: * This is really:
* p2->p_next = allproc; * p2->p_next = allproc;
@ -183,10 +181,13 @@ again:
(volatile struct proc **)&Vp2->p_next; (volatile struct proc **)&Vp2->p_next;
*(volatile struct proc ***)&Vp2->p_prev = &allproc; *(volatile struct proc ***)&Vp2->p_prev = &allproc;
allproc = Vp2; allproc = Vp2;
Vp2->p_forw = NULL; /* shouldn't be necessary */
Vp2->p_back = NULL; /* shouldn't be necessary */
#undef Vp2 #undef Vp2
p2->p_forw = p2->p_back = NULL; /* shouldn't be necessary */
/* Insert on the hash chain. */
hash = &pidhash[PIDHASH(p2->p_pid)];
p2->p_hash = *hash;
*hash = p2;
/* /*
* Make a proc table entry for the new process. * Make a proc table entry for the new process.
@ -203,16 +204,19 @@ again:
* Increase reference counts on shared objects. * Increase reference counts on shared objects.
* The p_stats and p_sigacts substructs are set in vm_fork. * The p_stats and p_sigacts substructs are set in vm_fork.
*/ */
p2->p_flag = P_INMEM;
if (p1->p_flag & P_PROFIL)
startprofclock(p2);
MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred), MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred),
M_SUBPROC, M_WAITOK); M_SUBPROC, M_WAITOK);
bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred)); bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred));
p2->p_cred->p_refcnt = 1; p2->p_cred->p_refcnt = 1;
crhold(p1->p_ucred); crhold(p1->p_ucred);
if (p1->p_textvp) { /* bump references to the text vnode (for procfs) */
p2->p_textvp = p1->p_textvp; p2->p_textvp = p1->p_textvp;
if (p2->p_textvp)
VREF(p2->p_textvp); VREF(p2->p_textvp);
}
p2->p_fd = fdcopy(p1); p2->p_fd = fdcopy(p1);
/* /*
@ -228,17 +232,10 @@ again:
p2->p_limit->p_refcnt++; p2->p_limit->p_refcnt++;
} }
p2->p_flag = P_INMEM;
if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT) if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
p2->p_flag |= P_CONTROLT; p2->p_flag |= P_CONTROLT;
if (isvfork) if (isvfork)
p2->p_flag |= P_PPWAIT; p2->p_flag |= P_PPWAIT;
{
struct proc **hash = &pidhash[PIDHASH(p2->p_pid)];
p2->p_hash = *hash;
*hash = p2;
}
p2->p_pgrpnxt = p1->p_pgrpnxt; p2->p_pgrpnxt = p1->p_pgrpnxt;
p1->p_pgrpnxt = p2; p1->p_pgrpnxt = p2;
p2->p_pptr = p1; p2->p_pptr = p1;
@ -258,10 +255,6 @@ again:
} }
#endif #endif
#if defined(tahoe)
p2->p_vmspace->p_ckey = p1->p_vmspace->p_ckey; /* XXX move this */
#endif
/* /*
* This begins the section where we must prevent the parent * This begins the section where we must prevent the parent
* from being swapped. * from being swapped.
@ -302,13 +295,13 @@ again:
p1->p_flag &= ~P_NOSWAP; p1->p_flag &= ~P_NOSWAP;
/* /*
* Preserve synchronization semantics of vfork. * Preserve synchronization semantics of vfork. If waiting for
* If waiting for child to exec or exit, set P_PPWAIT * child to exec or exit, set P_PPWAIT on child, and sleep on our
* on child, and sleep on our proc (in case of exit). * proc (in case of exit).
*/ */
if (isvfork) if (isvfork)
while (p2->p_flag & P_PPWAIT) while (p2->p_flag & P_PPWAIT)
tsleep((caddr_t)p1, PWAIT, "ppwait", 0); tsleep(p1, PWAIT, "ppwait", 0);
/* /*
* Return child pid to parent process, * Return child pid to parent process,

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. * Copyright (c) 1982, 1986, 1989, 1991, 1993
* All rights reserved. * The Regents of the University of California. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,32 +30,93 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)kern_proc.c 7.16 (Berkeley) 6/28/91 * from: @(#)kern_proc.c 8.4 (Berkeley) 1/4/94
* $Id: kern_proc.c,v 1.6 1994/05/04 03:41:56 cgd Exp $ * $Id: kern_proc.c,v 1.7 1994/05/19 05:57:50 cgd Exp $
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/map.h>
#include <sys/kernel.h> #include <sys/kernel.h>
#include <sys/proc.h> #include <sys/proc.h>
#include <sys/buf.h> #include <sys/buf.h>
#include <sys/acct.h> #include <sys/acct.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/file.h> #include <sys/file.h>
#include <ufs/quota.h> /* XXX */
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/malloc.h> #include <sys/malloc.h>
#include <sys/mbuf.h> #include <sys/mbuf.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/tty.h> #include <sys/tty.h>
#include <ufs/quota.h> /*
* Structure associated with user cacheing.
*/
struct uidinfo {
struct uidinfo *ui_next;
struct uidinfo **ui_prev;
uid_t ui_uid;
long ui_proccnt;
} **uihashtbl;
u_long uihash; /* size of hash table - 1 */
#define UIHASH(uid) ((uid) & uihash)
/* static */ void pgdelete __P((struct pgrp *pgrp)); /*
* Allocate a hash table.
*/
usrinfoinit()
{
uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash);
}
/*
* Change the count associated with number of processes
* a given user is using.
*/
int
chgproccnt(uid, diff)
uid_t uid;
int diff;
{
register struct uidinfo **uipp, *uip, *uiq;
uipp = &uihashtbl[UIHASH(uid)];
for (uip = *uipp; uip; uip = uip->ui_next)
if (uip->ui_uid == uid)
break;
if (uip) {
uip->ui_proccnt += diff;
if (uip->ui_proccnt > 0)
return (uip->ui_proccnt);
if (uip->ui_proccnt < 0)
panic("chgproccnt: procs < 0");
if (uiq = uip->ui_next)
uiq->ui_prev = uip->ui_prev;
*uip->ui_prev = uiq;
FREE(uip, M_PROC);
return (0);
}
if (diff <= 0) {
if (diff == 0)
return(0);
panic("chgproccnt: lost user");
}
MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK);
if (uiq = *uipp)
uiq->ui_prev = &uip->ui_next;
uip->ui_next = uiq;
uip->ui_prev = uipp;
*uipp = uip;
uip->ui_uid = uid;
uip->ui_proccnt = diff;
return (diff);
}
/* /*
* Is p an inferior of the current process? * Is p an inferior of the current process?
*/ */
int
inferior(p) inferior(p)
register struct proc *p; register struct proc *p;
{ {
@ -73,12 +134,12 @@ struct proc *
pfind(pid) pfind(pid)
register pid_t pid; register pid_t pid;
{ {
register struct proc *p = pidhash[PIDHASH(pid)]; register struct proc *p;
for (; p; p = p->p_hash) for (p = pidhash[PIDHASH(pid)]; p != NULL; p = p->p_hash)
if (p->p_pid == pid) if (p->p_pid == pid)
return (p); return (p);
return ((struct proc *)0); return (NULL);
} }
/* /*
@ -88,18 +149,18 @@ struct pgrp *
pgfind(pgid) pgfind(pgid)
register pid_t pgid; register pid_t pgid;
{ {
register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)]; register struct pgrp *pgrp;
for (; pgrp; pgrp = pgrp->pg_hforw) for (pgrp = pgrphash[PIDHASH(pgid)];
pgrp != NULL; pgrp = pgrp->pg_hforw)
if (pgrp->pg_id == pgid) if (pgrp->pg_id == pgid)
return (pgrp); return (pgrp);
return ((struct pgrp *)0); return (NULL);
} }
/* /*
* Move p to a new or existing process group (and session) * Move p to a new or existing process group (and session)
*/ */
void
enterpgrp(p, pgid, mksess) enterpgrp(p, pgid, mksess)
register struct proc *p; register struct proc *p;
pid_t pgid; pid_t pgid;
@ -110,12 +171,14 @@ enterpgrp(p, pgid, mksess)
int n; int n;
#ifdef DIAGNOSTIC #ifdef DIAGNOSTIC
if (pgrp && mksess) /* firewalls */ if (pgrp != NULL && mksess) /* firewalls */
panic("enterpgrp: setsid into non-empty pgrp"); panic("enterpgrp: setsid into non-empty pgrp");
if (SESS_LEADER(p)) if (SESS_LEADER(p))
panic("enterpgrp: session leader attempted setpgrp"); panic("enterpgrp: session leader attempted setpgrp");
#endif #endif
if (pgrp == NULL) { if (pgrp == NULL) {
pid_t savepid = p->p_pid;
struct proc *np;
/* /*
* new process group * new process group
*/ */
@ -125,6 +188,8 @@ enterpgrp(p, pgid, mksess)
#endif #endif
MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
M_WAITOK); M_WAITOK);
if ((np = pfind(savepid)) == NULL || np != p)
return (ESRCH);
if (mksess) { if (mksess) {
register struct session *sess; register struct session *sess;
@ -155,7 +220,7 @@ enterpgrp(p, pgid, mksess)
pgrp->pg_jobc = 0; pgrp->pg_jobc = 0;
pgrp->pg_mem = NULL; pgrp->pg_mem = NULL;
} else if (pgrp == p->p_pgrp) } else if (pgrp == p->p_pgrp)
return; return (0);
/* /*
* Adjust eligibility of affected pgrps to participate in job control. * Adjust eligibility of affected pgrps to participate in job control.
@ -168,13 +233,16 @@ enterpgrp(p, pgid, mksess)
/* /*
* unlink p from old process group * unlink p from old process group
*/ */
for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) {
if (*pp == p) { if (*pp == p) {
*pp = p->p_pgrpnxt; *pp = p->p_pgrpnxt;
goto done; break;
} }
panic("enterpgrp: can't find p on old pgrp"); }
done: #ifdef DIAGNOSTIC
if (pp == NULL)
panic("enterpgrp: can't find p on old pgrp");
#endif
/* /*
* delete old if empty * delete old if empty
*/ */
@ -186,33 +254,36 @@ done:
p->p_pgrp = pgrp; p->p_pgrp = pgrp;
p->p_pgrpnxt = pgrp->pg_mem; p->p_pgrpnxt = pgrp->pg_mem;
pgrp->pg_mem = p; pgrp->pg_mem = p;
return (0);
} }
/* /*
* remove process from process group * remove process from process group
*/ */
void
leavepgrp(p) leavepgrp(p)
register struct proc *p; register struct proc *p;
{ {
register struct proc **pp = &p->p_pgrp->pg_mem; register struct proc **pp = &p->p_pgrp->pg_mem;
for (; *pp; pp = &(*pp)->p_pgrpnxt) for (; *pp; pp = &(*pp)->p_pgrpnxt) {
if (*pp == p) { if (*pp == p) {
*pp = p->p_pgrpnxt; *pp = p->p_pgrpnxt;
goto done; break;
} }
panic("leavepgrp: can't find p in pgrp"); }
done: #ifdef DIAGNOSTIC
if (pp == NULL)
panic("leavepgrp: can't find p in pgrp");
#endif
if (!p->p_pgrp->pg_mem) if (!p->p_pgrp->pg_mem)
pgdelete(p->p_pgrp); pgdelete(p->p_pgrp);
p->p_pgrp = 0; p->p_pgrp = 0;
return (0);
} }
/* /*
* delete a process group [internal] * delete a process group
*/ */
void
pgdelete(pgrp) pgdelete(pgrp)
register struct pgrp *pgrp; register struct pgrp *pgrp;
{ {
@ -221,13 +292,16 @@ pgdelete(pgrp)
if (pgrp->pg_session->s_ttyp != NULL && if (pgrp->pg_session->s_ttyp != NULL &&
pgrp->pg_session->s_ttyp->t_pgrp == pgrp) pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
pgrp->pg_session->s_ttyp->t_pgrp = NULL; pgrp->pg_session->s_ttyp->t_pgrp = NULL;
for (; *pgp; pgp = &(*pgp)->pg_hforw) for (; *pgp; pgp = &(*pgp)->pg_hforw) {
if (*pgp == pgrp) { if (*pgp == pgrp) {
*pgp = pgrp->pg_hforw; *pgp = pgrp->pg_hforw;
goto done; break;
} }
panic("pgdelete: can't find pgrp on hash chain"); }
done: #ifdef DIAGNOSTIC
if (pgp == NULL)
panic("pgdelete: can't find pgrp on hash chain");
#endif
if (--pgrp->pg_session->s_count == 0) if (--pgrp->pg_session->s_count == 0)
FREE(pgrp->pg_session, M_SESSION); FREE(pgrp->pg_session, M_SESSION);
FREE(pgrp, M_PGRP); FREE(pgrp, M_PGRP);
@ -304,7 +378,6 @@ orphanpg(pg)
#ifdef debug #ifdef debug
/* DEBUG */ /* DEBUG */
void
pgrpdump() pgrpdump()
{ {
register struct pgrp *pgrp; register struct pgrp *pgrp;

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 1982, 1986, 1989, 1990, 1991 Regents of the University * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
* of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc. * (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed * All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph * to the University of California by American Telephone and Telegraph
@ -35,8 +35,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)kern_prot.c 7.21 (Berkeley) 5/3/91 * from: @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
* $Id: kern_prot.c,v 1.14 1994/05/17 04:21:57 cgd Exp $ * $Id: kern_prot.c,v 1.15 1994/05/19 05:57:55 cgd Exp $
*/ */
/* /*
@ -53,7 +53,6 @@
#include <sys/malloc.h> #include <sys/malloc.h>
/* ARGSUSED */ /* ARGSUSED */
int
getpid(p, uap, retval) getpid(p, uap, retval)
struct proc *p; struct proc *p;
void *uap; void *uap;
@ -68,7 +67,6 @@ getpid(p, uap, retval)
} }
/* ARGSUSED */ /* ARGSUSED */
int
getppid(p, uap, retval) getppid(p, uap, retval)
struct proc *p; struct proc *p;
void *uap; void *uap;
@ -80,7 +78,6 @@ getppid(p, uap, retval)
} }
/* Get process group ID; note that POSIX getpgrp takes no parameter */ /* Get process group ID; note that POSIX getpgrp takes no parameter */
int
getpgrp(p, uap, retval) getpgrp(p, uap, retval)
struct proc *p; struct proc *p;
void *uap; void *uap;
@ -92,7 +89,6 @@ getpgrp(p, uap, retval)
} }
/* ARGSUSED */ /* ARGSUSED */
int
getuid(p, uap, retval) getuid(p, uap, retval)
struct proc *p; struct proc *p;
void *uap; void *uap;
@ -107,7 +103,6 @@ getuid(p, uap, retval)
} }
/* ARGSUSED */ /* ARGSUSED */
int
geteuid(p, uap, retval) geteuid(p, uap, retval)
struct proc *p; struct proc *p;
void *uap; void *uap;
@ -119,7 +114,6 @@ geteuid(p, uap, retval)
} }
/* ARGSUSED */ /* ARGSUSED */
int
getgid(p, uap, retval) getgid(p, uap, retval)
struct proc *p; struct proc *p;
void *uap; void *uap;
@ -139,7 +133,6 @@ getgid(p, uap, retval)
* correctly in a library function. * correctly in a library function.
*/ */
/* ARGSUSED */ /* ARGSUSED */
int
getegid(p, uap, retval) getegid(p, uap, retval)
struct proc *p; struct proc *p;
void *uap; void *uap;
@ -154,8 +147,6 @@ struct getgroups_args {
u_int gidsetsize; u_int gidsetsize;
gid_t *gidset; gid_t *gidset;
}; };
int
getgroups(p, uap, retval) getgroups(p, uap, retval)
struct proc *p; struct proc *p;
register struct getgroups_args *uap; register struct getgroups_args *uap;
@ -180,7 +171,6 @@ getgroups(p, uap, retval)
} }
/* ARGSUSED */ /* ARGSUSED */
int
setsid(p, uap, retval) setsid(p, uap, retval)
register struct proc *p; register struct proc *p;
void *uap; void *uap;
@ -190,7 +180,7 @@ setsid(p, uap, retval)
if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) { if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
return (EPERM); return (EPERM);
} else { } else {
enterpgrp(p, p->p_pid, 1); (void)enterpgrp(p, p->p_pid, 1);
*retval = p->p_pid; *retval = p->p_pid;
return (0); return (0);
} }
@ -209,14 +199,11 @@ setsid(p, uap, retval)
* there must exist some pid in same session having pgid (EPERM) * there must exist some pid in same session having pgid (EPERM)
* pid must not be session leader (EPERM) * pid must not be session leader (EPERM)
*/ */
struct setpgid_args { struct setpgid_args {
int pid; /* target process id */ int pid; /* target process id */
int pgid; /* target pgrp id */ int pgid; /* target pgrp id */
}; };
/* ARGSUSED */ /* ARGSUSED */
int
setpgid(curp, uap, retval) setpgid(curp, uap, retval)
struct proc *curp; struct proc *curp;
register struct setpgid_args *uap; register struct setpgid_args *uap;
@ -235,7 +222,7 @@ setpgid(curp, uap, retval)
return (ESRCH); return (ESRCH);
if (targp->p_session != curp->p_session) if (targp->p_session != curp->p_session)
return (EPERM); return (EPERM);
if (targp->p_flag&P_EXEC) if (targp->p_flag & P_EXEC)
return (EACCES); return (EACCES);
} else } else
targp = curp; targp = curp;
@ -247,16 +234,13 @@ setpgid(curp, uap, retval)
if ((pgrp = pgfind(uap->pgid)) == 0 || if ((pgrp = pgfind(uap->pgid)) == 0 ||
pgrp->pg_session != curp->p_session) pgrp->pg_session != curp->p_session)
return (EPERM); return (EPERM);
enterpgrp(targp, uap->pgid, 0); return (enterpgrp(targp, uap->pgid, 0));
return (0);
} }
struct setuid_args { struct setuid_args {
uid_t uid; uid_t uid;
}; };
/* ARGSUSED */ /* ARGSUSED */
int
setuid(p, uap, retval) setuid(p, uap, retval)
struct proc *p; struct proc *p;
struct setuid_args *uap; struct setuid_args *uap;
@ -275,9 +259,12 @@ setuid(p, uap, retval)
(error = suser(pc->pc_ucred, &p->p_acflag))) (error = suser(pc->pc_ucred, &p->p_acflag)))
return (error); return (error);
/* /*
* Everything's okay, do it. Copy credentials so other references do * Everything's okay, do it.
* not see our changes. * Transfer proc count to new user.
* Copy credentials so other references do not see our changes.
*/ */
(void)chgproccnt(pc->p_ruid, -1);
(void)chgproccnt(uid, 1);
pc->pc_ucred = crcopy(pc->pc_ucred); pc->pc_ucred = crcopy(pc->pc_ucred);
pc->pc_ucred->cr_uid = uid; pc->pc_ucred->cr_uid = uid;
pc->p_ruid = uid; pc->p_ruid = uid;
@ -289,9 +276,7 @@ setuid(p, uap, retval)
struct seteuid_args { struct seteuid_args {
uid_t euid; uid_t euid;
}; };
/* ARGSUSED */ /* ARGSUSED */
int
seteuid(p, uap, retval) seteuid(p, uap, retval)
struct proc *p; struct proc *p;
struct seteuid_args *uap; struct seteuid_args *uap;
@ -322,9 +307,7 @@ seteuid(p, uap, retval)
struct setgid_args { struct setgid_args {
gid_t gid; gid_t gid;
}; };
/* ARGSUSED */ /* ARGSUSED */
int
setgid(p, uap, retval) setgid(p, uap, retval)
struct proc *p; struct proc *p;
struct setgid_args *uap; struct setgid_args *uap;
@ -352,9 +335,7 @@ setgid(p, uap, retval)
struct setegid_args { struct setegid_args {
gid_t egid; gid_t egid;
}; };
/* ARGSUSED */ /* ARGSUSED */
int
setegid(p, uap, retval) setegid(p, uap, retval)
struct proc *p; struct proc *p;
struct setegid_args *uap; struct setegid_args *uap;
@ -378,74 +359,11 @@ setegid(p, uap, retval)
return (0); return (0);
} }
#ifdef COMPAT_43
struct osetreuid_args {
uid_t ruid;
uid_t euid;
};
/* ARGSUSED */
int
osetreuid(p, uap, retval)
register struct proc *p;
struct osetreuid_args *uap;
int *retval;
{
register struct pcred *pc = p->p_cred;
struct seteuid_args args;
/*
* we assume that the intent of setting ruid is to be able to get
* back ruid priviledge. So we make sure that we will be able to
* do so, but do not actually set the ruid.
*/
if (uap->ruid != (uid_t)-1 && uap->ruid != pc->p_ruid &&
uap->ruid != pc->p_svuid)
return (EPERM);
if (uap->euid == (uid_t)-1)
return (0);
args.euid = uap->euid;
return (seteuid(p, &args, retval));
}
struct osetregid_args {
gid_t rgid;
gid_t egid;
};
/* ARGSUSED */
int
osetregid(p, uap, retval)
register struct proc *p;
struct osetregid_args *uap;
int *retval;
{
register struct pcred *pc = p->p_cred;
struct setegid_args args;
/*
* we assume that the intent of setting rgid is to be able to get
* back rgid priviledge. So we make sure that we will be able to
* do so, but do not actually set the rgid.
*/
if (uap->rgid != (gid_t)-1 && uap->rgid != pc->p_rgid &&
uap->rgid != pc->p_svgid)
return (EPERM);
if (uap->egid == (gid_t)-1)
return (0);
args.egid = uap->egid;
return (setegid(p, &args, retval));
}
#endif
struct setgroups_args { struct setgroups_args {
u_int gidsetsize; u_int gidsetsize;
gid_t *gidset; gid_t *gidset;
}; };
/* ARGSUSED */ /* ARGSUSED */
int
setgroups(p, uap, retval) setgroups(p, uap, retval)
struct proc *p; struct proc *p;
struct setgroups_args *uap; struct setgroups_args *uap;
@ -468,10 +386,65 @@ setgroups(p, uap, retval)
return (0); return (0);
} }
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
struct setreuid_args {
int ruid;
int euid;
};
/* ARGSUSED */
osetreuid(p, uap, retval)
register struct proc *p;
struct setreuid_args *uap;
int *retval;
{
register struct pcred *pc = p->p_cred;
struct seteuid_args args;
/*
* we assume that the intent of setting ruid is to be able to get
* back ruid priviledge. So we make sure that we will be able to
* do so, but do not actually set the ruid.
*/
if (uap->ruid != (uid_t)-1 && uap->ruid != pc->p_ruid &&
uap->ruid != pc->p_svuid)
return (EPERM);
if (uap->euid == (uid_t)-1)
return (0);
args.euid = uap->euid;
return (seteuid(p, &args, retval));
}
struct setregid_args {
int rgid;
int egid;
};
/* ARGSUSED */
osetregid(p, uap, retval)
register struct proc *p;
struct setregid_args *uap;
int *retval;
{
register struct pcred *pc = p->p_cred;
struct setegid_args args;
/*
* we assume that the intent of setting rgid is to be able to get
* back rgid priviledge. So we make sure that we will be able to
* do so, but do not actually set the rgid.
*/
if (uap->rgid != (gid_t)-1 && uap->rgid != pc->p_rgid &&
uap->rgid != pc->p_svgid)
return (EPERM);
if (uap->egid == (gid_t)-1)
return (0);
args.egid = uap->egid;
return (setegid(p, &args, 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) groupmember(gid, cred)
gid_t gid; gid_t gid;
register struct ucred *cred; register struct ucred *cred;
@ -492,7 +465,6 @@ groupmember(gid, cred)
* indicating use of super-powers. * indicating use of super-powers.
* Returns 0 or error. * Returns 0 or error.
*/ */
int
suser(cred, acflag) suser(cred, acflag)
struct ucred *cred; struct ucred *cred;
u_short *acflag; u_short *acflag;
@ -523,17 +495,14 @@ crget()
* Free a cred structure. * Free a cred structure.
* Throws away space when ref count gets to 0. * Throws away space when ref count gets to 0.
*/ */
void
crfree(cr) crfree(cr)
struct ucred *cr; struct ucred *cr;
{ {
int s = splimp(); /* ??? */ int s;
if (--cr->cr_ref != 0) { s = splimp(); /* ??? */
(void) splx(s); if (--cr->cr_ref == 0)
return; FREE((caddr_t)cr, M_CRED);
}
FREE((caddr_t)cr, M_CRED);
(void) splx(s); (void) splx(s);
} }
@ -573,14 +542,11 @@ crdup(cr)
/* /*
* Get login name, if available. * Get login name, if available.
*/ */
struct getlogin_args { struct getlogin_args {
char *namebuf; char *namebuf;
u_int namelen; u_int namelen;
}; };
/* ARGSUSED */ /* ARGSUSED */
int
getlogin(p, uap, retval) getlogin(p, uap, retval)
struct proc *p; struct proc *p;
struct getlogin_args *uap; struct getlogin_args *uap;
@ -596,13 +562,10 @@ getlogin(p, uap, retval)
/* /*
* Set login name. * Set login name.
*/ */
struct setlogin_args { struct setlogin_args {
char *namebuf; char *namebuf;
}; };
/* ARGSUSED */ /* ARGSUSED */
int
setlogin(p, uap, retval) setlogin(p, uap, retval)
struct proc *p; struct proc *p;
struct setlogin_args *uap; struct setlogin_args *uap;