Add jail_attach support.
authorJoerg Sonnenberger <joerg@dragonflybsd.org>
Mon, 31 Jan 2005 22:29:59 +0000 (22:29 +0000)
committerJoerg Sonnenberger <joerg@dragonflybsd.org>
Mon, 31 Jan 2005 22:29:59 +0000 (22:29 +0000)
Inspired-by: FreeBSD
Manpage-by: Paul Herman
Add sysctl jail.list and jailed() helper functions.

Obtained-from: FreeBSD

Add jexec and jls.

Obtained-from: FreeBSD

Move reference counting into prison_hold / prison_free functions.
Fix an incorrect increment in fork1, the prison structure is not
directly copied and the cr reference counting applies to prison here
too. Begin moving explicit pointer checks for cr_prison != NULL
to the new jailed() function. Move the sys/varsym.h include in
sys/jail.h to the kernel part. Prepare for jail-local securelevel.

15 files changed:
lib/libc/sys/Makefile.inc
lib/libc/sys/jail.2
lib/libc/sys/jail_attach.2 [new file with mode: 0644]
sys/kern/kern_fork.c
sys/kern/kern_jail.c
sys/kern/kern_prot.c
sys/sys/jail.h
sys/sys/kinfo.h
usr.sbin/Makefile
usr.sbin/jexec/Makefile [new file with mode: 0644]
usr.sbin/jexec/jexec.8 [new file with mode: 0644]
usr.sbin/jexec/jexec.c [new file with mode: 0644]
usr.sbin/jls/Makefile [new file with mode: 0644]
usr.sbin/jls/jls.8 [new file with mode: 0644]
usr.sbin/jls/jls.c [new file with mode: 0644]

index 861db04..6fd957c 100644 (file)
@@ -1,6 +1,6 @@
 #      @(#)Makefile.inc        8.3 (Berkeley) 10/24/94
 # $FreeBSD: src/lib/libc/sys/Makefile.inc,v 1.75.2.7 2003/04/22 17:31:18 trhodes Exp $
-# $DragonFly: src/lib/libc/sys/Makefile.inc,v 1.7 2004/11/23 19:05:53 eirikn Exp $
+# $DragonFly: src/lib/libc/sys/Makefile.inc,v 1.8 2005/01/31 22:29:59 joerg Exp $
 
 # sys sources
 .PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/sys ${.CURDIR}/../libc/sys
@@ -90,7 +90,7 @@ MAN+= _exit.2 accept.2 access.2 acct.2 adjtime.2 \
        getpeername.2 getpgrp.2 getpid.2 getpriority.2 getrlimit.2 \
        getrusage.2 getsid.2 getsockname.2 \
        getsockopt.2 gettimeofday.2 getuid.2 \
-       intro.2 ioctl.2 issetugid.2 jail.2 kill.2 \
+       intro.2 ioctl.2 issetugid.2 jail.2 jail_attach.2 kill.2 \
        kldfind.2 kldfirstmod.2 kldload.2 kldnext.2 kldstat.2 kldsym.2 \
        kldunload.2 ktrace.2 kqueue.2 link.2 listen.2 lseek.2 \
        madvise.2 mincore.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 mmap.2 \
index 51b790b..160c78b 100644 (file)
@@ -7,7 +7,7 @@
 .\"----------------------------------------------------------------------------
 .\"
 .\"$FreeBSD: src/lib/libc/sys/jail.2,v 1.10.2.10 2002/12/12 05:26:38 trhodes Exp $
-.\"$DragonFly: src/lib/libc/sys/jail.2,v 1.2 2003/06/17 04:26:47 dillon Exp $
+.\"$DragonFly: src/lib/libc/sys/jail.2,v 1.3 2005/01/31 22:29:59 joerg Exp $
 .\"
 .Dd April 28, 1999
 .Dt JAIL 2
@@ -30,10 +30,10 @@ system call sets up a jail and locks the current process in it.
 The argument is a pointer to a structure describing the prison:
 .Bd -literal -offset indent
 struct jail {
-       u_int32_t       version;
-        char           *path;
-        char           *hostname;
-        u_int32_t      ip_number;
+       uint32_t        version;
+       char            *path;
+       char            *hostname;
+       uint32_t        ip_number;
 };
 .Ed
 .Pp
