source: server/common/patches/httpd-suexec-scripts.patch @ 403

Last change on this file since 403 was 403, checked in by presbrey, 17 years ago
allow directives like SetEnv PYTHONPATH/PERL5LIB etc.
File size: 6.0 KB
RevLine 
[1]1# scripts.mit.edu httpd suexec patch
[315]2# Copyright (C) 2006, 2007  Jeff Arnold <jbarnold@mit.edu>, Joe Presbrey <presbrey@mit.edu>, Anders Kaseorg <andersk@mit.edu>
[1]3#
4# This program is free software; you can redistribute it and/or
5# modify it under the terms of the GNU General Public License
6# as published by the Free Software Foundation; either version 2
7# of the License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
17#
18# See /COPYRIGHT in this repository for more information.
19#
[103]20--- httpd-2.2.2/support/Makefile.in.old 2005-07-06 19:15:34.000000000 -0400
21+++ httpd-2.2.2/support/Makefile.in     2007-01-20 17:12:51.000000000 -0500
22@@ -60,7 +60,7 @@
23
24 suexec_OBJECTS = suexec.lo
25 suexec: $(suexec_OBJECTS)
26-       $(LINK) $(suexec_OBJECTS)
27+       $(LINK) -lselinux $(suexec_OBJECTS)
28
29 htcacheclean_OBJECTS = htcacheclean.lo
30 htcacheclean: $(htcacheclean_OBJECTS)
[1]31--- httpd-2.2.2/support/suexec.c.old    2006-04-21 21:53:06.000000000 -0400
[315]32+++ httpd-2.2.2/support/suexec.c        2007-05-22 10:32:04.000000000 -0400
[298]33@@ -30,6 +30,8 @@
34  *
35  */
36 
37+#define STATIC_CAT_PATH "/usr/local/bin/static-cat"
38+
39 #include "apr.h"
40 #include "ap_config.h"
41 #include "suexec.h"
42@@ -46,6 +48,7 @@
[103]43 #include <stdio.h>
44 #include <stdarg.h>
45 #include <stdlib.h>
46+#include <selinux/selinux.h>
47 
48 #ifdef HAVE_PWD_H
49 #include <pwd.h>
[403]50@@ -95,6 +98,9 @@
[1]51 {
52     /* variable name starts with */
53     "HTTP_",
54+    "HTTPS_",
55     "SSL_",
[403]56+    "PERL",
57+    "PYTHON",
[1]58 
59     /* variable name is */
[403]60@@ -140,6 +146,7 @@
[1]61     "UNIQUE_ID=",
62     "USER_NAME=",
63     "TZ=",
64+    "PHPRC=",
65     NULL
66 };
67 
[403]68@@ -245,6 +252,53 @@
[298]69     environ = cleanenv;
70 }
71 
72+static const char *static_extensions[] = {
73+    "html",
74+    "css",
75+    "gif",
76+    "jpg",
77+    "png",
78+    "htm",
79+    "jpeg",
80+    "js",
81+    "ico",
82+    "xml",
83+    "xsl",
84+    "tiff",
85+    "tif",
86+    "tgz",
87+    "tar",
88+    "jar",
89+    "zip",
90+    "pdf",
91+    "ps",
92+    "doc",
93+    "xls",
94+    "ppt",
95+    "swf",
96+    "mp3",
97+    "mov",
98+    "wmv",
99+    "mpg",
100+    "mpeg",
101+    "avi",
102+    "il",
103+    "JPG",
[315]104+    "xhtml",
[298]105+    NULL
106+};
107+
108+static int is_static_extension(const char *file)
109+{
110+    const char *extension = strrchr(file, '.');
111+    const char **p;
112+    if (extension == NULL) return 0;
113+    for (p = static_extensions; *p; ++p) {
114+        if (strcmp(extension + 1, *p) == 0) return 1;
115+    }
116+    return 0;
117+}
118+
119 int main(int argc, char *argv[])
120 {
121     int userdir = 0;        /* ~userdir flag             */
[403]122@@ -450,7 +504,7 @@
[103]123      * Error out if attempt is made to execute as root or as
124      * a UID less than AP_UID_MIN.  Tsk tsk.
125      */
126-    if ((uid == 0) || (uid < AP_UID_MIN)) {
127+    if ((uid == 0) || (uid < AP_UID_MIN && uid != 102)) {
128         log_err("cannot run as forbidden uid (%d/%s)\n", uid, cmd);
129         exit(107);
130     }
[403]131@@ -482,6 +536,19 @@
[103]132         log_err("failed to setuid (%ld: %s)\n", uid, cmd);
133         exit(110);
134     }
[403]135+    if (is_selinux_enabled()) {
136+       if (uid == 102) {
137+           if (setexeccon("system_u:system_r:signup_t:s0") == -1) {
138+               log_err("failed to setexeccon (%ld: %s) to signup_t\n", uid, cmd);
139+               exit(201);
140+           }
141+       } else {
142+           if (setexeccon("user_u:user_r:user_t:s0") == -1) {
143+               log_err("failed to setexeccon (%ld: %s) to user_t\n", uid, cmd);
144+               exit(202);
145+           }
146+       }
[103]147+    }
148 
149     /*
150      * Get the current working directory, as well as the proper
[403]151@@ -513,6 +580,13 @@
[1]152             exit(113);
153         }
154     }
[298]155+    size_t expected_len = strlen(target_homedir)+1+strlen(AP_USERDIR_SUFFIX)+1;
156+    char *expected = malloc(expected_len);
157+    snprintf(expected, expected_len, "%s/%s", target_homedir, AP_USERDIR_SUFFIX);
[300]158+    if (strncmp(cwd, expected, expected_len-1) != 0) {
[1]159+        log_err("error: file's directory not a subdirectory of user's home directory (%s, %s)\n", cwd, expected);
160+        exit(114);
161+    }
162 
163     if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
164         log_err("command not in docroot (%s/%s)\n", cwd, cmd);
[403]165@@ -530,15 +604,17 @@
[1]166     /*
167      * Error out if cwd is writable by others.
168      */
169+#if 0
170     if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) {
171         log_err("directory is writable by others: (%s)\n", cwd);
172         exit(116);
173     }
174+#endif
175 
176     /*
177      * Error out if we cannot stat the program.
178      */
179-    if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) {
180+    if (((lstat(cmd, &prg_info)) != 0) /*|| (S_ISLNK(prg_info.st_mode))*/) {
181         log_err("cannot stat program: (%s)\n", cmd);
182         exit(117);
183     }
[403]184@@ -546,10 +622,12 @@
[1]185     /*
186      * Error out if the program is writable by others.
187      */
188+#if 0
189     if ((prg_info.st_mode & S_IWOTH) || (prg_info.st_mode & S_IWGRP)) {
190         log_err("file is writable by others: (%s/%s)\n", cwd, cmd);
191         exit(118);
192     }
193+#endif
194 
195     /*
196      * Error out if the file is setuid or setgid.
[403]197@@ -563,6 +641,7 @@
[1]198      * Error out if the target name/group is different from
199      * the name/group of the cwd or the program.
200      */
201+#if 0
202     if ((uid != dir_info.st_uid) ||
203         (gid != dir_info.st_gid) ||
204         (uid != prg_info.st_uid) ||
[403]205@@ -574,6 +653,7 @@
[1]206                 prg_info.st_uid, prg_info.st_gid);
207         exit(120);
208     }
209+#endif
210     /*
211      * Error out if the program is not executable for the user.
212      * Otherwise, she won't find any error in the logs except for
[403]213@@ -609,6 +689,13 @@
[298]214         log = NULL;
215     }
216 
217+    if (is_static_extension(cmd)) {
218+        argv[2] = STATIC_CAT_PATH;
219+        execv(STATIC_CAT_PATH, &argv[2]);
220+       log_err("(%d)%s: static_cat exec failed (%s)\n", errno, strerror(errno), argv[2]);
221+       exit(255);
222+    }
223+
224     /*
225      * Execute the command, replacing our image with its own.
226      */
Note: See TracBrowser for help on using the repository browser.