User Tools

Site Tools


samba:fsmo-roles

Check, Reassign and Seize FSMO Roles

All domain controllers (DCs) in an Active Directory infrastructure are identical except for one key difference. There are seven Active Directory Domain Controller Roles distributed among the DCs. Typically, one DC will have all seven roles, but this is not a requirement. Any DC can have any role. These roles are transferable and can be seized if needed — for example, from a dead server.

If you have never transferred these roles, the first DC you provisioned your Active Directory with will own all FSMO roles.

See this for a more complete description of Flexible Single-Master Operations.

Show Me the FSMO Roles

For now, all we want to know is who owns these roles.

samba-tool fsmo show | cut -f1-2 -d,
SchemaMasterRole owner: CN=NTDS Settings,CN=DC1
InfrastructureMasterRole owner: CN=NTDS Settings,CN=DC1
RidAllocationMasterRole owner: CN=NTDS Settings,CN=DC1
PdcEmulationMasterRole owner: CN=NTDS Settings,CN=DC1
DomainNamingMasterRole owner: CN=NTDS Settings,CN=DC1
DomainDnsZonesMasterRole owner: CN=NTDS Settings,CN=DC1
ForestDnsZonesMasterRole owner: CN=NTDS Settings,CN=DC1

Transferring the FSMO Roles

If we need to transfer the roles (for example, if we are going to demote the DC that owns the FSMO roles), execute this from another DC:

Please note: Administrator password is required to transfer 'domaindns' and 'forestdns'.

samba-tool fsmo transfer --role=all -U "MAD\Administrator"
 
FSMO transfer of 'rid' role successful
FSMO transfer of 'pdc' role successful
FSMO transfer of 'naming' role successful
FSMO transfer of 'infrastructure' role successful
FSMO transfer of 'schema' role successful
 
Password for [MAD\Administrator]:
 
FSMO transfer of 'domaindns' role successful
FSMO transfer of 'forestdns' role successful

Seizing the Roles from a Dead Server

If you have a dead DC, you can “seize” the roles from another DC.

samba-tool fsmo seize --role=all -U "MAD\Administrator"

If you have a dead DC, you also need to remotely demote it.

Do not reconnect a server that has been remotely demoted or had its FSMO roles seized, as this will break your AD.

One PdcEmulationMasterRole owner, one DNS Record

When the PDC Emulator role is transferred to another domain controller, a new DNS record is generated. Samba does not remove the previous PDC Emulator entry from DNS. If DC1 held the PDC Emulator role and it has been transferred to DC2, two records will exist.

host -t SRV _ldap._tcp.pdc._msdcs.mad.caponato.es
 
_ldap._tcp.pdc._msdcs.mad.caponato.es has SRV record 0 100 389 dc1.mad.caponato.es.
_ldap._tcp.pdc._msdcs.mad.caponato.es has SRV record 0 100 389 dc2.mad.caponato.es.

After transferring or assigning FSMO roles, ensure that only one DNS record exists for the PDC Emulator role. To achieve this, delete all other entries by editing DNS with tools like RSAT from Windows.

If you're temporarily transferring roles to upgrade Samba on a DC, make sure to update DNS after completing the upgrade and transferring roles back.

I use this script to automatically check the PdcEmulationMasterRole owner and remove older PDC DNS entries

This can be included as part of your DC maintenance.

Note: In July 2025, this script was updated by Rowland Penny. It’s genuinely an honour that someone of Rowland Penny’s calibre, a recognised member of the Samba Team and a key contributor to its documentation and community support, took the time to refine this script. His version not only improves robustness and portability but also reflects a deep understanding of Samba’s inner workings and best practices. I’m flattered that an expert of his standing considered my original work worth enhancing and sharing.

Rowland’s version introduces dynamic domain detection instead of hardcoding values, adds root privilege checks, and uses a more robust approach to handle DNS records with arrays and clear conditions for no, correct, or incorrect entries. It also switches to Kerberos authentication (-P) instead of username/password, improves error handling, and makes the script portable and safer to run in different Samba environments.