@@ -53,9 +53,11 @@ from the inside of the prison.
 The
 .Dq Li ip_number
 can be set to the IP number assigned to the prison.
-.Sh PRISON?
+.Sh PRISON
 Once a process has been put in a prison, it and its decendants cannot escape
-the prison.  It is not possible to add a process to a preexisting prison.
+the prison.
+A process can be attached to a prison by calling
+.Xr jail_attach 2 .
 .Pp
 Inside the prison, the concept of "superuser" is very diluted.  In general,
 it can be assumed that nothing can be mangled from inside a prison which
@@ -75,6 +77,10 @@ It is possible to identify a process as jailed by examining
 it will show a field near the end of the line, either as
 a single hyphen for a process at large, or the hostname currently
 set for the prison for jailed processes.
+
+The program
+.Xr jls 8
+ca be used to identify all active jails.
 .Sh ERRORS
 .Fn jail
 will fail if:
@@ -93,7 +99,11 @@ Please consult the
 manual page for details.
 .Sh SEE ALSO
 .Xr chdir 2 ,
-.Xr chroot 2
+.Xr chroot 2 ,
+.Xr jail 8 ,
+.Xr jail_attach 2 ,
+.Xr jexec 8 ,
+.Xr jls 8
 .Sh HISTORY
 The
 .Fn jail
diff --git a/lib/libc/sys/jail_attach.2 b/lib/libc/sys/jail_attach.2
new file mode 100644 (file)
index 0000000..a8aa7c5
--- /dev/null
@@ -0,0 +1,82 @@
+.\" 
+.\" Copyright (c) 2005 The DragonFly Project.  All rights reserved.
+.\" This code is derived from software contributed to The DragonFly Project
+.\" by Paul Herman.
+.\" 
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in
+.\"    the documentation and/or other materials provided with the
+.\"    distribution.
+.\" 3. Neither the name of The DragonFly Project nor the names of its
+.\"    contributors may be used to endorse or promote products derived
+.\"    from this software without specific, prior written permission.
+.\" 
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $DragonFly: src/lib/libc/sys/jail_attach.2,v 1.1 2005/01/31 22:29:59 joerg Exp $
+.\"
+.Dd January 31, 2005
+.Dt JAIL_ATTACH 2
+.Os
+.Sh NAME
+.Nm jail_attach
+.Nd attach current process to an existing jail
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/jail.h
+.Ft int
+.Fn jail_attach "int id"
+.Sh DESCRIPTION
+The
+.Nm
+system call attaches the current process to an existing jail referenced by
+.Nm id .
+.Pp
+The argument is an int referencing the ID of the prison.
+.Sh ERRORS
+.Fn jail_attach
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The user is not the super user, or is already in a prison.
+.It Bq Er EINVAL
+The prison referenced by
+.Nm id
+does not exist.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr jail 2 ,
+.Xr chroot 2 ,
+.Xr jail 8 ,
+.Xr jexec 8 ,
+.Xr jls 8
+.Sh HISTORY
+The
+.Fn jail_attach
+function call first appeared in
+.Fx 5.1 
+and subsequently appeared in
+.Dx 1.1
+.Sh AUTHORS
+The jail_attach man page was written by
+.An Paul Herman .
index 6049902..33c72ab 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
  * $FreeBSD: src/sys/kern/kern_fork.c,v 1.72.2.14 2003/06/26 04:15:10 silby Exp $
- * $DragonFly: src/sys/kern/kern_fork.c,v 1.31 2005/01/19 19:05:21 eirikn Exp $
+ * $DragonFly: src/sys/kern/kern_fork.c,v 1.32 2005/01/31 22:29:59 joerg Exp $
  */
 
 #include "opt_ktrace.h"
@@ -373,10 +373,8 @@ again:
                startprofclock(p2);
        p2->p_ucred = crhold(p1->p_ucred);
 
-       if (p2->p_ucred->cr_prison) {
-               p2->p_ucred->cr_prison->pr_ref++;
+       if (jailed(p2->p_ucred))
                p2->p_flag |= P_JAILED;
-       }
 
        if (p2->p_args)
                p2->p_args->ar_ref++;
index e7b734e..a9460e0 100644 (file)
@@ -7,24 +7,30 @@
  * ----------------------------------------------------------------------------
  *
  * $FreeBSD: src/sys/kern/kern_jail.c,v 1.6.2.3 2001/08/17 01:00:26 rwatson Exp $
