about summary refs log tree commit diff
path: root/src/libstore/remote-store.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2006-11-30T19·54+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2006-11-30T19·54+0000
commit765bdfe542d3250329dea98b69db2271419f31b6 (patch)
tree3eba766da3d72f36b5ea417b79e0dc275b954135 /src/libstore/remote-store.cc
parent40b3f64b55f98e03b3173541b8d94cd924099223 (diff)
* When NIX_REMOTE is set to "slave", fork off nix-worker in slave
  mode.  Presumably nix-worker would be setuid to the Nix store user.
  The worker performs all operations on the Nix store and database, so
  the caller can be completely unprivileged.

  This is already much more secure than the old setuid scheme, since
  the worker doesn't need to do Nix expression evaluation and so on.
  Most importantly, this means that it doesn't need to access any user
  files, with all resulting security risks; it only performs pure
  store operations.

  Once this works, it is easy to move to a daemon model that forks off
  a worker for connections established through a Unix domain socket.
  That would be even more secure.

Diffstat (limited to 'src/libstore/remote-store.cc')
-rw-r--r--src/libstore/remote-store.cc54
1 files changed, 53 insertions, 1 deletions
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index 27717a816a53..6f3c110a3df8 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -1,12 +1,64 @@
+#include "serialise.hh"
+#include "util.hh"
 #include "remote-store.hh"
 
+#include <iostream>
+#include <unistd.h>
+
 
 namespace nix {
 
 
 RemoteStore::RemoteStore()
 {
-    throw Error("not implemented");
+    toChild.create();
+    fromChild.create();
+
+
+    /* Start the worker. */
+    string worker = "nix-worker";
+
+    child = fork();
+    
+    switch (child) {
+        
+    case -1:
+        throw SysError("unable to fork");
+
+    case 0:
+        try { /* child */
+
+            fromChild.readSide.close();
+            if (dup2(fromChild.writeSide, STDOUT_FILENO) == -1)
+                throw SysError("dupping write side");
+
+            toChild.writeSide.close();
+            if (dup2(toChild.readSide, STDIN_FILENO) == -1)
+                throw SysError("dupping read side");
+
+            execlp(worker.c_str(), worker.c_str(),
+                "-vvv", "--slave", NULL);
+            
+            throw SysError(format("executing `%1%'") % worker);
+            
+        } catch (std::exception & e) {
+            std::cerr << format("child error: %1%\n") % e.what();
+        }
+        quickExit(1);
+    }
+
+    fromChild.writeSide.close();
+    toChild.readSide.close();
+
+    from.fd = fromChild.readSide;
+    to.fd = toChild.writeSide;
+
+    
+    /* Send the magic greeting, check for the reply. */
+    writeInt(0x6e697864, to);
+    
+    unsigned int magic = readInt(from);
+    if (magic != 0x6478696e) throw Error("protocol mismatch");
 }