summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2021-02-01 10:49:11 -0500
committerJakob Kaivo <jkk@ung.org>2021-02-01 10:49:11 -0500
commit08c30d1a3d2256b2e613c4d5d8c68d6819be6a85 (patch)
tree4c92babc0d7c263b6a4e91f48e26e159a4d3dbf2
parentb85457d8773990791c9d202bd9ca52c9f6f034cd (diff)
first draft of front-end
-rw-r--r--privexec/Makefile26
-rw-r--r--privexec/privexec.c72
2 files changed, 98 insertions, 0 deletions
diff --git a/privexec/Makefile b/privexec/Makefile
new file mode 100644
index 0000000..26cafe6
--- /dev/null
+++ b/privexec/Makefile
@@ -0,0 +1,26 @@
+.POSIX:
+
+# This Makefile was generated by maje
+# See https://gitlab.com/jkaivo/maje/ for more information
+# Do not edit this Makefile by hand
+
+CC=c99
+LD=$(CC)
+CFLAGS=-Wall -Wextra -Wpedantic -Werror -g
+LDFLAGS=
+LDLIBS=
+SRCDIR=.
+OBJDIR=.
+BINDIR=$(OBJDIR)
+
+all: $(BINDIR)/privexec
+
+clean:
+ rm -f $(BINDIR)/privexec $(OBJDIR)/*.o
+
+$(BINDIR)/privexec: $(OBJDIR)/privexec.o
+$(OBJDIR)/privexec.o: $(SRCDIR)/privexec.c
+ $(CC) $(CFLAGS) -o $@ -c $(SRCDIR)/privexec.c
+
+$(BINDIR)/privexec:
+ $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/*.o $(LDLIBS)
diff --git a/privexec/privexec.c b/privexec/privexec.c
new file mode 100644
index 0000000..1b7a54e
--- /dev/null
+++ b/privexec/privexec.c
@@ -0,0 +1,72 @@
+#define _POSIX_C_SOURCE 200809L
+#include <spawn.h>
+#include <stdio.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#ifndef PATH_CHECK
+#define PATH_CHECK "/usr/local/lib/privexec/check"
+#endif
+
+#ifndef PATH_EXEC
+#define PATH_EXEC "/usr/local/lib/privexec/exec"
+#endif
+
+static int exec_with_privileges(char *argv[])
+{
+ argv[0] = PATH_EXEC;
+ execv(argv[0], argv);
+ perror(argv[0]);
+ return 1;
+}
+
+static int check_privileges(char *argv[])
+{
+ argv[0] = PATH_CHECK;
+ pid_t pid = 0;
+ if (posix_spawn(&pid, argv[0], NULL, NULL, argv, NULL) != 0) {
+ perror(PATH_CHECK);
+ return 1;
+ }
+
+ int status = 1;
+ if (waitpid(pid, &status, 0) != 0) {
+ perror(PATH_CHECK);
+ return 1;
+ }
+
+ return status;
+}
+
+int main(int argc, char *argv[])
+{
+ const char *name = argv[0];
+ if (name == NULL) {
+ fprintf(stderr, "NULL execution not supported\n");
+ return 1;
+ }
+
+ /* no options, but allow for -- */
+ int c;
+ while ((c = getopt(argc, argv, "")) != -1) {
+ switch (c) {
+ default:
+ return 1;
+ }
+ }
+
+ argc -= (optind - 1);
+ argv += (optind - 1);
+
+ if (argc < 2) {
+ printf("%s: missing operands\n", name);
+ return 1;
+ }
+
+ if (check_privileges(argv) == 0) {
+ return exec_with_privileges(argv);
+ }
+
+ /* error message already displayed by check_privileges() */
+ return 1;
+}