nixpkgs/modules/security/setuid-wrappers.nix
Eelco Dolstra c96f0d75f0 * Move the setuid wrappers activation scriptlet to
modules/security/setuid-wrappers.nix.
* Removed the "path" activation scriptlet.  The partial ordering was
  underspecified (there was nothing ensuring that it came near the end
  of the activation script), and it wasn't needed in any case.

svn path=/nixos/branches/modular-nixos/; revision=15726
2009-05-25 15:36:57 +00:00

128 lines
4 KiB
Nix

{pkgs, config, ...}:
with pkgs.lib;
let
options = {
security = {
setuidPrograms = mkOption {
default = [
"passwd" "su" "crontab" "ping" "ping6"
"fusermount" "wodim" "cdrdao" "growisofs"
];
description = ''
Only the programs from system path listed her will be made setuid root
(through a wrapper program). It's better to set
<option>security.extraSetuidPrograms</option>.
'';
};
# !!! obsolete
extraSetuidPrograms = mkOption {
default = [];
example = ["fusermount"];
description = ''
This option lists additional programs that must be made setuid
root.
'';
};
setuidOwners = mkOption {
default = [];
example = [{
program = "sendmail";
owner = "nobody";
group = "postdrop";
setuid = false;
setgid = true;
}];
description = ''
This option allows the ownership and permissions on the setuid
wrappers for specific programs to be overriden from the
default (setuid root, but not setgid root).
'';
};
wrapperDir = mkOption {
default = "/var/setuid-wrappers";
description = ''
This option defines the path to the setuid wrappers. It
should generally not be overriden.
'';
};
};
};
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
strip -s $out/bin/setuid-wrapper
'';
};
in
{
require = [options];
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
''
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);
in 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}
'' [ "defaultPath" "users" ];
};
};
}