* 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:
parent
f31e2718b7
commit
dba1964122
|
@ -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" ];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue