summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--srcx/jkill.c26
-rw-r--r--srcx/jps.c35
-rw-r--r--srcx/util.c657
-rw-r--r--srcx/util.h10
4 files changed, 392 insertions, 336 deletions
diff --git a/srcx/jkill.c b/srcx/jkill.c
index 4311ed8..953095e 100644
--- a/srcx/jkill.c
+++ b/srcx/jkill.c
@@ -84,15 +84,17 @@ static void usage_jail(const char* name);
int main(int argc, char* argv[])
{
- int r, jid;
- int ret = 0;
+ struct xprison* sxp = NULL;
+ struct xprison* xp = NULL;
+ size_t len;
+ int jid, r, ret = 0;
pid_t child;
/*
* When running in a jail we do things slightly
* differently, and accept different args
*/
- if(running_in_jail())
+ if(running_in_jail() != 0)
{
parse_jail_opts(argc, argv);
@@ -114,17 +116,23 @@ int main(int argc, char* argv[])
argc -= optind;
argv += optind;
+ len = get_jail_sysctl(&sxp);
+
/* For each jail */
for(; argc > 0; argc--, argv++)
{
- jid = translate_jail_name(argv[0]);
- if(jid == -1)
+ xp = find_jail(str, len, sxp);
+
+ if(xp == NULL)
{
warnx("unknown jail host name: %s", argv[0]);
ret = 1;
continue;
}
+ /* This makes sure we can use kvm funcs in jail */
+ kvm_prepare_jail(xp);
+
/*
* We fork and the child goes into the jail and
* does the dirty work. Unless in debug mode where
@@ -141,6 +149,11 @@ int main(int argc, char* argv[])
/* The child */
case 0:
#endif
+ jid = xp->pri_id;
+
+ /* Always free jail info before going into jail */
+ free_jail_sysctl(len, sxp);
+
if(jail_attach(jid) == -1)
err(1, "couldn't attach to jail");
@@ -164,6 +177,7 @@ int main(int argc, char* argv[])
argv++;
}
+ free_jail_sysctl(len, sxp);
return ret;
}
}
@@ -304,7 +318,7 @@ static int kill_jail(const char* jail)
int cmdargs = JAIL_RUN_CONSOLE;
/* Open the kernel interface */
- kd = open_kvm_handle(jail, errbuf);
+ kd = kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, NULL, O_RDONLY, errbuf);
if(kd == NULL)
errx(1, "couldn't connect to kernel: %s", errbuf);
diff --git a/srcx/jps.c b/srcx/jps.c
index 8b12b4a..867364d 100644
--- a/srcx/jps.c
+++ b/srcx/jps.c
@@ -61,9 +61,11 @@ static void run_jail_ps(int argc, char* argv[]);
int main(int argc, char* argv[])
{
- int ch = 0;
+ struct xprison* sxp = NULL;
+ struct xprison* xp = NULL;
+ size_t len;
+ int jid, ch = 0;
int simple = 0;
- int jid = 0;
while((ch = getopt(argc, argv, "i")) != -1)
{
@@ -86,19 +88,29 @@ int main(int argc, char* argv[])
if(argc == 0)
usage();
- if(running_in_jail())
+ if(running_in_jail() != 0)
errx(1, "can't run from inside jail");
/* Translate the jail name into an id if neccessary */
- jid = translate_jail_name(argv[0]);
- if(jid == -1)
+ len = get_jail_sysctl(&sxp);
+ xp = find_jail(argv[0], len, sxp);
+
+ if(xp == NULL)
errx(1, "unknown jail host name: %s", argv[0]);
argc--;
argv++;
+ /* This makes sure we can use kvm funcs in jail */
+ kvm_prepare_jail(xp);
+
+ jid = xp->pr_id;
+
+ /* Always free jail info before going into jail */
+ free_jail_sysctl(len, sxp);
+
/* Go into the jail */
- if(jail_attach(jid) == -1)
+ if(jail_attach(xp->pr_id) == -1)
err(1, "couldn't attach to jail");
if(simple)
@@ -126,21 +138,12 @@ static void usage()
static void run_jail_ps(int argc, char* argv[])
{
- char errbuf[_POSIX2_LINE_MAX];
char** args;
- kvm_t* kd;
int i;
if(!check_jail_command(NULL, "/bin/ps"))
exit(1);
- /* Make sure we can use kvm functionality here */
- kd = open_kvm_handle(NULL, errbuf);
- if(kd == NULL)
- errx(1, "couldn't connect to kernel: %s", errbuf);
-
- kvm_close(kd);
-
/*
* TODO: We need to purge down the environment here.
* If the jail is in any way malicious or compromised
@@ -166,7 +169,7 @@ static void print_jail_ids()
char errbuf[_POSIX2_LINE_MAX];
/* Open kernel interface */
- kd = open_kvm_handle(NULL, errbuf);
+ kd = kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, NULL, O_RDONLY, errbuf);
if(kd == NULL)
errx(1, "couldn't connect to kernel: %s", errbuf);
diff --git a/srcx/util.c b/srcx/util.c
index 31ee3bd..137ca24 100644
--- a/srcx/util.c
+++ b/srcx/util.c
@@ -61,149 +61,178 @@ extern char** environ;
size_t get_jail_sysctl(struct xprison** ret)
{
- struct xprison* xp;
- size_t len;
- *ret = NULL;
+ struct xprison* xp;
+ size_t len;
+ *ret = NULL;
- if(sysctlbyname("security.jail.list", NULL, &len, NULL, 0) == -1)
- err(1, "couldn't list jails");
+ if(sysctlbyname("security.jail.list", NULL, &len, NULL, 0) == -1)
+ err(1, "couldn't list jails");
retry:
- if(len <= 0)
- return 0;
+ if(len <= 0)
+ return 0;
- xp = calloc(len, 1);
- if(xp == NULL)
- err(1, "out of memory");
+ xp = calloc(len, 1);
+ if(xp == NULL)
+ err(1, "out of memory");
- if(sysctlbyname("security.jail.list", xp, &len, NULL, 0) == -1)
- {
- if(errno == ENOMEM)
+ if(sysctlbyname("security.jail.list", xp, &len, NULL, 0) == -1)
{
- free(xp);
- goto retry;
+ if(errno == ENOMEM)
+ {
+ free(xp);
+ goto retry;
+ }
+
+ err(1, "couldn't list jails");
}
- err(1, "couldn't list jails");
- }
+ if(len < sizeof(*xp) || len % sizeof(*xp) || xp->pr_version != XPRISON_VERSION)
+ errx(1, "kernel and userland out of sync");
- if(len < sizeof(*xp) || len % sizeof(*xp) || xp->pr_version != XPRISON_VERSION)
- errx(1, "kernel and userland out of sync");
+ *ret = xp;
+ return len / sizeof(*xp);
+}
- *ret = xp;
- return len / sizeof(*xp);
+void free_jail_sysctl(size_t len, struct xprison* xp)
+{
+ if(len == 0 || xp == NULL)
+ return;
+
+ /*
+ * An extra precaution to prevent leakage of information
+ * into the jail.
+ */
+
+ memset(xp, 0, sizeof(struct xprison) * len);
+ free(xp);
}
-int translate_jail_name(const char* str)
+struct xprison* find_jail(const char* str, size_t len, struct xprison* xp)
{
- struct xprison* xp = NULL;
- size_t len, i;
- char* e;
- int jid = -1;
+ int jid;
+ size_t i;
+ char* e;
+
+ if(len == 0 || xp == NULL)
+ return NULL;
- len = get_jail_sysctl(&xp);
- if(len == 0)
- goto done;
+ jid = strtol(str, &e, 10);
- jid = strtol(str, &e, 10);
+ /* If it was all a number ... */
+ if(!*e)
+ {
+ if(jid <= 0)
+ errx(1, "invalid jail id: %s", str);
- /* If it was all a number ... */
- if(!*e)
- {
- if(jid <= 0)
- errx(1, "invalid jail id: %s", str);
+ /* Validate the number */
+ for(i = 0; i < len; i++)
+ {
+ if(jid == xp[i].pr_id)
+ return &(xp[i]);
+ }
+ }
- /* Validate the number */
for(i = 0; i < len; i++)
{
- if(jid == xp[i].pr_id)
- goto done;
+ if(strcmp(xp[i].pr_host, str) == 0)
+ return &(xp[i]);
}
- jid = -1;
- }
+ return NULL;
+}
- jid = -1;
+int translate_jail_name(const char* str)
+{
+ struct xprison* sxp = NULL;
+ struct xprison* xp = NULL;
+ size_t len;
+ int jid = -1;
- for(i = 0; i < len; i++)
- {
- if(strcmp(xp[i].pr_host, str) == 0)
+ len = get_jail_sysctl(&sxp);
+ if(sxp)
{
- jid = xp[i].pr_id;
- break;
- }
- }
+ xp = find_jail(str, sxp);
+ if(xp != NULL)
+ jid = xp->pr_id;
-done:
- if(xp)
- free(xp);
+ free(sxp);
+ }
- return jid;
+ return jid;
}
-kvm_t* open_kvm_handle(const char* jail, char* errbuf)
+int kvm_prepare_jail(struct xprison* xp)
{
- /*
- * Basically the kvm routines won't work in a jail unless there's
- * a /dev/null device for us to use as the file names. If it's
- * missing we have to create it.
- */
-
- struct stat sb;
- int nodir = 0;
- int nonull = 0;
-
- if(stat(_PATH_DEVNULL, &sb) == -1)
- {
- if(errno == ENOTDIR)
- {
- nodir = 1;
- nonull = 1;
- }
+ /*
+ * Basically the kvm routines won't work in a jail unless there's
+ * a /dev/null device for us to use as the file names. If it's
+ * missing we have to create it.
+ */
+
+ struct stat sb;
+ char* path;
+ int nodir = 0;
+ int nonull = 0;
+
+ path = (char*)alloca(strlen(_PATH_DEVNULL) + 2 + strlen(xp->pr_path));
- else if(errno == ENOENT)
+ strcpy(path, xp->pr_path);
+ strcat(path, _PATH_DEVNULL);
+
+ if(stat(path, &sb) == -1)
{
- nonull = 1;
+ if(errno == ENOTDIR)
+ {
+ nodir = 1;
+ nonull = 1;
+ }
+
+ else if(errno == ENOENT)
+ {
+ nonull = 1;
+ }
+
+ else
+ {
+ err(1, "couldn't stat file: %s", path);
+ }
}
- else
+ if(nodir)
{
- err(1, "%s%scouldn't stat file: %s", jail ? jail : "",
- jail ? ": " : "", _PATH_DEVNULL);
- }
- }
+ strcpy(path, xp->pr_path);
+ strcat(path, _PATH_DEV);
- if(nodir)
- {
- warnx("%s%sthe %s directory doesn't exist in jail. creating...",
- jail ? jail : "", jail ? ": " : "", _PATH_DEV);
+ warnx("the %s directory doesn't exist. creating...", path);
- if(mkdir(_PATH_DEV, 0) == -1 ||
- chmod(_PATH_DEV, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
- {
- warn("%s%scouldn't create %s directory",
- jail ? jail : "", jail ? ": " : "", _PATH_DEV);
- nonull = 0;
+ if(mkdir(path, 0) == -1 ||
+ chmod(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
+ {
+ warn("couldn't create %s directory", path);
+ return -1;
+ }
}
- }
- if(nonull)
- {
- mode_t mode = 0666 | S_IFCHR;
- dev_t dev = makedev(2, 2);
+ if(nonull)
+ {
+ mode_t mode = 0666 | S_IFCHR;
+ dev_t dev = makedev(2, 2);
+
+ strcpy(path, xp->pr_path);
+ strcat(path, _PATH_DEVNULL);
- warnx("%s%sthe %s device doesn't exist in jail. creating...",
- jail ? jail : "", jail ? ": " : "", _PATH_DEVNULL);
+ warnx("the %s device doesn't exist in jail. creating...", path);
- if(mknod(_PATH_DEVNULL, mode, dev) == -1)
- {
- warn("%s%scouldn't create %s device",
- jail ? jail : "", jail ? ": " : "", _PATH_DEVNULL);
+ if(mknod(path, mode, dev) == -1)
+ {
+ warn("couldn't create %s device", path);
+ return -1;
+ }
}
- }
- return kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, NULL, O_RDONLY, errbuf);
+ return 0;
}
/*
@@ -215,119 +244,120 @@ kvm_t* open_kvm_handle(const char* jail, char* errbuf)
int running_in_jail()
{
- int count;
- kvm_t* kd = 0;
- struct kinfo_proc* kp;
- char errbuf[_POSIX2_LINE_MAX];
- int result = -1;
+ int count;
+ kvm_t* kd = 0;
+ struct kinfo_proc* kp;
+ int result = -1;
- kd = open_kvm_handle(NULL, errbuf);
- if(kd == NULL)
- errx(1, "couldn't connect to kernel: %s", errbuf);
+ kd = kvm_open(_PATH_DEVNULL, _PATH_DEVNULL, NULL, O_RDONLY, NULL);
+ if(kd == NULL)
+ return -1;
- kp = kvm_getprocs(kd, KERN_PROC_PID, getpid(), &count);
- if(kp == NULL)
- errx(1, "couldn't list processes: %s", kvm_geterr(kd));
+ kp = kvm_getprocs(kd, KERN_PROC_PID, getpid(), &count);
- result = (kp->ki_flag & P_JAILED) ? 1 : 0;
- kvm_close(kd);
+ if(kp == NULL)
+ result = -1;
+ else
+ result = (kp->ki_flag & P_JAILED) ? 1 : 0;
+
+ kvm_close(kd);
- return result;
+ return result;
}
int check_jail_command(const char* jail, const char* cmd)
{
- struct stat sb;
+ struct stat sb;
- if(stat(cmd, &sb) == -1)
- {
- if(errno == EACCES || errno == ELOOP || errno == ENAMETOOLONG ||
- errno == ENOENT || errno == ENOTDIR)
+ if(stat(cmd, &sb) == -1)
{
- warn("%s%scan't execute in jail: %s", jail ? jail : "",
- jail ? ": " : "", cmd);
- return 0;
- }
+ if(errno == EACCES || errno == ELOOP || errno == ENAMETOOLONG ||
+ errno == ENOENT || errno == ENOTDIR)
+ {
+ warn("%s%scan't execute in jail: %s", jail ? jail : "",
+ jail ? ": " : "", cmd);
+ return 0;
+ }
- err(1, "%s%scouldn't stat file: %s", jail ? jail : "",
- jail ? ": " : "", cmd);
- }
+ err(1, "%s%scouldn't stat file: %s", jail ? jail : "",
+ jail ? ": " : "", cmd);
+ }
- if(!(sb.st_mode & S_IFREG))
- {
- warnx("%s%snot a regular file: %s", jail ? jail : "",
+ if(!(sb.st_mode & S_IFREG))
+ {
+ warnx("%s%snot a regular file: %s", jail ? jail : "",
jail ? ": " : "", cmd);
- return 0;
- }
+ return 0;
+ }
- if(sb.st_uid != 0)
- {
- warnx("%s%snot owned by root: %s", jail ? jail : "",
+ if(sb.st_uid != 0)
+ {
+ warnx("%s%snot owned by root: %s", jail ? jail : "",
jail ? ": " : "", cmd);
- return 0;
- }
+ return 0;
+ }
- return 1;
+ return 1;
}
int run_overlay_command(const char* jail, const char* cmd, char* env[],
char* args[])
{
- if(args)
- execve(cmd, args, env);
- else
- execle(cmd, cmd, NULL, env);
+ if(args)
+ execve(cmd, args, env);
+ else
+ execle(cmd, cmd, NULL, env);
- warn("%s%serror executing: %s: %s", jail ? jail : "",
+ warn("%s%serror executing: %s: %s", jail ? jail : "",
jail ? ": " : "", cmd);
- return 0;
+ return 0;
}
int run_simple_command(const char* jail, const char* cmd, char* env[],
char* args[], int opts)
{
- pid_t pid;
- int status = 0;
+ pid_t pid;
+ int status = 0;
- if(opts & JAIL_RUN_NOFORK)
- return run_overlay_command(jail, cmd, env, args);
+ if(opts & JAIL_RUN_NOFORK)
+ return run_overlay_command(jail, cmd, env, args);
- switch((pid = fork()))
- {
- case -1:
- err(1, "couldn't fork child process");
- break;
+ switch((pid = fork()))
+ {
+ case -1:
+ err(1, "couldn't fork child process");
+ break;
- /* This is the child here */
- case 0:
- if(args)
- execve(cmd, args, env);
- else
- execle(cmd, cmd, NULL, env);
+ /* This is the child here */
+ case 0:
+ if(args)
+ execve(cmd, args, env);
+ else
+ execle(cmd, cmd, NULL, env);
- exit(errno);
- break;
+ exit(errno);
+ break;
- /* This is the parent process */
- default:
+ /* This is the parent process */
+ default:
- /* If the processes exited then break out */
- if(waitpid(pid, &status, 0) == -1)
- err(1, "couldn't wait on child process");
+ /* If the processes exited then break out */
+ if(waitpid(pid, &status, 0) == -1)
+ err(1, "couldn't wait on child process");
- /* Return any status codes */
- if(WEXITSTATUS(status) != 0)
- {
- warnx("%s%serror executing: %s: %s", jail ? jail : "",
- jail ? ": " : "", cmd, strerror(WEXITSTATUS(status)));
- return 0;
- }
+ /* Return any status codes */
+ if(WEXITSTATUS(status) != 0)
+ {
+ warnx("%s%serror executing: %s: %s", jail ? jail : "",
+ jail ? ": " : "", cmd, strerror(WEXITSTATUS(status)));
+ return 0;
+ }
- break;
- }
+ break;
+ }
- return 1;
+ return 1;
}
/* read & write ends of a pipe */
@@ -342,155 +372,162 @@ int run_simple_command(const char* jail, const char* cmd, char* env[],
int run_dup_command(const char* jail, const char* cmd, char* env[],
char* args[], int opts)
{
- int outpipe[2];
- pid_t pid;
-
- /*
- * Special function to duplicate output of a command to two
- * files.
- *
- * NOTE: Yes, I know this may seem like overkill, but system,
- * popen and all those guys would hang with certain rc scripts.
- * Those which opened a daemon in the background ('&') but still
- * kept their output going to the same stdin/stdout handles.
- */
-
- /* Create a pipe for the child process */
- if(pipe(outpipe) < 0)
- return -1;
-
- switch(pid = fork())
- {
- case -1:
- err(1, "couldn't fork child process");
- break;
-
- /* This is the child here */
- case 0:
+ int outpipe[2];
+ pid_t pid;
+
+ /*
+ * Special function to duplicate output of a command to two
+ * files.
+ *
+ * NOTE: Yes, I know this may seem like overkill, but system,
+ * popen and all those guys would hang with certain rc scripts.
+ * Those which opened a daemon in the background ('&') but still
+ * kept their output going to the same stdin/stdout handles.
+ */
+
+ /* Create a pipe for the child process */
+ if(pipe(outpipe) < 0)
+ return -1;
+
+ switch(pid = fork())
{
- /* Fix up our end of the pipe */
- if(dup2(outpipe[WRITE_END], STDOUT) < 0 ||
- dup2(outpipe[WRITE_END], STDERR) < 0)
- exit(errno);
+ case -1:
+ err(1, "couldn't fork child process");
+ break;
- /* Okay, now run whatever command it was */
- if(args)
- execve(cmd, args, env);
- else
- execle(cmd, cmd, NULL, env);
-
- /* In case it returns then have to do this to get
- children to disconnect from stdout */
- fflush(stdout);
- fclose(stdout);
- close(outpipe[WRITE_END]);
-
- exit(errno);
- }
- break;
-
-
- /* And this is the parent */
- default:
- {
- int console = -1;
- int ret;
- int status = 0;
- fd_set readmask;
- char buff[256];
- struct timeval timeout = { 0, 10000 };
-
- FD_ZERO(&readmask);
-
- /* Open the console file and write the header */
- if(opts & JAIL_RUN_CONSOLE)
- console = open(_PATH_CONSOLE, O_WRONLY | O_APPEND);
-
- /* No blocking on the child processes pipe */
- fcntl(outpipe[READ_END], F_SETFL, fcntl(outpipe[READ_END], F_GETFL, 0) | O_NONBLOCK);
-
- /* Loop until the process dies or no more output */
- while(1)
- {
- FD_SET(outpipe[READ_END], &readmask);
+ /* This is the child here */
+ case 0:
+ {
+ /* Fix up our end of the pipe */
+ if(dup2(outpipe[WRITE_END], STDOUT) < 0 ||
+ dup2(outpipe[WRITE_END], STDERR) < 0)
+ exit(errno);
+
+ /* Okay, now run whatever command it was */
+ if(args)
+ execve(cmd, args, env);
+ else
+ execle(cmd, cmd, NULL, env);
+
+ /* In case it returns then have to do this to get
+ children to disconnect from stdout */
+ fflush(stdout);
+ fclose(stdout);
+ close(outpipe[WRITE_END]);
+
+ exit(errno);
+ }
+ break;
- if(select(FD_SETSIZE, &readmask, NULL, NULL, &timeout) == -1)
- err(1, "couldn't select");
- if(FD_ISSET(outpipe[READ_END], &readmask))
+ /* And this is the parent */
+ default:
{
- /* Read text */
- while((ret = read(outpipe[READ_END], buff, 256)) > 0)
- {
- if(opts & JAIL_RUN_STDOUT)
- write(STDOUT, buff, ret);
-
- if(opts & JAIL_RUN_STDERR)
- write(STDERR, buff, ret);
+ int console = -1;
+ int ret;
+ int status = 0;
+ int waited = 0;
+ fd_set readmask;
+ char buff[256];
+ struct timeval timeout = { 0, 10000 };
+
+ FD_ZERO(&readmask);
+
+ /* Open the console file and write the header */
+ if(opts & JAIL_RUN_CONSOLE)
+ console = open(_PATH_CONSOLE, O_WRONLY | O_APPEND);
+
+ /* No blocking on the child processes pipe */
+ fcntl(outpipe[READ_END], F_SETFL, fcntl(outpipe[READ_END], F_GETFL, 0) | O_NONBLOCK);
+
+ /* Loop until the process dies or no more output */
+ while(1)
+ {
+ FD_SET(outpipe[READ_END], &readmask);
+
+ if(select(FD_SETSIZE, &readmask, NULL, NULL, &timeout) == -1)
+ err(1, "couldn't select");
+
+ if(FD_ISSET(outpipe[READ_END], &readmask))
+ {
+ /* Read text */
+ while((ret = read(outpipe[READ_END], buff, 256)) > 0)
+ {
+ if(opts & JAIL_RUN_STDOUT)
+ write(STDOUT, buff, ret);
+
+ if(opts & JAIL_RUN_STDERR)
+ write(STDERR, buff, ret);
+
+ if(console != -1)
+ write(console, buff, ret);
+ }
+ }
+
+ /* Or if there's an error or end of file */
+ if(ret == -1 && errno != EAGAIN || ret == 0)
+ break;
+
+ /* If the processes exited then break out */
+ if(waitpid(pid, &status, WNOHANG) == pid)
+ {
+ waited = 1;
+ break;
+ }
+ }
+
+ if(!waited)
+ waitpid(pid, &status, 0);
+
+ /* Return any status codes */
+ if(WEXITSTATUS(status) != 0)
+ {
+ warnx("%s%serror executing: %s: %s", jail ? jail : "",
+ jail ? ": " : "", cmd, strerror(WEXITSTATUS(status)));
+ return 0;
+ }
+
+ /* Clean up */
+ close(outpipe[READ_END]);
if(console != -1)
- write(console, buff, ret);
- }
+ close(console);
}
-
- /* If the processes exited then break out */
- if(waitpid(pid, &status, WNOHANG) == pid)
- break;
-
- /* Or if there's an error or end of file */
- if(ret == -1 && errno != EAGAIN || ret == 0)
- break;
- }
-
- /* Return any status codes */
- if(WEXITSTATUS(status) != 0)
- {
- warnx("%s%serror executing: %s: %s", jail ? jail : "",
- jail ? ": " : "", cmd, strerror(WEXITSTATUS(status)));
- return 0;
- }
-
- /* Clean up */
- close(outpipe[READ_END]);
-
- if(console != -1)
- close(console);
+ break;
}
- break;
- }
- return 1;
+ return 1;
}
int run_jail_command(const char* jail, const char* cmd, char* args[], int opts)
{
- char* env[5];
- char* t;
- int j;
-
- memset(env, 0, sizeof(env));
-
-#define MAKE_ENV_VAR(n) \
- t = getenv(n); \
- if(t != NULL) \
- { \
- env[j] = alloca(strlen(n) + 2 + strlen(t)); \
- sprintf(env[j], "%s=%s", (char*)(n), t); \
- j++; \
- }
-
- /* Prepare an environment for the cmd */
- env[0] = "PATH=" _PATH_STDPATH;
- j = 1;
-
- MAKE_ENV_VAR("TERM");
- MAKE_ENV_VAR("COLUMNS");
- MAKE_ENV_VAR("LINES");
-
- if(opts & JAIL_RUN_OUTPUT)
- return run_dup_command(jail, cmd, env, args, opts);
- else
- return run_simple_command(jail, cmd, env, args, opts);
+ char* env[5];
+ char* t;
+ int j;
+
+ memset(env, 0, sizeof(env));
+
+#define MAKE_ENV_VAR(n) \
+ t = getenv(n); \
+ if(t != NULL) \
+ { \
+ env[j] = alloca(strlen(n) + 2 + strlen(t)); \
+ sprintf(env[j], "%s=%s", (char*)(n), t); \
+ j++; \
+ }
+
+ /* Prepare an environment for the cmd */
+ env[0] = "PATH=" _PATH_STDPATH;
+ j = 1;
+
+ MAKE_ENV_VAR("TERM");
+ MAKE_ENV_VAR("COLUMNS");
+ MAKE_ENV_VAR("LINES");
+
+ if(opts & JAIL_RUN_OUTPUT)
+ return run_dup_command(jail, cmd, env, args, opts);
+ else
+ return run_simple_command(jail, cmd, env, args, opts);
}
diff --git a/srcx/util.h b/srcx/util.h
index fed9261..0696438 100644
--- a/srcx/util.h
+++ b/srcx/util.h
@@ -39,14 +39,16 @@
#ifndef __UTIL_H__
#define __UTIL_H__
-#include <sys/jail.h>
-#include <kvm.h>
+struct xprison;
int translate_jail_name(const char* str);
int running_in_jail();
-kvm_t* open_kvm_handle(const char* jail, char* errbuf);
-size_t get_jail_sysctl(struct xprison** ret);
+size_t get_jail_sysctl(struct xprison** xp);
+void free_jail_sysctl(size_t len, struct xprison* xp);
+
+int kvm_prepare_jail(struct xprison* xp);
+struct xprison* find_jail(const char* str, size_t len, struct xprison* xp);
#define JAIL_RUN_CONSOLE 0x00000001 /* Output stuff to the jail console if available */
#define JAIL_RUN_STDOUT 0x00000002 /* Output to stdout */