1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 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);
|