Initiation
This article describes how the domain join mechanism of a Windows client works within a UCS@school domain. Beyond the user-facing process on the Windows client, this guide focuses on the underlying backend execution.
It covers the relevant modules, triggers, and execution flows on both the responsible School Replica Directory Node and the UCS Primary Directory Node. Additionally, it details how Samba detects a new computer, how UCS@school validates the requesting user’s permissions, and how the computer account is created within the correct school Organizational Unit (OU).
1. What Does “Joining a Windows Client to the Domain” Mean?
During a domain join, a Windows client becomes a managed member of the UCS@school domain. To achieve this, the system requires a dedicated computer account within the directory. This account is separate from the personal user account of the individual executing the join; it identifies the machine itself and is later used for machine trust relationships and domain service access.
From the user’s perspective, the operation appears as a standard Windows wizard. In the backend, however, it triggers a chain of dependent processes: authentication, LDAP communication, computer account verification, authorization of the joining user, object creation, and subsequent account utilization by Samba.
2. Participating Systems and Technical Terminology
Primary Directory Node
The Primary Directory Node serves as the central authority for directory data across the UCS domain. It holds the complete data set and acts as the target for central write operations in LDAP.
Replica Directory Node
A Replica Directory Node delivers local services for a specific school. In a UCS@school environment, only data relevant to the respective School OU is replicated to the local LDAP, maintaining operational isolation between schools.
During the join process, the Replica Node serves as the active entry point: the Windows client communicates with the local Samba service running on the school Replica. The Samba LDB module runs here and initiates the school-specific join sequence. Central LDAP creation is subsequently handled via an administrative directory connection to the Primary Directory Node.
LDAP and SamDB
LDAP acts as the primary directory interface for object queries and creation. For Active Directory functionality, Samba uses its own directory and database view (SamDB). In log outputs, this access is represented as Samba LDAP or SamDB operations.
Samba LDB Module
An LDB module allows inspection or modification of LDAP operations inside Samba. UCS@school activates the univention_samaccountname_ldap_check module to intercept and manage computer account creation.
UMC and UDM
The Univention Management Console (UMC) exposes administrative control interface commands. Univention Directory Manager (UDM) is the management abstraction layer used to provision directory objects such as Windows computers. The relevant UMC command is:
selectiveudm/create_windows_computer
univention-management-console-module-selective-udm/35univention-management-console-module-selective-udm.inst:umc_operation_create "selective-udm" "Domain management operations for Replica Directory Nodes with a selective replicated directory" "" "selectiveudm/create_windows_computer"
univention-management-console-module-selective-udm/umc/selective-udm.xml: <command name="selectiveudm/create_windows_computer" function="create_windows_computer" />
3. Custom Join Processing in UCS@school
In a standard Active Directory environment, Samba creates computer accounts directly inside a default central container. UCS@school must account for the organizational context of the target school.
Rather than placing the computer account arbitrarily in a global container, it must be provisioned inside the computer container of the corresponding School OU. Furthermore, account creation privileges are restricted. To enforce this, UCS@school combines three security controls:
- Target school context determination
- User SID and group membership verification
- Object provisioning via UDM at a pre-defined target path
4. Initial Processing: The LDAP Search
When a join is initiated, Samba first verifies whether the computer account already exists. A typical log entry appears as follows:
LDAP SearchRequest
dn=CN=CLIENT-01,CN=Computers,DC=deadpool,DC=intranet
result: No such object
In this context, No such object indicates that the account does not yet exist.
Samba then attempts to create the computer as a new object:
LDAP AddRequest
dn=CN=CLIENT-01,CN=Computers,DC=deadpool,DC=intranet
This Add request serves as the primary trigger for the subsequent UCS@school execution logic.
Excerpt from log.samba on the School Replica during a successful join sequence:
[2026/07/03 14:50:56.648017, 5, pid=12514, effective(0, 0), real(0, 0), class=ldapsrv] ../../source4/ldap_server/ldap_backend.c:836(ldapsrv_SearchRequest)
ldapsrv_SearchRequest: ldb_request BASE dn=CN=CLIENT-01,CN=Computers,DC=deadpool,DC=intranet filter=(ObjectClass=*)
[2026/07/03 14:50:56.648088, 5, pid=12514, effective(0, 0), real(0, 0), class=ldapsrv] ../../source4/ldap_server/ldap_backend.c:1049(ldapsrv_SearchRequest)
ldapsrv_SearchRequest: LDAP Query: Duration was 0.00s, SearchRequest by S-1-5-21-2115944803-654306598-698463119-500 from ipv4:10.150.2.61:49554 filter: [(ObjectClass=*)] basedn: [CN=CLIENT-01,CN=Computers,DC=deadpool,DC=intranet] scope: [BASE] result: No such object
[2026/07/03 14:50:56.648103, 10, pid=12514, effective(0, 0), real(0, 0), class=ldapsrv] ../../source4/ldap_server/ldap_backend.c:1083(ldapsrv_SearchRequest)
ldapsrv_SearchRequest: error
[2026/07/03 14:50:56.648433, 10, pid=12514, effective(0, 0), real(0, 0), class=ldapsrv] ../../source4/ldap_server/ldap_backend.c:1215(ldapsrv_AddRequest)
ldapsrv_AddRequest: dn: CN=CLIENT-01,CN=Computers,DC=deadpool,DC=intranet
[2026/07/03 14:50:56.648446, 10, pid=12514, effective(0, 0), real(0, 0), class=ldapsrv] ../../source4/ldap_server/ldap_backend.c:1223(ldapsrv_AddRequest)
ldapsrv_AddRequest: dn: [CN=CLIENT-01,CN=Computers,DC=deadpool,DC=intranet]
[2026/07/03 14:50:56.651750, 1, pid=13363, effective(0, 0), real(0, 0), class=ldb] ../../lib/ldb-samba/ldb_wrap.c:79(ldb_wrap_debug)
ldb: univention_samaccountname_ldap_check: calling ucs-school-create_windows_computer
The search uses scope: [BASE], causing Samba to query the exact DN provided. No such object confirms that CLIENT-01 does not exist, triggering the LDAP Add request. The final log line confirms that the LDB module on the Replica Node initiates the downstream UCS@school workflow:
ldb: univention_samaccountname_ldap_check: calling ucs-school-create_windows_computer
5. Handover to the LDB Module
On configured systems, the LDB module is registered via the Univention Configuration Registry (UCR) variable:
samba4/ldb/sam/module/prepend="univention_samaccountname_ldap_check"
The configuration setup is defined across repository packages as follows:
ucs-school-metapackage/62ucs-school-nonedu-replica.inst: samba4/ldb/sam/module/prepend="univention_samaccountname_ldap_check"
ucs-school-metapackage/62ucs-school-replica.inst: samba4/ldb/sam/module/prepend="univention_samaccountname_ldap_check"
ucs-school-metapackage/debian/ucs-school-singleserver.preinst: samba4/ldb/sam/module/prepend?"univention_samaccountname_ldap_check"
Module Purpose
Without this interception layer, Samba would create the client object inside the generic computer container. UCS@school must evaluate the target school context (School OU) and validate the joining user’s permissions.
The LDB module intercepts the relevant LDAP Add request and redirects execution to the UCS@school management path. It does not evaluate group memberships directly or generate the UDM object itself; rather, it identifies the operation and invokes the corresponding UCS@school handler.
The module source code is available in the official repository:
univention_samaccountname_ldap_check.c
ldb_debug(ldb, LDB_DEBUG_ERROR, ("%s: calling ucs-school-create_windows_computer\n"), ldb_module_get_name(module));
if (opt_unicodePwd != NULL) {
status = execl("/usr/sbin/ucs-school-create_windows_computer", "/usr/sbin/ucs-school-create_windows_computer", "-s", ldap_master, "-P", machine_pass, "-U", opt_my_samaccoutname, "selectiveudm/create_windows_computer", "-o", opt_name, "-o", opt_unicodePwd, "-o", "decode_password=yes", "-o", opt_usersid, NULL);
} else {
status = execl("/usr/sbin/ucs-school-create_windows_computer", "/usr/sbin/ucs-school-create_windows_computer", "-s", ldap_master, "-P", machine_pass, "-U", opt_my_samaccoutname, "selectiveudm/create_windows_computer", "-o", opt_name, "-o", opt_usersid, NULL);
}
if (status == -1) { // otherwise it wouldn't be here
ldb_debug(ldb, LDB_DEBUG_ERROR, ("%s: exec of /usr/sbin/ucs-school-create_windows_computer failed: %s\n"), ldb_module_get_name(module), strerror(errno));
}
_exit(status);
} else {
close(fd[1]); // close writing end
6. Execution Flow: LDB Module to UMC Command
Runtime logs document the transition:
univention_samaccountname_ldap_check:
calling ucs-school-create_windows_computer
The LDB module executes the helper binary:
/usr/sbin/ucs-school-create_windows_computer
This helper program acts as an intermediary. It accepts parameters extracted during the Samba process and invokes the UMC command selectiveudm/create_windows_computer.
The helper script source code is structured as follows:
ucs-school-create_windows_computer
options = dict(x.split('=', 1) for x in args.options)
options['school'] = SchoolSearchBase.getOU(ucr.get('ldap/hostdn', '')) or SchoolSearchBase.getOU(ucr.get('dhcpd/ldap/base', ''))
client = Client(args.server, args.username, args.password)
result = client.umc_command(args.command, options).result
already_exists = result.get('already_exists')
dn_ol = result.get('dn')
if not dn_ol:
# sys.exit(1)
sys.exit(0) # for compatibility with univention-management-console-module-selective-udm before 5.0.0-2
if samba4_addmachine == 'dummy':
sys.exit(3)
dn_s4 = dn_ol[:len(dn_ol) - len(ldap_base)] + samba4_ldap_base
print(dn_s4)
if already_exists:
sys.exit(4)
Both the LDB module and the helper execute locally on the School Replica. From there, the UMC command is dispatched containing the join parameters. The UMC handler uses an administrative write connection against the central directory database on the Primary Directory Node.
Passed parameters include the computer name, user SID, machine password, and encoded computer secret.
7. User Authorization via UMC Command and UCR Variable
The UMC command registration is defined in:
univention-management-console-module-selective-udm/umc/selective-udm.xml
Implementation details are located in:
univention-management-console-module-selective-udm/umc/python/selective-udm/__init__.py
The process resolves the user object using the provided user SID and checks its group assignments. Allowed groups are controlled via the UCR variable ucsschool/windows/join/groups, which defaults to Domain Admins.
univention-management-console-module-selective-udm/debian/univention-management-console-module-selective-udm.univention-config-registry-variables:[ucsschool/windows/join/groups]
univention-management-console-module-selective-udm/umc/python/selective-udm/__init__.py: allowed_groups = ucr.get("ucsschool/windows/join/groups", "Domain Admins").split(",")
univention-management-console-module-selective-udm/umc/python/selective-udm/__init__.py: "modified by setting the UCR variable ucsschool/windows/join/groups."
If the SID cannot be resolved, or if the user lacks membership in an authorized group, execution terminates.
8. Account Provisioning inside the School OU
Upon successful authorization, the system evaluates the school context. The UMC handler configures the target destination to point to the computer container of the target school:
ldap_position.setDn(search_base.computers)
univention-management-console-module-selective-udm/umc/python/selective-udm/__init__.py: ldap_position.setDn(search_base.computers)
The computers/windows UDM module is loaded to create the computer object. Computer names are normalized, stripping trailing $ symbols appended by legacy Samba implementations.
If the account exists, the command suppresses generic errors, returning the existing DN along with already_exists set to True.
9. Primary Node vs. Replica Node Processing
The Replica Directory Node handles the initial client request within the local school service context. The UMC command uses a read-only user connection for authorization and an administrative write connection for object creation, separating identity verification from administrative modification tasks.
Directory changes propagate from the Primary LDAP service to the School Replica via the Notifier/Listener replication system. Integration tests explicitly wait for replication completion before asserting object state or verifying attributes on the School Replica.
10. Verifying Join Success
Integration tests validate successful completion using two criteria:
- The computer account is queryable via
udm computers/windows list. - The machine account successfully authenticates to the
Samba SYSVOL shareusing its machine password.
This sequence confirms both LDAP object provisioning and operational availability within domain services.
11. Complete Execution Call Chain
Windows Client
|
| LDAP Search: Does the computer account exist?
v
Samba LDAP/SamDB
|
| LDAP Add: Create computer account request
v
univention_samaccountname_ldap_check
|
| Invokes ucs-school-create_windows_computer
v
UMC: selectiveudm/create_windows_computer
|
| Validates SID and group memberships
| Resolves target School OU
| Invokes UDM computers/windows.create()
v
Computer account created in School OU
|
| Directory replication and machine authentication
v
Successful domain service access
Conclusion
While the Windows client initiates a standard domain join, UCS@school manages computer account provisioning through explicit hooks. The Samba LDB module intercepts the LDAP Add request, executes the UCS@school helper binary, and delegates execution to the UMC command structure. This workflow verifies user authorization, targets the correct School OU, and provisions the object via UDM.
Summary:
Samba triggers the join request, the LDB module routes execution, UMC handles authorization, UDM places the computer account, and LDAP/SamDB replication maintains overall domain availability.