at 21.11-pre 3.6 kB view raw
1# This module defines a system-wide environment that will be 2# initialised by pam_env (that is, not only in shells). 3{ config, lib, pkgs, ... }: 4 5with lib; 6 7let 8 9 cfg = config.environment; 10 11in 12 13{ 14 15 options = { 16 17 environment.sessionVariables = mkOption { 18 default = {}; 19 description = '' 20 A set of environment variables used in the global environment. 21 These variables will be set by PAM early in the login process. 22 23 The value of each session variable can be either a string or a 24 list of strings. The latter is concatenated, interspersed with 25 colon characters. 26 27 Note, due to limitations in the PAM format values may not 28 contain the <literal>"</literal> character. 29 30 Also, these variables are merged into 31 <xref linkend="opt-environment.variables"/> and it is 32 therefore not possible to use PAM style variables such as 33 <code>@{HOME}</code>. 34 ''; 35 type = with types; attrsOf (either str (listOf str)); 36 apply = mapAttrs (n: v: if isList v then concatStringsSep ":" v else v); 37 }; 38 39 environment.profileRelativeSessionVariables = mkOption { 40 type = types.attrsOf (types.listOf types.str); 41 example = { PATH = [ "/bin" ]; MANPATH = [ "/man" "/share/man" ]; }; 42 description = '' 43 Attribute set of environment variable used in the global 44 environment. These variables will be set by PAM early in the 45 login process. 46 47 Variable substitution is available as described in 48 <citerefentry> 49 <refentrytitle>pam_env.conf</refentrytitle> 50 <manvolnum>5</manvolnum> 51 </citerefentry>. 52 53 Each attribute maps to a list of relative paths. Each relative 54 path is appended to the each profile of 55 <option>environment.profiles</option> to form the content of 56 the corresponding environment variable. 57 58 Also, these variables are merged into 59 <xref linkend="opt-environment.profileRelativeEnvVars"/> and it is 60 therefore not possible to use PAM style variables such as 61 <code>@{HOME}</code>. 62 ''; 63 }; 64 65 }; 66 67 config = { 68 69 system.build.pamEnvironment = 70 let 71 suffixedVariables = 72 flip mapAttrs cfg.profileRelativeSessionVariables (envVar: suffixes: 73 flip concatMap cfg.profiles (profile: 74 map (suffix: "${profile}${suffix}") suffixes 75 ) 76 ); 77 78 # We're trying to use the same syntax for PAM variables and env variables. 79 # That means we need to map the env variables that people might use to their 80 # equivalent PAM variable. 81 replaceEnvVars = replaceStrings ["$HOME" "$USER"] ["@{HOME}" "@{PAM_USER}"]; 82 83 pamVariable = n: v: 84 ''${n} DEFAULT="${concatStringsSep ":" (map replaceEnvVars (toList v))}"''; 85 86 pamVariables = 87 concatStringsSep "\n" 88 (mapAttrsToList pamVariable 89 (zipAttrsWith (n: concatLists) 90 [ 91 # Make sure security wrappers are prioritized without polluting 92 # shell environments with an extra entry. Sessions which depend on 93 # pam for its environment will otherwise have eg. broken sudo. In 94 # particular Gnome Shell sometimes fails to source a proper 95 # environment from a shell. 96 { PATH = [ config.security.wrapperDir ]; } 97 98 (mapAttrs (n: toList) cfg.sessionVariables) 99 suffixedVariables 100 ])); 101 in 102 pkgs.writeText "pam-environment" "${pamVariables}\n"; 103 104 }; 105 106}