summaryrefslogtreecommitdiffstats
path: root/debian/patches/suexec-custom.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/suexec-custom.patch')
-rw-r--r--debian/patches/suexec-custom.patch190
1 files changed, 190 insertions, 0 deletions
diff --git a/debian/patches/suexec-custom.patch b/debian/patches/suexec-custom.patch
new file mode 100644
index 0000000..37b761d
--- /dev/null
+++ b/debian/patches/suexec-custom.patch
@@ -0,0 +1,190 @@
+Description: the actual patch to make suexec-custom read a config file
+Forwarded: not-needed
+Author: Stefan Fritsch <sf@debian.org>
+Last-Update: 2018-07-17
+--- a/support/suexec-custom.c
++++ b/support/suexec-custom.c
+@@ -29,6 +29,7 @@
+ *
+ *
+ */
++#define SUEXEC_CONFIG_DIR "/etc/apache2/suexec/"
+
+ #include "apr.h"
+ #include "ap_config.h"
+@@ -39,6 +40,7 @@
+ #include <sys/types.h>
+ #include <string.h>
+ #include <time.h>
++#include <ctype.h>
+ #if APR_HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+@@ -222,6 +224,26 @@
+ return;
+ }
+
++static int read_line(char *buf, FILE *file) {
++ char *p;
++ p = fgets(buf, AP_MAXPATH+1, file);
++ if (!p) return 0;
++ if (*p == '\0') return 1;
++
++ p = buf;
++ while (*p)
++ p++;
++ p--;
++
++ /* remove trailing space and slash */
++ while ( isspace(*p) && p >= buf )
++ *p-- = '\0';
++ while ( *p == '/' && p >= buf )
++ *p-- = '\0';
++
++ return 1;
++}
++
+ static void clean_env(void)
+ {
+ char **cleanenv;
+@@ -286,6 +308,11 @@
+ struct stat dir_info; /* directory info holder */
+ struct stat prg_info; /* program info holder */
+ int cwdh; /* handle to cwd */
++ char *suexec_docroot = NULL;
++ char *suexec_userdir_suffix = NULL;
++ char *filename = NULL;
++ FILE *configfile;
++
+
+ /*
+ * Start with a "clean" environment
+@@ -315,15 +342,10 @@
+ || (! strcmp(AP_HTTPD_USER, pw->pw_name)))
+ #endif /* _OSD_POSIX */
+ ) {
+-#ifdef AP_DOC_ROOT
+- fprintf(stderr, " -D AP_DOC_ROOT=\"%s\"\n", AP_DOC_ROOT);
+-#endif
++ fprintf(stderr, " -D SUEXEC_CONFIG_DIR=%s\n", SUEXEC_CONFIG_DIR);
+ #ifdef AP_GID_MIN
+ fprintf(stderr, " -D AP_GID_MIN=%d\n", AP_GID_MIN);
+ #endif
+-#ifdef AP_HTTPD_USER
+- fprintf(stderr, " -D AP_HTTPD_USER=\"%s\"\n", AP_HTTPD_USER);
+-#endif
+ #if defined(AP_LOG_SYSLOG)
+ fprintf(stderr, " -D AP_LOG_SYSLOG\n");
+ #elif defined(AP_LOG_EXEC)
+@@ -338,9 +360,6 @@
+ #ifdef AP_UID_MIN
+ fprintf(stderr, " -D AP_UID_MIN=%d\n", AP_UID_MIN);
+ #endif
+-#ifdef AP_USERDIR_SUFFIX
+- fprintf(stderr, " -D AP_USERDIR_SUFFIX=\"%s\"\n", AP_USERDIR_SUFFIX);
+-#endif
+ exit(0);
+ }
+ /*
+@@ -355,23 +374,6 @@
+ target_gname = argv[2];
+ cmd = argv[3];
+
+- /*
+- * Check to see if the user running this program
+- * is the user allowed to do so as defined in
+- * suexec.h. If not the allowed user, error out.
+- */
+-#ifdef _OSD_POSIX
+- /* User name comparisons are case insensitive on BS2000/OSD */
+- if (strcasecmp(AP_HTTPD_USER, pw->pw_name)) {
+- log_err("user mismatch (%s instead of %s)\n", pw->pw_name, AP_HTTPD_USER);
+- exit(103);
+- }
+-#else /*_OSD_POSIX*/
+- if (strcmp(AP_HTTPD_USER, pw->pw_name)) {
+- log_err("user mismatch (%s instead of %s)\n", pw->pw_name, AP_HTTPD_USER);
+- exit(103);
+- }
+-#endif /*_OSD_POSIX*/
+
+ /*
+ * Check for a leading '/' (absolute path) in the command to be executed,
+@@ -396,6 +398,59 @@
+ }
+
+ /*
++ * Check to see if the user running this program
++ * is the user allowed to do so as defined in
++ * SUEXEC_CONFIG_DIR/username
++ * If not, error out.
++ */
++ suexec_docroot = malloc(AP_MAXPATH+1);
++ suexec_userdir_suffix = malloc(AP_MAXPATH+1);
++ if (!suexec_docroot || !suexec_userdir_suffix ||
++ asprintf(&filename, SUEXEC_CONFIG_DIR "%s", pw->pw_name) == -1) {
++ log_err("malloc failed\n");
++ exit(120);
++ }
++
++ configfile = fopen(filename, "r");
++ if (!configfile) {
++ log_err("User %s not allowed: Could not open config file %s\n", pw->pw_name, filename);
++ exit(123);
++ }
++
++ if (!read_line(suexec_docroot, configfile)) {
++ log_err("Could not read docroot from %s\n", filename);
++ exit(124);
++ }
++
++ if (!read_line(suexec_userdir_suffix, configfile)) {
++ log_err("Could not read userdir suffix from %s\n", filename);
++ exit(125);
++ }
++
++ fclose(configfile);
++
++ if (userdir) {
++ if ( !isalnum(*suexec_userdir_suffix) && suexec_userdir_suffix[0] != '.') {
++ log_err("userdir suffix disabled in %s\n", filename);
++ exit(126);
++ }
++ }
++ else {
++ if (suexec_docroot[0] != '/') {
++ log_err("docroot disabled in %s\n", filename);
++ exit(127);
++ }
++
++ if (suexec_docroot[1] == '/' ||
++ suexec_docroot[1] == '.' ||
++ suexec_docroot[1] == '\0' )
++ {
++ log_err("invalid docroot %s in %s\n", suexec_docroot, filename);
++ exit(128);
++ }
++ }
++
++ /*
+ * Error out if the target username is invalid.
+ */
+ if (strspn(target_uname, "1234567890") != strlen(target_uname)) {
+@@ -538,7 +593,7 @@
+
+ if (userdir) {
+ if (((chdir(target_homedir)) != 0) ||
+- ((chdir(AP_USERDIR_SUFFIX)) != 0) ||
++ ((chdir(suexec_userdir_suffix)) != 0) ||
+ ((getcwd(dwd, AP_MAXPATH)) == NULL) ||
+ ((fchdir(cwdh)) != 0)) {
+ log_err("cannot get docroot information (%s)\n", target_homedir);
+@@ -546,7 +601,7 @@
+ }
+ }
+ else {
+- if (((chdir(AP_DOC_ROOT)) != 0) ||
++ if (((chdir(suexec_docroot)) != 0) ||
+ ((getcwd(dwd, AP_MAXPATH)) == NULL) ||
+ ((fchdir(cwdh)) != 0)) {
+ log_err("cannot get docroot information (%s)\n", AP_DOC_ROOT);