diff options
author | Ludovic Courtès <ludo@gnu.org> | 2015-05-11 17:04:26 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2015-05-11 17:04:26 +0200 |
commit | 766481d606e4b1860307692d6a44723983662d45 (patch) | |
tree | 7e6d112047bb03f7761ca8a41c02ac2a84b73c84 /nix/nix-daemon/nix-daemon.cc | |
parent | c69944c511b89d3fdbffe00353e27d1e1c5f670c (diff) | |
parent | fdee1ced43fb495d612a29e955141cdf6b9a95ba (diff) | |
download | guix-766481d606e4b1860307692d6a44723983662d45.tar.gz |
Merge commit 'fdee1ced43fb495d612a29e955141cdf6b9a95ba' into nix
Diffstat (limited to 'nix/nix-daemon/nix-daemon.cc')
-rw-r--r-- | nix/nix-daemon/nix-daemon.cc | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/nix/nix-daemon/nix-daemon.cc b/nix/nix-daemon/nix-daemon.cc index 265131c613..f2141ee536 100644 --- a/nix/nix-daemon/nix-daemon.cc +++ b/nix/nix-daemon/nix-daemon.cc @@ -7,6 +7,8 @@ #include "affinity.hh" #include "globals.hh" +#include <algorithm> + #include <cstring> #include <unistd.h> #include <signal.h> @@ -17,6 +19,8 @@ #include <sys/un.h> #include <fcntl.h> #include <errno.h> +#include <pwd.h> +#include <grp.h> using namespace nix; @@ -450,7 +454,7 @@ static void performOp(bool trusted, unsigned int clientVersion, case wopImportPaths: { startWork(); TunnelSource source(from); - Paths paths = store->importPaths(true, source); + Paths paths = store->importPaths(!trusted, source); stopWork(); writeStrings(paths, to); break; @@ -769,6 +773,27 @@ static void setSigChldAction(bool autoReap) } +bool matchUser(const string & user, const string & group, const Strings & users) +{ + if (find(users.begin(), users.end(), "*") != users.end()) + return true; + + if (find(users.begin(), users.end(), user) != users.end()) + return true; + + for (auto & i : users) + if (string(i, 0, 1) == "@") { + if (group == string(i, 1)) return true; + struct group * gr = getgrnam(i.c_str() + 1); + if (!gr) continue; + for (char * * mem = gr->gr_mem; *mem; mem++) + if (user == string(*mem)) return true; + } + + return false; +} + + #define SD_LISTEN_FDS_START 3 @@ -854,22 +879,33 @@ static void daemonLoop() closeOnExec(remote); - /* Get the identity of the caller, if possible. */ - uid_t clientUid = -1; - pid_t clientPid = -1; bool trusted = false; + pid_t clientPid = -1; #if defined(SO_PEERCRED) + /* Get the identity of the caller, if possible. */ ucred cred; socklen_t credLen = sizeof(cred); - if (getsockopt(remote, SOL_SOCKET, SO_PEERCRED, &cred, &credLen) != -1) { - clientPid = cred.pid; - clientUid = cred.uid; - if (clientUid == 0) trusted = true; - } -#endif + if (getsockopt(remote, SOL_SOCKET, SO_PEERCRED, &cred, &credLen) == -1) + throw SysError("getting peer credentials"); + + clientPid = cred.pid; + + struct passwd * pw = getpwuid(cred.uid); + string user = pw ? pw->pw_name : int2String(cred.uid); - printMsg(lvlInfo, format("accepted connection from pid %1%, uid %2%") % clientPid % clientUid); + struct group * gr = getgrgid(cred.gid); + string group = gr ? gr->gr_name : int2String(cred.gid); + + if (matchUser(user, group, settings.trustedUsers)) + trusted = true; + + if (!trusted && !matchUser(user, group, settings.allowedUsers)) + throw Error(format("user `%1%' is not allowed to connect to the Nix daemon") % user); + + printMsg(lvlInfo, format((string) "accepted connection from pid %1%, user %2%" + + (trusted ? " (trusted)" : "")) % clientPid % user); +#endif /* Fork a child to handle the connection. */ startProcess([&]() { |