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 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> | ||||
|  |  | |||
|  | @ -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") { | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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. */ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue