summary refs log tree commit diff
path: root/modules/security
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2009-08-16 17:24:59 +0000
committerEelco Dolstra <eelco.dolstra@logicblox.com>2009-08-16 17:24:59 +0000
commitdba1964122f9a5589d8cdf0a13acc4ff4dcdc99e (patch)
treea6013bf0f4047f077bed39fdb68625ca801fcaec /modules/security
parentf31e2718b73fe9d8857c26dd76f4d472e90580d0 (diff)
downloadnixpkgs-dba1964122f9a5589d8cdf0a13acc4ff4dcdc99e.tar
nixpkgs-dba1964122f9a5589d8cdf0a13acc4ff4dcdc99e.tar.gz
nixpkgs-dba1964122f9a5589d8cdf0a13acc4ff4dcdc99e.tar.bz2
nixpkgs-dba1964122f9a5589d8cdf0a13acc4ff4dcdc99e.tar.lz
nixpkgs-dba1964122f9a5589d8cdf0a13acc4ff4dcdc99e.tar.xz
nixpkgs-dba1964122f9a5589d8cdf0a13acc4ff4dcdc99e.tar.zst
nixpkgs-dba1964122f9a5589d8cdf0a13acc4ff4dcdc99e.zip
* setuid-wrappers: support setting the mode. For instance, some
  programs require that the mode is 4550 so that execution of the
  setuid program can be restricted to members of a group.
* setuid-wrappers: remove a race condition in the creation of the
  wrappers if the ownership or mode was different than root:root and
  4555.
* setuid-wrappers: allow the full path of the wrapped program to be
  specified, rather than looking it up in $PATH.

svn path=/nixos/trunk/; revision=16733
Diffstat (limited to 'modules/security')
-rw-r--r--modules/security/setuid-wrappers.nix85
1 files changed, 39 insertions, 46 deletions
diff --git a/modules/security/setuid-wrappers.nix b/modules/security/setuid-wrappers.nix
index 105cb4fe85f..103929a12d4 100644
--- a/modules/security/setuid-wrappers.nix
+++ b/modules/security/setuid-wrappers.nix
@@ -4,11 +4,13 @@ with pkgs.lib;
 
 let
 
+  inherit (config.security) wrapperDir;
+
   setuidWrapper = pkgs.stdenv.mkDerivation {
     name = "setuid-wrapper";
     buildCommand = ''
       ensureDir $out/bin
-      gcc -Wall -O2 -DWRAPPER_DIR=\"${config.security.wrapperDir}\" ${./setuid-wrapper.c} -o $out/bin/setuid-wrapper
+      gcc -Wall -O2 -DWRAPPER_DIR=\"${wrapperDir}\" ${./setuid-wrapper.c} -o $out/bin/setuid-wrapper
       strip -s $out/bin/setuid-wrapper
     '';
   };
@@ -76,56 +78,47 @@ in
   
     system.activationScripts.setuid =
       let
-        setuidPrograms = builtins.toString (
-          config.security.setuidPrograms ++
-          config.security.extraSetuidPrograms ++
-          map (x: x.program) config.security.setuidOwners
-        );
-
-        adjustSetuidOwner = concatStrings (map
-          (_entry: let entry = {
-            owner = "nobody";
-            group = "nogroup";
-            setuid = false;
-            setgid = false;
-          } //_entry; in
+        setuidPrograms =
+          (map (x: { program = x; owner = "root"; group = "root"; setuid = true; })
+            (config.security.setuidPrograms ++
+             config.security.extraSetuidPrograms))
+          ++ config.security.setuidOwners;
+
+        makeSetuidWrapper =
+          { program
+          , source ? ""
+          , owner ? "nobody"
+          , group ? "nogroup"
+          , setuid ? false
+          , setgid ? false
+          , permissions ? "u+rx,g+rx,o+rx"
+          }:
+
           ''
-            chown ${entry.owner}.${entry.group} $wrapperDir/${entry.program}
-            chmod u${if entry.setuid then "+" else "-"}s $wrapperDir/${entry.program} 
-            chmod g${if entry.setgid then "+" else "-"}s $wrapperDir/${entry.program}
-          '')
-          config.security.setuidOwners);
+            source=${if source != "" then source else "$(PATH=$SETUID_PATH type -tP ${program})"}
+            if test -z "$source"; then
+                # If we can't find the program, fall back to the
+                # system profile.
+                source=/nix/var/nix/profiles/default/bin/${program}
+            fi
+            
+            cp ${setuidWrapper}/bin/setuid-wrapper ${wrapperDir}/${program}
+            echo -n "$source" > ${wrapperDir}/${program}.real
+            chmod 0000 ${wrapperDir}/${program} # to prevent races
+            chown ${owner}.${group} ${wrapperDir}/${program}
+            chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" ${wrapperDir}/${program}
+          '';
 
       in pkgs.stringsWithDeps.fullDepEntry
         ''
           # Look in the system path and in the default profile for
-          # programs to be wrapped.  However, having setuid programs
-          # in a profile is problematic, since the NixOS activation
-          # script won't be rerun automatically when you install a
-          # wrappable program in the profile with nix-env.
-          SETUID_PATH=/nix/var/nix/profiles/default/sbin:/nix/var/nix/profiles/default/bin:${config.system.path}/bin:${config.system.path}/sbin
-
-          wrapperDir=${config.security.wrapperDir}
-          if test -d $wrapperDir; then rm -f $wrapperDir/*; fi # */
-          mkdir -p $wrapperDir
-          
-          for i in ${setuidPrograms}; do
-              program=$(PATH=$SETUID_PATH type -tP $i)
-              if test -z "$program"; then
-                  # XXX: It would be preferable to detect this problem before
-                  # `activate-configuration' is invoked.
-                  #echo "WARNING: No executable named \`$i' was found" >&2
-                  #echo "WARNING: but \`$i' was specified as a setuid program." >&2
-                  true
-              else
-                  cp ${setuidWrapper}/bin/setuid-wrapper $wrapperDir/$i
-                  echo -n "$program" > $wrapperDir/$i.real
-                  chown root.root $wrapperDir/$i
-                  chmod 4755 $wrapperDir/$i
-              fi
-          done
-
-          ${adjustSetuidOwner}
+          # programs to be wrapped.
+          SETUID_PATH=${config.system.path}/bin:${config.system.path}/sbin
+
+          if test -d ${wrapperDir}; then rm -f ${wrapperDir}/*; fi # */
+          mkdir -p ${wrapperDir}
+
+          ${concatMapStrings makeSetuidWrapper setuidPrograms}
         '' [ "defaultPath" "users" ];
 
   };