Lost an evening to this, so you don't have to.
The fix everyone hands you is a single checkbox that quietly downgrades how your Mac stores its password. The clean alternative — Kerberos, the exact thing your iPhone already uses — is "impossible" according to three sources I dug up, one of them Apple's own Heimdal source. They're wrong. What follows is the whole path: why it breaks, why the popular fix is the bad one, and the two setups that actually work (a one-shot command and a hands-off automount).
My Mac mini shares a folder over SMB. My iPhone mounts it fine. My Linux box:
$ smbclient -L 192.168.0.153 -U tmlr%remote
session setup failed: NT_STATUS_LOGON_FAILURE
Same username, same password, rejected. Every "fix" on the internet ends with "turn on Windows File Sharing for that user on the Mac." That works, and it's the wrong answer. Here's why, and what to do instead.
The problem
The credentials are correct — the iPhone's connecting just fine. The handshake even completes; run it with -d3 and you'll see the full NTLMSSP exchange finish before the Mac rejects you. So this isn't networking, isn't the password, isn't the SMB dialect. It's authentication, and only Linux hits it.
Why: two doors, one account
macOS keeps several credentials for a local account, not one. Look:
$ dscl . -read /Users/tmlr AuthenticationAuthority
AuthenticationAuthority: ;ShadowHash;HASHLIST:<SALTED-SHA512-PBKDF2,SRP-RFC5054-4096-SHA512-PBKDF2>
;Kerberosv5;;tmlr@LKDC:SHA1.XXXX;LKDC:SHA1.XXXX;
Two things matter in there:
-
HASHLISTisSALTED-SHA512-PBKDF2(login) and an SRP verifier. There is no NT hash. - There's a
Kerberosv5identity in a realm calledLKDC:SHA1.<40 hex>.
SMB auth has two doors into this account:
-
NTLMv2 — validates against a stored NT hash. Linux
smbclientandmount.cifsknock here. - Kerberos — validates against the Mac's built-in Local KDC (LKDC), which every Mac runs. Apple clients knock here.
Your iPhone walks through the Kerberos door and never touches the NT hash. Linux tries the NTLM door, and on a fresh account that door was never built — macOS only mints the NT hash when you tick "Windows File Sharing." So the handshake completes and then fails the credential check: LOGON_FAILURE.
That's the whole mystery. The iPhone succeeding tells you nothing about the NT hash, because the iPhone isn't using it.
The right fix is Kerberos
The popular fix — tick the per-user Windows sharing box — makes macOS store an NT hash. Apple's own docs say that password is then "stored in a less secure manner." You're bolting a weaker credential onto the Mac to satisfy a Linux client. No thanks.
Do what the iPhone does: authenticate over Kerberos to the LKDC. No NT hash, nothing weakened.
Worth noting up front: half the internet (and Apple's Heimdal source) will tell you a non-Apple client can't get a TGT from an LKDC because Apple uses proprietary SRP preauth. On an account that also has a normal Kerberos key — which mine did — MIT kinit just works with plain encrypted-timestamp preauth. Test it before believing the "impossible."
Making smbclient work
1. Find the realm. Apple publishes it as an mDNS _kerberos TXT record. This is exactly how the iPhone discovers it:
IP=$(avahi-resolve -4 -n mini.local | awk '{print $2}')
dig @"$IP" -p 5353 +short -t TXT _kerberos.mini.local
# "LKDC:SHA1.3A0D9D58C5DDED406F63333CFCDE40D414A7949A"
(Use the IPv4. The link-local IPv6 responder breaks dig's unicast query.)
2. Point krb5 at it. No global config needed — use KRB5_CONFIG:
# ~/.config/krb5-mac.conf
[realms]
LKDC:SHA1.3A0D...949A = {
kdc = 192.168.0.153
}
There's no SRV discovery for LKDC realms, so the kdc = line is mandatory. dns_lookup_kdc won't save you.
3. Get a ticket.
export KRB5_CONFIG=~/.config/krb5-mac.conf
kinit tmlr@LKDC:SHA1.3A0D...949A
4. The SPN trap. This is where it gets stupid. smbclient builds its Kerberos service principal from the hostname you give it — cifs/mini.local. The Mac doesn't register that. It registers cifs/LKDC:SHA1.<hash>. Ask for cifs/mini.local and the KDC refers you to a phantom LOCAL realm that has no such principal:
Server not found in Kerberos database while getting credentials for cifs/mini.local@...
Fix: put the LKDC name where the hostname goes, and force the real IP with -I so that colon-riddled "hostname" is never resolved on the network:
smbclient "//LKDC:SHA1.3A0D...949A/Music" -I 192.168.0.153 -U tmlr --use-kerberos=required
The colon in the UNC doesn't faze Samba's parser. You land at smb: \>. Pure Kerberos, no NT hash.
Helper script. Self-discovering, nothing hardcoded but the hostname, config in a temp dir that's wiped on exit:
#!/usr/bin/env bash
set -euo pipefail
HOST=${MINISMB_HOST:-mini.local}
ACCT=${MINISMB_USER:-tmlr}
SHARE=${1:-Music}; shift 2>/dev/null || true
IP=$(avahi-resolve -4 -n "$HOST" | awk '{print $2; exit}')
REALM=$(dig @"$IP" -p 5353 +short -t TXT "_kerberos.$HOST" | tr -d '"')
workdir=$(mktemp -d); trap 'rm -rf "$workdir"' EXIT
export KRB5_CONFIG="$workdir/krb5.conf"
cat > "$KRB5_CONFIG" <<EOF
[realms]
$REALM = {
kdc = $IP
}
EOF
klist -s 2>/dev/null || kinit "$ACCT@$REALM"
smbclient "//$REALM/$SHARE" -I "$IP" -U "$ACCT" --use-kerberos=required "$@"
minismb, minismb Documents, minismb Music -c 'ls'. IP drifts on DHCP? It re-discovers every run.
Persistent automount with systemd
For an always-on /mnt/mac, mount.cifs needs a ticket at mount time — as root, no prompt. That means a keytab. The mount ticket is fetched by cifs.upcall, which runs as root and reads /etc/krb5.conf, so the realm has to live there. The interactive path stayed fully user-local; a kernel mount can't.
Keytab. ktutil is interactive and prompts per addent:
$ ktutil
ktutil: addent -password -p tmlr@LKDC:SHA1.3A0D...949A -k 1 -e aes256-cts-hmac-sha1-96
ktutil: addent -password -p tmlr@LKDC:SHA1.3A0D...949A -k 1 -e aes128-cts-hmac-sha1-96
ktutil: wkt /home/tmlr/.config/minismb/mini.keytab
ktutil: quit
Verify it can pull a TGT with no password:
kinit -kt ~/.config/minismb/mini.keytab tmlr@LKDC:SHA1.3A0D...949A && klist
If that fails with a preauth error, your LKDC uses a non-default salt — read it out of KRB5_TRACE=/dev/stderr kinit ... (etype info ... salt "...") and match it. Mine used the default (realm+principal), so plain addent worked.
Realm for root — /etc/krb5.conf.d/lkdc-mini.conf:
[realms]
LKDC:SHA1.3A0D...949A = {
kdc = mini.local
}
kdc = mini.local (not an IP) keeps the KDC side immune to DHCP drift, assuming nss-mdns resolves .local. Make sure /etc/krb5.conf has includedir /etc/krb5.conf.d/.
Keep a TGT alive — user units:
# ~/.config/systemd/user/minismb-tgt.service
[Unit]
Description=Refresh LKDC TGT from keytab
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
Environment=KRB5CCNAME=FILE:/tmp/krb5cc_%U
ExecStart=/usr/bin/kinit -kt %h/.config/minismb/mini.keytab tmlr@LKDC:SHA1.3A0D...949A
# ~/.config/systemd/user/minismb-tgt.timer
[Unit]
Description=Keep the LKDC TGT fresh
[Timer]
OnStartupSec=30s
OnUnitActiveSec=8h
Persistent=true
[Install]
WantedBy=timers.target
Mount + automount — system units:
# /etc/systemd/system/mnt-mac.mount
[Unit]
Description=Mac mini /Music over SMB (LKDC Kerberos)
After=network-online.target minismb-tgt.service
Wants=network-online.target
[Mount]
What=//LKDC:SHA1.3A0D...949A/Music
Where=/mnt/mac
Type=cifs
Options=sec=krb5,cruid=1000,uid=1000,gid=1000,vers=3.0,ip=192.168.0.153,_netdev,nofail
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/mnt-mac.automount
[Unit]
Description=Automount Mac mini /Music
[Automount]
Where=/mnt/mac
TimeoutIdleSec=600
[Install]
WantedBy=multi-user.target
Enable:
systemctl --user daemon-reload
systemctl --user enable --now minismb-tgt.timer
systemctl --user start minismb-tgt.service
sudo systemctl daemon-reload
sudo systemctl enable --now mnt-mac.automount
ls /mnt/mac
Two gotchas that cost me an hour:
-
vers=3.1.1fails withDialect not supported by server. Usevers=3.0.smbclientauto-negotiates and dodges this; the kernel client doesn't. -
ip=is static — the colon UNC isn't DNS-resolvable, so you must pass an IP, and a.mountunit can't run a resolver. Give the Mac a DHCP reservation and this stays put. (Only the SMBip=cares; the KDC usesmini.local.)
And that's it. On-access mount, keytab-driven, no password ever, and the Mac keeps only its strong credentials. Same door the iPhone uses.
Top comments (0)