* Joshua Slive wrote:
> Is there any particular reason why suexec can't log an error to stderr as
> well as to its own logfile? I guess it could be a way to find out some
> information about file permissions that would not ordinarily be available.
> What about writing "suexec failure; see suexec_log for more details" to
> stderr?
>
> The point is that "premature end of script headers" is the current
> contents of the error log for suexec failures. This catch-all error is
> really quite unhelpful, and results in lots of extra debugging time. It
> is especially bad because many third-party packagers enable suexec by
> default; so many people are using it without even knowing it.
Totally agreed.
I've attached a patch for suexec that writes an additional message to
stderr, which shows up in the approriate error log.
But I'd very like some security review before committing it.
(Otherwise I hope to wake up the people, when I'm committing ...)
nd
--
sub the($){+shift} sub answer (){ord q
[* It is always 42! *] }
print the answer
# Andr� Malo # http://www.perlig.de/ #
Index: support/suexec.c
===================================================================
RCS file: /home/cvs/httpd-2.0/support/suexec.c,v
retrieving revision 1.22
diff -u -r1.22 suexec.c
--- support/suexec.c 3 Feb 2003 17:53:27 -0000 1.22
+++ support/suexec.c 4 Feb 2003 21:33:05 -0000
@@ -170,7 +170,7 @@
};
-static void err_output(const char *fmt, va_list ap)
+static void err_output(int is_error, const char *fmt, va_list ap)
{
#ifdef AP_LOG_EXEC
time_t timevar;
@@ -178,12 +178,17 @@
if (!log) {
if ((log = fopen(AP_LOG_EXEC, "a")) == NULL) {
- fprintf(stderr, "failed to open log file\n");
+ fprintf(stderr, "suexec failure: could not open log file\n");
perror("fopen");
exit(1);
}
}
+ if (is_error) {
+ fprintf(stderr, "suexec policy violation: see suexec log for more "
+ "details\n");
+ }
+
time(&timevar);
lt = localtime(&timevar);
@@ -204,7 +209,19 @@
va_list ap;
va_start(ap, fmt);
- err_output(fmt, ap);
+ err_output(1, fmt, ap); /* 1 == is_error */
+ va_end(ap);
+#endif /* AP_LOG_EXEC */
+ return;
+}
+
+static void log_no_err(const char *fmt,...)
+{
+#ifdef AP_LOG_EXEC
+ va_list ap;
+
+ va_start(ap, fmt);
+ err_output(0, fmt, ap); /* 0 == !is_error */
va_end(ap);
#endif /* AP_LOG_EXEC */
return;
@@ -441,10 +458,10 @@
* Log the transaction here to be sure we have an open log
* before we setuid().
*/
- log_err("uid: (%s/%s) gid: (%s/%s) cmd: %s\n",
- target_uname, actual_uname,
- target_gname, actual_gname,
- cmd);
+ log_no_err("uid: (%s/%s) gid: (%s/%s) cmd: %s\n",
+ target_uname, actual_uname,
+ target_gname, actual_gname,
+ cmd);
/*
* Error out if attempt is made to execute as root or as