How to Package and Register a Restricted LDAP Read-Only ACL in UCS
This article describes how to create a Debian package that registers a restricted LDAP read-only ACL in Univention Corporate Server (UCS). The example grants a dedicated LDAP account read access to a specific LDAP subtree while preventing access to other branches and denying write operations.
1. Create the package directory
mkdir -p ~/ldap-acl-test/debian
mkdir -p ~/ldap-acl-test/usr/share/ldap-acl-test
cd ~/ldap-acl-test
The resulting directory structure will look as follows:
ldap-acl-test/
├── 50ldap-acl-test.inst
├── usr/
│ └── share/
│ └── ldap-acl-test/
│ └── 65ldap-readonly.acl
└── debian/
├── changelog
├── control
├── install
└── rules
2. Create the ACL file
nano usr/share/ldap-acl-test/65ldap-readonly.acl
Example content:
access to dn.subtree="ou=schule1,dc=example,dc=de"
by dn.base="uid=ldap-readonly,cn=users,dc=example,dc=de" read
by * +0 break
access to *
by dn.base="uid=ldap-readonly,cn=users,dc=example,dc=de" none stop
by * +0 break
Adjust the following values to match your environment:
ou=schule1,dc=example,dc=de
uid=ldap-readonly,cn=users,dc=example,dc=de
The ACL grants the account:
- Read access to the
ou=schule1,...branch - Read access to all subordinate objects within this branch
- No access to other branches
- No write permissions
The file name 65ldap-readonly.acl is also the file name that will later be used in the UCR template directory:
/etc/univention/templates/files/etc/ldap/slapd.conf.d/65ldap-readonly.acl
3. Create the join script
nano 50ldap-acl-test.inst
Content:
#!/bin/sh
VERSION=1
. /usr/share/univention-join/joinscripthelper.lib
. /usr/share/univention-lib/ldap.sh
joinscript_init
export UNIVENTION_APP_IDENTIFIER="ldap-acl-test-1.0"
ucs_registerLDAPExtension "$@" \
--ucsversionstart "5.2-0" \
--ucsversionend "5.99-0" \
--acl /usr/share/ldap-acl-test/65ldap-readonly.acl || die
joinscript_save_current_version
exit 0
Important:
- The ACL file is specified with
--acl. - The path points to the source file installed by the package.
--acland the corresponding file path must be specified together.- The script must not later be executed directly with
bash 50ldap-acl-test.inst.
Make the script executable:
chmod 755 50ldap-acl-test.inst
4. Create the Debian control file
nano debian/control
Content:
Source: ldap-acl-test
Section: univention
Priority: optional
Maintainer: MiracErde <Miro@example.de>
Build-Depends:
debhelper-compat (= 13),
univention-join-dev
Standards-Version: 4.3.0.3
Package: ldap-acl-test
Architecture: all
Depends:
univention-join,
shell-univention-lib,
${misc:Depends}
Description: Restricted LDAP read-only ACL
Installs a UCS LDAP ACL for a restricted read-only account.
5. Create the Debian rules file
nano debian/rules
Content:
#!/usr/bin/make -f
%:
dh $@ --with univention-join
Make the file executable:
chmod 755 debian/rules
The --with univention-join option ensures that the join script is correctly processed as a package join script.
6. Create the installation file
nano debian/install
Content:
usr/share/ldap-acl-test/65ldap-readonly.acl usr/share/ldap-acl-test/
After installing the package, this places the ACL file at:
/usr/share/ldap-acl-test/65ldap-readonly.acl
The final destination directory is managed by the UCS LDAP listener.
7. Create the Debian changelog
Using dch:
dch --create \
--package ldap-acl-test \
--newversion 1.0-1 \
"Register restricted LDAP read-only ACL"
Alternatively, create the file manually:
nano debian/changelog
ldap-acl-test (1.0-1) unstable; urgency=medium
* Register restricted LDAP read-only ACL.
-- Administrator <root@example.de> Fri, 11 Sep 2026 17:00:00 +0200
8. Build the package
From the package directory:
cd ~/ldap-acl-test
dpkg-buildpackage -us -uc -b
The resulting package is located one directory level above:
ls -l ~/ldap-acl-test_*.deb
9. Install the package
dpkg -i ~/ldap-acl-test_*.deb
Verify that the ACL file has been installed:
ls -l /usr/share/ldap-acl-test/65ldap-readonly.acl
The join script should have been installed by dh-univention-join:
ls -l /usr/lib/univention-install/50ldap-acl-test.inst
10. Run the join script correctly
Do not run the join script as follows:
bash 50ldap-acl-test.inst
Running the script this way prevents UCS from automatically determining the Debian package name.
Use:
univention-run-join-scripts
Alternatively, you can run the join script through the UCS management interface.
ucs_registerLDAPExtension can now automatically determine:
- The Debian package name
- The installed package version
- The join script context
Therefore, the following options are normally not required in a production join script:
--packagename
--packageversion
11. Verify that the LDAP extension has been registered
udm settings/ldapacl list
Look for an object associated with ldap-acl-test.
Also verify that the file has been placed in the intended UCR template directory:
ls -l /etc/univention/templates/files/etc/ldap/slapd.conf.d/
The expected file is:
/etc/univention/templates/files/etc/ldap/slapd.conf.d/65ldap-readonly.acl
12. Verify the LDAP configuration and listener
The listener should update the configuration automatically. If you encounter problems, check:
journalctl -u univention-directory-listener
Additionally:
ucr commit /etc/ldap/slapd.conf
systemctl restart slapd
Running ucr commit manually is normally not required, but it can be used for verification or after correcting the configuration.
13. Test access
Test the permitted branch:
ldapsearch -x \
-D "uid=ldap-readonly,cn=users,dc=example,dc=de" \
-W \
-b "ou=schule1,dc=example,dc=de"
Test a branch that is not permitted:
ldapsearch -x \
-D "uid=ldap-readonly,cn=users,dc=example,dc=de" \
-W \
-b "cn=users,dc=example,dc=de"
Access to the second branch must either be denied or return no results.
root@Bremen:~# ldapsearch -x -D "uid=ldap-readonly,cn=users,dc=deadpool,dc=intranet" -W -b "cn=users,dc=deadpool,dc=intranet"
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <cn=users,dc=deadpool,dc=intranet> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# search result
search: 2
result: 32 No such object
The registration creates a replicated settings/ldapacl object. Based on this object, the UCS LDAP listener distributes the file, including to:
/etc/univention/templates/files/etc/ldap/slapd.conf.d/
root@Bremen:~# ls -lah /etc/univention/templates/files/etc/ldap/slapd.conf.d/65ldap-readonly.acl
-rw-r--r-- 1 root nogroup 257 Sep 11 18:43 /etc/univention/templates/files/etc/ldap/slapd.conf.d/65ldap-readonly.acl
Documentation
- Packaging LDAP ACL Extensions (5. Lightweight Directory Access Protocol (LDAP) in UCS — Univention Corporate Server - Manual for developers)
- ucs_registerLDAPExtension (https://docs.software-univention.de/developer-reference/5.2/en/join.html#ucs-registerldapextension)
See also: