1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.security.pam.mount;
7
8 anyPamMount = any (attrByPath ["pamMount"] false) (attrValues config.security.pam.services);
9in
10
11{
12 options = {
13
14 security.pam.mount = {
15 enable = mkOption {
16 type = types.bool;
17 default = false;
18 description = ''
19 Enable PAM mount system to mount fileystems on user login.
20 '';
21 };
22
23 extraVolumes = mkOption {
24 type = types.listOf types.str;
25 default = [];
26 description = ''
27 List of volume definitions for pam_mount.
28 For more information, visit <link
29 xlink:href="http://pam-mount.sourceforge.net/pam_mount.conf.5.html" />.
30 '';
31 };
32
33 additionalSearchPaths = mkOption {
34 type = types.listOf types.package;
35 default = [];
36 example = literalExpression "[ pkgs.bindfs ]";
37 description = ''
38 Additional programs to include in the search path of pam_mount.
39 Useful for example if you want to use some FUSE filesystems like bindfs.
40 '';
41 };
42
43 fuseMountOptions = mkOption {
44 type = types.listOf types.str;
45 default = [];
46 example = literalExpression ''
47 [ "nodev" "nosuid" "force-user=%(USER)" "gid=%(USERGID)" "perms=0700" "chmod-deny" "chown-deny" "chgrp-deny" ]
48 '';
49 description = ''
50 Global mount options that apply to every FUSE volume.
51 You can define volume-specific options in the volume definitions.
52 '';
53 };
54 };
55
56 };
57
58 config = mkIf (cfg.enable || anyPamMount) {
59
60 environment.systemPackages = [ pkgs.pam_mount ];
61 environment.etc."security/pam_mount.conf.xml" = {
62 source =
63 let
64 extraUserVolumes = filterAttrs (n: u: u.cryptHomeLuks != null || u.pamMount != {}) config.users.users;
65 mkAttr = k: v: ''${k}="${v}"'';
66 userVolumeEntry = user: let
67 attrs = {
68 user = user.name;
69 path = user.cryptHomeLuks;
70 mountpoint = user.home;
71 } // user.pamMount;
72 in
73 "<volume ${concatStringsSep " " (mapAttrsToList mkAttr attrs)} />\n";
74 in
75 pkgs.writeText "pam_mount.conf.xml" ''
76 <?xml version="1.0" encoding="utf-8" ?>
77 <!DOCTYPE pam_mount SYSTEM "pam_mount.conf.xml.dtd">
78 <!-- auto generated from Nixos: modules/config/users-groups.nix -->
79 <pam_mount>
80 <debug enable="0" />
81
82 <!-- if activated, requires ofl from hxtools to be present -->
83 <logout wait="0" hup="no" term="no" kill="no" />
84 <!-- set PATH variable for pam_mount module -->
85 <path>${makeBinPath ([ pkgs.util-linux ] ++ cfg.additionalSearchPaths)}</path>
86 <!-- create mount point if not present -->
87 <mkmountpoint enable="1" remove="true" />
88
89 <!-- specify the binaries to be called -->
90 <fusemount>${pkgs.fuse}/bin/mount.fuse %(VOLUME) %(MNTPT) -o ${concatStringsSep "," (cfg.fuseMountOptions ++ [ "%(OPTIONS)" ])}</fusemount>
91 <cryptmount>${pkgs.pam_mount}/bin/mount.crypt %(VOLUME) %(MNTPT)</cryptmount>
92 <cryptumount>${pkgs.pam_mount}/bin/umount.crypt %(MNTPT)</cryptumount>
93 <pmvarrun>${pkgs.pam_mount}/bin/pmvarrun -u %(USER) -o %(OPERATION)</pmvarrun>
94
95 ${concatStrings (map userVolumeEntry (attrValues extraUserVolumes))}
96 ${concatStringsSep "\n" cfg.extraVolumes}
97 </pam_mount>
98 '';
99 };
100
101 };
102}