diff options
Diffstat (limited to 'debian/patches/suexec-custom.patch')
-rw-r--r-- | debian/patches/suexec-custom.patch | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/debian/patches/suexec-custom.patch b/debian/patches/suexec-custom.patch new file mode 100644 index 0000000..9c7a732 --- /dev/null +++ b/debian/patches/suexec-custom.patch @@ -0,0 +1,192 @@ +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 +diff --git a/support/suexec-custom.c b/support/suexec-custom.c +index f3811a97..30bb644b 100644 +--- 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 @@ static void log_no_err(const char *fmt,...) + 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 pathbuf[512]; +@@ -288,6 +310,11 @@ int main(int argc, char *argv[]) + 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 +@@ -317,15 +344,10 @@ int main(int argc, char *argv[]) + || (! 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) +@@ -339,9 +361,6 @@ int main(int argc, char *argv[]) + #endif + #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); + } +@@ -357,23 +376,6 @@ int main(int argc, char *argv[]) + 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, +@@ -397,6 +399,59 @@ int main(int argc, char *argv[]) + userdir = 1; + } + ++ /* ++ * 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. + */ +@@ -538,7 +593,7 @@ int main(int argc, char *argv[]) + + 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 @@ int main(int argc, char *argv[]) + } + } + 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); |