diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-07-25 12:48:21 +0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-07-25 14:29:08 +0200 |
commit | 7c480ad89695c1309cc2ed5d07c166722476cd8c (patch) | |
tree | fb37df38f42a5a24bcf48d50f92f20ef9e0a4046 /nixos/modules/system | |
parent | 72af71d626d2e82f2db397a06a820da51c30bb0a (diff) | |
download | nixlib-7c480ad89695c1309cc2ed5d07c166722476cd8c.tar nixlib-7c480ad89695c1309cc2ed5d07c166722476cd8c.tar.gz nixlib-7c480ad89695c1309cc2ed5d07c166722476cd8c.tar.bz2 nixlib-7c480ad89695c1309cc2ed5d07c166722476cd8c.tar.lz nixlib-7c480ad89695c1309cc2ed5d07c166722476cd8c.tar.xz nixlib-7c480ad89695c1309cc2ed5d07c166722476cd8c.tar.zst nixlib-7c480ad89695c1309cc2ed5d07c166722476cd8c.zip |
setup-etc.pl: Keep track of copied files
We now track copied files in /etc/.clean. This is important, because otherwise files that are removed from environment.etc will not actually be removed from the file system. In particular, changing users.extraUsers.<user>.openssh.authorizedKeys.keys to an empty list would not cause /etc/ssh/authorized_keys.d/<user> to be removed, which was a security issue.
Diffstat (limited to 'nixos/modules/system')
-rw-r--r-- | nixos/modules/system/etc/etc.nix | 2 | ||||
-rw-r--r-- | nixos/modules/system/etc/setup-etc.pl | 41 |
2 files changed, 32 insertions, 11 deletions
diff --git a/nixos/modules/system/etc/etc.nix b/nixos/modules/system/etc/etc.nix index 22d55a9e246c..b57b03bcf962 100644 --- a/nixos/modules/system/etc/etc.nix +++ b/nixos/modules/system/etc/etc.nix @@ -132,7 +132,7 @@ in '' # Set up the statically computed bits of /etc. echo "setting up /etc..." - ${pkgs.perl}/bin/perl ${./setup-etc.pl} ${etc}/etc + ${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl ${./setup-etc.pl} ${etc}/etc ''; }; diff --git a/nixos/modules/system/etc/setup-etc.pl b/nixos/modules/system/etc/setup-etc.pl index 8ba9a370b27a..d7e15eccefcd 100644 --- a/nixos/modules/system/etc/setup-etc.pl +++ b/nixos/modules/system/etc/setup-etc.pl @@ -3,6 +3,7 @@ use File::Find; use File::Copy; use File::Path; use File::Basename; +use File::Slurp; my $etc = $ARGV[0] or die; my $static = "/etc/static"; @@ -46,35 +47,55 @@ sub cleanup { find(\&cleanup, "/etc"); +# Use /etc/.clean to keep track of copied files. +my @oldCopied = read_file("/etc/.clean", chomp => 1, err_mode => 'quiet'); +open CLEAN, ">>/etc/.clean"; + + # For every file in the etc tree, create a corresponding symlink in # /etc to /etc/static. The indirection through /etc/static is to make # switching to a new configuration somewhat more atomic. +my %created; +my @copied; + sub link { my $fn = substr $File::Find::name, length($etc) + 1 or next; my $target = "/etc/$fn"; File::Path::make_path(dirname $target); + $created{$fn} = 1; if (-e "$_.mode") { - open MODE, "<$_.mode"; - my $mode = <MODE>; chomp $mode; - close MODE; + my $mode = read_file("$_.mode"); chomp $mode; if ($mode eq "direct-symlink") { atomicSymlink readlink("$static/$fn"), $target or warn; } else { - open UID, "<$_.uid"; - my $uid = <UID>; chomp $uid; - close UID; - open GID, "<$_.gid"; - my $gid = <GID>; chomp $gid; - close GID; - + my $uid = read_file("$_.uid"); chomp $uid; + my $gid = read_file("$_.gid"); chomp $gid; copy "$static/$fn", "$target.tmp" or warn; chown int($uid), int($gid), "$target.tmp" or warn; chmod oct($mode), "$target.tmp" or warn; rename "$target.tmp", $target or warn; } + push @copied, $fn; + print CLEAN "$fn\n"; } elsif (-l "$_") { atomicSymlink "$static/$fn", $target or warn; } } find(\&link, $etc); + + +# Delete files that were copied in a previous version but not in the +# current. +foreach my $fn (@oldCopied) { + if (!defined $created{$fn}) { + $fn = "/etc/$fn"; + print STDERR "removing obsolete file ‘$fn’...\n"; + unlink "$fn"; + } +} + + +# Rewrite /etc/.clean. +close CLEAN; +write_file("/etc/.clean", map { "$_\n" } @copied); |