- * $DragonFly: src/sys/kern/kern_jail.c,v 1.6 2005/01/14 02:25:08 joerg Exp $
+ * $DragonFly: src/sys/kern/kern_jail.c,v 1.7 2005/01/31 22:29:59 joerg Exp $
  *
  */
 
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/kernel.h>
+#include <sys/kinfo.h>
 #include <sys/systm.h>
 #include <sys/errno.h>
 #include <sys/sysproto.h>
 #include <sys/malloc.h>
+#include <sys/nlookup.h>
+#include <sys/namecache.h>
 #include <sys/proc.h>
 #include <sys/jail.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
+#include <sys/kern_syscall.h>
 #include <net/if.h>
 #include <netinet/in.h>
 
+static struct prison   *prison_find(int);
+
 MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
 
 SYSCTL_NODE(, OID_AUTO, jail, CTLFLAG_RW, 0,
@@ -45,6 +51,35 @@ SYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
     &jail_sysvipc_allowed, 0,
     "Processes in jail can use System V IPC primitives");
 
+int    lastprid = 0;
+int    prisoncount = 0;
+
+LIST_HEAD(prisonlist, prison);
+struct prisonlist allprison = LIST_HEAD_INITIALIZER(&allprison);
+
+static int
+kern_jail_attach(int jid)
+{
+       struct proc *p = curthread->td_proc;
+       struct prison *pr;
+       int error;
+
+       pr = prison_find(jid);
+       if (pr == NULL)
+               return(EINVAL);
+
+       error = kern_chroot(pr->pr_root);
+       if (error)
+               return(error);
+
+       prison_hold(pr);
+       cratom(&p->p_ucred);
+       p->p_ucred->cr_prison = pr;
+       p->p_flag |= P_JAILED;
+
+       return(0);
+}
+
 /*
  * jail()
  *
@@ -53,43 +88,86 @@ SYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
 int
 jail(struct jail_args *uap) 
 {
-       int error;
-       struct prison *pr;
+       struct prison *pr, *tpr;
        struct jail j;
-       struct chroot_args ca;
        struct thread *td = curthread;
-       struct proc *p = td->td_proc;
+       int error, tryprid;
+       struct nlookupdata nd;
 
        error = suser(td);
        if (error)
-               return (error);
+               return(error);
        error = copyin(uap->jail, &j, sizeof j);
        if (error)
-               return (error);
+               return(error);
        if (j.version != 0)
-               return (EINVAL);
-       MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK);
-       bzero((caddr_t)pr, sizeof *pr);
+               return(EINVAL);
+       MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK | M_ZERO);
+
        error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0);
        if (error) 
                goto bail;
+       error = nlookup_init(&nd, j.path, UIO_USERSPACE, NLC_FOLLOW);
+       if (error)
+               goto nlookup_init_clean;
+       error = nlookup(&nd);
+       if (error)
+               goto nlookup_init_clean;
+       pr->pr_root = cache_hold(nd.nl_ncp);
+
        pr->pr_ip = j.ip_number;
        varsymset_init(&pr->pr_varsymset, NULL);
 
-       ca.path = j.path;
-       error = chroot(&ca);
+       tryprid = lastprid + 1;
+       if (tryprid == JAIL_MAX)
+               tryprid = 1;
+next:
+       LIST_FOREACH(tpr, &allprison, pr_list) {
+               if (tpr->pr_id != tryprid)
+                       continue;
+               tryprid++;
+               if (tryprid == JAIL_MAX) {
+                       error = EAGAIN;
+                       goto varsym_clean;
+               }
+               goto next;
+       }
+       pr->pr_id = lastprid = tryprid;
+       LIST_INSERT_HEAD(&allprison, pr, pr_list);
+       prisoncount++;
+
+       error = kern_jail_attach(pr->pr_id);
        if (error)
-               goto bail;
+               goto jail_attach_clean;
 
-       pr->pr_ref++;
-       cratom(&p->p_ucred);
-       p->p_ucred->cr_prison = pr;
-       p->p_flag |= P_JAILED;
+       nlookup_done(&nd);
        return (0);
 
+jail_attach_clean:
+       LIST_REMOVE(pr, pr_list);
+varsym_clean:
+       varsymset_clean(&pr->pr_varsymset);
+nlookup_init_clean:
+       nlookup_done(&nd);
 bail:
        FREE(pr, M_PRISON);
-       return (error);
+       return(error);
+}
+
+/*
+ * int jail_attach(int jid);
+ */
+int
+jail_attach(struct jail_attach_args *uap)
+{
+       struct thread *td = curthread;
+       int error;
+
+       error = suser(td);
+       if (error)
+               return(error);
+
+       return(kern_jail_attach(uap->jid));
 }
 
 int
