grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / network-filesystems / samba.nix
blob8df25e6373cabb2e934439a36c866bbc9645cbd8
1 { config, lib, pkgs, ... }:
2 let
3   cfg = config.services.samba;
5   settingsFormat = pkgs.formats.ini {
6     listToValue = lib.concatMapStringsSep " " (lib.generators.mkValueStringDefault { });
7   };
8   # Ensure the global section is always first
9   globalConfigFile = settingsFormat.generate "smb-global.conf" { global = cfg.settings.global; };
10   sharesConfigFile = settingsFormat.generate "smb-shares.conf" (lib.removeAttrs cfg.settings [ "global" ]);
12   configFile = pkgs.concatText "smb.conf" [ globalConfigFile sharesConfigFile ];
17   meta = {
18     doc = ./samba.md;
19     maintainers = [ lib.maintainers.anthonyroussel ];
20   };
22   imports = [
23     (lib.mkRemovedOptionModule [ "services" "samba" "defaultShare" ] "")
24     (lib.mkRemovedOptionModule [ "services" "samba" "syncPasswordsByPam" ] "This option has been removed by upstream, see https://bugzilla.samba.org/show_bug.cgi?id=10669#c10")
26     (lib.mkRemovedOptionModule [ "services" "samba" "configText" ] ''
27       Use services.samba.settings instead.
29       This is part of the general move to use structured settings instead of raw
30       text for config as introduced by RFC0042:
31       https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md
32     '')
33     (lib.mkRemovedOptionModule [ "services" "samba" "extraConfig" ] "Use services.samba.settings instead.")
34     (lib.mkRenamedOptionModule [ "services" "samba" "invalidUsers" ] [ "services" "samba" "settings" "global" "invalid users" ])
35     (lib.mkRenamedOptionModule [ "services" "samba" "securityType" ] [ "services" "samba" "settings" "global" "security" ])
36     (lib.mkRenamedOptionModule [ "services" "samba" "shares" ] [ "services" "samba" "settings" ])
38     (lib.mkRenamedOptionModule [ "services" "samba" "enableWinbindd" ] [ "services" "samba" "winbindd" "enable" ])
39     (lib.mkRenamedOptionModule [ "services" "samba" "enableNmbd" ] [ "services" "samba" "nmbd" "enable" ])
40   ];
42   ###### interface
44   options = {
45     services.samba = {
46       enable = lib.mkEnableOption "Samba, the SMB/CIFS protocol";
48       package = lib.mkPackageOption pkgs "samba" {
49         example = "samba4Full";
50       };
52       openFirewall = lib.mkEnableOption "opening the default ports in the firewall for Samba";
54       smbd = {
55         enable = lib.mkOption {
56           type = lib.types.bool;
57           default = true;
58           description = "Whether to enable Samba's smbd daemon.";
59         };
61         extraArgs = lib.mkOption {
62           type = lib.types.listOf lib.types.str;
63           default = [ ];
64           description = "Extra arguments to pass to the smbd service.";
65         };
66       };
68       nmbd = {
69         enable = lib.mkOption {
70           type = lib.types.bool;
71           default = true;
72           description = ''
73             Whether to enable Samba's nmbd, which replies to NetBIOS over IP name
74             service requests. It also participates in the browsing protocols
75             which make up the Windows "Network Neighborhood" view.
76           '';
77         };
79         extraArgs = lib.mkOption {
80           type = lib.types.listOf lib.types.str;
81           default = [ ];
82           description = "Extra arguments to pass to the nmbd service.";
83         };
84       };
86       winbindd = {
87         enable = lib.mkOption {
88           type = lib.types.bool;
89           default = true;
90           description = ''
91             Whether to enable Samba's winbindd, which provides a number of services
92             to the Name Service Switch capability found in most modern C libraries,
93             to arbitrary applications via PAM and ntlm_auth and to Samba itself.
94           '';
95         };
97         extraArgs = lib.mkOption {
98           type = lib.types.listOf lib.types.str;
99           default = [ ];
100           description = "Extra arguments to pass to the winbindd service.";
101         };
102       };
104       nsswins = lib.mkEnableOption ''
105         WINS NSS (Name Service Switch) plug-in.
107         Enabling it allows applications to resolve WINS/NetBIOS names (a.k.a.
108         Windows machine names) by transparently querying the winbindd daemon
109       '';
111       settings = lib.mkOption {
112         type = lib.types.submodule {
113           freeformType = settingsFormat.type;
114           options = {
115             global.security = lib.mkOption {
116               type = lib.types.enum [ "auto" "user" "domain" "ads" ];
117               default = "user";
118               description = "Samba security type.";
119             };
120             global."invalid users" = lib.mkOption {
121               type = lib.types.listOf lib.types.str;
122               default = [ "root" ];
123               description = "List of users who are denied to login via Samba.";
124             };
125             global."passwd program" = lib.mkOption {
126               type = lib.types.str;
127               default = "/run/wrappers/bin/passwd %u";
128               description = "Path to a program that can be used to set UNIX user passwords.";
129             };
130           };
131         };
132         default = {
133           "global" = {
134             "security" = "user";
135             "passwd program" = "/run/wrappers/bin/passwd %u";
136             "invalid users" = [ "root" ];
137           };
138         };
139         example = {
140           "global" = {
141             "security" = "user";
142             "passwd program" = "/run/wrappers/bin/passwd %u";
143             "invalid users" = [ "root" ];
144           };
145           "public" = {
146             "path" = "/srv/public";
147             "read only" = "yes";
148             "browseable" = "yes";
149             "guest ok" = "yes";
150             "comment" = "Public samba share.";
151           };
152         };
153         description = ''
154           Configuration file for the Samba suite in ini format.
155           This file is located in /etc/samba/smb.conf
157           Refer to <https://www.samba.org/samba/docs/current/man-html/smb.conf.5.html>
158           for all available options.
159         '';
160       };
161     };
162   };
164   ###### implementation
166   config = lib.mkMerge
167     [ { assertions =
168           [ { assertion = cfg.nsswins -> cfg.winbindd.enable;
169               message   = "If services.samba.nsswins is enabled, then services.samba.winbindd.enable must also be enabled";
170             }
171           ];
172       }
174       (lib.mkIf cfg.enable {
175         environment.etc."samba/smb.conf".source = configFile;
177         system.nssModules = lib.optional cfg.nsswins cfg.package;
178         system.nssDatabases.hosts = lib.optional cfg.nsswins "wins";
180         systemd = {
181           slices.system-samba = {
182             description = "Samba slice";
183           };
184           targets.samba = {
185             description = "Samba Server";
186             after = [ "network.target" ];
187             wants = [ "network-online.target" ];
188             wantedBy = [ "multi-user.target" ];
189           };
190           tmpfiles.rules = [
191             "d /var/lock/samba - - - - -"
192             "d /var/log/samba - - - - -"
193             "d /var/cache/samba - - - - -"
194             "d /var/lib/samba/private - - - - -"
195           ];
196         };
198         security.pam.services.samba = {};
199         environment.systemPackages = [ cfg.package ];
200         # Like other mount* related commands that need the setuid bit, this is
201         # required too.
202         security.wrappers."mount.cifs" = {
203           program = "mount.cifs";
204           source = "${lib.getBin pkgs.cifs-utils}/bin/mount.cifs";
205           owner = "root";
206           group = "root";
207           setuid = true;
208         };
210         networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ 139 445 ];
211         networking.firewall.allowedUDPPorts = lib.mkIf cfg.openFirewall [ 137 138 ];
212       })
214       (lib.mkIf (cfg.enable && cfg.nmbd.enable) {
215         systemd.services.samba-nmbd = {
216           description = "Samba NMB Daemon";
217           documentation = [ "man:nmbd(8)" "man:samba(7)" "man:smb.conf(5)" ];
219           after = [
220             "network.target"
221             "network-online.target"
222           ];
224           partOf = [ "samba.target" ];
225           wantedBy = [ "samba.target" ];
226           wants = [ "network-online.target" ];
228           environment.LD_LIBRARY_PATH = config.system.nssModules.path;
230           serviceConfig = {
231             ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
232             ExecStart = "${cfg.package}/sbin/nmbd --foreground --no-process-group ${lib.escapeShellArgs cfg.nmbd.extraArgs}";
233             LimitCORE = "infinity";
234             PIDFile = "/run/samba/nmbd.pid";
235             Slice = "system-samba.slice";
236             Type = "notify";
237           };
239           unitConfig.RequiresMountsFor = "/var/lib/samba";
241           restartTriggers = [ configFile ];
242         };
243       })
245       (lib.mkIf (cfg.enable && cfg.smbd.enable) {
246         systemd.services.samba-smbd = {
247           description = "Samba SMB Daemon";
248           documentation = [ "man:smbd(8)" "man:samba(7)" "man:smb.conf(5)" ];
250           after = [
251             "network.target"
252             "network-online.target"
253           ] ++ lib.optionals (cfg.nmbd.enable) [
254             "samba-nmbd.service"
255           ] ++ lib.optionals (cfg.winbindd.enable) [
256             "samba-winbindd.service"
257           ];
259           partOf = [ "samba.target" ];
260           wantedBy = [ "samba.target" ];
261           wants = [ "network-online.target" ];
263           environment.LD_LIBRARY_PATH = config.system.nssModules.path;
265           serviceConfig = {
266             ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
267             ExecStart = "${cfg.package}/sbin/smbd --foreground --no-process-group ${lib.escapeShellArgs cfg.smbd.extraArgs}";
268             LimitCORE = "infinity";
269             LimitNOFILE = 16384;
270             PIDFile = "/run/samba/smbd.pid";
271             Slice = "system-samba.slice";
272             Type = "notify";
273           };
275           unitConfig.RequiresMountsFor = "/var/lib/samba";
277           restartTriggers = [ configFile ];
278         };
279       })
281       (lib.mkIf (cfg.enable && cfg.winbindd.enable) {
282         systemd.services.samba-winbindd = {
283           description = "Samba Winbind Daemon";
284           documentation = [ "man:winbindd(8)" "man:samba(7)" "man:smb.conf(5)" ];
286           after = [
287             "network.target"
288           ] ++ lib.optionals (cfg.nmbd.enable) [
289             "samba-nmbd.service"
290           ];
292           partOf = [ "samba.target" ];
293           wantedBy = [ "samba.target" ];
295           environment.LD_LIBRARY_PATH = config.system.nssModules.path;
297           serviceConfig = {
298             ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
299             ExecStart = "${cfg.package}/sbin/winbindd --foreground --no-process-group ${lib.escapeShellArgs cfg.winbindd.extraArgs}";
300             LimitCORE = "infinity";
301             PIDFile = "/run/samba/winbindd.pid";
302             Slice = "system-samba.slice";
303             Type = "notify";
304           };
306           unitConfig.RequiresMountsFor = "/var/lib/samba";
308           restartTriggers = [ configFile ];
309         };
310       })
311     ];