Problem
In a school environment, DNS resolution of Windows clients via dig or nslookup no longer worked because the corresponding A record from the local DNS zone of the respective organizational unit (school) could not be resolved.
What was unusual was that not all Windows clients were affected, but rather many individual systems sporadically.
root@:~# dig CLIENT01.example.intranet
; <<>> DiG 9.18.x <<>> CLIENT01.example.intranet
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 26325
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;CLIENT01.example.intranet. IN A
;; AUTHORITY SECTION:
example.intranet. 3600 IN SOA .example.intranet. root.example.intranet. 47582 28800 7200 604800 3600
;; Query time: 0 msec
Root Cause
The affected clients and computer objects still existed in both the local LDAP directory and the local Samba database. What was missing were the A records of the affected clients. As a result, the systems could no longer be resolved via dig or nslookup.
root@:~# samba-tool dns query localhost example.intranet CLIENT01 A -P
ERROR(runtime): Record or zone does not exist. [WERR_DNS_ERROR_NAME_DOES_NOT_EXIST]
The reason for the missing A records was a Group Policy Object (GPO) configuration in the environment that disabled Dynamic DNS (DDNS) updates for Windows clients.
With this configuration enabled:
- Windows clients could no longer perform DDNS updates
- No DNS updates were sent to the configured Samba Domain Controller
- Samba no longer received network-specific updates from clients
As a result, the DNS records in Samba became outdated or disappeared entirely.
Solution
The easiest and recommended solution is to allow DDNS updates again for Windows clients so that DNS records are continuously refreshed.
The corresponding GPO setting is located here:
Computer Configuration
└── Administrative Templates
└── Network
└── DNS Client
└── Dynamic Update = Enabled
Investigation
The issue was investigated in more detail to understand why DNS resolution via dig failed for specific clients.
The local LDAP directory still contained both:
- the computer object
- the DNS object
However, Samba only contained the computer object, while the DNS record itself was missing.
Since the environment used dns/backend=samba, successful DNS resolution required the records to exist in the Samba DNS database.
Below is an example of the DNS record in the local LDAP directory:
root@:~# univention-ldapsearch -LLL relativeDomainName=CLIENT01
dn: relativeDomainName=CLIENT01,zoneName=example.intranet,cn=dns,dc=example,dc=intranet
objectClass: dNSZone
objectClass: univentionObject
objectClass: top
univentionObjectType: dns/host_record
zoneName: example.intranet
aRecord: 10.10.10.20
relativeDomainName: CLIENT01
The Samba DNS query showed that the DNS record did not exist in Samba:
root@:~# samba-tool dns query localhost example.intranet CLIENT01 A -P
ERROR(runtime): Record or zone does not exist. [WERR_DNS_ERROR_NAME_DOES_NOT_EXIST]
Example output of a correctly existing DNS record:
root@:~# ldbsearch -H /var/lib/samba/private/sam.ldb --cross-ncs "dc=CLIENT02"
# record 1
dn: DC=CLIENT02,DC=example.intranet,CN=MicrosoftDNS,DC=DomainDnsZones,DC=example,DC=intranet
objectClass: top
objectClass: dnsNode
instanceType: 4
whenCreated: 20250101010101.0Z
whenChanged: 20250101010101.0Z
dnsRecord:: BAABAAXwAAABAAAAAAADhAAAAAAAAAAACkUgXA==
dc: CLIENT02
The DNS record was resolvable correctly:
root@:~# samba-tool dns query localhost example.intranet CLIENT02 A -P
Name=, Records=1, Children=0
A: 10.10.10.21 (flags=f0, serial=1, ttl=900)
Verification of DNS Scavenging
It was verified whether DNS scavenging had been configured on the Samba Domain Controller.
This configuration was not enabled:
root@:~# testparm -sv | grep scav
dns zone scavenging = No
This raised the question:
Why were the A records automatically removed from Samba over time?
Why the DNS Records Were Removed
Samba 4 does not automatically delete DNS records in its default configuration unless DNS scavenging is enabled.
If records disappear sporadically, an active delete operation must have been sent directly to Samba.
The Role of Timestamps (whenCreated vs. dnsRecord)
In Active Directory and Samba 4, two completely different timestamp mechanisms exist for DNS entries.
Administrative LDAP Metadata
The following attributes are administrative metadata only:
whenCreatedwhenChanged
These values only indicate when the LDAP object was created or modified.
They have no influence on DNS aging or DNS record cleanup.
Internal DNS Timestamp (dwTimeStamp)
The actual DNS information is stored in the binary dnsRecord attribute.
Inside this attribute, Samba stores an internal timestamp measured in hours since the year 1601.
0→ static DNS record>0→ dynamic DNS record
Since the affected Windows clients previously used DDNS before the GPO was applied, the records were stored in Samba as dynamic DNS entries with valid timestamps.
The Windows “Active Unregister” Effect
Disabling DDNS via GPO does not always prevent Windows from sending DNS delete requests.
The Windows DNS Client service (Dnscache) may still send deregistration requests during:
- system shutdown
- DHCP lease release
- network changes
- switching between LAN and WLAN
In these cases, Windows sends a DNS DELETE update to the Samba Domain Controller.
Samba accepts the request and marks the DNS object as tombstoned.
The OpenLDAP directory is unaware of this deletion because the update bypasses the S4 Connector entirely.
Why This Happens Even Though DDNS Was Disabled
One would expect:
“If DDNS is disabled via GPO, Windows should stop sending any DNS updates.”
However, Windows networking behaves differently internally.
There are two documented scenarios where Windows still sends DNS DELETE updates.
1. Cleanup Behavior When the GPO Becomes Active
When the GPO disables DNS registration, Windows detects that:
- it may no longer register itself in DNS
- but an older dynamic DNS record still exists
To prevent stale DNS entries from remaining in the environment, Windows performs a final cleanup operation.
The DNS Client service sends a DNS DELETE request for its own A record to the configured DNS server.
Since future DDNS registrations are blocked by the GPO, the record disappears permanently.
2. DHCP Client Interaction (Option 81)
The GPO mainly affects the Windows DNS Client service.
However, DHCP interactions remain relevant.
Windows clients negotiate DNS update responsibilities using DHCP Option 81 (Client FQDN).
When:
- a DHCP lease expires
- the client shuts down cleanly
- the network changes
the DHCP subsystem may trigger a DNS deregistration process.
Depending on the DHCP configuration:
- either the client itself
- or the DHCP server on behalf of the client
sends a DNS DELETE request to Samba.
For more Information:
Why the Problem Appeared Sporadically
This behavior explains why the problem occurred only gradually over time.
Sequence of events:
- The GPO disabling DDNS was deployed.
- Not all clients processed the GPO simultaneously.
- DNS records only disappeared after specific network events occurred.
- Samba removed the records after receiving DELETE requests.
- LDAP still retained the original DNS objects.
This resulted in an inconsistent state between LDAP and Samba DNS.
Tombstoned DNS Objects
The deleted DNS records appeared in Samba as tombstoned objects:
root@:~# univention-s4search --cross-ncs dNSTombstoned=TRUE
dn: DC=CLIENT01,DC=example.intranet,CN=MicrosoftDNS,DC=DomainDnsZones,DC=example,DC=intranet
After some time, Samba permanently removed the tombstoned objects because no new DDNS updates recreated them.
Example Samba log output:
/var/log/samba/log.samba: dns_delete_tombstones: The tombstoned dns node DC=CLIENT01,DC=univention.de,CN=MicrosoftDNS,DC=DomainDnsZones,DC=univention,DC=de has 2 dns records, expected one.
/var/log/samba/log.samba: dns_delete_tombstones: The tombstoned dns node DC=CLIENT01,DC=univention.de,CN=MicrosoftDNS,DC=DomainDnsZones,DC=univention,DC=de has 2 dns records, expected one.
S4 Connector
A related issue may also affect recovery of tombstoned DNS objects from the S4-Connector.
The following fix may help restore tombstoned objects through the S4 Connector if DDNS is enabled again on the Windows clients.
- UCS 5.2 Erratum 408
Related bug report:
Conclusion
Re-enabling DDNS was the correct solution.
Windows clients in Active Directory environments are designed to manage their DNS records dynamically.
Disabling DDNS without implementing an alternative DNS lifecycle strategy inevitably leads to:
- inconsistent Samba DNS records
- tombstoned DNS objects
- stale LDAP entries
- failed DNS resolution
Additional Notes
The following Bash script can be used to compare DNS records stored in LDAP with records available in Samba DNS.
If a record is missing in Samba, it is recreated automatically.
Important:
The script only restores missing records in the Samba DB.
It does not solve the underlying issue caused by disabled DDNS.
If DDNS remains disabled, records may disappear again later.
#!/bin/bash
# 1. Determine UCS domain
DOMAIN=$(ucr get domainname)
if [ -z "$DOMAIN" ]; then
echo "Failed to determine UCS domain."
exit 1
fi
# 2. Ask for Administrator password (needed for samba-tool dns)
read -s -p "Enter UCS Administrator password: " ADMIN_PASS
echo ""
echo "Starting synchonization for domain: $DOMAIN"
echo "---------------------------------------------------"
# 3. Univention-ldapsearch for aRecords from Windows Clients
# We filter directly for the required attributes 'cn' and 'aRecord'
univention-ldapsearch -LLL "(&(objectClass=univentionWindows)(aRecord=*))" cn aRecord | awk '
/^dn:/ { cn=""; ip="" }
/^cn:/ { cn=$2 }
/^aRecord:/ { ip=$2; print cn, ip }
' | while read -r HOSTNAME IP; do
# Catch empty variables (in case parsing errors occur)
if [ -z "$HOSTNAME" ] || [ -z "$IP" ]; then
continue
fi
# 4. Check whether the record is already resolvable in the local DNS (Samba)
EXISTING_IP=$(dig @localhost +short "$HOSTNAME.$DOMAIN" A)
if [ "$EXISTING_IP" == "$IP" ]; then
echo "[OK] $HOSTNAME ($IP) already exists in Samba DNS. Skipping."
elif [ -n "$EXISTING_IP" ]; then
echo "[WARNUNG] $HOSTNAME Exists in Samba DNS, but has a different IP ($EXISTING_IP instead $IP). Skipping."
else
echo "[ADD] Add $HOSTNAME ($IP) to Samba-DNS"
# 5. Add entry via samba-tool
samba-tool dns add localhost "$DOMAIN" "$HOSTNAME" A "$IP" -U "Administrator" --password="$ADMIN_PASS"
# Check if successful
if [ $? -eq 0 ]; then
echo " -> Added successfully."
else
echo " -> Failure while adding from $HOSTNAME."
fi
fi
done
echo "---------------------------------------------------"
echo "Finished the Run."