1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 nssModulesPath = config.system.nssModules.path;
8 cfg = config.services.nscd;
9
10in
11
12{
13
14 ###### interface
15
16 options = {
17
18 services.nscd = {
19
20 enable = mkOption {
21 type = types.bool;
22 default = true;
23 description = lib.mdDoc ''
24 Whether to enable the Name Service Cache Daemon.
25 Disabling this is strongly discouraged, as this effectively disables NSS Lookups
26 from all non-glibc NSS modules, including the ones provided by systemd.
27 '';
28 };
29
30 enableNsncd = mkOption {
31 type = types.bool;
32 default = true;
33 description = lib.mdDoc ''
34 Whether to use nsncd instead of nscd from glibc.
35 This is a nscd-compatible daemon, that proxies lookups, without any caching.
36 Using nscd from glibc is discouraged.
37 '';
38 };
39
40 user = mkOption {
41 type = types.str;
42 default = "nscd";
43 description = lib.mdDoc ''
44 User account under which nscd runs.
45 '';
46 };
47
48 group = mkOption {
49 type = types.str;
50 default = "nscd";
51 description = lib.mdDoc ''
52 User group under which nscd runs.
53 '';
54 };
55
56 config = mkOption {
57 type = types.lines;
58 default = builtins.readFile ./nscd.conf;
59 description = lib.mdDoc ''
60 Configuration to use for Name Service Cache Daemon.
61 Only used in case glibc-nscd is used.
62 '';
63 };
64
65 package = mkOption {
66 type = types.package;
67 default =
68 if pkgs.stdenv.hostPlatform.libc == "glibc"
69 then pkgs.stdenv.cc.libc.bin
70 else pkgs.glibc.bin;
71 defaultText = lib.literalExpression ''
72 if pkgs.stdenv.hostPlatform.libc == "glibc"
73 then pkgs.stdenv.cc.libc.bin
74 else pkgs.glibc.bin;
75 '';
76 description = lib.mdDoc ''
77 package containing the nscd binary to be used by the service.
78 Ignored when enableNsncd is set to true.
79 '';
80 };
81
82 };
83
84 };
85
86
87 ###### implementation
88
89 config = mkIf cfg.enable {
90 environment.etc."nscd.conf".text = cfg.config;
91
92 users.users.${cfg.user} = {
93 isSystemUser = true;
94 group = cfg.group;
95 };
96
97 users.groups.${cfg.group} = { };
98
99 systemd.services.nscd =
100 {
101 description = "Name Service Cache Daemon"
102 + lib.optionalString cfg.enableNsncd " (nsncd)";
103
104 before = [ "nss-lookup.target" "nss-user-lookup.target" ];
105 wants = [ "nss-lookup.target" "nss-user-lookup.target" ];
106 wantedBy = [ "multi-user.target" ];
107 requiredBy = [ "nss-lookup.target" "nss-user-lookup.target" ];
108
109 environment = { LD_LIBRARY_PATH = nssModulesPath; };
110
111 restartTriggers = lib.optionals (!cfg.enableNsncd) ([
112 config.environment.etc.hosts.source
113 config.environment.etc."nsswitch.conf".source
114 config.environment.etc."nscd.conf".source
115 ] ++ optionals config.users.mysql.enable [
116 config.environment.etc."libnss-mysql.cfg".source
117 config.environment.etc."libnss-mysql-root.cfg".source
118 ]);
119
120 # In some configurations, nscd needs to be started as root; it will
121 # drop privileges after all the NSS modules have read their
122 # configuration files. So prefix the ExecStart command with "!" to
123 # prevent systemd from dropping privileges early. See ExecStart in
124 # systemd.service(5). We use a static user, because some NSS modules
125 # sill want to read their configuration files after the privilege drop
126 # and so users can set the owner of those files to the nscd user.
127 serviceConfig =
128 {
129 ExecStart =
130 if cfg.enableNsncd then "${pkgs.nsncd}/bin/nsncd"
131 else "!@${cfg.package}/bin/nscd nscd";
132 Type = if cfg.enableNsncd then "notify" else "forking";
133 User = cfg.user;
134 Group = cfg.group;
135 RemoveIPC = true;
136 PrivateTmp = true;
137 NoNewPrivileges = true;
138 RestrictSUIDSGID = true;
139 ProtectSystem = "strict";
140 ProtectHome = "read-only";
141 RuntimeDirectory = "nscd";
142 PIDFile = "/run/nscd/nscd.pid";
143 Restart = "always";
144 ExecReload =
145 lib.optionals (!cfg.enableNsncd) [
146 "${cfg.package}/bin/nscd --invalidate passwd"
147 "${cfg.package}/bin/nscd --invalidate group"
148 "${cfg.package}/bin/nscd --invalidate hosts"
149 ];
150 };
151 };
152 };
153}