@@ -169,3 +247,91 @@ prison_if(struct thread *td, struct sockaddr *sa)
                ok = 0;
        return (ok);
 }
+
+/*
+ * Returns a prison instance, or NULL on failure.
+ */
+static struct prison *
+prison_find(int prid)
+{
+       struct prison *pr;
+
+       LIST_FOREACH(pr, &allprison, pr_list) {
+               if (pr->pr_id == prid)
+                       break;
+       }
+       return(pr);
+}
+
+static int
+sysctl_jail_list(SYSCTL_HANDLER_ARGS)
+{
+       struct proc *p;
+       struct kinfo_prison *xp, *sxp;
+       struct prison *pr;
+       int count, error;
+
+       p = curthread->td_proc;
+
+       if (jailed(p->p_ucred))
+               return (0);
+retry:
+       count = prisoncount;
+
+       if (count == 0)
+               return(0);
+
+       sxp = xp = malloc(sizeof(*xp) * count, M_TEMP, M_WAITOK | M_ZERO);
+       if (count < prisoncount) {
+               free(sxp, M_TEMP);
+               goto retry;
+       }
+       count = prisoncount;
+       
+       LIST_FOREACH(pr, &allprison, pr_list) {
+               char *fullpath, *freepath;
+               xp->pr_version = KINFO_PRISON_VERSION;
+               xp->pr_id = pr->pr_id;
+               error = cache_fullpath(p, pr->pr_root, &fullpath, &freepath);
+               if (error == 0) {
+                       strlcpy(xp->pr_path, fullpath, sizeof(xp->pr_path));
+                       free(freepath, M_TEMP);
+               } else {
+                       bzero(xp->pr_path, sizeof(xp->pr_path));
+               }
+               strlcpy(xp->pr_host, pr->pr_host, sizeof(xp->pr_host));
+               xp->pr_ip = pr->pr_ip;
+               xp++;
+       }
+
+       error = SYSCTL_OUT(req, sxp, sizeof(*sxp) * count);
+       free(sxp, M_TEMP);
+       return(error);
+}
+
+SYSCTL_OID(_jail, OID_AUTO, list, CTLTYPE_STRUCT | CTLFLAG_RD, NULL, 0,
+          sysctl_jail_list, "S", "List of active jails");
+
+void
+prison_hold(struct prison *pr)
+{
+       pr->pr_ref++;
+}
+
+void
+prison_free(struct prison *pr)
+{
+       KKASSERT(pr->pr_ref >= 1);
+
+       if (--pr->pr_ref > 0)
+               return;
+
+       LIST_REMOVE(pr, pr_list);
+       prisoncount--;
+
+       if (pr->pr_linux != NULL)
+               free(pr->pr_linux, M_PRISON);
+       varsymset_clean(&pr->pr_varsymset);
+       cache_drop(pr->pr_root);
+       free(pr, M_PRISON);
+}
index c0346f1..967e1e0 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
  * $FreeBSD: src/sys/kern/kern_prot.c,v 1.53.2.9 2002/03/09 05:20:26 dd Exp $
- * $DragonFly: src/sys/kern/kern_prot.c,v 1.19 2005/01/14 02:25:08 joerg Exp $
+ * $DragonFly: src/sys/kern/kern_prot.c,v 1.20 2005/01/31 22:29:59 joerg Exp $
  */
 
 /*
@@ -927,12 +927,8 @@ crfree(struct ucred *cr)
                /*
                 * Destroy empty prisons
                 */
