Problem
On a UCS@school Replica Node, the join script 96univention-samba4slavepdc.inst does not complete successfully.
The following output can be found in /var/log/univention/join.log:
RUNNING 96univention-samba4slavepdc.inst
2026-04-16 12:34:44.032879903+02:00 (in joinscript_init)
Object exists: cn=Builtin,dc=intern,dc=univention,dc=de
The relative ID (SAMBA) is already in use: 556.
EXITCODE=3
98da3c94-922c-4f32-b431-e5b31675777b
univention-join-hooks: looking for hook type "join/post-joinscripts" on ucs-primary.intern.univention.de
Found hooks:
Do 16. Apr 12:34:46 CEST 2026
univention-run-join-scripts finished
Root Cause
The issue is caused by a previous Active Directory (AD) takeover, where a German Microsoft AD environment was migrated into UCS LDAP using the ad-takeover application.
During this process, both German and English group names were imported, resulting in conflicting Relative IDs (RIDs).
The following log entry indicates the conflict:
Object exists: cn=Builtin,dc=intern,dc=univention,dc=de
The relative ID (SAMBA) is already in use: 556.
Further details are documented in the following bug report, which describes the same behavior:
https://forge.univention.org/bugzilla/show_bug.cgi?id=55911
Environment
root@ucs-primary:~/univention-support# univention-app info
UCS: 5.2-4 errata349
Installed: adtakeover=9.0 samba4=4.21 ucsschool=5.2v4
Investigation
To identify affected objects, perform an LDAP search for all entries below cn=Builtin:
univention-ldapsearch -LLL -b "cn=Builtin,$(ucr get ldap/base)" | less
A follow-up search for RID 556 confirms the issue described in the bug report:
dn: cn=Netzwerkkonfigurations-Operatoren,cn=Builtin,dc=intern,dc=univention,dc=de
gidNumber: 5062
sambaGroupType: 2
univentionGroupType: -2147483643
sambaSID: S-1-5-32-556
objectClass: posixGroup
objectClass: top
objectClass: univentionObject
objectClass: univentionGroup
objectClass: sambaGroupMapping
univentionObjectType: groups/group
cn: Netzwerkkonfigurations-Operatoren
Workaround
Until an official fix is released, the following workaround can be applied.
The workaround replaces the failing join script with a modified version that tolerates pre-existing objects.
1. Backup the existing join script
mv /usr/lib/univention-install/96univention-samba4slavepdc.inst /usr/lib/univention-install/96univention-samba4slavepdc.inst.bak
2. Create a new join script with the same name
touch /usr/lib/univention-install/96univention-samba4slavepdc.inst
3. Insert the following content into the new join script
#!/bin/bash
#
# Univention Samba4 Replica Directory Node PDC helper
# join script
#
# SPDX-FileCopyrightText: 2013-2026 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only
## joinscript api: bindpwdfile
VERSION=3
. /usr/share/univention-join/joinscripthelper.lib
joinscript_init
. /usr/share/univention-lib/all.sh
. /usr/share/univention-samba4/lib/all.sh
NAME="S4 SlavePDC"
eval "$(univention-config-registry shell)"
# This join script is a Workaround for Bug #30105:
# This code was copied from UCS 3.1-0 98univention-samba4-dns.inst
# samba4 allowed on this system?
if is_ucr_true samba4/disabled; then
echo "WARNING: samba4 on this system is not allowed."
echo " The samba4 join stops here. To rerun the"
echo " join script, use "
echo " -> univention-run-join-scripts"
exit 0
fi
is_school_slave ()
{
local ldap_hostdn="$(ucr get ldap/hostdn)"
univention-ldapsearch -LLL -b "$ldap_hostdn" "(&(univentionService=UCS@school)(univentionServerRole=slave))" dn | grep -qi "^dn:"
}
if ! is_school_slave; then
# This join script should only run on a UCS@school Replica Directory Node
# See bug 47234.
echo "INFO: This system is not a UCS@school Replica Directory Node."
joinscript_save_current_version
exit 0
fi
## Check if Samba 4 setup is done
LDB_URI="tdb:///var/lib/samba/private/sam.ldb"
domaindn="DC=${kerberos_realm//./,DC=}" # that's what /usr/share/pyshared/samba/provision.py uses
if ! ldbsearch -H "$LDB_URI" -b "$domaindn" -s base dn 2>/dev/null| grep -qi ^"dn: $domaindn"; then
echo "Samba4 backend database not available yet, exiting joinscript $(basename "$0")."
exit 1
fi
_create_default_s4_groups ()
{
udm container/cn create "$@" --set name=Builtin --ignore_exists || die
udm groups/group create "$@" --set name="$(custom_groupname "Network Configuration Operators")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members in this group can have some administrative privileges to manage configuration of networking features" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="556" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Read-Only Domain Controllers")" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--set description="Members of this group are Read-Only Domain Controllers in the domain" \
--set sambaGroupType="2" \
--set adGroupType="-2147483646" \
--set sambaRID="521" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Remote Desktop Users")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members in this group are granted the right to logon remotely" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="555" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Distributed COM Users")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members are allowed to launch, activate and use Distributed COM objects on this machine." \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="562" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Pre-Windows 2000 Compatible Access")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="A backward compatibility group which allows read access on all users and groups in the domain" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="554" ||die
udm groups/group create "$@" --set name="$(custom_groupname "RAS and IAS Servers")" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--set description="Servers in this group can access remote access properties of users" \
--set sambaGroupType="2" \
--set adGroupType="-2147483644" \
--set sambaRID="553" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Enterprise Admins")" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--append users="uid=$(custom_username Administrator),cn=users,$ldap_base" \
--set description="Designated administrators of the enterprise" \
--set sambaGroupType="2" \
--set adGroupType="-2147483640" \
--set sambaRID="519" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Account Operators")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members can administer domain user and group accounts" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="548" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Terminal Server License Servers")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members of this group can update user accounts in Active Directory with information about license issuance, for the purpose of tracking and reporting TS Per User CAL usage" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="561" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Domain Controllers")" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--set description="All domain controllers in the domain" \
--set sambaGroupType="2" \
--set adGroupType="-2147483646" \
--set sambaRID="516" ||die
udm groups/group modify "$@" --dn "cn=$(custom_groupname "Domain Controllers"),cn=groups,$ldap_base" \
--append hosts="$ldap_hostdn"
udm groups/group create "$@" --set name="$(custom_groupname "Server Operators")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members can administer domain servers" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="549" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Cert Publishers")" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--set description="Members of this group are permitted to publish certificates to the directory" \
--set sambaGroupType="2" \
--set adGroupType="-2147483644" \
--set sambaRID="517" ||die
udm groups/group create "$@" --set name="DnsUpdateProxy" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--set description="DNS clients who are permitted to perform dynamic updates on behalf of some other clients (such as DHCP servers)." \
--set sambaGroupType="2" \
--set adGroupType="-2147483646" \
--set sambaRID="1102" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Performance Monitor Users")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members of this group can access performance counter data locally and remotely" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="558" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Guests")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--append nestedGroup="cn=$(custom_groupname "Domain Guests"),cn=groups,$ldap_base" \
--set description="Guests have the same access as members of the Users group by default, except for the Guest account which is further restricted" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="546" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Certificate Service DCOM Access")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members of this group are allowed to connect to Certification Authorities in the enterprise" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="574" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Schema Admins")" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--append users="uid=$(custom_username Administrator),cn=users,$ldap_base" \
--set description="Designated administrators of the schema" \
--set sambaGroupType="2" \
--set adGroupType="-2147483640" \
--set sambaRID="518" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Enterprise Read-Only Domain Controllers")" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--set description="Members of this group are Read-Only Domain Controllers in the enterprise" \
--set sambaGroupType="2" \
--set adGroupType="-2147483640" \
--set sambaRID="498" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Replicator")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Supports file replication in a domain" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="552" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Domain Computers")" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--set description="All workstations and servers joined to the domain" \
--set sambaGroupType="2" \
--set adGroupType="-2147483646" \
--set sambaRID="515" ||die
udm groups/group create "$@" --set name="DnsAdmins" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--set description="DNS Administrators Group" \
--set sambaGroupType="2" \
--set adGroupType="-2147483644" \
--set sambaRID="1101" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Windows Authorization Access Group")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members of this group have access to the computed tokenGroupsGlobalAndUniversal attribute on User objects" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="560" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Incoming Forest Trust Builders")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members of this group can create incoming, one-way trusts to this forest" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="557" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Event Log Readers")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members of this group can read event logs from local machine" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="573" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Group Policy Creator Owners")" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--set description="Members in this group can modify group policy for the domain" \
--set sambaGroupType="2" \
--set adGroupType="-2147483646" \
--set sambaRID="520" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Performance Log Users")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members of this group may schedule logging of performance counters, enable trace providers, and collect event traces both locally and via remote access to this computer" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="559" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Administrators")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--append users="uid=$(custom_username Administrator),cn=users,$ldap_base" \
--append nestedGroup="cn=$(custom_groupname "Domain Admins"),cn=groups,$ldap_base" \
--append nestedGroup="cn=$(custom_groupname "Enterprise Admins"),cn=groups,$ldap_base" \
--set description="Administrators have complete and unrestricted access to the computer/domain" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="544" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Allowed RODC Password Replication Group")" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--set description="Members in this group can have their passwords replicated to all read-only domain controllers in the domain" \
--set sambaGroupType="2" \
--set adGroupType="-2147483644" \
--set sambaRID="571" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Users")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--append nestedGroup="cn=$(custom_groupname "Domain Users"),cn=groups,$ldap_base" \
--set description="Users are prevented from making accidental or intentional system-wide changes and can run most applications" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="545" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Backup Operators")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Backup Operators can override security restrictions for the sole purpose of backing up or restoring files" \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="551" ||die
udm groups/group create "$@" --set name="$(custom_groupname "IIS_IUSRS")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Built-in group used by Internet Information Services." \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="568" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Denied RODC Password Replication Group")" \
--ignore_exists \
--position "cn=groups,$ldap_base" \
--append users="uid=krbtgt,cn=users,$ldap_base" \
--append nestedGroup="cn=$(custom_groupname "Read-only Domain Controllers"),cn=groups,$ldap_base" \
--append nestedGroup="cn=$(custom_groupname "Group Policy Creator Owners"),cn=groups,$ldap_base" \
--append nestedGroup="cn=$(custom_groupname "Domain Admins"),cn=groups,$ldap_base" \
--append nestedGroup="cn=$(custom_groupname "Cert Publishers"),cn=groups,$ldap_base" \
--append nestedGroup="cn=$(custom_groupname "Enterprise Admins"),cn=groups,$ldap_base" \
--append nestedGroup="cn=$(custom_groupname "Schema Admins"),cn=groups,$ldap_base" \
--append nestedGroup="cn=$(custom_groupname "Domain Controllers"),cn=groups,$ldap_base" \
--set description="Members in this group cannot have their passwords replicated to any read-only domain controllers in the domain" \
--set sambaGroupType="2" \
--set adGroupType="-2147483644" \
--set sambaRID="572" ||die
udm groups/group create "$@" --set name="$(custom_groupname "Cryptographic Operators")" \
--ignore_exists \
--position "cn=Builtin,$ldap_base" \
--set description="Members are authorized to perform cryptographic operations." \
--set sambaGroupType="2" \
--set adGroupType="-2147483643" \
--set sambaRID="569" ||die
}
_update_groups ()
{
users_default_administrator=$(custom_username "Administrator")
groups_default_domainadmins=$(custom_groupname "Domain Admins")
groups_default_domainusers=$(custom_groupname "Domain Users")
groups_default_domainguests=$(custom_groupname "Domain Guests")
udm groups/group modify "$@" --dn "cn=$groups_default_domainguests,cn=groups,$ldap_base" --set description='All domain guests'
udm groups/group modify "$@" --dn "cn=$groups_default_domainusers,cn=groups,$ldap_base" --set description='All domain users'
udm groups/group modify "$@" --dn "cn=$groups_default_domainadmins,cn=groups,$ldap_base" --set description='Designated administrators of the domain'
udm users/user modify "$@" --dn "uid=$users_default_administrator,cn=users,$ldap_base" --set description='Built-in account for administering the computer/domain'
udm groups/group modify "$@" --dn "cn=$(custom_groupname "Group Policy Creator Owners"),cn=groups,$ldap_base" --append users="uid=$users_default_administrator,cn=users,$ldap_base"
}
_update_container ()
{
udm container/cn create "$@" --ignore_exists --set name=System
udm container/cn modify "$@" --dn "cn=System,$ldap_base" --set description='Builtin system settings'
udm container/cn create "$@" --ignore_exists --set name='Managed Service Accounts' --set description='Default container for managed service accounts'
udm container/cn create "$@" --ignore_exists --set name='PSPs' --position "cn=System,$ldap_base"
}
_create_default_s4_groups "$@"
_update_groups "$@"
_update_container "$@"
ucs_addServiceToLocalhost "${NAME}" "$@"
joinscript_save_current_version
exit 0
4. Make the script executable
chmod +x /usr/lib/univention-install/96univention-samba4slavepdc.inst
5. Re-run the join script
univention-run-join-scripts --run-scripts --force 96univention-samba4slavepdc.inst
Summary
This issue is caused by RID conflicts introduced during an AD takeover with mixed-language group names.
The workaround replaces the failing join script with a modified version that tolerates pre-existing objects.
This approach should only be used as a temporary solution until an official fix is provided.