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:
parent
0c730887c4
commit
049c0eb49c
4 changed files with 90 additions and 3 deletions
|
@ -479,6 +479,48 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||||
</varlistentry>
|
</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>
|
</variablelist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
|
@ -63,6 +63,8 @@ Settings::Settings()
|
||||||
lockCPU = getEnv("NIX_AFFINITY_HACK", "1") == "1";
|
lockCPU = getEnv("NIX_AFFINITY_HACK", "1") == "1";
|
||||||
showTrace = false;
|
showTrace = false;
|
||||||
enableImportNative = false;
|
enableImportNative = false;
|
||||||
|
trustedUsers = Strings({"root"});
|
||||||
|
allowedUsers = Strings({"*"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,6 +154,8 @@ void Settings::update()
|
||||||
get(logServers, "log-servers");
|
get(logServers, "log-servers");
|
||||||
get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
|
get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
|
||||||
get(useCaseHack, "use-case-hack");
|
get(useCaseHack, "use-case-hack");
|
||||||
|
get(trustedUsers, "trusted-users");
|
||||||
|
get(allowedUsers, "allowed-users");
|
||||||
|
|
||||||
string subs = getEnv("NIX_SUBSTITUTERS", "default");
|
string subs = getEnv("NIX_SUBSTITUTERS", "default");
|
||||||
if (subs == "default") {
|
if (subs == "default") {
|
||||||
|
|
|
@ -203,6 +203,15 @@ struct Settings {
|
||||||
/* Whether the importNative primop should be enabled */
|
/* Whether the importNative primop should be enabled */
|
||||||
bool enableImportNative;
|
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:
|
private:
|
||||||
SettingsMap settings, overrides;
|
SettingsMap settings, overrides;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "affinity.hh"
|
#include "affinity.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -18,6 +20,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
|
|
||||||
|
@ -451,7 +454,7 @@ static void performOp(bool trusted, unsigned int clientVersion,
|
||||||
case wopImportPaths: {
|
case wopImportPaths: {
|
||||||
startWork();
|
startWork();
|
||||||
TunnelSource source(from);
|
TunnelSource source(from);
|
||||||
Paths paths = store->importPaths(true, source);
|
Paths paths = store->importPaths(!trusted, source);
|
||||||
stopWork();
|
stopWork();
|
||||||
writeStrings(paths, to);
|
writeStrings(paths, to);
|
||||||
break;
|
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
|
#define SD_LISTEN_FDS_START 3
|
||||||
|
|
||||||
|
|
||||||
|
@ -870,9 +894,17 @@ static void daemonLoop()
|
||||||
struct passwd * pw = getpwuid(cred.uid);
|
struct passwd * pw = getpwuid(cred.uid);
|
||||||
string user = pw ? pw->pw_name : int2String(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
|
#endif
|
||||||
|
|
||||||
/* Fork a child to handle the connection. */
|
/* Fork a child to handle the connection. */
|
||||||
|
|
Loading…
Reference in a new issue