Commit 988c5981 authored by Anthony Roussel's avatar Anthony Roussel Committed by Pascal Bach
Browse files

nixos/samba: migrate to structural settings (RFC42)

parent 6423eb0f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -335,6 +335,13 @@

- The `replay-sorcery` package and module was removed as it unmaintained upstream. Consider using `gpu-screen-recorder` or `obs-studio` instead.

- To follow [RFC 0042](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md) a few options of `samba` have been moved from `extraConfig` to the new freeform option `settings` and renamed, e.g.:
  - `services.samba.invalidUsers` to `services.samba.settings.global."invalid users"`
  - `services.samba.securityType` to `services.samba.settings.global."security type"`
  - `services.samba.shares` to `services.samba.settings`
  - `services.samba.enableWinbindd` to `services.samba.winbindd.enable`
  - `services.samba.enableNmbd` to `services.samba.nmbd.enable`

- `zx` was updated to v8, which introduces several breaking changes.
  See the [v8 changelog](https://github.com/google/zx/releases/tag/8.0.0) for more information.

+37 −76
Original line number Diff line number Diff line
@@ -3,35 +3,12 @@
with lib;

let

  smbToString = x: if builtins.typeOf x == "bool"
                   then boolToString x
                   else toString x;

  cfg = config.services.samba;

  samba = cfg.package;

  shareConfig = name:
    let share = getAttr name cfg.shares; in
    "[${name}]\n " + (smbToString (
       map
         (key: "${key} = ${smbToString (getAttr key share)}\n")
         (attrNames share)
    ));
  settingsFormat = pkgs.formats.ini { };
  configFile = settingsFormat.generate "smb.conf" cfg.settings;

  configFile = pkgs.writeText "smb.conf"
    (if cfg.configText != null then cfg.configText else
    ''
      [global]
      security = ${cfg.securityType}
      passwd program = /run/wrappers/bin/passwd %u
      invalid users = ${smbToString cfg.invalidUsers}

      ${cfg.extraConfig}

      ${smbToString (map shareConfig (attrNames cfg.shares))}
    '');
  samba = cfg.package;

  # This may include nss_ldap, needed for samba if it has to use ldap.
  nssModulesPath = config.system.nssModules.path;
@@ -68,6 +45,19 @@ in
  imports = [
    (mkRemovedOptionModule [ "services" "samba" "defaultShare" ] "")
    (mkRemovedOptionModule [ "services" "samba" "syncPasswordsByPam" ] "This option has been removed by upstream, see https://bugzilla.samba.org/show_bug.cgi?id=10669#c10")

    (lib.mkRemovedOptionModule [ "services" "samba" "configText" ] ''
      Use services.samba.settings instead.

      This is part of the general move to use structured settings instead of raw
      text for config as introduced by RFC0042:
      https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md
    '')
    (lib.mkRemovedOptionModule [ "services" "samba" "extraConfig" ] "Use services.samba.settings instead.")
    (lib.mkRenamedOptionModule [ "services" "samba" "invalidUsers" ] [ "services" "samba" "settings" "global" "invalid users" ])
    (lib.mkRenamedOptionModule [ "services" "samba" "securityType" ] [ "services" "samba" "settings" "global" "security type" ])
    (lib.mkRenamedOptionModule [ "services" "samba" "shares" ] [ "services" "samba" "settings" ])

  ];

  ###### interface
@@ -125,41 +115,6 @@ in
        example = "samba4Full";
      };

      invalidUsers = mkOption {
        type = types.listOf types.str;
        default = [ "root" ];
        description = ''
          List of users who are denied to login via Samba.
        '';
      };

      extraConfig = mkOption {
        type = types.lines;
        default = "";
        description = ''
          Additional global section and extra section lines go in here.
        '';
        example = ''
          guest account = nobody
          map to guest = bad user
        '';
      };

      configText = mkOption {
        type = types.nullOr types.lines;
        default = null;
        description = ''
          Verbatim contents of smb.conf. If null (default), use the
          autogenerated file from NixOS instead.
        '';
      };

      securityType = mkOption {
        type = types.enum [ "auto" "user" "domain" "ads" ];
        default = "user";
        description = "Samba security type";
      };

      nsswins = mkOption {
        default = false;
        type = types.bool;
@@ -170,25 +125,31 @@ in
        '';
      };

      shares = mkOption {
      settings = lib.mkOption {
        type = lib.types.submodule { freeformType = settingsFormat.type; };
        default = {};
        description = ''
          A set describing shared resources.
          See {command}`man smb.conf` for options.
        '';
        type = types.attrsOf (types.attrsOf types.unspecified);
        example = literalExpression ''
          { public =
            { path = "/srv/public";
              "read only" = true;
              browseable = "yes";
        example = {
          "global" = {
            "security" = "user";
            "passwd program" = "/run/wrappers/bin/passwd %u";
            "invalid users" = "root";
          };
          "public" = {
            "path" = "/srv/public";
            "read only" = "yes";
            "browseable" = "yes";
            "guest ok" = "yes";
              comment = "Public samba share.";
            "comment" = "Public samba share.";
          };
          }
        '';
        };
        description = ''
          Configuration file for the Samba suite in ini format.
          This file is located in /etc/samba/smb.conf

          Refer to <https://www.samba.org/samba/docs/current/man-html/smb.conf.5.html>
          for all available options.
        '';
      };
    };

  };
+34 −31
Original line number Diff line number Diff line
import ./make-test-python.nix ({ pkgs, ... }:

{
import ./make-test-python.nix ({ pkgs, ... }: {
  name = "samba";

  meta.maintainers = [ ];

  nodes =
    { client =
        { pkgs, ... }:
        { virtualisation.fileSystems =
            { "/public" = {
  nodes = {
    client =
      { ... }:
      {
        virtualisation.fileSystems = {
          "/public" = {
            fsType = "cifs";
            device = "//server/public";
            options = [ "guest" ];
@@ -19,22 +18,26 @@ import ./make-test-python.nix ({ pkgs, ... }:

    server =
      { ... }:
        { services.samba.enable = true;
          services.samba.openFirewall = true;
          services.samba.shares.public =
            { path = "/public";
      {
        services.samba = {
          enable = true;
          openFirewall = true;
          settings = {
            "public" = {
              "path" = "/public";
              "read only" = true;
              browseable = "yes";
              "browseable" = "yes";
              "guest ok" = "yes";
              comment = "Public samba share.";
              "comment" = "Public samba share.";
            };
          };
        };
      };
  };

  # client# [    4.542997] mount[777]: sh: systemd-ask-password: command not found

  testScript =
    ''
  testScript = ''
    server.start()
    server.wait_for_unit("samba.target")
    server.succeed("mkdir -p /public; echo bar > /public/foo")