aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/env-common.xml11
-rw-r--r--doc/manual/installation.xml248
-rw-r--r--doc/manual/nix-env.xml43
-rw-r--r--doc/manual/opt-inst-syn.xml15
-rw-r--r--src/libexpr/primops.cc3
5 files changed, 274 insertions, 46 deletions
diff --git a/doc/manual/env-common.xml b/doc/manual/env-common.xml
index 89ee78c76..fdfbaf59a 100644
--- a/doc/manual/env-common.xml
+++ b/doc/manual/env-common.xml
@@ -263,6 +263,17 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
</varlistentry>
+<varlistentry xml:id="envar-remote"><term><envar>NIX_REMOTE</envar></term>
+
+ <listitem><para>This variable should be set to
+ <literal>daemon</literal> if you want to use the Nix daemon to
+ executed Nix operations, which is necessary in <link
+ linkend="ssec-multi-user">multi-user Nix installations</link>.
+ Otherwise, it should be left unset.</para></listitem>
+
+</varlistentry>
+
+
</variablelist>
diff --git a/doc/manual/installation.xml b/doc/manual/installation.xml
index 3a143e44f..72e4b541a 100644
--- a/doc/manual/installation.xml
+++ b/doc/manual/installation.xml
@@ -100,14 +100,16 @@ ubiquitous 2.5.4a won't. Note that these are only required if you
modify the parser or when you are building from the Subversion
repository.</para>
-<para>Nix uses Sleepycat's Berkeley DB and CWI's ATerm library. These
-are included in the Nix source distribution. If you build from the
-Subversion repository, you must download them yourself and place them
-in the <filename>externals/</filename> directory. See
+<para>Nix uses Sleepycat's Berkeley DB, CWI's ATerm library and the
+bzip2 compressor (including the bzip2 library). These are included in
+the Nix source distribution. If you build from the Subversion
+repository, you must download them yourself and place them in the
+<filename>externals/</filename> directory. See
<filename>externals/Makefile.am</filename> for the precise URLs of
these packages. Alternatively, if you already have them installed,
-you can use <command>configure</command>'s <option>--with-bdb</option>
-and <option>--with-aterm</option> options to point to their respective
+you can use <command>configure</command>'s
+<option>--with-bdb</option>, <option>--with-aterm</option> and
+<option>--with-bzip2</option> options to point to their respective
locations. Note that Berkeley DB <emphasis>must</emphasis> be version
4.5; other versions may not have compatible database formats.</para>
@@ -118,19 +120,21 @@ locations. Note that Berkeley DB <emphasis>must</emphasis> be version
<para>After unpacking or checking out the Nix sources, issue the
following commands:
- </para>
<screen>
$ ./configure <replaceable>options...</replaceable>
$ make
$ make install</screen>
+</para>
+
<para>When building from the Subversion repository, these should be
preceded by the command:
- </para>
<screen>
-$ ./boostrap</screen>
+$ ./bootstrap</screen>
+
+</para>
<para>The installation path can be specified by passing the
<option>--prefix=<replaceable>prefix</replaceable></option> to
@@ -165,20 +169,24 @@ Hat Linux. They have been known to work work on SuSE Linux 8.1 and
distribution based on <literal>glibc</literal> 2.3 or later.</para>
<para>Once downloaded, the RPMs can be installed or upgraded using
-<command>rpm -U</command>. For example,</para>
+<command>rpm -U</command>. For example,
<screen>
$ rpm -U nix-0.5pre664-1.i386.rpm</screen>
+</para>
+
<para>The RPMs install into the directory <filename>/nix</filename>.
Nix can be uninstalled using <command>rpm -e nix</command>. After
this it will be necessary to manually remove the Nix store and other
-auxiliary data:</para>
+auxiliary data:
<screen>
$ rm -rf /nix/store
$ rm -rf /nix/var</screen>
+</para>
+
</section>
@@ -187,7 +195,7 @@ $ rm -rf /nix/var</screen>
<para>You can install the latest stable version of Nix through Nix
itself by subscribing to the channel <link
xlink:href="http://nix.cs.uu.nl/dist/nix/channels-v3/nix-stable" />,
-or the latest unstable version by subscribing to the channel<link
+or the latest unstable version by subscribing to the channel <link
xlink:href="http://nix.cs.uu.nl/dist/nix/channels-v3/nix-unstable" />.
You can also do a <link linkend="sec-one-click">one-click
installation</link> by clicking on the package links at <link
@@ -231,33 +239,215 @@ class="username">root</systemitem> all the time.</para>
</section>
-<section><title>Multi-user mode</title>
-
-<para></para>
+<section xml:id="ssec-multi-user"><title>Multi-user mode</title>
+<para>To allow a Nix store to be shared safely among multiple users,
+it is important that users are not able to run builders that modify
+the Nix store or database in arbitrary ways, or that interfere with
+builds started by other users. If they could do so, they could
+install a Trojan horse in some package and compromise the accounts of
+other users.</para>
-<!--
-
-warning: the nix-builders group should contain *only* the Nix
-builders, and nothing else. If the Nix account is compromised, you
-can execute programs under the accounts in the nix-builders group, so
-it obviously shouldn’t contain any “real” user accounts. So don’t use
-an existing group like <literal>users</literal> — just create a new
-one.
-
--->
+<para>To prevent this, the Nix store and database are owned by some
+privileged user (usually <literal>root</literal>) and builders are
+executed under special user accounts (usually named
+<literal>nixbld1</literal>, <literal>nixbld2</literal>, etc.). When a
+unprivileged user runs a Nix command, actions that operate on the Nix
+store (such as builds) are forwarded to a <emphasis>Nix
+daemon</emphasis> running under the owner of the Nix store/database
+that performs the operation.</para>
<note><para>Multi-user mode has one important limitation: only
<systemitem class="username">root</systemitem> can run <command
linkend="sec-nix-pull">nix-pull</command> to register the availability
-of pre-built binaries. However, those registrations
-<emphasis>are</emphasis> used by all users to speed up
-builds.</para></note>
+of pre-built binaries. However, those registrations are shared by all
+users, so they still get the benefit from <command>nix-pull</command>s
+done by <systemitem class="username">root</systemitem>.</para></note>
+
+
+<section><title>Setting up the build users</title>
+
+<para>The <emphasis>build users</emphasis> are the special UIDs under
+which builds are performed. They should all be members of the
+<emphasis>build users group</emphasis> (usually called
+<literal>nixbld</literal>). This group should have no other members.
+The build users should not be members of any other group.</para>
+
+<para>Here is a typical <filename>/etc/group</filename> definition of
+the build users group with 10 build users:
+
+<programlisting>
+nixbld:!:30000:nixbld1,nixbld2,nixbld3,nixbld4,nixbld5,nixbld6,nixbld7,nixbld8,nixbld9,nixbld10
+</programlisting>
+
+In this example the <literal>nixbld</literal> group has UID 30000, but
+of course it can be anything that doesn’t collide with an existing
+group.</para>
+
+<para>Here is the corresponding part of
+<filename>/etc/passwd</filename>:
+
+<programlisting>
+nixbld1:x:30001:65534:Nix build user 1:/var/empty:/noshell
+nixbld2:x:30002:65534:Nix build user 2:/var/empty:/noshell
+nixbld3:x:30003:65534:Nix build user 3:/var/empty:/noshell
+...
+nixbld10:x:30010:65534:Nix build user 10:/var/empty:/noshell
+</programlisting>
+
+The home directory of the build users should not exist or should be an
+empty directory to which they do not have write access.</para>
+
+<para>The build users should have write access to the Nix store, but
+they should not have the right to delete files. Thus the Nix store’s
+group should be the build users group, and it should have the sticky
+bit turned on (like <filename>/tmp</filename>):
+
+<screen>
+$ chgrp nixbld /nix/store
+$ chmod 1777 /nix/store
+</screen>
+
+</para>
+
+<para>Finally, you should tell Nix to use the build users by
+specifying the build users group in the <link
+linkend="conf-build-users-group"><literal>build-users-group</literal>
+option</link> in the <link linkend="sec-conf-file">Nix configuration
+file</link> (<literal>/nix/etc/nix/nix.conf</literal>):
+
+<programlisting>
+build-users-group = nixbld
+</programlisting>
+
+</para>
+
+</section>
+
+
+<section><title>Nix store/database owned by root</title>
+
+<para>The simplest setup is to let <literal>root</literal> own the Nix
+store and database. I.e.,
+
+<screen>
+$ chown -R root /nix/store /nix/var/nix</screen>
+
+</para>
+
+<para>The Nix daemon should be started as follows (as
+<literal>root</literal>):
+
+<screen>
+$ nix-worker --daemon</screen>
+
+You’ll want to put that line somewhere in your system’s boot
+scripts.</para>
+
+<para>To let unprivileged users use the daemon, they should set the
+<link linkend="envar-remote"><envar>NIX_REMOTE</envar> environment
+variable</link> to <literal>daemon</literal>. So you should put a
+line like
+
+<programlisting>
+export NIX_REMOTE=daemon</programlisting>
+
+into the users’ login scripts.</para>
</section>
-</section> <!-- end of permissions section -->
+<section><title>Nix store/database not owned by root</title>
+
+<para>It is also possible to let the Nix store and database be owned
+by a non-root user, which should be more secure<footnote><para>Note
+however that even when the Nix daemon runs as root, not
+<emphasis>that</emphasis> much code is executed as root: Nix
+expression evaluation is performed by the calling (unprivileged) user,
+and builds are performed under the special build user accounts. So
+only the code that accesses the database and starts builds is executed
+as <literal>root</literal>.</para></footnote>. Typically, this user
+is a special account called <literal>nix</literal>, but it can be
+named anything. It should own the Nix store and database:
+
+<screen>
+$ chown -R root /nix/store /nix/var/nix</screen>
+
+and of course <command>nix-worker --daemon</command> should be started
+under that user, e.g.,
+
+<screen>
+$ su - nix -c "exec /nix/bin/nix-worker --daemon"</screen>
+
+</para>
+
+<para>There is a catch, though: non-<literal>root</literal> users
+cannot start builds under the build user accounts, since the
+<function>setuid</function> system call is obviously privileged. To
+allow a non-<literal>root</literal> Nix daemon to use the build user
+feature, it calls a setuid-root helper program,
+<command>nix-setuid-helper</command>. This program is installed in
+<filename><replaceable>prefix</replaceable>/libexec/nix-setuid-helper</filename>.
+To set the permissions properly (Nix’s <command>make install</command>
+doesn’t do this, since we don’t want to ship setuid-root programs
+out-of-the-box):
+
+<screen>
+$ chown root.root /nix/libexec/nix-setuid-helper
+$ chmod 4755 /nix/libexec/nix-setuid-helper
+</screen>
+
+(This example assumes that the Nix binaries are installed in
+<filename>/nix</filename>.)</para>
+
+<para>Of course, the <command>nix-setuid-helper</command> command
+should not be usable by just anybody, since then anybody could run
+commands under the Nix build user accounts. For that reason there is
+a configuration file <filename>/etc/nix-setuid.conf</filename> that
+restricts the use of the helper. This file should be a text file
+containing precisely two lines, the first being the Nix daemon user
+and the second being the build users group, e.g.,
+
+<programlisting>
+nix
+nixbld
+</programlisting>
+
+The setuid-helper barfs if it is called by a user other than the one
+specified on the first line, or if it is asked to execute a build
+under a user who is not a member of the group specified on the second
+line. The file <filename>/etc/nix-setuid.conf</filename> must be
+owned by root, and must not be group- or world-writable. The
+setuid-helper barfs if this is not the case.</para>
+
+</section>
+
+
+<section><title>Restricting access</title>
+
+<para>To limit which users can perform Nix operations, you can use the
+permissions on the directory
+<filename>/nix/var/nix/daemon-socket</filename>. For instance, if you
+want to restrict the use of Nix to the members of a group called
+<literal>nix-users</literal>, do
+
+<screen>
+$ chgrp nix-users /nix/var/nix/daemon-socket
+$ chmod ug=rwx,o= /nix/var/nix/daemon-socket
+</screen>
+
+This way, users who are not in the <literal>nix-users</literal> group
+cannot connect to the Unix domain socket
+<filename>/nix/var/nix/daemon-socket/socket</filename>, so they cannot
+perform Nix operations.</para>
+
+</section>
+
+
+</section> <!-- end of multi-user -->
+
+
+</section> <!-- end of security -->
<section><title>Using Nix</title>
diff --git a/doc/manual/nix-env.xml b/doc/manual/nix-env.xml
index 9b9127921..9af8c0c02 100644
--- a/doc/manual/nix-env.xml
+++ b/doc/manual/nix-env.xml
@@ -21,13 +21,6 @@
<arg><option>--arg</option> <replaceable>name</replaceable> <replaceable>value</replaceable></arg>
<arg>
<group choice='req'>
- <arg choice='plain'><option>--attr</option></arg>
- <arg choice='plain'><option>-A</option></arg>
- </group>
- <replaceable>attrPath</replaceable>
- </arg>
- <arg>
- <group choice='req'>
<arg choice='plain'><option>--file</option></arg>
<arg choice='plain'><option>-f</option></arg>
</group>
@@ -45,9 +38,6 @@
<replaceable>system</replaceable>
</arg>
<arg><option>--dry-run</option></arg>
- <arg><option>--from-expression</option></arg>
- <arg><option>-E</option></arg>
- <arg><option>--from-profile</option> <replaceable>path</replaceable></arg>
<arg choice='plain'><replaceable>operation</replaceable></arg>
<arg rep='repeat'><replaceable>options</replaceable></arg>
<arg rep='repeat'><replaceable>arguments</replaceable></arg>
@@ -190,6 +180,7 @@ linkend="sec-common-options" />.</para>
<arg choice='plain'><option>--install</option></arg>
<arg choice='plain'><option>-i</option></arg>
</group>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-inst-syn.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(/db:nop/*)" />
<group choice='opt'>
<arg choice='plain'><option>--preserve-installed</option></arg>
<arg choice='plain'><option>-P</option></arg>
@@ -397,6 +388,7 @@ the following paths will be substituted:
<arg choice='plain'><option>--upgrade</option></arg>
<arg choice='plain'><option>-u</option></arg>
</group>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-inst-syn.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(/db:nop/*)" />
<group choice='opt'>
<arg choice='plain'><option>--lt</option></arg>
<arg choice='plain'><option>--leq</option></arg>
@@ -592,25 +584,21 @@ $ nix-env -e '*' <lineannotation>(remove everything)</lineannotation></screen>
<arg choice='plain'><option>--query</option></arg>
<arg choice='plain'><option>-q</option></arg>
</group>
- <arg><option>--xml</option></arg>
<group choice='opt'>
<arg choice='plain'><option>--installed</option></arg>
<arg choice='plain'><option>--available</option></arg>
<arg choice='plain'><option>-a</option></arg>
</group>
+
<sbr />
+
<arg>
<group choice='req'>
<arg choice='plain'><option>--status</option></arg>
<arg choice='plain'><option>-s</option></arg>
</group>
</arg>
- <arg>
- <group choice='req'>
- <arg choice='plain'><option>--attr</option></arg>
- <arg choice='plain'><option>-A</option></arg>
- </group>
- </arg>
+ <arg><option>--attr-path</option></arg>
<arg><option>--no-name</option></arg>
<arg>
<group choice='req'>
@@ -622,6 +610,27 @@ $ nix-env -e '*' <lineannotation>(remove everything)</lineannotation></screen>
<arg><option>--drv-path</option></arg>
<arg><option>--out-path</option></arg>
<arg><option>--description</option></arg>
+ <arg><option>--meta</option></arg>
+
+ <sbr />
+
+ <arg><option>--xml</option></arg>
+ <arg>
+ <group choice='req'>
+ <arg choice='plain'><option>--prebuilt-only</option></arg>
+ <arg choice='plain'><option>-b</option></arg>
+ </group>
+ </arg>
+ <arg>
+ <group choice='req'>
+ <arg choice='plain'><option>--attr</option></arg>
+ <arg choice='plain'><option>-A</option></arg>
+ </group>
+ <replaceable>attribute-path</replaceable>
+ </arg>
+
+ <sbr />
+
<arg choice='plain' rep='repeat'><replaceable>names</replaceable></arg>
</cmdsynopsis>
diff --git a/doc/manual/opt-inst-syn.xml b/doc/manual/opt-inst-syn.xml
new file mode 100644
index 000000000..1c32325e5
--- /dev/null
+++ b/doc/manual/opt-inst-syn.xml
@@ -0,0 +1,15 @@
+<nop xmlns="http://docbook.org/ns/docbook">
+
+ <arg>
+ <group choice='req'>
+ <arg choice='plain'><option>--attr</option></arg>
+ <arg choice='plain'><option>-A</option></arg>
+ </group>
+ </arg>
+
+ <arg><option>--from-expression</option></arg>
+ <arg><option>-E</option></arg>
+
+ <arg><option>--from-profile</option> <replaceable>path</replaceable></arg>
+
+</nop>
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index b9ba3da64..2a96e25a8 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -789,6 +789,7 @@ static Expr prim_listToAttrs(EvalState & state, const ATermVector & args)
}
}
+
static Expr prim_removeAttrs(EvalState & state, const ATermVector & args)
{
ATermMap attrs;
@@ -803,6 +804,7 @@ static Expr prim_removeAttrs(EvalState & state, const ATermVector & args)
return makeAttrs(attrs);
}
+
/* Determine whether the argument is a list. */
static Expr prim_isAttrs(EvalState & state, const ATermVector & args)
{
@@ -810,6 +812,7 @@ static Expr prim_isAttrs(EvalState & state, const ATermVector & args)
return makeBool(matchAttrs(evalExpr(state, args[0]), list));
}
+
/*************************************************************
* Lists
*************************************************************/