-               if (cr->cr_prison && !--cr->cr_prison->pr_ref) {
-                       if (cr->cr_prison->pr_linux != NULL)
-                               FREE(cr->cr_prison->pr_linux, M_PRISON);
-                       varsymset_clean(&cr->cr_prison->pr_varsymset);
-                       FREE(cr->cr_prison, M_PRISON);
-               }
+               if (jailed(cr))
+                       prison_free(cr->cr_prison);
                cr->cr_prison = NULL;   /* safety */
 
                FREE((caddr_t)cr, M_CRED);
@@ -959,8 +955,8 @@ cratom(struct ucred **pcr)
                uihold(newcr->cr_uidinfo);
        if (newcr->cr_ruidinfo)
                uihold(newcr->cr_ruidinfo);
-       if (newcr->cr_prison)
-               ++newcr->cr_prison->pr_ref;
+       if (jailed(newcr))
+               prison_hold(newcr->cr_prison);
        newcr->cr_ref = 1;
        crfree(oldcr);
        *pcr = newcr;
@@ -984,8 +980,8 @@ crcopy(struct ucred *cr)
                uihold(newcr->cr_uidinfo);
        if (newcr->cr_ruidinfo)
                uihold(newcr->cr_ruidinfo);
-       if (newcr->cr_prison)
-               ++newcr->cr_prison->pr_ref;
+       if (jailed(newcr))
+               prison_hold(newcr->cr_prison);
        newcr->cr_ref = 1;
        crfree(cr);
        return (newcr);
@@ -1007,8 +1003,8 @@ crdup(cr)
                uihold(newcr->cr_uidinfo);
        if (newcr->cr_ruidinfo)
                uihold(newcr->cr_ruidinfo);
-       if (newcr->cr_prison)
-               ++newcr->cr_prison->pr_ref;
+       if (jailed(newcr))
+               prison_hold(newcr->cr_prison);
        newcr->cr_ref = 1;
        return (newcr);
 }
index e4193e4..4916ce5 100644 (file)
@@ -7,32 +7,35 @@
  * ----------------------------------------------------------------------------
  *
  * $FreeBSD: src/sys/sys/jail.h,v 1.8.2.2 2000/11/01 17:58:06 rwatson Exp $
- * $DragonFly: src/sys/sys/jail.h,v 1.4 2005/01/14 02:25:08 joerg Exp $
+ * $DragonFly: src/sys/sys/jail.h,v 1.5 2005/01/31 22:29:59 joerg Exp $
  *
  */
 
 #ifndef _SYS_JAIL_H_
 #define _SYS_JAIL_H_
 
-#include <sys/varsym.h>
-
 struct jail {
-       u_int32_t       version;
+       uint32_t        version;
        char            *path;
        char            *hostname;
-       u_int32_t       ip_number;
+       uint32_t        ip_number;
 };
 
 #ifndef _KERNEL
 
-int jail (struct jail *);
+int jail(struct jail *);
+int jail_attach(int);
 
 #else /* _KERNEL */
 
+#include <sys/varsym.h>
+
 #ifdef MALLOC_DECLARE
 MALLOC_DECLARE(M_PRISON);
 #endif
 
+#define        JAIL_MAX        999999
+
 /*
  * This structure describes a prison.  It is pointed to by all struct
  * proc's of the inmates.  pr_ref keeps track of them and is used to
@@ -40,11 +43,15 @@ MALLOC_DECLARE(M_PRISON);
  */
 
 struct prison {
-       int             pr_ref;
-       char            pr_host[MAXHOSTNAMELEN];
-       u_int32_t       pr_ip;
-       void            *pr_linux;
-       struct varsymset pr_varsymset;
+       LIST_ENTRY(prison) pr_list;                     /* all prisons */
+       int             pr_id;                          /* prison id */
+       int             pr_ref;                         /* reference count */
+       struct namecache *pr_root;                      /* namecache entry of root */
+       char            pr_host[MAXHOSTNAMELEN];        /* host name */
+       uint32_t        pr_ip;                          /* IP address */
+       void            *pr_linux;                      /* Linux ABI emulation */
+       int              pr_securelevel;                /* jail securelevel */
+       struct varsymset pr_varsymset;                  /* jail varsyms */
 };
 
 /*
@@ -54,5 +61,17 @@ extern int   jail_set_hostname_allowed;
 extern int     jail_socket_unixiproute_only;
 extern int     jail_sysvipc_allowed;
 
+void   prison_hold(struct prison *);
+void   prison_free(struct prison *);
+
+/*
+ * Return 1 if the passed credential is in a jail, otherwise 0.
+ */
+static __inline int
+jailed(struct ucred *cred)
+{
+       return(cred->cr_prison != NULL);
+}
+
 #endif /* !_KERNEL */
 #endif /* !_SYS_JAIL_H_ */