Enjoy:

#!/bin/bash
# del_pdc_rec.sh by Rowland Penny
 
# This is my version of a script by Luis Peromarta
# The original can be found here:
# http://samba.bigbird.es/doku.php?id=samba:fsmo-roles
 
# make sure this is being run by root or with sudo
if [ "$(whoami)" != "root" ]; then
	echo "$(basename "$0") must be run by root or with sudo"
	exit 1
fi
 
# Define domain variables
DNS_DOMAIN="$(hostname -d)"
if [ -z "$DNS_DOMAIN" ]; then
	echo "Cannot obtain DNS domain."
	exit 1
fi
ZONE="_msdcs.$DNS_DOMAIN"
 
# Get the current PDC Emulator DC, extract server name, ensure it is in lowercase
PDC_EMULATOR=$(samba-tool fsmo show | grep 'PdcEmulationMasterRole' | awk -F, '{print $2}' | cut -d= -f2 | tr '[:upper:]' '[:lower:]')
if [ -z "$PDC_EMULATOR" ]; then
	echo "Cannot find DC with PDC_Emulator FSMO role."
	exit 2
fi
echo "DC with PDC_Emulator FSMO role: $PDC_EMULATOR.$DNS_DOMAIN"
 
# Check DNS SRV records specifically for the PDC emulator and format nicely
echo "Checking DNS SRV records for the PDC Emulator..."
DNS_SRV_RECORDS=()
mapfile -t DNS_SRV_RECORDS < <(host -t SRV _ldap._tcp.pdc."$ZONE" | awk '{print $NF}' | awk -F '.' '{print $1}')
if [ "${#DNS_SRV_RECORDS[@]}" -eq 0 ]; then
	# no PDC_Emulator dns record found, samba_dnsupdate should create one shortly
	# so do nothing
	echo "no records found"
	exit 0
elif [ "${#DNS_SRV_RECORDS[@]}" -eq 1 ] && [ "${DNS_SRV_RECORDS[0]}" = "$PDC_EMULATOR" ]; then
	# only one, correct record, do nothing
	echo "correct record found"
	exit 0
fi
 
# Output DNS SRV entries
printf "Found '%s' DNS SRV records:\\n" "${#DNS_SRV_RECORDS[@]}"
printf '%s\n' "${DNS_SRV_RECORDS[@]}"
 
for DC in "${DNS_SRV_RECORDS[@]}" ; do
	if [ "$DC" != "$PDC_EMULATOR" ]; then
		echo "Incorrect DNS entry found: '$DC.$DNS_DOMAIN' : Deleting..."
		# Use samba-tool to delete the incorrect DNS entry
		samba-tool dns delete "$PDC_EMULATOR"."$DNS_DOMAIN" "$ZONE" _ldap._tcp.pdc SRV "$DC.$DNS_DOMAIN 389 0 100" -P >/dev/null 2>&1
		ret=$?
		if [ $ret -eq 0 ]; then
			echo "Successfully deleted incorrect DNS entry: $DC.$DNS_DOMAIN"
		else
			echo "Failed to delete DNS entry: $DC.$DNS_DOMAIN"
		fi
	fi
done
 
echo "PDC Emulator and DNS validation completed."
 
exit 0

Run the script like this:

root@dc1:~/bin# ./del_pdc_rec.sh 
DC with PDC_Emulator FSMO role: dc2.mad.caponato.es
Checking DNS SRV records for the PDC Emulator...
Found '2' DNS SRV records:
dc1
dc2
Incorrect DNS entry found: 'dc1.mad.caponato.es' : Deleting...
Successfully deleted incorrect DNS entry: dc1.mad.caponato.es
PDC Emulator and DNS validation completed.

