* Added jail header dependencies for mkmf Makefile.
* Renamed header file (bsdjail -> jail)
* Fixed copyright
* Initial commit of primary functionality
* Attach to a running jail
* Create a new jail
* List and instantiate existing jails
* Fetch information about existing jails
* Still needs...
* Attach "in a block" fleshed out
* Documentation and better comments
* Tests (of some kind, this will be tough)
* Update for not-yet-MFC'ed multiple IP jail patch in FBSD 7.2-STABLE
/*
*
* bsdjail.c - Ruby jparallel
* $Id$
*
* vim: set nosta noet ts=4 sw=4:
*
* Authors:
* * Michael Granger <ged@FaerieMUD.org>
* * Mahlon E. Smith <mahlon@martini.nu>
*
* Copyright (c) 2006 The FaerieMUD Consortium.
*
* This work is licensed under the Creative Commons Attribution License. To
* view a copy of this license, visit
* http://creativecommons.org/licenses/by/1.0 or send a letter to Creative
* Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
#include "bsdjail.h"
VALUE rbjail_mBSD;
VALUE rbjail_cBSDJail;
/*
struct jail {
u_int32_t version;
char *path;
char *hostname;
u_int32_t ip_number;
};
*/
static void
rbjail_do_jail_attach( int jid )
{
if ( jail_attach(jid) == -1 )
rb_sys_fail( "jail_attach" );
}
/* Mostly ripped off from Ruby's process.c */
static VALUE
rbjail_attach_block( int jid )
{
int pid;
rb_secure(2);
fflush(stdout);
fflush(stderr);
switch ( pid = fork() ) {
case 0:
rb_thread_atfork();
if ( rb_block_given_p() ) {
int status;
rbjail_do_jail_attach( jid );
rb_protect( rb_yield, Qundef, &status );
ruby_stop( status );
}
return Qnil;
case -1:
rb_sys_fail( "fork(2)" );
return Qnil;
default:
return INT2FIX( pid );
}
}
static VALUE
rbjail_attach( int argc, VALUE *argv, VALUE self )
{
VALUE jidnum, rval;
int jid;
rb_scan_args( argc, argv, "1", &jidnum );
jid = NUM2INT( jidnum );
if ( rb_block_given_p() ) {
rval = rbjail_attach_block( jid );
}
else {
rbjail_do_jail_attach( jid );
rval = Qtrue;
}
return rval;
}
static VALUE
rbjail_list( VALUE self )
{
struct xprison *xp;
struct in_addr in;
size_t i, len;
/* Get the size of the xprison and allocate memory to it. */
if ( sysctlbyname("security.jail.list", NULL, &len, NULL, 0) == -1 )
rb_sys_fail("sysctlbyname(): security.jail.list");
xp = ALLOCA_N( struct xprison, 1 );
/* Get and sanity check the current prison list */
if ( sysctlbyname("security.jail.list", xp, &len, NULL, 0) == -1 ) {
rb_sys_fail("sysctlbyname(): security.jail.list");
}
if ( len < sizeof(*xp) || len % sizeof(*xp) ||
xp->pr_version != XPRISON_VERSION )
rb_fatal("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++;
}
return self;
}
void
Init_bsdjail( void )
{
rbjail_mBSD = rb_define_module( "BSD" );
rbjail_cBSDJail = rb_define_class_under( rbjail_mBSD, "Jail", rb_cObject );
rb_define_singleton_method( rbjail_cBSDJail, "list", rbjail_list, 0 );
/*
rb_define_alloc_function( rbjail_cBSDJail, );
rb_define_method( rbjail_cBSDJail, "attach", rbjail_attach, -1 );
*/
}