Commit d7869f46 authored by lethalman's avatar lethalman
Browse files

Merge pull request #8602 from ts468/upstream.pam

Security: integrate pam_mount into PAM of NixOS
parents d1bb5179 7b6f2791
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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";
+1 −0
Original line number Diff line number Diff line
@@ -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
+16 −2
Original line number Diff line number Diff line
@@ -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"}
        '';
    };

+72 −0
Original line number Diff line number Diff line
{ 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 <link
          xlink:href="http://pam-mount.sourceforge.net/pam_mount.conf.5.html" />.
        '';
      };
    };

  };

  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: "<volume user=\"${user.name}\" path=\"${user.cryptHomeLuks}\" mountpoint=\"${user.home}\" />\n";
        in
         pkgs.writeText "pam_mount.conf.xml" ''
          <?xml version="1.0" encoding="utf-8" ?>
          <!DOCTYPE pam_mount SYSTEM "pam_mount.conf.xml.dtd">
          <!-- auto generated from Nixos: modules/config/users-groups.nix -->
          <pam_mount>
          <debug enable="0" />

          ${concatStrings (map userVolumeEntry (attrValues extraUserVolumes))}
          ${concatStringsSep "\n" cfg.extraVolumes}

          <!-- if activated, requires ofl from hxtools to be present -->
          <logout wait="0" hup="no" term="no" kill="no" />
          <!-- set PATH variable for pam_mount module -->
          <path>${pkgs.utillinux}/bin</path>
          <!-- create mount point if not present -->
          <mkmountpoint enable="1" remove="true" />

          <!-- specify the binaries to be called -->
          <cryptmount>${pkgs.pam_mount}/bin/mount.crypt %(VOLUME) %(MNTPT)</cryptmount>
          <cryptumount>${pkgs.pam_mount}/bin/umount.crypt %(MNTPT)</cryptumount>
          <pmvarrun>${pkgs.pam_mount}/bin/pmvarrun -u %(USER) -o %(OPERATION)</pmvarrun>
          </pam_mount>
          '';
    }];

  };
}