diff options
author | zimbatm <zimbatm@zimbatm.com> | 2022-11-30 14:54:59 +0100 |
---|---|---|
committer | zimbatm <zimbatm@zimbatm.com> | 2022-11-30 21:09:41 +0100 |
commit | 9da75fdaf147dc525861e8a534780d563c897dba (patch) | |
tree | 54592762208f3249ee1713f714cb1107ef027acb | |
parent | d40fea9aeb8840fea0d377baa4b38e39b9582458 (diff) |
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.
-rw-r--r-- | nixos/modules/config/update-users-groups.pl | 33 | ||||
-rw-r--r-- | nixos/modules/config/users-groups.nix | 15 |
2 files changed, 39 insertions, 9 deletions
diff --git a/nixos/modules/config/update-users-groups.pl b/nixos/modules/config/update-users-groups.pl index 4368ec24ea9e..7ec4235db51a 100644 --- a/nixos/modules/config/update-users-groups.pl +++ b/nixos/modules/config/update-users-groups.pl @@ -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) { diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix index b538a0119c06..69fd04a8c06f 100644 --- a/nixos/modules/config/users-groups.nix +++ b/nixos/modules/config/users-groups.nix @@ -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} ''; }; |