Warning: If you run the script immediately after transferring the FSMO roles, there can be a short delay before the new PDC Emulator DNS record is created. This happens because samba_dnsupdate may not yet have refreshed the DNS zone with the updated role holder. During this brief window, the script might report no PDC Emulator record or appear as if there is no valid PDC, even though the transfer itself completed correctly. For example, after transferring the role back to dc1, running the script may produce:

root@dc1:~/bin# ./del_pdc_rec.sh 
DC with PDC_Emulator FSMO role: dc1.mad.caponato.es
Checking DNS SRV records for the PDC Emulator...
Found '2' DNS SRV records:
dc2
Incorrect DNS entry found: 'dc2.mad.caponato.es' : Deleting...
Successfully deleted incorrect DNS entry: dc2.mad.caponato.es
PDC Emulator and DNS validation completed.

Immediately after the FSMO role transfer, samba_dnsupdate hasn’t yet created the new SRV record for dc1, so the script sees:

  • The old record for dc2 (incorrect)
  • No record yet for dc1 (because it hasn’t been created by samba_dnsupdate)

As a result, when the script runs, it deletes what appears to be the “incorrect” record — but once samba_dnsupdate runs a few minutes later, the correct record for dc1 will be created automatically and everything will normalise.

This is my old script, left here for historic reasons. Use the one above.

#!/bin/bash
# del_pdc_rec.sh by Luis Peromarta
 
# Define domain variables
DOMAIN="mad.caponato.es"
ZONE="_msdcs.$DOMAIN"
SAMBA_USER="administrator"  # Define the username to execute the samba-tool command
BASE_DN="dc=mad,dc=caponato,dc=es"
 
# Get the PDC Emulator DC, extract server name, convert to lowercase
PDC_EMULATOR=$(samba-tool fsmo show | grep 'PdcEmulationMasterRole' | awk -F, '{print $2}' | cut -d= -f2 | tr '[:upper:]' '[:lower:]')
echo "PDC Emulator (lowercase): $PDC_EMULATOR"
 
# Set SAMBA_SERVER to the PDC Emulator
SAMBA_SERVER=$PDC_EMULATOR
echo "SAMBA Server (PDC Emulator): $SAMBA_SERVER"
 
# Check DNS SRV records specifically for the PDC emulator and format nicely
echo "Checking DNS SRV records for the PDC Emulator..."
DNS_SRV_RECORDS=$(host -t SRV _ldap._tcp.pdc.$ZONE | awk '/has SRV record/ {print $NF}' | sed 's/.$//' | tr '[:upper:]' '[:lower:]')
 
# Output DNS SRV entries
echo "Found DNS SRV records:"
echo "$DNS_SRV_RECORDS"
 
# Loop through DNS SRV records and compare hostnames with the PDC Emulator
for DNS_ENTRY in $DNS_SRV_RECORDS; do
    # Extract just the hostname from the DNS entry
    DNS_HOSTNAME=$(echo "$DNS_ENTRY" | cut -d. -f1)
 
    if [ "$DNS_HOSTNAME" != "$PDC_EMULATOR" ]; then
        echo "Incorrect DNS entry found: $DNS_ENTRY. Deleting..."
 
        # Use samba-tool to delete the incorrect DNS entry with the correct format
        samba-tool dns delete $SAMBA_SERVER.$DOMAIN $ZONE _ldap._tcp.pdc SRV "$DNS_ENTRY 389 0 100" -U $SAMBA_USER
        if [ $? -eq 0 ]; then
            echo "Successfully deleted incorrect DNS entry: $DNS_ENTRY"
        else
            echo "Failed to delete DNS entry: $DNS_ENTRY"
        fi
    else
        echo "Correct DNS entry: $DNS_ENTRY"
    fi
done
 
echo "PDC Emulator and DNS validation completed."

Caponato's Samba notebook. Start here or return to Main menu.

samba/fsmo-roles.txt · Last modified: by caponato