summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jstart.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/jstart.c b/src/jstart.c
new file mode 100644
index 0000000..b244aa4
--- /dev/null
+++ b/src/jstart.c
@@ -0,0 +1,134 @@
+
+/* A lot of code from jail.c in */
+/* TODO: Attribute properly */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/jail.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <paths.h>
+#include <stdio.h>
+#include <err.h>
+#include <unistd.h>
+#include <limits.h>
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#define START_SCRIPT "/etc/rc"
+static char* START_ARGS[] = { _PATH_BSHELL, START_SCRIPT };
+
+static void usage();
+static void check_command(const char* cmd);
+static void run_command(const char* cmd, char* args[]);
+
+int main(int argc, char* argv[])
+{
+ int ch;
+ struct jail j;
+ struct in_addr in;
+
+ argc--;
+ argv++;
+
+ if(argc < 3)
+ usage();
+
+ if(getuid() != 0)
+ errx(1, "must be run as root");
+
+ if(chdir(argv[0]) != 0)
+ err(1, "couldn't change to jail directory: %s", argv[0]);
+
+ if(inet_aton(argv[2], &in) != 1)
+ errx(1, "invalid ip address: %s", argv[2]);
+
+ memset(&j, 0, sizeof(j));
+ j.version = 0;
+ j.path = argv[0];
+ j.hostname = argv[1];
+ j.ip_number = ntohl(in.s_addr);
+
+ /* Here's where we actually go into the jail */
+ if(jail(&j) != 0)
+ err(1, "couldn't create jail");
+
+ argc -= 3;
+ argv += 3;
+
+ if(argc == 0)
+ {
+ check_command(START_SCRIPT);
+ run_command(START_ARGS[0], START_ARGS);
+ }
+
+ else
+ {
+ check_command(argv[0]);
+ run_command(argv[0], argv);
+ }
+
+ return 0;
+}
+
+static void usage()
+{
+ fprintf(stderr, "usage: jstart path hostname ip-number [command ...]\n");
+ exit(2);
+}
+
+static void check_command(const char* cmd)
+{
+ struct stat sb;
+
+ if(stat(cmd, &sb) == -1)
+ {
+ if(errno == EACCES || errno == ELOOP || errno == ENAMETOOLONG ||
+ errno == ENOENT || errno == ENOTDIR)
+ {
+ err(1, "can't execute in jail: %s", cmd);
+ }
+
+ err(1, "couldn't stat file: %s", cmd);
+ }
+
+ if(!(sb.st_mode & S_IFREG))
+ errx(1, "not a regular file: %s", cmd);
+
+ if(sb.st_uid != 0)
+ errx(1, "not owned by root: %s", cmd);
+}
+
+static void run_command(const char* cmd, char* args[])
+{
+ 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(execve(cmd, args, env) != 0)
+ err("couldn't execute command: %s", cmd);
+}
+