Start privilege testing framework
authorMichael Neumann <mneumann@.(none)>
Mon, 5 Jan 2009 14:02:50 +0000 (15:02 +0100)
committerMichael Neumann <mneumann@.(none)>
Mon, 5 Jan 2009 14:02:50 +0000 (15:02 +0100)
tools/regression/priv/Makefile [new file with mode: 0644]
tools/regression/priv/README [new file with mode: 0644]
tools/regression/priv/test.c [new file with mode: 0644]
tools/regression/priv/test.h [new file with mode: 0644]
tools/regression/priv/test_acct.c [new file with mode: 0644]

diff --git a/tools/regression/priv/Makefile b/tools/regression/priv/Makefile
new file mode 100644 (file)
index 0000000..71c7b66
--- /dev/null
@@ -0,0 +1,13 @@
+compile: test_acct
+
+run: compile
+       ./test_acct
+
+clean:
+       rm *.o test_acct
+
+test.o: test.c
+       ${CC} -c test.c
+
+test_acct: test_acct.c test.o test.h
+       ${CC} -o test_acct test.o test_acct.c
diff --git a/tools/regression/priv/README b/tools/regression/priv/README
new file mode 100644 (file)
index 0000000..d5847fe
--- /dev/null
@@ -0,0 +1 @@
+Checks for correct priv(9) behaviour. 
diff --git a/tools/regression/priv/test.c b/tools/regression/priv/test.c
new file mode 100644 (file)
index 0000000..3749c21
--- /dev/null
@@ -0,0 +1,151 @@
+#include <sys/types.h>
+#include <sys/jail.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void setup(); 
+void teardown();
+
+uid_t unpriv_uid = 5000;
+gid_t unpriv_gid = 5000;
+
+void
+test(int (*fn)(), int expected, char *msg, char *msg2)
+{
+       int retval;
+
+       setup();
+       retval = fn();
+       teardown();
+
+       printf("%s (%s): ", msg, msg2);
+
+       if (retval == expected) {
+               printf("OK\n");
+       } else {
+               printf("FAILED (was: %d, expected: %d)\n", retval, expected);
+       }
+       fflush(stdout);
+}
+
+void 
+test_as_root(int (*fn)(), int expected, char *msg)
+{
+       if (getuid() != 0) {
+               fprintf(stderr, "must be run as root\n");
+               exit(-1);
+       }
+
+       test(fn, expected, msg, "as root");
+}
+
+void 
+test_as_jailed_root(int (*fn)(), int expected, char *msg)
+{
+       if (getuid() != 0) {
+               fprintf(stderr, "must be run as root\n");
+               exit(-1);
+       }
+
+       int child = fork();
+
+       if (child == -1) {
+               fprintf(stderr, "fork failed\n");
+               exit(-2);
+       }
+
+       if (child) {
+               struct jail j;
+               j.version = 1;
+               j.path = "/";
+               j.hostname = "jail";
+               j.n_ips = 0;
+
+               int jid = jail(&j);
+               if (jid < 0) {
+                       fprintf(stderr, "jail failed\n");
+                       exit(-1); // TODO
+               }
+               test(fn, expected, msg, "as jailed root");
+               exit(0);
+       }
+       else {
+               waitpid(child, NULL, 0);
+       }
+}
+
+void 
+test_as_unpriv(int (*fn)(), int expected, char *msg)
+{
+       if (getuid() != 0) {
+               fprintf(stderr, "must be run as root\n");
+               exit(-1);
+       }
+
+       int child = fork();
+
+       if (child == -1) {
+               fprintf(stderr, "fork failed\n");
+               exit(-2);
+       }
+
+       if (child) {
+               setgid(unpriv_gid);
+               setuid(unpriv_uid);
+
+               if (getuid() != unpriv_uid || getgid() != unpriv_gid) {
+                       fprintf(stderr, "setuid/gid failed\n");
+                       exit(-1); // TODO
+               }
+               test(fn, expected, msg, "as unpriv");
+               exit(0);
+       }
+       else {
+               waitpid(child, NULL, 0);
+       }
+}
+
+void 
+test_as_jailed_unpriv(int (*fn)(), int expected, char *msg)
+{
+       if (getuid() != 0) {
+               fprintf(stderr, "must be run as root\n");
+               exit(-1);
+       }
+
+       int child = fork();
+
+       if (child == -1) {
+               fprintf(stderr, "fork failed\n");
+               exit(-2);
+       }
+
+       if (child) {
+               struct jail j;
+               j.version = 1;
+               j.path = "/";
+               j.hostname = "jail";
+               j.n_ips = 0;
+
+               int jid = jail(&j);
+               if (jid < 0) {
+                       fprintf(stderr, "jail failed\n");
+                       exit(-1); // TODO
+               }
+
+               setgid(unpriv_gid);
+               setuid(unpriv_uid);
+
+               if (getuid() != unpriv_uid || getgid() != unpriv_gid) {
+                       fprintf(stderr, "setuid/gid failed\n");
+                       exit(-1); // TODO
+               }
+               test(fn, expected, msg, "as jailed unpriv");
+               exit(0);
+       }
+       else {
+               waitpid(child, NULL, 0);
+       }
+}
diff --git a/tools/regression/priv/test.h b/tools/regression/priv/test.h
new file mode 100644 (file)
index 0000000..29b75a2
--- /dev/null
@@ -0,0 +1,5 @@
+void test(int (*fn)(), int expected, char *msg, char *msg2);
+void test_as_root(int (*fn)(), int expected, char *msg);
+void test_as_jailed_root(int (*fn)(), int expected, char *msg);
+void test_as_unpriv(int (*fn)(), int expected, char *msg);
+void test_as_jailed_unpriv(int (*fn)(), int expected, char *msg);
diff --git a/tools/regression/priv/test_acct.c b/tools/regression/priv/test_acct.c
new file mode 100644 (file)
index 0000000..7bae90f
--- /dev/null
@@ -0,0 +1,44 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include "test.h"
+
+static char *tmp_file;
+
+void
+setup() {
+       tmp_file = "./tmpfile";
+       int fh = open(tmp_file, O_CREAT | O_TRUNC | O_WRONLY, 0666);
+       close(fh);
+}
+
+void
+teardown() {
+       unlink(tmp_file);
+}
+
+int
+test_acct() {
+       int error;
+
+       error = acct(tmp_file);
+       if (error == -1)
+               return errno;
+
+       error = acct(NULL);
+       if (error == -1)
+               return errno;
+
+       return 0;
+}
+
+int main()
+{
+       test_as_root            (test_acct, 0, "acct");
+       test_as_jailed_root     (test_acct, EPERM, "acct");
+       test_as_unpriv          (test_acct, EPERM, "acct");
+       test_as_jailed_unpriv   (test_acct, EPERM, "acct");
+
+       return 0;
+}