nix-daemon: Add trusted-users and allowed-users options

‘trusted-users’ is a list of users and groups that have elevated
rights, such as the ability to specify binary caches. It defaults to
‘root’. A typical value would be ‘@wheel’ to specify all users in the
wheel group.

‘allowed-users’ is a list of users and groups that are allowed to
connect to the daemon. It defaults to ‘*’. A typical value would be
‘@users’ to specify the ‘users’ group.
This commit is contained in:
Eelco Dolstra 2014-07-17 16:57:07 +02:00
parent 0c730887c4
commit 049c0eb49c
4 changed files with 90 additions and 3 deletions

View file

@ -479,6 +479,48 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
</varlistentry>
<varlistentry xml:id="conf-trusted-users"><term><literal>trusted-users</literal></term>
<listitem>
<para>A list of names of users (separated by whitespace) that
have additional rights when connecting to the Nix daemon, such
as the ability to specify additional binary caches, or to import
unsigned NARs. You can also specify groups by prefixing them
with <literal>@</literal>; for instance,
<literal>@wheel</literal> means all users in the
<literal>wheel</literal> group. The default is
<literal>root</literal>.</para>
<warning><para>The users listed here have the ability to
compromise the security of a multi-user Nix store. For instance,
they could install Trojan horses subsequently executed by other
users. So you should consider carefully whether to add users to
this list.</para></warning>
</listitem>
</varlistentry>
<varlistentry xml:id="conf-allowed-users"><term><literal>allowed-users</literal></term>
<listitem>
<para>A list of names of users (separated by whitespace) that
are allowed to connect to the Nix daemon. As with the
<option>trusted-users</option> option, you can specify groups by
prefixing them with <literal>@</literal>. Also, you can allow
all users by specifying <literal>*</literal>. The default is
<literal>*</literal>.</para>
<para>Note that trusted users are always allowed to connect.</para>
</listitem>
</varlistentry>
</variablelist>
</para>

View file

@ -63,6 +63,8 @@ Settings::Settings()
lockCPU = getEnv("NIX_AFFINITY_HACK", "1") == "1";
showTrace = false;
enableImportNative = false;
trustedUsers = Strings({"root"});
allowedUsers = Strings({"*"});
}
@ -152,6 +154,8 @@ void Settings::update()
get(logServers, "log-servers");
get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
get(useCaseHack, "use-case-hack");
get(trustedUsers, "trusted-users");
get(allowedUsers, "allowed-users");
string subs = getEnv("NIX_SUBSTITUTERS", "default");
if (subs == "default") {

View file

@ -203,6 +203,15 @@ struct Settings {
/* Whether the importNative primop should be enabled */
bool enableImportNative;
/* List of users that have elevated rights in the Nix daemon, such
as the ability to specify additional binary caches, or to
import unsigned NARs. */
Strings trustedUsers;
/* List of users that are allowed to connect to the daemon, in
addition to the trusted users. These have normal rights. */
Strings allowedUsers;
private:
SettingsMap settings, overrides;

View file

@ -7,6 +7,8 @@
#include "affinity.hh"
#include "globals.hh"
#include <algorithm>
#include <cstring>
#include <unistd.h>
#include <signal.h>
@ -18,6 +20,7 @@
#include <fcntl.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
using namespace nix;
@ -451,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;
@ -770,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
@ -870,9 +894,17 @@ static void daemonLoop()
struct passwd * pw = getpwuid(cred.uid);
string user = pw ? pw->pw_name : int2String(cred.uid);
if (cred.uid == 0) trusted = true;
struct group * gr = getgrgid(cred.gid);
string group = gr ? gr->gr_name : int2String(cred.gid);
printMsg(lvlInfo, format("accepted connection from pid %1%, user %2%") % clientPid % user);
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. */