{ config, lib, pkgs, ... }: with lib; let cfg = config.custom.samba-share; in { options.custom.samba-share = { enable = mkEnableOption "enable custom.samba-share"; folders = mkOption { default = { }; type = with types; attrsOf str; description = '' folders to share as readonly ''; example = { public = "/srv/downloads/movies"; }; }; private = mkOption { default = { }; type = with types; attrsOf (submodule { options = { users = mkOption { type = with types; str; description = '' System users allowed to access the folder. To set password: # nix-shell -p samba # smbpasswd -a ''; }; folder = mkOption { type = with types; str; }; }; }); }; }; config = mkMerge [ (mkIf cfg.enable { networking.firewall.enable = true; networking.firewall.allowPing = true; networking.firewall.allowedTCPPorts = [ 445 139 ]; networking.firewall.allowedUDPPorts = [ 137 138 ]; services.samba = { enable = true; # services.samba.securityType = "share"; extraConfig = '' guest account = smbguest map to guest = bad user # disable printing load printers = no printing = bsd printcap name = /dev/null disable spoolss = yes ''; shares = mapAttrs' (name: path: { name = name; value = { browsable = "yes"; comment = "read only share ${name}"; path = path; "read only" = "yes"; "guest ok" = "yes"; }; }) cfg.folders // (mapAttrs' (name: { users, folder, ... }: { name = name; value = { browsable = "yes"; comment = "read only share ${name}"; path = folder; "read only" = "no"; "valid users" = users; "guest ok" = "false"; }; }) cfg.private); }; users.users.smbguest = { name = "smbguest"; uid = config.ids.uids.smbguest; description = "smb guest user"; home = "/home/smbguest"; createHome = true; }; }) # todo : maybe better to have a parameter for this (mkIf config.services.syncthing.enable { users.groups."syncthing".members = [ "smbguest" ]; }) ]; }