nixos/update-users-groups: add support for account expiry
Introduce a `users.users.<name>.expires` option to allows setting an expiry date to user accounts. This is useful when members should gain temporary access and you don't want to have to roll out another system update to disable them.
This commit is contained in:
parent
d40fea9aeb
commit
9da75fdaf1
2 changed files with 39 additions and 9 deletions
|
@ -4,6 +4,7 @@ use File::Path qw(make_path);
|
|||
use File::Slurp;
|
||||
use Getopt::Long;
|
||||
use JSON;
|
||||
use DateTime;
|
||||
|
||||
# Keep track of deleted uids and gids.
|
||||
my $uidMapFile = "/var/lib/nixos/uid-map";
|
||||
|
@ -22,6 +23,22 @@ sub updateFile {
|
|||
write_file($path, { atomic => 1, binmode => ':utf8', perms => $perms // 0644 }, $contents) or die;
|
||||
}
|
||||
|
||||
# Converts an ISO date to number of days since 1970-01-01
|
||||
sub dateToDays {
|
||||
my ($date) = @_;
|
||||
my ($year, $month, $day) = split('-', $date, -3);
|
||||
my $dt = DateTime->new(
|
||||
year => $year,
|
||||
month => $month,
|
||||
day => $day,
|
||||
hour => 0,
|
||||
minute => 0,
|
||||
second => 0,
|
||||
time_zone => 'UTC',
|
||||
);
|
||||
return $dt->epoch / 86400;
|
||||
}
|
||||
|
||||
sub nscdInvalidate {
|
||||
system("nscd", "--invalidate", $_[0]) unless $is_dry;
|
||||
}
|
||||
|
@ -283,14 +300,16 @@ my %shadowSeen;
|
|||
|
||||
foreach my $line (-f "/etc/shadow" ? read_file("/etc/shadow", { binmode => ":utf8" }) : ()) {
|
||||
chomp $line;
|
||||
my ($name, $hashedPassword, @rest) = split(':', $line, -9);
|
||||
my $u = $usersOut{$name};;
|
||||
# struct name copied from `man 3 shadow`
|
||||
my ($sp_namp, $sp_pwdp, $sp_lstch, $sp_min, $sp_max, $sp_warn, $sp_inact, $sp_expire, $sp_flag) = split(':', $line, -9);
|
||||
my $u = $usersOut{$sp_namp};;
|
||||
next if !defined $u;
|
||||
$hashedPassword = "!" if !$spec->{mutableUsers};
|
||||
$hashedPassword = $u->{hashedPassword} if defined $u->{hashedPassword} && !$spec->{mutableUsers}; # FIXME
|
||||
chomp $hashedPassword;
|
||||
push @shadowNew, join(":", $name, $hashedPassword, @rest) . "\n";
|
||||
$shadowSeen{$name} = 1;
|
||||
$sp_pwdp = "!" if !$spec->{mutableUsers};
|
||||
$sp_pwdp = $u->{hashedPassword} if defined $u->{hashedPassword} && !$spec->{mutableUsers}; # FIXME
|
||||
$sp_expire = dateToDays($u->{expires}) if defined $u->{expires};
|
||||
chomp $sp_pwdp;
|
||||
push @shadowNew, join(":", $sp_namp, $sp_pwdp, $sp_lstch, $sp_min, $sp_max, $sp_warn, $sp_inact, $sp_expire, $sp_flag) . "\n";
|
||||
$shadowSeen{$sp_namp} = 1;
|
||||
}
|
||||
|
||||
foreach my $u (values %usersOut) {
|
||||
|
|
|
@ -308,6 +308,17 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
expires = mkOption {
|
||||
type = types.nullOr (types.strMatching "[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}");
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Set the date on which the user's account will no longer be
|
||||
accessible. The date is expressed in the format YYYY-MM-DD, or null
|
||||
to disable the expiry.
|
||||
A user whose account is locked must contact the system
|
||||
administrator before being able to use the system again.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge
|
||||
|
@ -433,7 +444,7 @@ let
|
|||
name uid group description home homeMode createHome isSystemUser
|
||||
password passwordFile hashedPassword
|
||||
autoSubUidGidRange subUidRanges subGidRanges
|
||||
initialPassword initialHashedPassword;
|
||||
initialPassword initialHashedPassword expires;
|
||||
shell = utils.toShellPath u.shell;
|
||||
}) cfg.users;
|
||||
groups = attrValues cfg.groups;
|
||||
|
@ -587,7 +598,7 @@ in {
|
|||
install -m 0700 -d /root
|
||||
install -m 0755 -d /home
|
||||
|
||||
${pkgs.perl.withPackages (p: [ p.FileSlurp p.JSON ])}/bin/perl \
|
||||
${pkgs.perl.withPackages (p: [ p.FileSlurp p.JSON p.DateTime ])}/bin/perl \
|
||||
-w ${./update-users-groups.pl} ${spec}
|
||||
'';
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue