After days of configuration and research, I couldn’t find a single source that covered everything needed for this setup end to end. My job requires centralized SSSD across all Linux servers, so here’s what I got working on both RHEL 8 and OpenSUSE 15.6.
The stack: Samba for SMB/CIFS, SSSD for AD integration, Kerberos for authentication, and realmd for domain join.
What you need before starting: DNS resolving your domain controllers, NTP/Chrony running and synced, a domain admin account with join privileges, and the following info on hand — domain name (company.com), DC hostname (dc1.company.com).
Step 1: Package Installation
RHEL/CentOS/Rocky Linux
sudo dnf install -y realmd sssd oddjob oddjob-mkhomedir adcli \ samba-common-tools krb5-workstation chrony samba samba-client \ cifs-utils policycoreutils-python-utils
sudo systemctl enable --now chronydsudo systemctl enable sssdUbuntu/Debian
sudo apt updatesudo apt install -y realmd sssd sssd-tools libnss-sss libpam-sss \ adcli samba-common-bin krb5-user chrony samba smbclient \ cifs-utils
sudo systemctl enable --now chronysudo systemctl enable sssdOpenSUSE Leap / Tumbleweed
sudo zypper install -y realmd sssd sssd-ad adcli \ samba krb5-client chrony samba-client cifs-utils
sudo systemctl enable --now chronydsudo systemctl enable sssdNote
SSSD is only enabled here, not started — it has no configuration yet. realm join (Step 4) will create the initial sssd.conf and start the service automatically.
Note
Ubuntu and OpenSUSE use AppArmor, not SELinux. The policycoreutils-python-utils package and semanage/restorecon commands throughout this guide are RHEL/CentOS-specific. Skip them on Debian-based and OpenSUSE systems.
Step 2: DNS and Time
/etc/resolv.conf
nameserver 192.168.1.10nameserver 192.168.1.11search company.comdomain company.comVerify:
dig company.comdig _ldap._tcp.company.com SRV/etc/chrony.conf
server dc1.company.com iburst preferserver dc2.company.com iburst# RHEL/CentOS/OpenSUSEsudo systemctl restart chronyd# Ubuntu/Debiansudo systemctl restart chrony
chronyc sources -vtimedatectl statusNote
Kerberos requires time to be within 5 minutes of the domain controllers. If clock skew exceeds this, authentication will fail with KRB5KRB_AP_ERR_SKEW.
Step 3: Kerberos Configuration
/etc/krb5.conf
[libdefaults] default_realm = COMPANY.COM dns_lookup_kdc = true dns_lookup_realm = false rdns = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true udp_preference_limit = 0
[realms] COMPANY.COM = { kdc = dc1.company.com admin_server = dc1.company.com default_domain = company.com }
[domain_realm] .company.com = COMPANY.COM company.com = COMPANY.COM
[logging] default = SYSLOG:NOTICE:DAEMONTest it:
kinit administrator@COMPANY.COMklistkdestroyStep 4: Domain Join
sudo realm discover company.com
sudo realm join company.com -U administrator \ --client-software=sssd \ --membership-software=samba
sudo realm listnet ads testjoinNote
realm join --membership-software=samba calls net ads join internally — no need to run it again. It auto-configures /etc/sssd/sssd.conf, /etc/krb5.conf, and /etc/krb5.keytab. The custom sssd.conf in Step 6 intentionally replaces what realm join generated with a production-ready configuration.
Step 5: PAM Configuration
RHEL/CentOS/Rocky Linux
sudo authselect select sssd with-mkhomedir --forcesudo systemctl enable --now oddjobdOpenSUSE
sudo pam-config --add --ssssudo pam-config --add --mkhomedirUbuntu/Debian
pam-auth-update handles this automatically when libpam-sss is installed. No manual steps needed.
Step 6: SSSD Configuration
/etc/sssd/sssd.conf
[sssd]enable_files_domain = truedomains = company.comconfig_file_version = 2services = nss, pam
[domain/local]id_provider = files
[domain/company.com]ad_domain = company.comkrb5_realm = COMPANY.COMrealmd_tags = manages-system joined-with-sambacache_credentials = Trueid_provider = adad_update_samba_machine_account_password = True
full_name_format = %3$s\%1$suse_fully_qualified_names = Falsefallback_homedir = /home/%udefault_shell = /bin/bash
# Requires POSIX attributes (uidNumber, gidNumber) set in ADldap_id_mapping = False
krb5_store_password_if_offline = True
access_provider = simplesimple_allow_groups = linuxadmins@company.com, itstaff@company.comsimple_allow_users = testuser@company.com
enumerate = Falsesudo chmod 600 /etc/sssd/sssd.confsudo systemctl restart sssdsudo systemctl enable sssdNote
ldap_id_mapping = False requires that all AD users and groups have POSIX attributes (uidNumber, gidNumber) configured in Active Directory. If they don’t, user lookups will fail silently. Set to True to let SSSD generate consistent IDs algorithmically instead.
Step 7: NSS Configuration
/etc/nsswitch.conf
passwd: files sssgroup: files sssshadow: files sssnetgroup: sss filesNote
Do not add winbind to passwd or group here. In this setup, SSSD handles all NSS resolution. Winbind runs only as an internal Samba component for ID mapping via the sss backend. Mixing sss and winbind in nsswitch causes duplicate lookups and inconsistent results.
Step 8: Samba Configuration
/etc/samba/smb.conf
[global] realm = COMPANY.COM workgroup = COMPANY security = ads
kerberos method = secrets and keytab dedicated keytab file = /etc/krb5.keytab
log file = /var/log/samba/log.%m log level = 2
vfs objects = acl_xattr map acl inherit = yes store dos attributes = yes
template homedir = /home/%U template shell = /bin/bash
idmap config * : backend = tdb idmap config * : range = 10000-199999 idmap config COMPANY : range = 200000-2147483647 idmap config COMPANY : backend = sss
client signing = mandatory server signing = mandatory
socket options = TCP_NODELAY IPTOS_LOWDELAY
[shared] path = /srv/shared read only = no browsable = yes valid users = @linuxadmins, @itstaff force group = linuxadmins create mask = 0664 directory mask = 0775
[data] path = /srv/data read only = no browsable = yes valid users = @dataaccess force group = dataaccess create mask = 0660 directory mask = 0770
[homes] comment = Home Directories valid users = %S browsable = no read only = no create mask = 0700 directory mask = 0700Note
idmap config COMPANY : backend = sss tells Samba’s winbind to delegate ID mapping to SSSD for the COMPANY domain. The default tdb backend handles the * (fallback) range. The sss backend is read-only, so a writable fallback is required.
Note
Group names in valid users must match how SSSD exposes them. With use_fully_qualified_names = False, groups resolve as linuxadmins — not linuxadmins@company.com. Using the FQDN form here will silently block all access.
Validate the configuration before starting services:
sudo testparm -sCreate Share Directories
sudo mkdir -p /srv/shared /srv/data
sudo chgrp linuxadmins /srv/sharedsudo chmod 775 /srv/sharedsudo chgrp dataaccess /srv/datasudo chmod 770 /srv/data
# SELinux (RHEL/CentOS only)sudo setsebool -P samba_export_all_ro=1 samba_export_all_rw=1sudo setsebool -P use_samba_home_dirs=onsudo setsebool -P samba_enable_home_dirs=onsudo semanage fcontext -a -t samba_share_t "/srv/shared(/.*)?"sudo semanage fcontext -a -t samba_share_t "/srv/data(/.*)?"sudo restorecon -R /srv/shared /srv/dataStep 9: Start Services and Test
RHEL/CentOS/Rocky Linux / OpenSUSE
sudo systemctl enable --now smb winbindsudo systemctl status smb winbindUbuntu/Debian
sudo systemctl enable --now smbd winbindsudo systemctl status smbd winbindVerify user and group resolution
getent passwd testuser@company.comid testuser@company.comgetent group linuxadmins@company.comTest share access
# List sharessmbclient -L localhost -U testuser@company.com
# Test share accesssmbclient //localhost/shared -U testuser@company.comFrom a Windows client: \\linux-server\shared
Step 10: Firewall
RHEL/CentOS/Rocky Linux / OpenSUSE
# The samba service already includes ports 137/udp, 138/udp, 139/tcp, 445/tcpsudo firewall-cmd --permanent --add-service=sambasudo firewall-cmd --reloadUbuntu/Debian
sudo ufw allow sambasudo ufw statusStep 11: Troubleshooting
Cache
sudo sss_cache -Esudo systemctl restart sssd
sudo net cache flush
# If TDB corruption suspectedsudo systemctl stop smb winbind # or smbd on Ubuntusudo rm -f /var/lib/samba/*.tdbsudo systemctl start winbind smb # or smbd on UbuntuLogs
sudo tail -f /var/log/sssd/sssd_company.com.logsudo tail -f /var/log/samba/log.smbdFor deeper SSSD debugging, add debug_level = 9 in the [domain/company.com] section and restart sssd.
AD Connectivity and Auth
sudo net ads infosudo net ads user info testusersudo net ads group info "linuxadmins"klist -k /etc/krb5.keytab
# Winbind checkssudo wbinfo -t # verify trust secretsudo wbinfo -n "COMPANY\testuser" # resolve a specific user (safe)# Avoid wbinfo -u / wbinfo -g in large AD environments — enumerates all# domain users/groups and can cause significant load on domain controllers
# Active connectionssudo smbstatusCommon Errors
NT_STATUS_ACCESS_DENIED:
id username@company.comsudo testparm -sls -Z /srv/shared # SELinux context (RHEL only)Users not resolving:
sudo sss_cache -Esudo systemctl restart sssd winbindgetent passwd username@company.comAuthentication failures:
klistkinit username@COMPANY.COMchronyc sources -vnet ads testjoinMaintenance Script
sudo nano /usr/local/bin/samba-maintenance.sh#!/bin/bash# SSSD manages machine account password rotation automatically via# ad_update_samba_machine_account_password = True — do not run# net ads changetrustpw here as it conflicts with SSSD's management.sss_cache -Etdbbackup /var/lib/samba/*.tdb 2>/dev/null || truenet ads testjoinecho "Maintenance completed: $(date)"sudo chmod +x /usr/local/bin/samba-maintenance.sh
# Weekly cronecho "0 2 * * 0 /usr/local/bin/samba-maintenance.sh >> /var/log/samba-maintenance.log 2>&1" | sudo crontab -