summary refs log tree commit diff
path: root/nixos/modules/config
diff options
context:
space:
mode:
authorzimbatm <zimbatm@zimbatm.com>2022-11-30 14:54:59 +0100
committerzimbatm <zimbatm@zimbatm.com>2022-11-30 21:09:41 +0100
commit9da75fdaf147dc525861e8a534780d563c897dba (patch)
tree54592762208f3249ee1713f714cb1107ef027acb /nixos/modules/config
parentd40fea9aeb8840fea0d377baa4b38e39b9582458 (diff)
downloadnixpkgs-9da75fdaf147dc525861e8a534780d563c897dba.tar
nixpkgs-9da75fdaf147dc525861e8a534780d563c897dba.tar.gz
nixpkgs-9da75fdaf147dc525861e8a534780d563c897dba.tar.bz2
nixpkgs-9da75fdaf147dc525861e8a534780d563c897dba.tar.lz
nixpkgs-9da75fdaf147dc525861e8a534780d563c897dba.tar.xz
nixpkgs-9da75fdaf147dc525861e8a534780d563c897dba.tar.zst
nixpkgs-9da75fdaf147dc525861e8a534780d563c897dba.zip
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.
Diffstat (limited to 'nixos/modules/config')
-rw-r--r--nixos/modules/config/update-users-groups.pl33
-rw-r--r--nixos/modules/config/users-groups.nix15
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 4368ec24ea9..7ec4235db51 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 b538a0119c0..69fd04a8c06 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}
       '';
     };