diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix
index 9d48edf2f26c..478f433b431c 100644
--- a/nixos/modules/config/users-groups.nix
+++ b/nixos/modules/config/users-groups.nix
@@ -108,6 +108,15 @@ let
description = "The user's home directory.";
};
+ cryptHomeLuks = mkOption {
+ type = with types; nullOr str;
+ default = null;
+ description = ''
+ Path to encrypted luks device that contains
+ the user's home directory.
+ '';
+ };
+
shell = mkOption {
type = types.str;
default = "/run/current-system/sw/bin/nologin";
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 76ee1b7f9c65..6d51c668f1d3 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -84,6 +84,7 @@
./security/grsecurity.nix
./security/pam.nix
./security/pam_usb.nix
+ ./security/pam_mount.nix
./security/polkit.nix
./security/prey.nix
./security/rngd.nix
diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix
index 35622b12ea33..02520fb88cdd 100644
--- a/nixos/modules/security/pam.nix
+++ b/nixos/modules/security/pam.nix
@@ -126,6 +126,14 @@ let
'';
};
+ pamMount = mkOption {
+ default = config.security.pam.mount.enable;
+ type = types.bool;
+ description = ''
+ Enable PAM mount (pam_mount) system to mount fileystems on user login.
+ '';
+ };
+
allowNullPassword = mkOption {
default = false;
type = types.bool;
@@ -224,7 +232,9 @@ let
${optionalString cfg.usbAuth
"auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so"}
${optionalString cfg.unixAuth
- "auth ${if config.security.pam.enableEcryptfs then "required" else "sufficient"} pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth"}
+ "auth ${if (config.security.pam.enableEcryptfs || cfg.pamMount) then "required" else "sufficient"} pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth"}
+ ${optionalString cfg.pamMount
+ "auth optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
${optionalString config.security.pam.enableEcryptfs
"auth required ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
${optionalString cfg.otpwAuth
@@ -238,12 +248,14 @@ let
auth [default=die success=done] ${pam_ccreds}/lib/security/pam_ccreds.so action=validate use_first_pass
auth sufficient ${pam_ccreds}/lib/security/pam_ccreds.so action=store use_first_pass
''}
- ${optionalString (! config.security.pam.enableEcryptfs) "auth required pam_deny.so"}
+ ${optionalString (!(config.security.pam.enableEcryptfs || cfg.pamMount)) "auth required pam_deny.so"}
# Password management.
${optionalString config.security.pam.enableEcryptfs
"password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
password requisite pam_unix.so nullok sha512
+ ${optionalString cfg.pamMount
+ "password optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
${optionalString config.users.ldap.enable
"password sufficient ${pam_ldap}/lib/security/pam_ldap.so"}
${optionalString config.krb5.enable
@@ -280,6 +292,8 @@ let
"session required ${pkgs.pam}/lib/security/pam_limits.so conf=${makeLimitsConf cfg.limits}"}
${optionalString (cfg.showMotd && config.users.motd != null)
"session optional ${pkgs.pam}/lib/security/pam_motd.so motd=${motd}"}
+ ${optionalString cfg.pamMount
+ "session optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
'';
};
diff --git a/nixos/modules/security/pam_mount.nix b/nixos/modules/security/pam_mount.nix
new file mode 100644
index 000000000000..a5299728348d
--- /dev/null
+++ b/nixos/modules/security/pam_mount.nix
@@ -0,0 +1,72 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.security.pam.mount;
+
+ anyPamMount = any (attrByPath ["pamMount"] false) (attrValues config.security.pam.services);
+in
+
+{
+ options = {
+
+ security.pam.mount = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable PAM mount system to mount fileystems on user login.
+ '';
+ };
+
+ extraVolumes = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = ''
+ List of volume definitions for pam_mount.
+ For more information, visit .
+ '';
+ };
+ };
+
+ };
+
+ config = mkIf (cfg.enable || anyPamMount) {
+
+ environment.systemPackages = [ pkgs.pam_mount ];
+ environment.etc = [{
+ target = "security/pam_mount.conf.xml";
+ source =
+ let
+ extraUserVolumes = filterAttrs (n: u: u.cryptHomeLuks != null) config.users.extraUsers;
+ userVolumeEntry = user: "\n";
+ in
+ pkgs.writeText "pam_mount.conf.xml" ''
+
+
+
+
+
+
+ ${concatStrings (map userVolumeEntry (attrValues extraUserVolumes))}
+ ${concatStringsSep "\n" cfg.extraVolumes}
+
+
+
+
+ ${pkgs.utillinux}/bin
+
+
+
+
+ ${pkgs.pam_mount}/bin/mount.crypt %(VOLUME) %(MNTPT)
+ ${pkgs.pam_mount}/bin/umount.crypt %(MNTPT)
+ ${pkgs.pam_mount}/bin/pmvarrun -u %(USER) -o %(OPERATION)
+
+ '';
+ }];
+
+ };
+}