summaryrefslogtreecommitdiff
path: root/srcx/util.c
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2004-05-18 16:23:45 +0000
committerStef Walter <stef@memberwebs.com>2004-05-18 16:23:45 +0000
commit4bef00e8f39ef127ff8922d0931e7ffd95950d20 (patch)
treeb8f4a5387c0619fae659f43ea330a6b0ef75140c /srcx/util.c
parent887d8b57c4aa291919c8eec6b2af5a5f5259ac6d (diff)
Tested on FreeBSD 5.2.1. Fixed bugs.
Diffstat (limited to 'srcx/util.c')
-rw-r--r--srcx/util.c233
1 files changed, 134 insertions, 99 deletions
diff --git a/srcx/util.c b/srcx/util.c
index 6c1d811..8591292 100644
--- a/srcx/util.c
+++ b/srcx/util.c
@@ -1,11 +1,13 @@
#include <sys/types.h>
-#include <sys/user.h>
-#include <sys/proc.h>
#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/stat.h>
#include <sys/jail.h>
#include <sys/sysctl.h>
#include <sys/file.h>
+#include <sys/wait.h>
#include <err.h>
#include <errno.h>
@@ -16,26 +18,15 @@
#include <kvm.h>
#include <paths.h>
-int translate_jail_name(const char* str)
-{
- struct xprison* sxp;
- struct xprison* xp;
- size_t len, i;
- char* e;
- int jid;
+#include "util.h"
- jid = strtol(str, &e, 10);
+extern char** environ;
- /* If it was all a number ... */
- if(!*e)
- {
- if(jid > 0)
- return jid;
-
- errx(1, "invalid jail id: %s", str);
- }
-
- /* ... otherwise it's a name */
+size_t get_jail_sysctl(struct xprison** ret)
+{
+ struct xprison* xp;
+ size_t len;
+ *ret = NULL;
if(sysctlbyname("security.jail.list", NULL, &len, NULL, 0) == -1)
err(1, "couldn't list jails");
@@ -43,17 +34,17 @@ int translate_jail_name(const char* str)
retry:
if(len <= 0)
- return -1;
+ return 0;
- sxp = xp = calloc(len, 1);
- if(sxp == NULL)
+ 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)
{
- free(sxp);
+ free(xp);
goto retry;
}
@@ -63,19 +54,55 @@ retry:
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);
+}
+
+int translate_jail_name(const char* str)
+{
+ struct xprison* xp = NULL;
+ size_t len, i;
+ char* e;
+ int jid;
+
+ len = get_jail_sysctl(&xp);
+ if(len == 0)
+ goto done;
+
+ jid = strtol(str, &e, 10);
+
+ /* 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)
+ goto done;
+ }
+
+ jid = -1;
+ }
+
jid = -1;
- for(i = 0; i < (len / sizeof(*xp)); i++)
+ for(i = 0; i < len; i++)
{
- if(strcmp(xp->pr_host, str) == 0)
+ if(strcmp(xp[i].pr_host, str) == 0)
{
- jid = xp->pr_id;
+ jid = xp[i].pr_id;
break;
}
}
- free(sxp);
- return -1;
+done:
+ if(xp)
+ free(xp);
+
+ return jid;
}
/*
@@ -93,8 +120,7 @@ int running_in_jail()
char errbuf[_POSIX2_LINE_MAX];
int result = -1;
- kd = kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, _PATH_DEVNULL,
- O_RDONLY, errbuf);
+ kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
if(kd == NULL)
errx(1, "couldn't connect to kernel: %s", errbuf);
@@ -115,46 +141,56 @@ int check_jail_command(const char* jail, const char* cmd)
if(stat(cmd, &sb) == -1)
{
- if(errno == EACCESS || errno == ELOOP || errno == ENAMETOOLONG ||
+ if(errno == EACCES || errno == ELOOP || errno == ENAMETOOLONG ||
errno == ENOENT || errno == ENOTDIR)
{
- warn("%s%scan't execute in jail: %s", , jail ? jail : "",
- jail ? jail : ": ", cmd);
+ 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 ? 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 : "",
- jail ? jail : ": ", cmd);
- return 0;
- }
-
- if(!(sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
- {
- warnx("%s%snot executable: %s", , jail ? jail : "",
- jail ? jail : ": ", cmd);
+ warnx("%s%snot a regular file: %s", jail ? jail : "",
+ jail ? ": " : "", cmd);
return 0;
}
if(sb.st_uid != 0)
{
warnx("%s%snot owned by root: %s", jail ? jail : "",
- jail ? jail : ": ", cmd);
+ jail ? ": " : "", cmd);
return 0;
}
return 1;
}
-int run_simple_command(const char* jail, const char* cmd, char* args[])
+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);
+
+ warn("%s%serror executing: %s: %s", jail ? jail : "",
+ jail ? ": " : "", cmd);
+ return 0;
+}
+
+int run_simple_command(const char* jail, const char* cmd, char* env[],
+ char* args[], int opts)
{
pid_t pid;
- int status;
+ int status = 0;
+
+ if(opts & JAIL_RUN_NOFORK)
+ return run_overlay_command(jail, cmd, env, args);
switch((pid = fork()))
{
@@ -165,7 +201,7 @@ int run_simple_command(const char* jail, const char* cmd, char* args[])
/* This is the child here */
case 0:
if(args)
- exect(cmd, args, env);
+ execve(cmd, args, env);
else
execle(cmd, cmd, NULL, env);
@@ -176,14 +212,14 @@ int run_simple_command(const char* jail, const char* cmd, char* args[])
default:
/* If the processes exited then break out */
- if(waitpid(pid, &status, 0) == pid)
- break;
+ if(waitpid(pid, &status, 0) == -1)
+ err(1, "couldn't wait on child process");
/* Return any status codes */
- if(status != 0)
+ if(WEXITSTATUS(status) != 0)
{
warnx("%s%serror executing: %s: %s", jail ? jail : "",
- jail ? jail : ": ", cmd, strerror(status));
+ jail ? ": " : "", cmd, strerror(WEXITSTATUS(status)));
return 0;
}
@@ -193,7 +229,17 @@ int run_simple_command(const char* jail, const char* cmd, char* args[])
return 1;
}
-int run_dup_command(const char* jail, const char* cmd, char* argv[] args, int opts)
+/* read & write ends of a pipe */
+#define READ_END 0
+#define WRITE_END 1
+
+/* pre-set file descriptors */
+#define STDIN 0
+#define STDOUT 1
+#define STDERR 2
+
+int run_dup_command(const char* jail, const char* cmd, char* env[],
+ char* args[], int opts)
{
int outpipe[2];
pid_t pid;
@@ -228,7 +274,7 @@ int run_dup_command(const char* jail, const char* cmd, char* argv[] args, int op
/* Okay, now run whatever command it was */
if(args)
- exect(cmd, args, env);
+ execve(cmd, args, env);
else
execle(cmd, cmd, NULL, env);
@@ -250,12 +296,13 @@ int run_dup_command(const char* jail, const char* cmd, char* argv[] args, int op
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_OUT_CONSOLE)
+ if(opts & JAIL_RUN_CONSOLE)
console = open(_PATH_CONSOLE, O_WRONLY | O_APPEND);
/* No blocking on the child processes pipe */
@@ -274,10 +321,10 @@ int run_dup_command(const char* jail, const char* cmd, char* argv[] args, int op
/* Read text */
while((ret = read(outpipe[READ_END], buff, 256)) > 0)
{
- if(opts & JAIL_OUT_STDOUT)
+ if(opts & JAIL_RUN_STDOUT)
write(STDOUT, buff, ret);
- if(opts & JAIL_OUT_STDERR)
+ if(opts & JAIL_RUN_STDERR)
write(STDERR, buff, ret);
if(console != -1)
@@ -295,10 +342,10 @@ int run_dup_command(const char* jail, const char* cmd, char* argv[] args, int op
}
/* Return any status codes */
- if(status != 0)
+ if(WEXITSTATUS(status) != 0)
{
warnx("%s%serror executing: %s: %s", jail ? jail : "",
- jail ? jail : ": ", cmd, strerror(status));
+ jail ? ": " : "", cmd, strerror(WEXITSTATUS(status)));
return 0;
}
@@ -314,53 +361,41 @@ int run_dup_command(const char* jail, const char* cmd, char* argv[] args, int op
return 1;
}
-#define MAKE_ENV_VAR(v, n) \
-{ \
- char* t = getenv(n); \
- t = t ? t : ""; \
- (v) = alloca(strlen(n) + 2 + strlen(t)); \
- sprintf((v), "%s=%s", (n), (v)); \
-}
-
-/* read & write ends of a pipe */
-#define READ_END 0
-#define WRITE_END 1
-
-/* pre-set file descriptors */
-#define STDIN 0
-#define STDOUT 1
-#define STDERR 2
int run_jail_command(const char* jail, const char* cmd, char* args[], int opts)
{
char* env[5];
+ char* t;
+ int j;
+ char** x;
+
+ 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;
- env[1] = NULL;
+ j = 1;
- /*
- * If we're outputing to the console then we need a
- * few more environement variables. Processes like
- * 'ps' depend on them for formatting.
- */
- if(!opts || opts & JAIL_OUT_STDOUT ||
- opts & JAIL_OUT_STDERR)
- {
- /* TODO: For fun debugging. Remove later */
- t = getenv(VAR);
- t = t ? t : NULL;
- env[1] = alloca(sizeof("TERM") + 2 + strlen(t));
- sprintf(env[1], "%s=%s", "TERM", t);
-
- MAKE_ENV_VAR(env[1], "TERM");
- MAKE_ENV_VAR(env[2], "COLUMNS");
- MAKE_ENV_VAR(env[3], "LINES");
- env[4] = NULL;
- }
+ MAKE_ENV_VAR("TERM");
+ MAKE_ENV_VAR("COLUMNS");
+ MAKE_ENV_VAR("LINES");
- if(opts)
- return run_dup_command(jail, cmd, args, opts);
+ if(opts & JAIL_RUN_OUTPUT)
+ return run_dup_command(jail, cmd, env, args, opts);
else
- return run_simple_command(jail, cmd, args);
+ return run_simple_command(jail, cmd, env, args, opts);
}
+
+
+
+
+
+