index e351953..0f38410 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/sys/kinfo.h,v 1.2 2004/12/22 11:01:49 joerg Exp $
+ * $DragonFly: src/sys/sys/kinfo.h,v 1.3 2005/01/31 22:29:59 joerg Exp $
  */
 
 #ifndef _SYS_KINFO_H
@@ -67,4 +67,13 @@ struct kinfo_clockinfo {
        int     ci_profhz;      /* profiling clock frequency */
 };
 
+struct kinfo_prison {
+       int              pr_version;
+       int              pr_id;
+       char             pr_path[MAXPATHLEN];
+       char             pr_host[MAXHOSTNAMELEN];
+       uint32_t         pr_ip;
+};
+#define        KINFO_PRISON_VERSION    1
+
 #endif
index 7fc2b7b..9a3b022 100644 (file)
@@ -1,6 +1,6 @@
 #      From: @(#)Makefile      5.20 (Berkeley) 6/12/93
 # $FreeBSD: src/usr.sbin/Makefile,v 1.183.2.14 2003/04/16 11:01:51 ru Exp $
-# $DragonFly: src/usr.sbin/Makefile,v 1.18 2005/01/04 19:58:53 joerg Exp $
+# $DragonFly: src/usr.sbin/Makefile,v 1.19 2005/01/31 22:29:59 joerg Exp $
 
 # XXX MISSING:         mkproto
 SUBDIR=        IPXrouted \
@@ -40,6 +40,8 @@ SUBDIR=       IPXrouted \
        inetd \
        iostat \
        jail \
+       jexec \
+       jls \
        kbdcontrol \
        kbdmap \
        kernbb \
