Page MenuHomePhabricator

D7589.diff

diff --git a/src/applications/config/option/PhabricatorPHDConfigOptions.php b/src/applications/config/option/PhabricatorPHDConfigOptions.php
--- a/src/applications/config/option/PhabricatorPHDConfigOptions.php
+++ b/src/applications/config/option/PhabricatorPHDConfigOptions.php
@@ -41,6 +41,14 @@
"of output, but can help debug issues. Daemons launched in debug ".
"mode with 'phd debug' are always launched in verbose mode. See ".
"also 'phd.trace'.")),
+ $this->newOption('phd.user', 'string', null)
+ ->setSummary(pht("System user to run daemons as."))
+ ->setDescription(
+ pht(
+ "Specify a system user to run the daemons as. Primarily, this ".
+ "user will own the working copies of any repositories that ".
+ "Phabricator imports or manages. This option is new and ".
+ "experimental.")),
$this->newOption('phd.trace', 'bool', false)
->setBoolOptions(
array(
diff --git a/src/applications/diffusion/controller/DiffusionServeController.php b/src/applications/diffusion/controller/DiffusionServeController.php
--- a/src/applications/diffusion/controller/DiffusionServeController.php
+++ b/src/applications/diffusion/controller/DiffusionServeController.php
@@ -326,7 +326,10 @@
$input = PhabricatorStartup::getRawInput();
- list($err, $stdout, $stderr) = id(new ExecFuture('%s', $bin))
+ $command = csprintf('%s', $bin);
+ $command = PhabricatorDaemon::sudoCommandAsDaemonUser($command);
+
+ list($err, $stdout, $stderr) = id(new ExecFuture('%C', $command))
->setEnv($env, true)
->write($input)
->resolve();
@@ -422,7 +425,10 @@
$input = strlen($input)."\n".$input."0\n";
}
- list($err, $stdout, $stderr) = id(new ExecFuture('%s serve --stdio', $bin))
+ $command = csprintf('%s serve --stdio', $bin);
+ $command = PhabricatorDaemon::sudoCommandAsDaemonUser($command);
+
+ list($err, $stdout, $stderr) = id(new ExecFuture('%C', $command))
->setEnv($env, true)
->setCWD($repository->getLocalPath())
->write("{$cmd}\n{$args}{$input}")
@@ -545,5 +551,6 @@
return $has_pack && $is_hangup;
}
+
}
diff --git a/src/applications/diffusion/ssh/DiffusionSSHGitReceivePackWorkflow.php b/src/applications/diffusion/ssh/DiffusionSSHGitReceivePackWorkflow.php
--- a/src/applications/diffusion/ssh/DiffusionSSHGitReceivePackWorkflow.php
+++ b/src/applications/diffusion/ssh/DiffusionSSHGitReceivePackWorkflow.php
@@ -22,9 +22,10 @@
// This is a write, and must have write access.
$this->requireWriteAccess();
- $future = new ExecFuture(
- 'git-receive-pack %s',
- $repository->getLocalPath());
+ $command = csprintf('git-receive-pack %s', $repository->getLocalPath());
+ $command = PhabricatorDaemon::sudoCommandAsDaemonUser($command);
+
+ $future = new ExecFuture('%C', $command);
$err = $this->newPassthruCommand()
->setIOChannel($this->getIOChannel())
diff --git a/src/applications/diffusion/ssh/DiffusionSSHGitUploadPackWorkflow.php b/src/applications/diffusion/ssh/DiffusionSSHGitUploadPackWorkflow.php
--- a/src/applications/diffusion/ssh/DiffusionSSHGitUploadPackWorkflow.php
+++ b/src/applications/diffusion/ssh/DiffusionSSHGitUploadPackWorkflow.php
@@ -19,7 +19,10 @@
$path = head($args->getArg('dir'));
$repository = $this->loadRepository($path);
- $future = new ExecFuture('git-upload-pack %s', $repository->getLocalPath());
+ $command = csprintf('git-upload-pack -- %s', $repository->getLocalPath());
+ $command = PhabricatorDaemon::sudoCommandAsDaemonUser($command);
+
+ $future = new ExecFuture('%C', $command);
$err = $this->newPassthruCommand()
->setIOChannel($this->getIOChannel())
diff --git a/src/applications/diffusion/ssh/DiffusionSSHMercurialServeWorkflow.php b/src/applications/diffusion/ssh/DiffusionSSHMercurialServeWorkflow.php
--- a/src/applications/diffusion/ssh/DiffusionSSHMercurialServeWorkflow.php
+++ b/src/applications/diffusion/ssh/DiffusionSSHMercurialServeWorkflow.php
@@ -39,12 +39,12 @@
throw new Exception("Expected `hg ... serve`!");
}
- $future = new ExecFuture(
- 'hg -R %s serve --stdio',
- $repository->getLocalPath());
+ $command = csprintf('hg -R %s serve --stdio', $repository->getLocalPath());
+ $command = PhabricatorDaemon::sudoCommandAsDaemonUser($command);
- $io_channel = $this->getIOChannel();
+ $future = new ExecFuture('%C', $command);
+ $io_channel = $this->getIOChannel();
$protocol_channel = new DiffusionSSHMercurialWireClientProtocolChannel(
$io_channel);
diff --git a/src/applications/diffusion/ssh/DiffusionSSHSubversionServeWorkflow.php b/src/applications/diffusion/ssh/DiffusionSSHSubversionServeWorkflow.php
--- a/src/applications/diffusion/ssh/DiffusionSSHSubversionServeWorkflow.php
+++ b/src/applications/diffusion/ssh/DiffusionSSHSubversionServeWorkflow.php
@@ -38,7 +38,10 @@
throw new Exception("Expected `svnserve -t`!");
}
- $future = new ExecFuture('svnserve -t');
+ $command = csprintf('svnserve -t');
+ $command = PhabricatorDaemon::sudoCommandAsDaemonUser($command);
+
+ $future = new ExecFuture('%C', $command);
$this->inProtocol = new DiffusionSubversionWireProtocol();
$this->outProtocol = new DiffusionSubversionWireProtocol();
diff --git a/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php b/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php
--- a/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php
+++ b/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php
@@ -120,5 +120,4 @@
return $this->hasWriteAccess;
}
-
}
diff --git a/src/infrastructure/daemon/PhabricatorDaemon.php b/src/infrastructure/daemon/PhabricatorDaemon.php
--- a/src/infrastructure/daemon/PhabricatorDaemon.php
+++ b/src/infrastructure/daemon/PhabricatorDaemon.php
@@ -19,4 +19,35 @@
return PhabricatorUser::getOmnipotentUser();
}
+
+ /**
+ * Format a command so it executes as the daemon user, if a daemon user is
+ * defined. This wraps the provided command in `sudo -u ...`, roughly.
+ *
+ * @param PhutilCommandString Command to execute.
+ * @return PhutilCommandString `sudo` version of the command.
+ */
+ public static function sudoCommandAsDaemonUser($command) {
+ $user = PhabricatorEnv::getEnvConfig('phd.user');
+ if (!$user) {
+ // No daemon user is set, so just run this as ourselves.
+ return $command;
+ }
+
+ // Get the absolute path so we're safe against the caller wiping out
+ // PATH.
+ $sudo = Filesystem::resolveBinary('sudo');
+ if (!$sudo) {
+ throw new Exception(pht("Unable to find 'sudo'!"));
+ }
+
+ // Flags here are:
+ //
+ // -E: Preserve the environment.
+ // -n: Non-interactive. Exit with an error instead of prompting.
+ // -u: Which user to sudo to.
+
+ return csprintf('%s -E -n -u %s -- %C', $sudo, $user, $command);
+ }
+
}

File Metadata

Mime Type
text/x-diff
Storage Engine
amazon-s3
Storage Format
Raw Data
Storage Handle
phabricator/bq/av/23h4vwt74eird4bd
Default Alt Text
D7589.diff (6 KB)

Event Timeline