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
|
--- src/support/suexec.c.orig Mon Jun 21 19:51:41 1999
+++ src/support/suexec.c Thu Sep 9 18:58:04 1999
@@ -70,11 +70,35 @@
*
*
*/
+/*
+ * "System" CGI modification 97.05.10 by Rick Franchuk (rickf@netnation.com)
+ *
+ * I found that while it's great to make scripts run under the UID and GID
+ * specified in httpd.conf or what /etc/passwd says is 'cool', suEXEC can
+ * really put a damper on 'System' cgi's, forcing copies of the scripts
+ * to be installed into users' home directories. That didn't seem very
+ * fitting... so I changed it so that the target UID check is disabled in
+ * a system directory #defined in suexec+.h. I hope you all find it useful.
+ *
+ * The docroot check had to be bypassed to allow functionality for VirtualHost
+ * entries. I'm somewhat suprised noone encountered that behavior before.
+ */
+ /*
+ * "FPEXE modification made on 98.05.19 by Scot Hetzel (hetzels@westbend.net)
+ * based on previous FPEXE modifications supplied by Mark Wormgoor
+ * (riddles@ipe.nl)
+ *
+ * Changes were made in order to use Suexec and Frontpage 98 at the same time.
+ * After we change to the target_uid and target_gid. We check if cmd = FPEXE,
+ * if it does then we execute the cmd without performing any further tests.
+ *
+ */
#include "ap_config.h"
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <login_cab.h>
#include <stdarg.h>
@@ -250,6 +274,7 @@
char *cmd; /* command to be executed */
char cwd[AP_MAXPATH]; /* current working directory */
char dwd[AP_MAXPATH]; /* docroot working directory */
+ login_cap_t *lc; /* user resource limits */
struct passwd *pw; /* password entry holder */
struct group *gr; /* group entry holder */
struct stat dir_info; /* directory info holder */
@@ -404,6 +429,19 @@
}
/*
+ * Apply user resource limits based on login class.
+ */
+ if ((lc = login_getclassbyname(pw->pw_class, pw)) == NULL) {
+ log_err("login_getclassbyname() failed\n");
+ exit(248);
+ }
+
+ if ((setusercontext(lc, pw, uid, LOGIN_SETRESOURCES)) != 0) {
+ log_err("setusercontext() failed\n");
+ exit(249);
+ }
+
+ /*
* Change UID/GID here so that the following tests work over NFS.
*
* Initialize the group access list for the target user,
@@ -423,6 +461,14 @@
}
/*
+ * We logged everything, changed to the target uid/gid, and know the
+ * user is ok. We run fpexe now and bail out before anything goes wrong.
+ */
+#ifdef FPEXE
+ if ((strcmp(cmd, FPEXE)) != NULL) {
+#endif
+
+ /*
* Get the current working directory, as well as the proper
* document root (dependant upon whether or not it is a
* ~userdir request). Error out if we cannot get either one,
@@ -453,10 +499,15 @@
}
}
+ /*
+ * This section must be commented out to work properly with
+ * VirtualHosts running CGI in thier own directories.
+ *
if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
log_err("command not in docroot (%s/%s)\n", cwd, cmd);
exit(114);
}
+ */
/*
* Stat the cwd and verify it is a directory, or error out.
@@ -502,6 +553,9 @@
* Error out if the target name/group is different from
* the name/group of the cwd or the program.
*/
+#ifdef SYSTEM_CGI
+ if (strncmp(cwd, SYSTEM_CGI, strlen(SYSTEM_CGI))) {
+#endif
if ((uid != dir_info.st_uid) ||
(gid != dir_info.st_gid) ||
(uid != prg_info.st_uid) ||
@@ -513,6 +567,10 @@
prg_info.st_uid, prg_info.st_gid);
exit(120);
}
+#ifdef SYSTEM_CGI
+ }
+#endif
+
/*
* Error out if the program is not executable for the user.
* Otherwise, she won't find any error in the logs except for
@@ -524,6 +582,49 @@
}
clean_env();
+
+#ifdef FPEXE
+ }
+ else {
+
+ /* The following taken from mod_frontpage.c to check permissions */
+
+ /*
+ * We can't stat the stub dir. Make sure the stub directory is not
+ * owned by root and not group/world writable
+ */
+ if ((lstat(FPSTUBDIR, &dir_info) == -1 ||
+ dir_info.st_uid ||
+ (dir_info.st_mode & (S_IWGRP | S_IWOTH)) ||
+ (!S_ISDIR(dir_info.st_mode)))) {
+ /*
+ * User recovery: set directory to be owned by by root with
+ * permissions r*x*-x*-x.
+ */
+ log_err("Incorrect permissions on stub directory \"%-.1024s\"",
+ FPSTUBDIR);
+ exit (250);
+ }
+
+ /*
+ * We can't stat the stub. Make sure the stub is not owned by root,
+ * set-uid, set-gid, and is not group/world writable or executable.
+ */
+ if ((stat(cmd, &prg_info) == -1 ||
+ prg_info.st_uid ||
+ !(prg_info.st_mode & S_ISUID) ||
+ (prg_info.st_mode & S_ISGID) ||
+ (prg_info.st_mode & (S_IWGRP | S_IWOTH)) ||
+ !(prg_info.st_mode & (S_IXGRP | S_IXOTH)))) {
+ /*
+ * User recovery: set stub to be owned by by root with permissions
+ * r*s*-x*-x.
+ */
+ log_err("Incorrect permissions on stub \"%-.1024s\"", cmd);
+ exit (251);
+ }
+ }
+#endif
/*
* Be sure to close the log file so the CGI can't
|