Skip to content

Role: samba

LAN-side SMB server on proxfold. Re-exports the existing /stash/rodneystash media tree to Windows clients (DaVinci Resolve workstation, Music drag-and-drop) without going through NFS or an intermediate LXC.

Hosts: proxfold (server). No client side — Windows is the consumer.

Tasks

Task Tag
Install samba, samba-common-bin (install_recommends: false) samba, install
Ensure samba service user exists (nologin, no home) samba, user
Probe pdbedit -L -u <user> for existing passdb entry samba, user
Create samba passdb entry via smbpasswd -s -a from vault password samba, user
Render /etc/samba/smb.conf from template, validated with testparm -s samba, config
Enable + start smbd and nmbd samba, service

Key variables

inventory/host_vars/proxfold.yml:

samba_server: true
samba_user: smbmedia
samba_shares:
  - name: media
    path: /stash/rodneystash
    comment: "Rodney stash"
    read_only: false
    force_user: root

Single read-write share for the whole rodneystash dataset. An earlier split (read-only media for DaVinci ingest + read-write music for hand-curated Plex adds) hit Windows' SMB MUP limit — one credential set per server identity, system error 1219 (Microsoft troubleshooting guide). Collapsing to a single share avoids the alias workaround. Drag-delete on Movies/TV Shows is now possible from Windows; mitigated only by operator care, but no worse than the existing arrstack container write access to the same paths.

Defaults (from roles/samba/defaults/main.yml):

Variable Default Purpose
samba_server false Role no-ops unless explicitly enabled
samba_user smbmedia Service user backing the passdb entry
samba_shares [] List of share dicts (see above)
samba_allowed_network 192.168.1.0/24 hosts allow ACL on the global block
samba_workgroup WORKGROUP NetBIOS workgroup name

Per-share keys: name, path, comment, read_only, browseable, valid_users, force_user, force_group.

Vault

  • vault_samba_user_password — SMB password for samba_user. Set via the append-only /dev/shm script pattern (the role consumes it via env, no_log: true).

Templates

  • smb.conf.j2 — full replacement for /etc/samba/smb.conf. The packaged sample (printers, [homes], usershare) is wiped out — render writes a minimal global block + an iteration over samba_shares.

Check-mode behaviour

The role survives --check --diff clean. Gotchas captured:

  • pdbedit -L -u probe sets check_mode: false (read-only, must run in check mode so the gate evaluates).
  • smbpasswd -a shell sets when: not ansible_check_mode (no user yet on a first-time apply).
  • systemd: state=started tasks for smbd/nmbd set when: not ansible_check_mode (unit doesn't exist until samba is installed).
  • Restart handlers Restart smbd / Restart nmbd also set when: not ansible_check_mode — they're flushed by the template task and would otherwise fail mid-flight on a fresh host.

Same pattern as the crowdsec_engine role's xcaddy build step. Per homelab-ansible CLAUDE.md: "systemd enables and similar fail when the target doesn't exist yet".

Why a separate samba role instead of folding into nfs?

The nfs role handles both server (proxfold) and client (arrstack) sides because the same set of nfs_* variables drive both. SMB has no client side — Windows clients are configured by hand in File Explorer / Credential Manager — so the role is genuinely server-only and the variable namespace is independent. Folding it into nfs would mix two unrelated concerns.

Why force user = root?

/stash/rodneystash contains files owned by mixed UIDs from the Plex / sonarr / radarr containers (each container has its own PUID). Doing UID mapping properly for SMB would require either:

  • A static unix user with primary/supplementary groups matching every container's PUID (fragile, has to change every time a container is added)
  • Per-container nobody ownership with idmap magic (complex, and breaks the existing NFS export's no_root_squash assumption)

force user = root makes smbd traverse as root regardless of authenticated identity. Files written from Windows land as root:root 0644 — within /stash/rodneystash that's no worse than the existing NFS export's no_root_squash semantics; Plex / Sonarr / Radarr keep consuming via the same paths. The operator is trusted on the LAN; if that ever changes, revisit by introducing a unix user that matches Plex's PUID and using force group plus dataset-wide setgid directories instead.

Windows client setup

Map drive: \\192.168.1.250\media with creds smbmedia / vault_samba_user_password. Store in Credential Manager (cmdkey /add:192.168.1.250 /user:smbmedia /pass:... or via the Map Network Drive dialog with "Remember my credentials").

DaVinci Resolve ingests fine over SMB on a wired LAN connection. Re-link on import resolves UNC paths transparently.