* 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
This commit is contained in:
Eelco Dolstra 2009-08-16 17:24:59 +00:00
parent f31e2718b7
commit dba1964122

View file

@ -4,11 +4,13 @@ with pkgs.lib;
let let
inherit (config.security) wrapperDir;
setuidWrapper = pkgs.stdenv.mkDerivation { setuidWrapper = pkgs.stdenv.mkDerivation {
name = "setuid-wrapper"; name = "setuid-wrapper";
buildCommand = '' buildCommand = ''
ensureDir $out/bin 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 strip -s $out/bin/setuid-wrapper
''; '';
}; };
@ -76,56 +78,47 @@ in
system.activationScripts.setuid = system.activationScripts.setuid =
let let
setuidPrograms = builtins.toString ( setuidPrograms =
config.security.setuidPrograms ++ (map (x: { program = x; owner = "root"; group = "root"; setuid = true; })
config.security.extraSetuidPrograms ++ (config.security.setuidPrograms ++
map (x: x.program) config.security.setuidOwners config.security.extraSetuidPrograms))
); ++ config.security.setuidOwners;
makeSetuidWrapper =
{ program
, source ? ""
, owner ? "nobody"
, group ? "nogroup"
, setuid ? false
, setgid ? false
, permissions ? "u+rx,g+rx,o+rx"
}:
adjustSetuidOwner = concatStrings (map
(_entry: let entry = {
owner = "nobody";
group = "nogroup";
setuid = false;
setgid = false;
} //_entry; in
'' ''
chown ${entry.owner}.${entry.group} $wrapperDir/${entry.program} source=${if source != "" then source else "$(PATH=$SETUID_PATH type -tP ${program})"}
chmod u${if entry.setuid then "+" else "-"}s $wrapperDir/${entry.program} if test -z "$source"; then
chmod g${if entry.setgid then "+" else "-"}s $wrapperDir/${entry.program} # If we can't find the program, fall back to the
'') # system profile.
config.security.setuidOwners); 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 in pkgs.stringsWithDeps.fullDepEntry
'' ''
# Look in the system path and in the default profile for # Look in the system path and in the default profile for
# programs to be wrapped. However, having setuid programs # programs to be wrapped.
# in a profile is problematic, since the NixOS activation SETUID_PATH=${config.system.path}/bin:${config.system.path}/sbin
# 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 # */
if test -d $wrapperDir; then rm -f $wrapperDir/*; fi # */ mkdir -p ${wrapperDir}
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} ${concatMapStrings makeSetuidWrapper setuidPrograms}
'' [ "defaultPath" "users" ]; '' [ "defaultPath" "users" ];
}; };