Common subdirectories: suphp-0.7.1/src-o//apache and suphp-0.7.1/src/apache
Common subdirectories: suphp-0.7.1/src-o//apache2 and suphp-0.7.1/src/apache2
diff -up suphp-0.7.1/src-o//Application.cpp suphp-0.7.1/src/Application.cpp
--- suphp-0.7.1/src-o//Application.cpp	2009-03-14 14:55:25.000000000 -0300
+++ suphp-0.7.1/src/Application.cpp	2010-06-11 16:57:51.000000000 -0300
@@ -66,6 +66,10 @@ int suPHP::Application::run(CommandLine&
         std::string scriptFilename;
         UserInfo targetUser;
         GroupInfo targetGroup;
+#ifdef COMMON_POOL
+        UserInfo commonUser;
+        GroupInfo commonGroup;
+#endif // COMMON_POOL
 
         // If caller is super-user, print info message and exit
         if (api.getRealProcessUser().isSuperUser()) {
@@ -95,10 +99,20 @@ int suPHP::Application::run(CommandLine&
         this->checkScriptFileStage1(scriptFilename, config, env);
 
         // Find out target user
-        this->checkProcessPermissions(scriptFilename, config, env, targetUser, targetGroup);
+        this->checkProcessPermissions(scriptFilename, config, env, targetUser, targetGroup
+#ifdef COMMON_POOL
+		, commonUser,
+		commonGroup
+#endif // COMMON_POOL
+	);
 
         // Now do checks that might require user info
-        this->checkScriptFileStage2(scriptFilename, config, env, targetUser, targetGroup);
+        this->checkScriptFileStage2(scriptFilename, config, env, targetUser, targetGroup
+#ifdef COMMON_POOL
+		, commonUser
+//		commonGroup
+#endif // COMMON_POOL
+);
 
         // Root privileges are needed for chroot()
         // so do this before changing process permissions
@@ -272,7 +286,12 @@ void suPHP::Application::checkScriptFile
     const Configuration& config,
     const Environment& environment,
     const UserInfo& targetUser,
-    const GroupInfo& targetGroup) const
+    const GroupInfo& targetGroup
+#ifdef COMMON_POOL
+    , const UserInfo& commonUser
+//    const GroupInfo& commonGroup
+#endif // COMMON_POOL
+) const
     throw (SystemException, SoftException) {
     Logger& logger = API_Helper::getSystemAPI().getSystemLogger();
     File scriptFile = File(scriptFilename);
@@ -281,7 +300,7 @@ void suPHP::Application::checkScriptFile
     // Get full path to script file
     File realScriptFile = File(scriptFile.getRealPath());
 
-    // Check wheter script is in one of the defined docroots
+    // Check whether script is in one of the defined docroots
     bool file_in_docroot = false;
     const std::vector<std::string> docroots = config.getDocroots();
     for (std::vector<std::string>::const_iterator i = docroots.begin(); i != docroots.end(); i++) {
@@ -314,8 +333,16 @@ void suPHP::Application::checkScriptFile
     }
 
     // Check directory ownership and permissions
-    checkParentDirectories(realScriptFile, targetUser, config);
-    checkParentDirectories(scriptFile, targetUser, config);
+    checkParentDirectories(realScriptFile, targetUser, config
+#ifdef COMMON_POOL
+    ,commonUser
+#endif // COMMON_POOL    
+    );
+    checkParentDirectories(scriptFile, targetUser, config
+#ifdef COMMON_POOL
+    , commonUser
+#endif // COMMON_POOL
+    );
 }
 
 void suPHP::Application::checkProcessPermissions(
@@ -323,7 +350,12 @@ void suPHP::Application::checkProcessPer
     const Configuration& config,
     const Environment& environment,
     UserInfo& targetUser,
-    GroupInfo& targetGroup) const
+    GroupInfo& targetGroup
+#ifdef COMMON_POOL
+    , UserInfo& commonUser,
+    GroupInfo& commonGroup
+#endif // COMMON_POOL
+) const
     throw (SystemException, SoftException, SecurityException) {
 
     File scriptFile = File(scriptFilename);
@@ -395,7 +427,40 @@ void suPHP::Application::checkProcessPer
     // Paranoid mode only
 
 #ifdef OPT_USERGROUP_PARANOID
-    if (targetUser != scriptFile.getUser()) {
+
+#ifdef COMMON_POOL
+    std::string commonUsername, commonGroupname;
+    
+    try {
+        targetUsername = config.getCommonUser();
+        targetGroupname = config.getCommonGroup();
+    } catch (KeyNotFoundException& e) {
+        throw SecurityException(
+            "Config variables SUPHP_COMMON_USER or SUPHP_COMMON_GROUP not set",
+            __FILE__, __LINE__);
+    }
+
+    if (commonUsername[0] == '#' && commonUsername.find_first_not_of(
+            "0123456789", 1) == std::string::npos) {
+        commonUser = api.getUserInfo(Util::strToInt(commonUsername.substr(1)));
+    } else {
+        commonUser = api.getUserInfo(commonUsername);
+    }
+
+    if (commonGroupname[0] == '#' && commonGroupname.find_first_not_of(
+            "0123456789", 1) == std::string::npos) {
+        commonGroup = api.getGroupInfo(
+            Util::strToInt(commonGroupname.substr(1)));
+    } else {
+        commonGroup = api.getGroupInfo(commonGroupname);
+    }
+#endif // COMMON_POOL
+    
+    if (targetUser != scriptFile.getUser()
+#ifdef COMMON_POOL
+	&& commonUser != scriptFile.getUser()
+#endif // COMMON_POOL
+    ) {
         std::string error ="Mismatch between target UID ("
             + Util::intToStr(targetUser.getUid()) + ") and UID ("
             + Util::intToStr(scriptFile.getUser().getUid()) + ") of file \""
@@ -404,7 +469,11 @@ void suPHP::Application::checkProcessPer
         throw SoftException(error, __FILE__, __LINE__);
     }
 
-    if (targetGroup != scriptFile.getGroup()) {
+    if (targetGroup != scriptFile.getGroup()
+#ifdef COMMON_POOL
+	&& commonGroup != scriptFile.getGroup()
+#endif // COMMON_POOL
+    ) {
         std::string error ="Mismatch between target GID ("
             + Util::intToStr(targetGroup.getGid()) + ") and GID ("
             + Util::intToStr(scriptFile.getGroup().getGid()) + ") of file \""
@@ -506,6 +575,8 @@ TargetMode suPHP::Application::getTarget
         return TARGETMODE_PHP;
     else if (interpreter == "execute:!self")
         return TARGETMODE_SELFEXECUTE;
+    else if (interpreter.substr(0, 8) == "execute:")
+        return TARGETMODE_OTHER;
     else
         throw SecurityException("Unknown Interpreter: " + interpreter,
                                 __FILE__, __LINE__);
@@ -522,10 +593,13 @@ void suPHP::Application::executeScript(c
         // Change working directory to script path
         API_Helper::getSystemAPI().setCwd(
             File(scriptFilename).getParentDirectory().getPath());
-        if (mode == TARGETMODE_PHP) {
-            std::string interpreterPath = interpreter.substr(4);
+        if (mode == TARGETMODE_PHP || mode == TARGETMODE_OTHER) {
+            std::string interpreterPath = interpreter.substr((mode==TARGETMODE_OTHER)?8:4);
             CommandLine cline;
-            cline.putArgument(interpreterPath);
+            cline.putArgument(scriptFilename);
+            if (mode==TARGETMODE_OTHER) {
+		    cline.putArgument(interpreterPath);
+	    }
             API_Helper::getSystemAPI().execute(interpreterPath, cline, env);
         } else if (mode == TARGETMODE_SELFEXECUTE) {
             CommandLine cline;
@@ -541,14 +615,22 @@ void suPHP::Application::executeScript(c
 
 void suPHP::Application::checkParentDirectories(const File& file,
                                                const UserInfo& owner,
-                                               const Configuration& config) const throw (SoftException) {
+                                               const Configuration& config
+#ifdef COMMON_POOL
+						, const UserInfo& commonUser
+#endif // COMMON_POOL
+) const throw (SoftException) {
     File directory = file;
     Logger& logger = API_Helper::getSystemAPI().getSystemLogger();
     do {
         directory = directory.getParentDirectory();
 
         UserInfo directoryOwner = directory.getUser();
-        if (directoryOwner != owner && !directoryOwner.isSuperUser()) {
+        if (directoryOwner != owner && !directoryOwner.isSuperUser()
+#ifdef COMMON_POOL
+		&& directoryOwner != commonUser
+#endif // COMMON_POOL
+		) {
             std::string error = "Directory " + directory.getPath()
                 + " is not owned by " + owner.getUsername();
             logger.logWarning(error);
diff -up suphp-0.7.1/src-o//Application.hpp suphp-0.7.1/src/Application.hpp
--- suphp-0.7.1/src-o//Application.hpp	2008-03-29 14:48:59.000000000 -0300
+++ suphp-0.7.1/src/Application.hpp	2010-06-11 16:55:49.000000000 -0300
@@ -26,7 +26,8 @@ namespace suPHP {
 
 enum TargetMode {
     TARGETMODE_PHP,
-    TARGETMODE_SELFEXECUTE
+    TARGETMODE_SELFEXECUTE,
+    TARGETMODE_OTHER
 };
 
 #define SUPHP_APPLICATION_H
@@ -78,7 +79,11 @@ namespace suPHP {
                              const Configuration& config, 
                              const Environment& environment,
                              const UserInfo& targetUser,
-                             const GroupInfo& targetGroup) const
+                             const GroupInfo& targetGroup
+#ifdef COMMON_POOL
+                             , const UserInfo& commonUser
+#endif
+			     ) const
             throw (SystemException, SoftException);
         
         /**
@@ -89,7 +94,12 @@ namespace suPHP {
                                       const Configuration& config,
                                       const Environment& environment,
                                       UserInfo& targetUser,
-                                      GroupInfo& targetGroup) const
+                                      GroupInfo& targetGroup
+#ifdef COMMON_POOL
+                                      , UserInfo& commonUser,
+                                      GroupInfo& commonGroup
+#endif
+				      ) const
             throw (SystemException, SoftException, SecurityException);
         
         /**
@@ -137,7 +147,11 @@ namespace suPHP {
          */
         void checkParentDirectories(const File& file,
                                     const UserInfo& owner,
-                                    const Configuration& config) const
+                                    const Configuration& config
+#ifdef COMMON_POOL
+                                    , const UserInfo& commonUser
+#endif
+				    ) const
             throw (SoftException);
 
 
diff -up suphp-0.7.1/src-o//Configuration.cpp suphp-0.7.1/src/Configuration.cpp
--- suphp-0.7.1/src-o//Configuration.cpp	2008-03-29 10:02:36.000000000 -0300
+++ suphp-0.7.1/src/Configuration.cpp	2010-06-11 16:06:37.000000000 -0300
@@ -112,6 +112,11 @@ suPHP::Configuration::Configuration() {
 #endif
     this->umask = 0077;
     this->chroot_path = "";
+    
+#ifdef COMMON_POOL
+    this->common_user = "";
+    this->common_group = "";
+#endif // COMMON_POOL    
 }
 
 void suPHP::Configuration::readFromFile(File& file) 
@@ -157,6 +162,12 @@ void suPHP::Configuration::readFromFile(
                 this->umask = Util::octalStrToInt(value);
             else if (key == "chroot")
                 this->chroot_path = value;
+#ifdef COMMON_POOL
+            else if (key == "common_user")
+                this->common_user = value;
+            else if (key == "common_group")
+                this->common_group = value;
+#endif // COMMON_POOL
             else 
                 throw ParsingException("Unknown option \"" + key + 
                                        "\" in section [global]", 
@@ -250,3 +261,13 @@ int suPHP::Configuration::getUmask() con
 std::string suPHP::Configuration::getChrootPath() const {
     return this->chroot_path;
 }
+
+#ifdef COMMON_POOL
+std::string suPHP::Configuration::getCommonUser() const {
+    return this->common_user;
+}
+
+std::string suPHP::Configuration::getCommonGroup() const {
+    return this->common_group;
+}
+#endif // COMMON_POOL
diff -up suphp-0.7.1/src-o//Configuration.hpp suphp-0.7.1/src/Configuration.hpp
--- suphp-0.7.1/src-o//Configuration.hpp	2008-03-29 10:02:36.000000000 -0300
+++ suphp-0.7.1/src/Configuration.hpp	2010-06-11 16:06:37.000000000 -0300
@@ -58,6 +58,11 @@ namespace suPHP {
         int min_gid;
         int umask;
         std::string chroot_path;
+    
+#ifdef COMMON_POOL
+	std::string common_user;
+	std::string common_group;
+#endif // COMMON_POOL
 
         /**
          * Converts string to bool
@@ -166,6 +171,18 @@ namespace suPHP {
          * Return chroot path
          */
         std::string getChrootPath() const;
+
+#ifdef COMMON_POOL
+        /**
+         * Return common pool user
+         */
+        std::string getCommonUser() const;
+	
+        /**
+         * Return common pool group
+         */
+        std::string getCommonGroup() const;
+#endif // COMMON_POOL
     };
 };
 
