at 23.05-pre 3.4 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 = lib.mdDoc '' 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 `"` character. 29 30 Also, these variables are merged into 31 [](#opt-environment.variables) and it is 32 therefore not possible to use PAM style variables such as 33 `@{HOME}`. 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 = lib.mdDoc '' 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 {manpage}`pam_env.conf(5)`. 49 50 Each attribute maps to a list of relative paths. Each relative 51 path is appended to the each profile of 52 {option}`environment.profiles` to form the content of 53 the corresponding environment variable. 54 55 Also, these variables are merged into 56 [](#opt-environment.profileRelativeEnvVars) and it is 57 therefore not possible to use PAM style variables such as 58 `@{HOME}`. 59 ''; 60 }; 61 62 }; 63 64 config = { 65 environment.etc."pam/environment".text = let 66 suffixedVariables = 67 flip mapAttrs cfg.profileRelativeSessionVariables (envVar: suffixes: 68 flip concatMap cfg.profiles (profile: 69 map (suffix: "${profile}${suffix}") suffixes 70 ) 71 ); 72 73 # We're trying to use the same syntax for PAM variables and env variables. 74 # That means we need to map the env variables that people might use to their 75 # equivalent PAM variable. 76 replaceEnvVars = replaceStrings ["$HOME" "$USER"] ["@{HOME}" "@{PAM_USER}"]; 77 78 pamVariable = n: v: 79 ''${n} DEFAULT="${concatStringsSep ":" (map replaceEnvVars (toList v))}"''; 80 81 pamVariables = 82 concatStringsSep "\n" 83 (mapAttrsToList pamVariable 84 (zipAttrsWith (n: concatLists) 85 [ 86 # Make sure security wrappers are prioritized without polluting 87 # shell environments with an extra entry. Sessions which depend on 88 # pam for its environment will otherwise have eg. broken sudo. In 89 # particular Gnome Shell sometimes fails to source a proper 90 # environment from a shell. 91 { PATH = [ config.security.wrapperDir ]; } 92 93 (mapAttrs (n: toList) cfg.sessionVariables) 94 suffixedVariables 95 ])); 96 in '' 97 ${pamVariables} 98 ''; 99 }; 100 101}