daemon: Set ownership of kept build directories to the calling user.

Fixes <http://bugs.gnu.org/15890>.

* nix/libstore/globals.hh (Settings) Add clientUid and clientGid.
* nix/nix-daemon/nix-daemon.cc (daemonLoop] Store UID and GID of the
  caller in settings.
* nix/libstore/build.cc (_chown): New function.
  (DerivationGoal::deleteTmpDir): Use it, change ownership of build
  directory if it is kept and the new owner is not root.
This commit is contained in:
Hartmut Goebel 2016-11-21 19:49:12 +01:00
parent 43e8824d3c
commit 2608e40988
No known key found for this signature in database
GPG key ID: 634A8DFFD3F631DF
3 changed files with 39 additions and 0 deletions

View file

@ -2631,6 +2631,21 @@ void DerivationGoal::closeLogFile()
}
static void _chown(const Path & path, uid_t uid, gid_t gid)
{
checkInterrupt();
if (lchown(path.c_str(), uid, gid) == -1) {
throw SysError(format("change owner and group of `%1%'") % path);
}
struct stat st = lstat(path);
if (S_ISDIR(st.st_mode)) {
for (auto & i : readDirectory(path))
_chown(path + "/" + i.name, uid, gid);
}
}
void DerivationGoal::deleteTmpDir(bool force)
{
if (tmpDir != "") {
@ -2639,6 +2654,12 @@ void DerivationGoal::deleteTmpDir(bool force)
format("note: keeping build directory `%2%'")
% drvPath % tmpDir);
chmod(tmpDir.c_str(), 0755);
// Change the ownership if clientUid is set. Never change the
// ownership or the group to "root" for security reasons.
if (settings.clientUid != (uid_t) -1 && settings.clientUid != 0) {
_chown(tmpDir, settings.clientUid,
settings.clientGid != 0 ? settings.clientGid : -1);
}
}
else
deletePath(tmpDir);