A script shall be executed on each or a certain UCS systems before/during/after the join process

Problem

A script shall be executed on each or a certain UCS systems before/during/after the join process.

Solution:

To solve this problem, since version 4.4-0, UCS brings the mechanism of join hooks with it. Join hooks are scripts that are registered in LDAP and then executed on any UCS system either before/during/after the join process.

Big fat warning:

Join hooks are a very powerful tool! The Join-Hooks should therefore be used with caution!
The scripts get the credentials of a join user (usually a user of the group “Domain Admins”) and are executed on the local UCS system as user “root”.
If a join hook script terminates with an exit code other than 0, the join process is aborted. This can lead to a deadlock situation, if the join hook can only be updated via a join script!

Step 1: create a join hook script

There are 3 different types of join hooks:

  • join/pre-join: This hook type is executed during the join BEFORE the computer account is created/updated (not executed with univention-run-join-scripts!).
  • join/pre-joinscripts: This hook type is generally executed BEFORE running join scripts and AFTER the host account has been update/created (for example, univention-join and univention-run-join-scripts).
  • join/post-joinscripts: This hook type is executed AFTER the execution of join scripts (e.g. univention-join and univention-run-join-scripts).

During execution, 5 parameters are passed to each hook, which can be evaluated, but do not have to be:

  • --server-role SERVERROLE: the UCS server role (e.g. “domaincontroller_slave”)
  • --master MASTER: the FQDN of the master
  • --hooktype TYPE: join/pre-join, join/pre-joinscripts or join/post-joinscripts
  • --binddn DN: Distiguished Name (DN) of the join user
  • --bindpwdfile FILENAME: Path of the password file of the join user.

Registered join hooks are always executed on all UCS systems. If certain actions are to be performed only on certain UCS systems (for example, only on domain controller slave systems), the join hook script must ensure this itself.

An example script to be registered that sets a UCR variable on UCS systems with the role Domaincontroller Slave must be stored as a file:

#!/bin/sh
if [ "$(ucr get server/role)" = "domaincontroller_slave" ] ; then
    ucr set foo/bar=123
fi

Step 2a: register join hook script in LDAP (manually)

The manual registration of the join hook script can be performed on the domain controller master as user root using the following commands:

. /usr/share/univention-lib/all.sh
ucs_registerLDAPExtension \
   --packagename "custom-hook1" \
   --packageversion "1.0" \
   --data /path/to/my/script/set-my-ucr.sh \
   --data_type="join/pre-joinscripts"

Note: to update the hook, the package version (here 1.0) must be increased and the package name must be retained.

Step 2b: register join hook script in LDAP (via join script)

Alternatively, you can also register the join hook in a join script (the better option for app developers!):

. /usr/share/univention-lib/all.sh
ucs_registerLDAPExtension "$@" \
   --data /usr/share/univention-example-package/set-my-ucr.sh \
   --data_type="join/pre-joinscripts" || the

Step 3: execution of the join hook

The hook is now executed when univention-run-join-scripts are executed:

root@slave123:~# univention-run-join-scripts 
univention-run-join-scripts: runs all join scripts existing on local computer.
copyright (c) 2001-2019 Univention GmbH, Germany

Running pre-joinscripts hook(s): done
Running 01univention-ldap-server-init.inst skipped (already executed)
Running 02univention-directory-notifier.inst skipped (already executed)
Running 03univention-directory-listener.inst skipped (already executed)
Running 04univention-ldap-client.inst skipped (already executed)
[...]
Running 98univention-pkgdb-tools.inst skipped (already executed)
Running post-joinscripts hook(s): done
root@slave123:~#

The log output of the hook can be found in the file /var/log/univention/join.log:

[...]
univention-run-join-scripts started
Sa 14. Sep 20:11:31 CEST 2019

univention-join-hooks: looking for hook type "join/pre-joinscripts" on slave123.example.ucs
Found hooks:
  cn=set-my-ucr.sh,cn=data,cn=univention,dc=example,dc=ucs
Running: set-my-ucr.sh (cn=set-my-ucr.sh,cn=data,cn=univention,dc=example,dc=ucs) in /tmp/tmpzhZn9K/tmpb29wRU
Create foo/bar
RUNNING 01univention-ldap-server-init.inst
EXITCODE=already_executed
[...]