Can't mount Samba share as a user

I’ve just experienced the issue that I can’t mount my file server as a user. Steps I’ve followed to make a mount point:

  1. added required packages in configuration.nix:
environment.systemPackages = with pkgs; [ cifs-utils samba ];
  1. confidured Samba to work with my old NAS in configuration.nix:
services.samba = {
    enable = true;
    securityType = "user";
  #  openFirewall = true;
    extraConfig = ''
      workgroup = WORKGROUP
      client min protocol = CORE
    '';
  };
  1. added a remote filesystem to configuration.nix:
fileSystems."/mnt/smb0" = {
      device = "//10.138.72.12/backup";
      fsType = "cifs";
      options = [ "username=bogdan" "users" "noauto" ]; #not sure if I need commas or whitespaces here. Changinf back and forth doesn't help
  };
  1. made network-discovery in Dolphin possible in configuration.nix:
    networking.firewall.extraCommands = ''iptables -t raw -A OUTPUT -p udp -m udp --dport 137 -j CT --helper netbios-ns'';
  2. created a mount folder:
    sudo mkdir /mnt
    sudo mkdir /mnt/smb0
  3. nixos-rebuild switch
[wynz@nixos-hp:~]$ mount /mnt/smb0
This program is not installed setuid root -  "user" CIFS mounts not supported.

This was a trouble on Fedora too (where I came from). Invoking sudo chmod u+s /bin/mount /bin/umount /usr/sbin/mount.cifs (source) fixed the prob. But here I can’t do this/, 'cause the Nix store is read-only.
I’ve searched the web and found that the developers have already set +s bit to mount and 'umount`, but it was almost 10 years ago (and they didn’t touch mount.cifs):

(EDIT: previously, posted a wrong link)

What can I do now?

Hmm, perhaps we should add the +s bit to the mount.cifs executable? Could you try this:

security.wrappers = {
  "mount.cifs".source = "${lib.getBin pkgs.cifs-utils}/bin/mount.cifs";
};

And try to nixos-rebuild switch and try to mount /mnt/smb0?

1 Like

