Many sysadmins face a dilemma when implementing Samba in Linux clusters: how to achieve centralized authentication without the complexity of full Active Directory domain membership. The typical scenario involves:
[libdefaults]
default_realm = DOMAIN.COM
dns_lookup_realm = false
dns_lookup_kdc = true
While Kerberos authentication works perfectly for shell access via PAM, Samba stubbornly refuses to cooperate without domain joining, throwing errors like:
failed to get SID for domain DOMAIN
NT_STATUS_CANT_ACCESS_DOMAIN_INFO
The fundamental issue lies in Samba's architecture. Unlike PAM which handles pure authentication, Samba requires both:
- Authentication (proving identity)
- Authorization (mapping to local permissions)
Here's why the PAM approach fails for Samba:
# pam_krb5.so only handles authn, not the required ID mapping
auth sufficient pam_krb5.so use_first_pass
We can leverage Samba's security = ads
mode without full domain joining:
[global]
security = ads
realm = DOMAIN.COM
workgroup = DOMAIN
kerberos method = system keytab
dedicated keytab file = /etc/krb5.keytab
idmap config * : backend = tdb
idmap config * : range = 10000-99999
Implementation steps:
- Create service principal:
samba-tool domain join DOMAIN.COM MEMBER \ --realm=DOMAIN.COM \ --server=dc1.domain.com \ --option="kerberosmethod=systemkeytab"
- Restrict access via local accounts:
valid users = @linuxgroup force group = linuxgroup
For environments where even minimal AD integration isn't possible:
Option 1: Proxy LDAP authentication
passdb backend = ldapsam:"ldap://ldap.domain.com"
ldap admin dn = "cn=admin,dc=domain,dc=com"
ldap suffix = "dc=domain,dc=com"
Option 2: SSSD integration
[sssd]
services = nss, pam, samba
config_file_version = 2
[samba]
krb5_ccname = FILE:/tmp/krb5cc_%u
Key diagnostic commands:
# Verify Kerberos tickets
klist -ke /etc/krb5.keytab
# Check Samba's domain trust
net ads testjoin
# Detailed authentication logging
smbcontrol all debug 10
Many Linux administrators face a peculiar situation where they need Samba to authenticate against Active Directory via Kerberos, but without full domain membership. The traditional approach using winbind
forces domain joining, which brings unnecessary complexity when you only need authentication without full AD integration.
Your existing Kerberos configuration shows the groundwork is already laid:
[realms]
DOMAIN.COM = {
kdc = dc1.domain.com
admin_server = dc1.domain.com
}
This configuration allows Linux systems to perform Kerberos authentication independently. When testing with kinit
, we see successful ticket acquisition:
$ kinit jdoe
Password for jdoe@DOMAIN.COM:
$ klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: jdoe@DOMAIN.COM
Valid starting Expires Service principal
01/12/15 15:36:16 01/13/15 01:36:25 krbtgt/DOMAIN.COM@DOMAIN.COM
renew until 01/19/15 15:36:16
Despite working PAM configurations like:
auth sufficient pam_krb5.so use_first_pass
Samba fails to leverage this because it performs additional domain-specific checks. The error "failed-to-get-SID" indicates Samba's expectation for domain membership information that isn't available in standalone Kerberos authentication.
To make Samba work with Kerberos authentication without domain joining, we need to modify both Samba and Kerberos configurations:
[global]
security = ADS
realm = DOMAIN.COM
kerberos method = secrets and keytab
dedicated keytab file = /etc/krb5.keytab
encrypt passwords = yes
Then create a service principal and keytab:
# kadmin -p adminuser -q "addprinc -randkey cifs/server.example.com"
# kadmin -p adminuser -q "ktadd -k /etc/krb5.keytab cifs/server.example.com"
For local authorization control while using Kerberos authentication, implement user mapping:
[global]
username map = /etc/samba/user.map
# /etc/samba/user.map contents:
!jdoe = localuser1
!* = nobody
This approach maps Kerberos-authenticated users to local accounts while maintaining centralized authentication.
For clustered environments where pure Kerberos might not suffice:
- LDAP backend with
passdb backend = ldapsam:"ldap://ldap.example.com"
- SQL-based backend with
passdb backend = sql
- Combined approach:
passdb backend = ldapsam:"ldap://ldap.example.com" tdbsam:/var/lib/samba/private/passdb.tdb
Each has trade-offs between complexity and functionality that should be evaluated based on specific requirements.