Das Problem
Du hast einen UCS Domain Controller erfolgreich demoted. Samba ist gestoppt, der neue DC läuft, FSMO-Rollen sind übertragen. Alles gut, oder?
Dann rufst du auf deinem Member Server wbinfo -i administrator auf:
failed to call wbcGetpwnam: WBC_ERR_DOMAIN_NOT_FOUND
Could not get info for user administrator
SMB-Freigaben sind nicht erreichbar. /etc/ldap/ldap.conf zeigt auf den alten, toten DC:
URI ldap://dc-vader.darkside.lan:7389 ldap://dc-obiwan.darkside.lan:7389
Logisch. dc-vader ist der demoted DC, dc-obiwan der neue Primary. Also schnell fixen:
ucr set ldap/server/name='dc-obiwan.darkside.lan'
Und dann das:
W: ldap/server/name is overridden by scope "ldap"
ucr get ldap/server/name gibt immer noch dc-vader.darkside.lan zurück. Facepalm.
Die Diagnose
Schritt 1: UCR scope “ldap” verstehen
Der Scope-Override bedeutet: Eine LDAP-Policy vom DC überschreibt den lokalen UCR-Wert. Also Policy prüfen:
# Auf dem Primary DC (dc-obiwan):
udm policies/ldapserver list
DN: cn=default-settings,cn=ldap,cn=policies,dc=darkside,dc=lan
ldapServer: dc-vader.darkside.lan ← da ist er!
ldapServer: dc-obiwan.darkside.lan
Policy fixen — dc-vader entfernen:
udm policies/ldapserver modify \
--dn "cn=default-settings,cn=ldap,cn=policies,dc=darkside,dc=lan" \
--remove ldapServer="dc-vader.darkside.lan"
Listener auf dem Member Server neu starten… und ldap/server/name zeigt immer noch auf dc-vader.
Hä?
Schritt 2: Den echten Täter finden — ldap_server.py
Zeit, tiefer zu graben. Was setzt ldap/server/name überhaupt?
cat /usr/lib/univention-directory-listener/system/ldap_server.py
Der relevante Teil:
filter = '(&(objectClass=univentionDomainController)(|(univentionServerRole=master)(univentionServerRole=backup)))'
def add_ldap_server(ucr, name, domain, role):
if role == 'master':
old_master = ucr.get('ldap/master')
changes = ['ldap/master=%s' % server_name]
if ucr.get('ldap/server/name') == old_master:
changes.append('ldap/server/name=%s' % server_name)
univention.config_registry.handler_set(changes)
Der Listener liest beim Start alle DC-Objekte mit univentionServerRole=master oder backup aus dem LDAP — und setzt ldap/server/name daraus. Nicht aus der Policy, nicht aus UCR: aus den DC-Objekten.
Schritt 3: Das DC-Objekt des alten DC prüfen
# Auf dc-obiwan:
ldapsearch -x -H ldap://localhost:7389 \
-D "cn=admin,dc=darkside,dc=lan" -w "$(cat /etc/ldap.secret)" \
-b "cn=dc,cn=computers,dc=darkside,dc=lan" \
"(|(univentionServerRole=master)(univentionServerRole=backup))" \
dn univentionServerRole cn
dn: cn=dc-vader,cn=dc,cn=computers,dc=darkside,dc=lan
univentionServerRole: master ← da ist der echte Täter!
dn: cn=dc-obiwan,cn=dc,cn=computers,dc=darkside,dc=lan
univentionServerRole: backup
dc-vader hat noch univentionServerRole=master im OpenLDAP — obwohl er seit Wochen demoted ist.
samba-tool domain demote entfernt das Samba-AD-Objekt. Das UCS-OpenLDAP-Objekt unter cn=dc,cn=computers bleibt unberührt. Und solange dc-vader als master im LDAP steht, setzt der Listener auf allen Member Servern beim Start ldap/server/name=dc-vader.darkside.lan.
Die Ursache
UCS hat zwei getrennte Verzeichnisse:
| Verzeichnis | Port | Inhalt | Geändert durch |
|---|---|---|---|
| Samba4 AD | 389 | AD-Objekte, Kerberos, GPOs | samba-tool domain demote |
| OpenLDAP (UCS) | 7389 | UCS-Computer-Objekte, Policies, UCR | udm computers/... |
samba-tool domain demote bereinigt das Samba-AD. Das UCS-OpenLDAP-Objekt (cn=dc-vader,cn=dc,cn=computers,... mit univentionServerRole=master) bleibt stehen. Das ist der blinde Fleck.
Der ldap_server.py Listener-Filter:
'(&(objectClass=univentionDomainController)(|(univentionServerRole=master)(univentionServerRole=backup)))'
…trifft weiterhin auf dc-vader zu. Beim Listener-Start auf dem Member Server wird ldap/server/name erneut auf dc-vader gesetzt — Policy-Cleanup hin oder her.
Die Lösung
1. Backup (immer!)
# Auf dc-obiwan:
ldapsearch -x -H ldap://localhost:7389 \
-D "cn=admin,dc=darkside,dc=lan" -w "$(cat /etc/ldap.secret)" \
-b "dc=darkside,dc=lan" \
"(|(cn=dc-vader)(univentionServerRole=master))" \
-LLL > /root/dc-vader-ldap-backup-$(date +%Y%m%d).ldif
2. UDM DC-Objekt entfernen
udm computers/domaincontroller_master remove \
--dn "cn=dc-vader,cn=dc,cn=computers,dc=darkside,dc=lan"
Object removed: cn=dc-vader,cn=dc,cn=computers,dc=darkside,dc=lan
3. Verifizieren: Nur noch aktive DCs
ldapsearch -x -H ldap://localhost:7389 \
-D "cn=admin,dc=darkside,dc=lan" -w "$(cat /etc/ldap.secret)" \
-b "cn=dc,cn=computers,dc=darkside,dc=lan" \
"(univentionServerRole=*)" dn univentionServerRole -LLL
Erwartung: Nur noch dc-obiwan (und eventuelle Replica DCs).
4. Listener auf dem Member Server neu starten
# Auf dem Member Server (z.B. srv-r2d2):
systemctl restart univention-directory-listener
sleep 15
ucr get ldap/server/name
# Erwartung: dc-obiwan.darkside.lan
5. Dienste neu starten und testen
ucr commit /etc/ldap/ldap.conf /etc/samba/smb.conf /etc/krb5.conf
systemctl restart winbind nmbd smbd
# Tests:
net ads testjoin # Join is OK
wbinfo -t # trust succeeded
wbinfo -i 'DARKSIDE+administrator' # Achtung: Winbind separator ist +, nicht \!
Lessons Learned
Checkliste nach einem UCS DC-Demote
Nach samba-tool domain demote IMMER prüfen:
[ ] UDM DC-Objekt des alten DC entfernen:
udm computers/domaincontroller_master remove --dn "cn=<alter-dc>,..."
[ ] LDAP-Policy prüfen und bereinigen:
udm policies/ldapserver list
→ Alle Referenzen auf den alten DC entfernen
[ ] Listener auf allen Member Servern neu starten:
systemctl restart univention-directory-listener
[ ] DNS-Bereinigung (SRV-Records!):
samba_dnsupdate --all-names
→ srvdc01-Einträge manuell aus _ldap._tcp, _kerberos._tcp entfernen
→ _domaincontroller_master._tcp für neuen DC anlegen
[ ] ucr get ldap/server/name auf Member Servern prüfen
Warum ucr set nicht hilft
ucr set ldap/server/name=... mit der Warnung W: overridden by scope "ldap" ist ein Symptom, kein Problem. Den UCR-Wert zu forcen würde beim nächsten Listener-Restart wieder überschrieben. Die Ursache (DC-Objekt im LDAP) muss behoben werden.
Winbind separator = +
In UCS-Member-Setups ist der Winbind-Separator standardmäßig +, nicht \. Also:
wbinfo -i 'DARKSIDE+administrator' # ✅ funktioniert
wbinfo -i 'DARKSIDE\administrator' # ❌ WBC_ERR_DOMAIN_NOT_FOUND
Das ist verwirrend, wenn man von reinen Windows-Umgebungen kommt.
Referenzen
- UCS Admin Guide: Domain Join
- Samba Wiki: Domain Demote
/usr/lib/univention-directory-listener/system/ldap_server.py— der Listener-Code erklärt das Verhalten vollständig