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.
22 The value of each variable can be either a string or a list of
23 strings. The latter is concatenated, interspersed with colon
24 characters.
25 '';
26 type = types.attrsOf (mkOptionType {
27 name = "a string or a list of strings";
28 merge = loc: defs:
29 let
30 defs' = filterOverrides defs;
31 res = (head defs').value;
32 in
33 if isList res then concatLists (getValues defs')
34 else if lessThan 1 (length defs') then
35 throw "The option `${showOption loc}' is defined multiple times, in ${showFiles (getFiles defs)}."
36 else if !isString res then
37 throw "The option `${showOption loc}' does not have a string value, in ${showFiles (getFiles defs)}."
38 else res;
39 });
40 apply = mapAttrs (n: v: if isList v then concatStringsSep ":" v else v);
41 };
42
43 };
44
45 config = {
46
47 system.build.pamEnvironment = pkgs.writeText "pam-environment"
48 ''
49 ${concatStringsSep "\n" (
50 (mapAttrsToList (n: v: ''${n}="${concatStringsSep ":" v}"'')
51 (zipAttrsWith (const concatLists) ([ (mapAttrs (n: v: [ v ]) cfg.sessionVariables) ]))))}
52 '';
53
54 };
55
56}