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