diff --git a/usr.sbin/jexec/Makefile b/usr.sbin/jexec/Makefile
new file mode 100644 (file)
index 0000000..f89e96e
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/usr.sbin/jexec/Makefile,v 1.1 2003/04/09 03:04:12 mike Exp $
+# $DragonFly: src/usr.sbin/jexec/Makefile,v 1.1 2005/01/31 22:29:59 joerg Exp $
+
+PROG=  jexec
+MAN=   jexec.8
+WARNS?=        6
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/jexec/jexec.8 b/usr.sbin/jexec/jexec.8
new file mode 100644 (file)
index 0000000..4b4ccc2
--- /dev/null
@@ -0,0 +1,53 @@
+.\"
+.\" Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: src/usr.sbin/jexec/jexec.8,v 1.2 2003/05/31 18:24:40 ru Exp $
+.\" $DragonFly: src/usr.sbin/jexec/jexec.8,v 1.1 2005/01/31 22:29:59 joerg Exp $
+.\"
+.Dd April 8, 2003
+.Dt JEXEC 8
+.Os
+.Sh NAME
+.Nm jexec
+.Nd "execute a command inside an existing jail"
+.Sh SYNOPSIS
+.Nm
+.Ar jid command ...
+.Sh DESCRIPTION
+The
+.Nm
+utility executes
+.Ar command
+inside the jail identified by
+.Ar jid .
+.Sh SEE ALSO
+.Xr jail_attach 2 ,
+.Xr jail 8 ,
+.Xr jls 8
+.Sh HISTORY
+The
+.Nm
+utility was added in
+.Fx 5.1 .
diff --git a/usr.sbin/jexec/jexec.c b/usr.sbin/jexec/jexec.c
new file mode 100644 (file)
index 0000000..8da3dec
--- /dev/null
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 2004 Joerg Sonnenberger <joerg@bec.de>
+ * Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/usr.sbin/jexec/jexec.c,v 1.2 2003/07/04 19:14:27 bmilekic Exp $
+ * $DragonFly: src/usr.sbin/jexec/jexec.c,v 1.1 2005/01/31 22:29:59 joerg Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/jail.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int     getjailid(const char *str);
+static void    usage(void);
+
+int
+main(int argc, char **argv)
+{
+       int jid;
+
+       if (argc < 3)
+               usage();
+       jid = getjailid(argv[1]);
+       if (jail_attach(jid) == -1)
+               err(1, "jail_attach(%d) failed", jid);
+       if (chdir("/") == -1)
+               err(1, "chdir(\"/\") failed");
+       if (execvp(argv[2], argv + 2) == -1)
+               err(1, "execvp(%s) failed", argv[2]);
+       exit(0);
+}
+
+static void
+usage(void)
+{
+       fprintf(stderr, "usage: jexec jid command [...]\n");
+       exit(1); 
+}
+
+static int
+getjailid(const char *str)
+{
+       long v;
+       char *ep;
+
+       errno = 0;
+       v = strtol(str, &ep, 10);
+       if (v < INT_MIN || v > INT_MAX || errno == ERANGE)
+               errc(1, ERANGE, "invalid jail id", str);
+       if (ep == str || *ep != '\0')
+               errx(1, "cannot parse jail id: %s.", str);
+
+       return((int)(v));
+}
diff --git a/usr.sbin/jls/Makefile b/usr.sbin/jls/Makefile
new file mode 100644 (file)
index 0000000..c6718a0
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/usr.sbin/jls/Makefile,v 1.1 2003/04/09 03:04:12 mike Exp $
+# $DragonFly: src/usr.sbin/jls/Makefile,v 1.1 2005/01/31 22:29:59 joerg Exp $
+
+PROG=  jls
+MAN=   jls.8
+WARNS?=        6
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/jls/jls.8 b/usr.sbin/jls/jls.8
new file mode 100644 (file)
index 0000000..5edc8ac
--- /dev/null
@@ -0,0 +1,51 @@
+.\"
+.\" Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: src/usr.sbin/jls/jls.8,v 1.1 2003/04/09 03:04:12 mike Exp $
+.\" $DragonFly: src/usr.sbin/jls/jls.8,v 1.1 2005/01/31 22:29:59 joerg Exp $
+.\"
+.Dd April 8, 2003
+.Dt JLS 8
+.Os
+.Sh NAME
+.Nm jls
+.Nd "list active jails"
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+The
+.Nm
+utility lists all active jails.
+Each jail is represented by one row which contains the following columns:
+jail identifier (JID), IP address, hostname, and path.
+.Sh SEE ALSO
+.Xr jail 2 ,
+.Xr jail 8 ,
+.Xr jexec 8
+.Sh HISTORY
+The
+.Nm
+utility was added in
+.Fx 5.1 .
diff --git a/usr.sbin/jls/jls.c b/usr.sbin/jls/jls.c
new file mode 100644 (file)
index 0000000..b66841c
--- /dev/null
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/usr.sbin/jls/jls.c,v 1.3 2003/04/22 13:24:56 mike Exp $
+ * $DragonFly: src/usr.sbin/jls/jls.c,v 1.1 2005/01/31 22:29:59 joerg Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/kinfo.h>
+#include <sys/sysctl.h>
+
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int
+main(void)
+{ 
+       struct kinfo_prison *sxp, *xp;
+       struct in_addr in;
+       size_t i, len;
+
+       if (sysctlbyname("jail.list", NULL, &len, NULL, 0) == -1)
+               err(1, "sysctlbyname(): jail.list");
+retry:
+       if (len == 0)
+               exit(0);        
+
+       sxp = xp = malloc(len);
+       if (sxp == NULL)
+               err(1, "malloc failed");
+
+       if (sysctlbyname("jail.list", xp, &len, NULL, 0) == -1) {
+               if (errno == ENOMEM) {
+                       free(sxp);
+                       goto retry;
+               }
+               err(1, "sysctlbyname(): jail.list");
+       }
+       if (len < sizeof(*xp) || len % sizeof(*xp) ||
+           xp->pr_version != KINFO_PRISON_VERSION)
+               errx(1, "Kernel and userland out of sync");
+
+       len /= sizeof(*xp);
+       printf("   JID  IP Address      Hostname                      Path\n");
+       for (i = 0; i < len; i++) {
+               in.s_addr = ntohl(xp->pr_ip);
+               printf("%6d  %-15.15s %-29.29s %.74s\n",
+                   xp->pr_id, inet_ntoa(in), xp->pr_host, xp->pr_path);
+               xp++;
+       }
+       free(sxp);
+       exit(0);
+}