]> granicus.if.org Git - apache/blobdiff - support/suexec.c
Create the pidfile world readable by adding APR_FPROT_WREAD. Use
[apache] / support / suexec.c
index e2118f28e750859284cc341532c287402f3f4523..e4c4ecb4bf3f6a726a4f08bbecadfb5ce737ce9e 100644 (file)
@@ -1,8 +1,9 @@
-/* Copyright 1999-2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -19,8 +20,8 @@
  ***********************************************************************
  *
  * NOTE! : DO NOT edit this code!!!  Unless you know what you are doing,
- *         editing this code might open up your system in unexpected 
- *         ways to would-be crackers.  Every precaution has been taken 
+ *         editing this code might open up your system in unexpected
+ *         ways to would-be crackers.  Every precaution has been taken
  *         to make this code as safe as possible; alter it at your own
  *         risk.
  *
@@ -45,6 +46,9 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdlib.h>
+#if APR_HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
 
 #ifdef HAVE_PWD_H
 #include <pwd.h>
 #include <grp.h>
 #endif
 
-/*
- ***********************************************************************
- * There is no initgroups() in QNX, so I believe this is safe :-)
- * Use cc -osuexec -3 -O -mf -DQNX suexec.c to compile.
- *
- * May 17, 1997.
- * Igor N. Kovalenko -- infoh mail.wplus.net
- ***********************************************************************
- */
-
-#if defined(NEED_INITGROUPS)
-int initgroups(const char *name, gid_t basegid)
-{
-    /* QNX and MPE do not appear to support supplementary groups. */
-    return 0;
-}
-#endif
-
-#if defined(SUNOS4)
-extern char *sys_errlist[];
-#define strerror(x) sys_errlist[(x)]
-#endif
-
 #if defined(PATH_MAX)
 #define AP_MAXPATH PATH_MAX
 #elif defined(MAXPATHLEN)
@@ -90,7 +71,7 @@ extern char *sys_errlist[];
 extern char **environ;
 static FILE *log = NULL;
 
-char *safe_env_lst[] =
+static const char *const safe_env_lst[] =
 {
     /* variable name starts with */
     "HTTP_",
@@ -106,7 +87,6 @@ char *safe_env_lst[] =
     "DOCUMENT_PATH_INFO=",
     "DOCUMENT_ROOT=",
     "DOCUMENT_URI=",
-    "FILEPATH_INFO=",
     "GATEWAY_INTERFACE=",
     "HTTPS=",
     "LAST_MODIFIED=",
@@ -135,6 +115,7 @@ char *safe_env_lst[] =
     "SERVER_ADDR=",
     "SERVER_PORT=",
     "SERVER_PROTOCOL=",
+    "SERVER_SIGNATURE=",
     "SERVER_SOFTWARE=",
     "UNIQUE_ID=",
     "USER_NAME=",
@@ -216,9 +197,9 @@ static void clean_env(void)
      */
     char **envp = environ;
     char *empty_ptr = NULL;
+
     environ = &empty_ptr; /* VERY safe environment */
-    
+
     if ((cleanenv = (char **) calloc(AP_ENVBUF, sizeof(char *))) == NULL) {
         log_err("failed to malloc memory for environment\n");
         exit(120);
@@ -394,13 +375,15 @@ int main(int argc, char *argv[])
             log_err("invalid target group name: (%s)\n", target_gname);
             exit(106);
         }
-        gid = gr->gr_gid;
-        actual_gname = strdup(gr->gr_name);
     }
     else {
-        gid = atoi(target_gname);
-        actual_gname = strdup(target_gname);
+        if ((gr = getgrgid(atoi(target_gname))) == NULL) {
+            log_err("invalid target group id: (%s)\n", target_gname);
+            exit(106);
+        }
     }
+    gid = gr->gr_gid;
+    actual_gname = strdup(gr->gr_name);
 
 #ifdef _OSD_POSIX
     /*
@@ -428,7 +411,7 @@ int main(int argc, char *argv[])
         }
     }
 #endif /*_OSD_POSIX*/
-    
+
     /*
      * Save these for later since initgroups will hose the struct
      */
@@ -437,7 +420,7 @@ int main(int argc, char *argv[])
     target_homedir = strdup(pw->pw_dir);
 
     /*
-     * Log the transaction here to be sure we have an open log 
+     * Log the transaction here to be sure we have an open log
      * before we setuid().
      */
     log_no_err("uid: (%s/%s) gid: (%s/%s) cmd: %s\n",
@@ -594,18 +577,27 @@ int main(int argc, char *argv[])
     umask(AP_SUEXEC_UMASK);
 #endif /* AP_SUEXEC_UMASK */
 
-    /* 
-     * Be sure to close the log file so the CGI can't
-     * mess with it.  If the exec fails, it will be reopened 
-     * automatically when log_err is called.  Note that the log
-     * might not actually be open if AP_LOG_EXEC isn't defined.
-     * However, the "log" cell isn't ifdef'd so let's be defensive
-     * and assume someone might have done something with it
-     * outside an ifdef'd AP_LOG_EXEC block.
-     */
+    /* Be sure to close the log file so the CGI can't mess with it. */
     if (log != NULL) {
+#if APR_HAVE_FCNTL_H
+        /*
+         * ask fcntl(2) to set the FD_CLOEXEC flag on the log file,
+         * so it'll be automagically closed if the exec() call succeeds.
+         */
+        fflush(log);
+        setbuf(log, NULL);
+        if ((fcntl(fileno(log), F_SETFD, FD_CLOEXEC) == -1)) {
+            log_err("error: can't set close-on-exec flag");
+            exit(122);
+        }
+#else
+        /*
+         * In this case, exec() errors won't be logged because we have already
+         * dropped privileges and won't be able to reopen the log file.
+         */
         fclose(log);
         log = NULL;
+#endif
     }
 
     /*