Description: the actual patch to make suexec-custom read a config file Forwarded: not-needed Author: Stefan Fritsch 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 #include #include +#include #if APR_HAVE_UNISTD_H #include #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);