Theoretically, it should work, but the rebuild tells me that we forgot the “owner” parameter:
error: The option `security.wrappers."mount.cifs".owner' is used but not defined.
As I understand, it should be similar to this example:

Am I missing something?

  security.wrappers."mount.cifs" = {
    source = "${lib.getBin pkgs.cifs-utils}/bin/mount.cifs";
    owner = "root";
    group = "root";
  };
[wynz@nixos-hp:~]$ mount /mnt/smb1
This program is not installed setuid root -  "user" CIFS mounts not supported.

I’ve never used security wrappers before. The initial permissions of the executable seem to be correct, but +s bit still isn’t set:

[wynz@nixos-hp:~]$ ls -l /nix/store/z6v13363sv14734xysisq5ar1mw6f122-cifs-utils-7.0/bin/mount.cifs
-r-xr-xr-x 1 root root 54496 Jan  1  1970 /nix/store/z6v13363sv14734xysisq5ar1mw6f122-cifs-utils-7.0/bin/mount.cifs

The security.wrappers API has changed a bit since 2020. Based on mount.davfs wrapper, try:

    security.wrappers."mount.cifs" = {
      program = "mount.cifs";
      source = "${lib.getBin pkgs.cifs-utils}/bin/mount.cifs";
      owner = "root";
      group = "root";
      setuid = true;
    };

Eventually we should add that wrapper somewhere in the samba NixOS module. If something doesn’t work for you, try to run readlink $(which mount.cifs) to see what exactly are you running.

1 Like

Woohoo, it’s working now!! :muscle:Thank you so much. :smiley: This was the biggest inconvinience for me.

1 Like

I’m glad it worked for you, would you like to open a PR for this issue? If you think it is too hard for you, would you be able to review a PR?

1 Like

Should the attr name still be "mount.davfs" in this case? Intuitively "mount.cifs" seems more appropriate, but perhaps that would fail to use the wrapper?

2 Likes

Yes of course, it was a typo:).

2 Likes

Sorry for the time spent to answer. I’ve already made changes to the nixos/modules/security/wrappers/default.nix to include the mount.cifs wrapper (is the location correct? I took it from your PR), and will figure out how to test it later. Will notify you when I’m done :slightly_smiling_face:

My PR? Which one, I literally just a second ago opened this PR

2 Likes

Ah, I see. You found a way to embed it in the samba service itself - it’s perfect!
Will it be OK if I test the changes on the next week? Currently, I don’t have access to my NixOS machine :upside_down_face:

2 Likes

Just tried it out myself.
At some point my KIO SMB connection broke (as in KDE), and simply following along with OP fixed it.
Actually it’s better than before, since streaming from my NAS now works with e.g. VLC, something the latter flat-out refused to do earlier :slight_smile:

1 Like

I’ve been having the same issue, although 1 of my mounts usually work, another works sometimes, and the third I haven’t seen it work.

I did as recommended but get this error:

error:
       … while evaluating the attribute 'config'
         at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:1:12284:
       … while calling the 'seq' builtin
         at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:1:12293:
       (stack trace truncated; use '--show-trace' to show the full, detailed trace)

       error: undefined variable 'lib'
       at /etc/nixos/configuration.nix:151:17:
          150|     program = "mount.cifs";
          151|     source = "${lib.getBin pkgs.cifs-utils}/bin/mount.cifs";
             |                 ^
          152|     owner = "root";
building Nix...
error:
       … while evaluating the attribute 'config'
         at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:1:12284:
       … while calling the 'seq' builtin
         at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:1:12293:
       (stack trace truncated; use '--show-trace' to show the full, detailed trace)

       error: undefined variable 'lib'
       at /etc/nixos/configuration.nix:151:17:
          150|     program = "mount.cifs";
          151|     source = "${lib.getBin pkgs.cifs-utils}/bin/mount.cifs";
             |                 ^
          152|     owner = "root";
building the system configuration...
error:
       … while evaluating the attribute 'config.system.build.toplevel'
         at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:1:12284:
       … while calling the 'seq' builtin
         at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:1:12293:
       (stack trace truncated; use '--show-trace' to show the full, detailed trace)

       error: undefined variable 'lib'
       at /etc/nixos/configuration.nix:151:17:
          150|     program = "mount.cifs";
          151|     source = "${lib.getBin pkgs.cifs-utils}/bin/mount.cifs";
             |                 ^
          152|     owner = "root";

Could you share your config?
The error is about lib not being bound, so perhaps it isn’t being injected.

Hi, thanx for your response, I think you are right, but I just don’t know how to fix that (and there are no suggestions here), here is my config:

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  # Bootloader.
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

#   nix.settings.experimental-features = [ "nix-command" "flakes" ];

  boot.initrd.luks.devices."luks-f2cd0410-db66-4784-9403-e2de6a4907d0".device = "/dev/disk/by-uuid/f2cd0410-db66-4784-9403-e2de6a4907d0";
  networking.hostName = "deneb"; # Define your hostname.
  # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Enable networking
  networking.networkmanager.enable = true;

  # To use solaar for Logitech devices
  hardware.logitech.wireless.enable = true;

  # Enable bluetooth
  hardware.bluetooth.enable = true; # enables support for Bluetooth
  hardware.bluetooth.powerOnBoot = true; # powers up the default Bluetooth controller on boot

  # Set your time zone.
  time.timeZone = "Europe/Amsterdam";

  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";

  i18n.extraLocaleSettings = {
    LC_ADDRESS = "nl_NL.UTF-8";
    LC_IDENTIFICATION = "nl_NL.UTF-8";
    LC_MEASUREMENT = "nl_NL.UTF-8";
    LC_MONETARY = "nl_NL.UTF-8";
    LC_NAME = "nl_NL.UTF-8";
    LC_NUMERIC = "nl_NL.UTF-8";
    LC_PAPER = "nl_NL.UTF-8";
    LC_TELEPHONE = "nl_NL.UTF-8";
    LC_TIME = "nl_NL.UTF-8";
  };

  # Enable the X11 windowing system.
  # You can disable this if you're only using the Wayland session.
  services.xserver.enable = true;

  # Enable the KDE Plasma Desktop Environment.
  services.displayManager.sddm.enable = true;
  services.desktopManager.plasma6.enable = true;

  # Configure keymap in X11
  services.xserver.xkb = {
    layout = "us";
    variant = "euro";
  };

  # Enable CUPS to print documents.
  services.printing.enable = true;

  # Enable sound with pipewire.
  hardware.pulseaudio.enable = false;
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    # If you want to use JACK applications, uncomment this
    #jack.enable = true;

    # use the example session manager (no others are packaged yet so this is enabled by default,
    # no need to redefine it in your config for now)
    #media-session.enable = true;
  };

  # Some stuff to run local LLMs
  services.ollama = {
    enable = true;
    # Optional: load models on startup
    loadModels = [ deepseek-r1:8b ];
  };
  services.open-webui.enable = true; # Find open webui on http://localhost:8080/

  # Enable touchpad support (enabled default in most desktopManager).
  # services.xserver.libinput.enable = true;

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.freek = {
    isNormalUser = true;
    description = "Freek van Hemert";
    extraGroups = [ "networkmanager" "wheel" ];
    packages = with pkgs; [
      kdePackages.kate
      kdePackages.ksshaskpass
      kdePackages.kwallet
      kdePackages.kwallet-pam
      solaar
      chromium
      libreoffice-fresh
      obsidian
      signal-desktop
      zed-editor
      vscode
      git
      buildah
      podman
      skopeo
      podman-tui # status of containers in the terminal
      tmux
    ];
  };

  # Install firefox.
  programs.firefox.enable = true;

  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
    wget
    tailscale
    incus
    curl
    htop
    cifs-utils
  ];

  services.tailscale.enable = true;

  # To enable sftp login with ssh keys in Dolphin
  programs.ssh.startAgent = true;
  security.pam.services.sddm.enableKwallet = true;

  # security.wrappers."mount.cifs" = {
  #   program = "mount.cifs";
  #   source = "${lib.getBin pkgs.cifs-utils}/bin/mount.cifs";
  #   owner = "root";
  #   group = "root";
  #   setuid = true;
  # };

  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable:

  # Enable the OpenSSH daemon.
  services.openssh.enable = true;

  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  networking.firewall.enable = true;

  # Enable common container config files in /etc/containers
  virtualisation.containers.enable = true;
  virtualisation = {
    podman = {
      enable = true;

      # Create a `docker` alias for podman, to use it as a drop-in replacement
      dockerCompat = true;

      # Required for containers under podman-compose to be able to talk to each other.
      defaultNetwork.settings.dns_enabled = true;
    };
  };

  # For mount.cifs, required unless domain name resolution is not needed.
  fileSystems."/mnt/arcturus/compute" = {
    device = "//arcturus.xxx.ts.net/compute";
    fsType = "cifs";
    options = let
      # this line prevents hanging on network split
      automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s";

    in ["${automount_opts},credentials=/etc/nixos/smb-secrets,uid=${toString config.users.users.freek.uid},gid=${toString config.users.groups.users.gid}"];
  };

  # For mount.cifs, required unless domain name resolution is not needed.
  fileSystems."/mnt/arcturus/qodon" = {
    device = "//arcturus.xxx.ts.net/qodon";
    fsType = "cifs";
    options = let
      # this line prevents hanging on network split
      automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s";

    in ["${automount_opts},credentials=/etc/nixos/smb-secrets,uid=${toString config.users.users.freek.uid},gid=${toString config.users.groups.users.gid}"];
  };

  # For mount.cifs, required unless domain name resolution is not needed.
  fileSystems."/mnt/arcturus/Lexogen" = {
    device = "//arcturus.xxx.ts.net/Lexogen";
    fsType = "cifs";
    options = let
      # this line prevents hanging on network split
      automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s";
    in ["${automount_opts},credentials=/etc/nixos/smb-secrets,uid=${toString config.users.users.freek.uid},gid=${toString config.users.groups.users.gid}"];
  };

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "24.11"; # Did you read the comment?

}

@freek simply add a lib to the arguments at the beginning:

{ config, pkgs, lib, ... }:

Or simply use pkgs.lib instead of lib in the commented out security.wrappers."mount.cifs" configuration.

1 Like

What bothers me more, is why don’t you use the NixOS module for samba?

services.samba.enable = true;

Should add that wrapper to your config. Are you trying to only enable the mount.cifs program without exposing via Samba any samba share?

There is no mention of this under Samba Client on Samba - NixOS Wiki, I just followed the instruction and it worked, except for writing as a user. But let’s see if it fixes things :slight_smile:

Ah yes, that does remove the error but I still can’t write as a user, let me try services.samba.enable = true; first.