at 23.05-pre 6.2 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.security.pam.mount; 7 8 oflRequired = cfg.logoutHup || cfg.logoutTerm || cfg.logoutKill; 9 10 fake_ofl = pkgs.writeShellScriptBin "fake_ofl" '' 11 SIGNAL=$1 12 MNTPT=$2 13 ${pkgs.lsof}/bin/lsof | ${pkgs.gnugrep}/bin/grep $MNTPT | ${pkgs.gawk}/bin/awk '{print $2}' | ${pkgs.findutils}/bin/xargs ${pkgs.util-linux}/bin/kill -$SIGNAL 14 ''; 15 16 anyPamMount = any (attrByPath ["pamMount"] false) (attrValues config.security.pam.services); 17in 18 19{ 20 options = { 21 22 security.pam.mount = { 23 enable = mkOption { 24 type = types.bool; 25 default = false; 26 description = lib.mdDoc '' 27 Enable PAM mount system to mount fileystems on user login. 28 ''; 29 }; 30 31 extraVolumes = mkOption { 32 type = types.listOf types.str; 33 default = []; 34 description = lib.mdDoc '' 35 List of volume definitions for pam_mount. 36 For more information, visit <http://pam-mount.sourceforge.net/pam_mount.conf.5.html>. 37 ''; 38 }; 39 40 additionalSearchPaths = mkOption { 41 type = types.listOf types.package; 42 default = []; 43 example = literalExpression "[ pkgs.bindfs ]"; 44 description = lib.mdDoc '' 45 Additional programs to include in the search path of pam_mount. 46 Useful for example if you want to use some FUSE filesystems like bindfs. 47 ''; 48 }; 49 50 fuseMountOptions = mkOption { 51 type = types.listOf types.str; 52 default = []; 53 example = literalExpression '' 54 [ "nodev" "nosuid" "force-user=%(USER)" "gid=%(USERGID)" "perms=0700" "chmod-deny" "chown-deny" "chgrp-deny" ] 55 ''; 56 description = lib.mdDoc '' 57 Global mount options that apply to every FUSE volume. 58 You can define volume-specific options in the volume definitions. 59 ''; 60 }; 61 62 debugLevel = mkOption { 63 type = types.int; 64 default = 0; 65 example = 1; 66 description = lib.mdDoc '' 67 Sets the Debug-Level. 0 disables debugging, 1 enables pam_mount tracing, 68 and 2 additionally enables tracing in mount.crypt. The default is 0. 69 For more information, visit <http://pam-mount.sourceforge.net/pam_mount.conf.5.html>. 70 ''; 71 }; 72 73 logoutWait = mkOption { 74 type = types.int; 75 default = 0; 76 description = lib.mdDoc '' 77 Amount of microseconds to wait until killing remaining processes after 78 final logout. 79 For more information, visit <http://pam-mount.sourceforge.net/pam_mount.conf.5.html>. 80 ''; 81 }; 82 83 logoutHup = mkOption { 84 type = types.bool; 85 default = false; 86 description = lib.mdDoc '' 87 Kill remaining processes after logout by sending a SIGHUP. 88 ''; 89 }; 90 91 logoutTerm = mkOption { 92 type = types.bool; 93 default = false; 94 description = lib.mdDoc '' 95 Kill remaining processes after logout by sending a SIGTERM. 96 ''; 97 }; 98 99 logoutKill = mkOption { 100 type = types.bool; 101 default = false; 102 description = lib.mdDoc '' 103 Kill remaining processes after logout by sending a SIGKILL. 104 ''; 105 }; 106 107 createMountPoints = mkOption { 108 type = types.bool; 109 default = true; 110 description = lib.mdDoc '' 111 Create mountpoints for volumes if they do not exist. 112 ''; 113 }; 114 115 removeCreatedMountPoints = mkOption { 116 type = types.bool; 117 default = true; 118 description = lib.mdDoc '' 119 Remove mountpoints created by pam_mount after logout. This 120 only affects mountpoints that have been created by pam_mount 121 in the same session. 122 ''; 123 }; 124 }; 125 126 }; 127 128 config = mkIf (cfg.enable || anyPamMount) { 129 130 environment.systemPackages = [ pkgs.pam_mount ]; 131 environment.etc."security/pam_mount.conf.xml" = { 132 source = 133 let 134 extraUserVolumes = filterAttrs (n: u: u.cryptHomeLuks != null || u.pamMount != {}) config.users.users; 135 mkAttr = k: v: ''${k}="${v}"''; 136 userVolumeEntry = user: let 137 attrs = { 138 user = user.name; 139 path = user.cryptHomeLuks; 140 mountpoint = user.home; 141 } // user.pamMount; 142 in 143 "<volume ${concatStringsSep " " (mapAttrsToList mkAttr attrs)} />\n"; 144 in 145 pkgs.writeText "pam_mount.conf.xml" '' 146 <?xml version="1.0" encoding="utf-8" ?> 147 <!DOCTYPE pam_mount SYSTEM "pam_mount.conf.xml.dtd"> 148 <!-- auto generated from Nixos: modules/config/users-groups.nix --> 149 <pam_mount> 150 <debug enable="${toString cfg.debugLevel}" /> 151 <!-- if activated, requires ofl from hxtools to be present --> 152 <logout wait="${toString cfg.logoutWait}" hup="${if cfg.logoutHup then "yes" else "no"}" term="${if cfg.logoutTerm then "yes" else "no"}" kill="${if cfg.logoutKill then "yes" else "no"}" /> 153 <!-- set PATH variable for pam_mount module --> 154 <path>${makeBinPath ([ pkgs.util-linux ] ++ cfg.additionalSearchPaths)}</path> 155 <!-- create mount point if not present --> 156 <mkmountpoint enable="${if cfg.createMountPoints then "1" else "0"}" remove="${if cfg.removeCreatedMountPoints then "true" else "false"}" /> 157 <!-- specify the binaries to be called --> 158 <fusemount>${pkgs.fuse}/bin/mount.fuse %(VOLUME) %(MNTPT) -o ${concatStringsSep "," (cfg.fuseMountOptions ++ [ "%(OPTIONS)" ])}</fusemount> 159 <fuseumount>${pkgs.fuse}/bin/fusermount -u %(MNTPT)</fuseumount> 160 <cryptmount>${pkgs.pam_mount}/bin/mount.crypt %(VOLUME) %(MNTPT)</cryptmount> 161 <cryptumount>${pkgs.pam_mount}/bin/umount.crypt %(MNTPT)</cryptumount> 162 <pmvarrun>${pkgs.pam_mount}/bin/pmvarrun -u %(USER) -o %(OPERATION)</pmvarrun> 163 ${optionalString oflRequired "<ofl>${fake_ofl}/bin/fake_ofl %(SIGNAL) %(MNTPT)</ofl>"} 164 ${concatStrings (map userVolumeEntry (attrValues extraUserVolumes))} 165 ${concatStringsSep "\n" cfg.extraVolumes} 166 </pam_mount> 167 ''; 168 }; 169 170 }; 171}