Support overriding the preferred shell for capsh.

Either supply --shell=/xx/yy as an argument to capsh, or
use the Make.Rules CAPSH_SHELL override when building.

This is an adaptation of an idea from Rosen Penev.

Signed-off-by: Andrew G. Morgan <[email protected]>
diff --git a/Make.Rules b/Make.Rules
index 8452002..d029296 100644
--- a/Make.Rules
+++ b/Make.Rules
@@ -87,6 +87,14 @@
 CGO_REQUIRED=$(shell $(topdir)/go/cgo-required.sh)
 endif
 
+# If you want capsh to launch with something other than /bin/bash
+# build like this:
+#
+#   make CAPSH_SHELL='-DSHELL=\"/bin/sh\"'
+#
+# or undefine the following:
+#CAPSH_SHELL := '-DSHELL="/bin/sh"'
+
 # When installing setcap, you can arrange for the installation process
 # to set its inheritable bit to be able to place capabilities on files.
 # It can be used in conjunction with pam_cap (associated with su and
diff --git a/progs/Makefile b/progs/Makefile
index 4c24f16..076e44f 100644
--- a/progs/Makefile
+++ b/progs/Makefile
@@ -23,7 +23,7 @@
 	$(CC) $(CFLAGS) -o $@ $< $(LIBCAPLIB) $(LDFLAGS)
 
 %.o: %.c $(INCS)
-	$(CC) $(IPATH) $(CFLAGS) -c $< -o $@
+	$(CC) $(IPATH) $(CAPSH_SHELL) $(CFLAGS) -c $< -o $@
 
 install: all
 	mkdir -p -m 0755 $(FAKEROOT)$(SBINDIR)
diff --git a/progs/capsh.c b/progs/capsh.c
index 1ebd0bf..3ffd56d 100644
--- a/progs/capsh.c
+++ b/progs/capsh.c
@@ -1,9 +1,9 @@
 /*
  * Copyright (c) 2008-11,16,19,2020 Andrew G. Morgan <[email protected]>
  *
- * This is a simple 'bash' wrapper program that can be used to
- * raise and lower both the bset and pI capabilities before invoking
- * /bin/bash (hardcoded right now).
+ * This is a simple 'bash' (-DSHELL) wrapper program that can be used
+ * to raise and lower both the bset and pI capabilities before
+ * invoking /bin/bash.
  *
  * The --print option can be used as a quick test whether various
  * capability manipulations work as expected (or not).
@@ -25,6 +25,10 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#ifndef SHELL
+#define SHELL "/bin/bash"
+#endif /* ndef SHELL */
+
 #define MAX_GROUPS       100   /* max number of supplementary groups for user */
 
 static char *binary(unsigned long value)
@@ -322,6 +326,7 @@
 {
     pid_t child;
     unsigned i;
+    const char *shell = SHELL;
 
     child = 0;
 
@@ -775,11 +780,13 @@
 	} else if (!strcmp("--print", argv[i])) {
 	    arg_print();
 	} else if ((!strcmp("--", argv[i])) || (!strcmp("==", argv[i]))) {
-	    argv[i] = strdup(argv[i][0] == '-' ? "/bin/bash" : argv[0]);
+	    argv[i] = strdup(argv[i][0] == '-' ? shell : argv[0]);
 	    argv[argc] = NULL;
 	    execve(argv[i], argv+i, envp);
-	    fprintf(stderr, "execve /bin/bash failed!\n");
+	    fprintf(stderr, "execve '%s' failed!\n", shell);
 	    exit(1);
+	} else if (!strncmp("--shell=", argv[i], 8)) {
+	    shell = argv[i]+8;
 	} else if (!strncmp("--has-p=", argv[i], 8)) {
 	    cap_value_t cap;
 	    cap_flag_value_t enabled;
@@ -887,8 +894,9 @@
 		   "  --inmode=<xxx> exit 1 if current mode is not <xxx>\n"
 		   "  --killit=<n>   send signal(n) to child\n"
 		   "  --forkfor=<n>  fork and make child sleep for <n> sec\n"
+		   "  --shell=/xx/yy use /xx/yy instead of " SHELL " for --\n"
 		   "  ==             re-exec(capsh) with args as for --\n"
-		   "  --             remaing arguments are for /bin/bash\n"
+		   "  --             remaing arguments are for " SHELL "\n"
 		   "                 (without -- [%s] will simply exit(0))\n",
 		   argv[0], argv[0]);