- std::string scriptFilename;
-
- // If caller is super-user, print info message and exit
- if (api.getRealProcessUser().isSuperUser()) {
- this->printAboutMessage();
- return 0;
- }
- config.readFromFile(cfgFile);
-
- // Check permissions (real uid, effective uid)
- this->checkProcessPermissions(config);
-
- // Initialize logger
- // not done before, because we need super-user privileges for
- // logging anyway
- logger.init(config);
-
- try {
- scriptFilename = env.getVar("SCRIPT_FILENAME");
- } catch (KeyNotFoundException& e) {
- logger.logError("Environment variable SCRIPT_FILENAME not set");
- this->printAboutMessage();
- return 1;
- }
-
- this->checkScriptFile(scriptFilename, config, env);
-
- // Root privileges are needed for chroot()
- // so do this before changing process permissions
- if (config.getChrootPath().length() > 0) {
- api.chroot(config.getChrootPath());
- }
-
- this->changeProcessPermissions(scriptFilename, config, env);
-
- interpreter = this->getInterpreter(env, config);
- targetMode = this->getTargetMode(interpreter);
-
- // Prepare environment for new process
- newEnv = this->prepareEnvironment(env, config, targetMode);
-
- // Set PATH_TRANSLATED to SCRIPT_FILENAME, otherwise
- // the PHP interpreter will not be able to find the script
- if (targetMode == TARGETMODE_PHP && newEnv.hasVar("PATH_TRANSLATED")) {
- newEnv.setVar("PATH_TRANSLATED", scriptFilename);
- }
-
- // Log attempt to execute script
- logger.logInfo("Executing \"" + scriptFilename + "\" as UID "
- + Util::intToStr(api.getEffectiveProcessUser().getUid())
- + ", GID "
- + Util::intToStr(
- api.getEffectiveProcessGroup().getGid()));
-
- this->executeScript(scriptFilename, interpreter, targetMode, newEnv,
- config);
-
- // Function should never return
- // So, if we get here, return with error code
- return 1;
+ std::string scriptFilename;
+ UserInfo targetUser;
+ GroupInfo targetGroup;
+
+ // If caller is super-user, print info message and exit
+ if (api.getRealProcessUser().isSuperUser()) {
+ this->printAboutMessage();
+ return 0;
+ }
+ config.readFromFile(cfgFile);
+
+ // Check permissions (real uid, effective uid)
+ this->checkProcessPermissions(config);
+
+ // Initialize logger
+ // not done before, because we need super-user privileges for
+ // logging anyway
+ logger.init(config);
+
+ try {
+ scriptFilename = env.getVar("SCRIPT_FILENAME");
+ } catch (KeyNotFoundException& e) {
+ logger.logError("Environment variable SCRIPT_FILENAME not set");
+ this->printAboutMessage();
+ return 1;
+ }
+
+
+ // Do checks that do not need target user info
+ this->checkScriptFileStage1(scriptFilename, config, env);
+
+ // Find out target user
+ this->checkProcessPermissions(scriptFilename, config, env, targetUser, targetGroup);
+
+ // Now do checks that might require user info
+ this->checkScriptFileStage2(scriptFilename, config, env, targetUser, targetGroup);
+
+ // Root privileges are needed for chroot()
+ // so do this before changing process permissions
+ if (config.getChrootPath().length() > 0) {
+ PathMatcher pathMatcher = PathMatcher(targetUser, targetGroup);
+ std::string chrootPath = pathMatcher.resolveVariables(config.getChrootPath());
+ api.chroot(chrootPath);
+ }
+
+ this->changeProcessPermissions(config, targetUser, targetGroup);
+
+ interpreter = this->getInterpreter(env, config);
+ targetMode = this->getTargetMode(interpreter);
+
+ // Prepare environment for new process
+ newEnv = this->prepareEnvironment(env, config, targetMode);
+
+ // Set PATH_TRANSLATED to SCRIPT_FILENAME, otherwise
+ // the PHP interpreter will not be able to find the script
+ if (targetMode == TARGETMODE_PHP && newEnv.hasVar("PATH_TRANSLATED")) {
+ newEnv.setVar("PATH_TRANSLATED", scriptFilename);
+ }
+
+ // Log attempt to execute script
+ logger.logInfo("Executing \"" + scriptFilename + "\" as UID "
+ + Util::intToStr(api.getEffectiveProcessUser().getUid())
+ + ", GID "
+ + Util::intToStr(
+ api.getEffectiveProcessGroup().getGid()));
+
+ this->executeScript(scriptFilename, interpreter, targetMode, newEnv,
+ config);
+
+ // Function should never return
+ // So, if we get here, return with error code
+ return 1;