Univention Bugzilla – Bug 47455
Document / replace /etc/ldap.secret
Last modified: 2023-07-28 13:03:18 CEST
The file /etc/ldap.secret exists on every DC Master/Backup and is owned by "root:DC Backup Hosts". It contains the credentials for "cn=admin,$ldap/base", which is equivalent to the "root" user of LDAP as that user is not restricted by certain LDAP ACLs. Recently the documentation about delegating domain join to other users was updated: Bug #47193: Each such admin must be a member of that group "DC backup hosts" as UCS systems join by logging in via ssh on the Master and then *locally* invoking "univention-server-join", which gets its credentials from "/etc/ldap.secret". The command has command line options to pass credentials explicitly, but they are not used - the credentials are *not* passed through ssh! Essentially this allows such users to bypass their user restrictions as they can use the "cn=admin" user to bypass certain LDAP ACLs: > rootdn "cn=admin,dc=..." Any hacked DC Backup host or the account of such an 'delegated domain join admin' allows full *write* access to the LDAP using that file. During the technical training one trainee asked what would break if that file was simply removed: - at least the domain joins script would need manual execution on DC Master/Backup the same as currently already necessary on DC Slave/Member-servers. - what else? 1. We should better document the implications of giving read access to that (and other secret) file(s). 2. We should - if possible - replace the mechanism to store credentials as (unencrypted) files in the file system: HSM, TPM, ... 3. The password is AFAIK never rotated and there is no documentation / mechanism to do so: If the password is ever leaked LDAP is compromised forever (until manually detected and changed). UCS Technical Training Task #10201
As a first step I guess we should fix the issue of Bug 47193 Comment 1. The workaround for that bug expanded the attack surface and is the origin of this discussion, so we should fix that escalation of privilege first.
Because of > access to attrs=userPassword > by anonymous auth > by * none break > access to dn="cn=admin,dc=qa50,dc=pmh" > by self write > by * none > access to * > by sockname="PATH=/var/run/slapd/ldapi" write > by dn.base="uid=Administrator,cn=users,dc=qa50,dc=pmh" write > by * none break in /etc/ldap/slapd.conf this is not enough: > ldappasswd -Y EXTERNAL -H ldapi:/// -T /etc/ldap.secret "cn=admin,$(ucr get ldap/base)" But this can be by-passwd via slapd-config: # Setup temporary password . /usr/share/univention-lib/base.sh tmp="$(mktemp)" create_machine_password >"$tmp" # Configure temporary passowr printf 'dn: olcDatabase={1}mdb,cn=config\nchangetype: modify\nadd: olcRootPW\nolcRootPW: %s\n\n' "$(slappasswd -T "$tmp")" | ldapmodify -QY EXTERNAL -H ldapi:/// # Create and change to new password create_machine_password >/etc/ldap.secret ldappasswd -H ldapi:/// -D "cn=admin,$(ucr get ldap/base)" -y "$tmp" -T /etc/ldap.secret # Unto temporary password printf 'dn: olcDatabase={1}mdb,cn=config\nchangetype: modify\ndelete: olcRootPW\n\n' | ldapmodify -QY EXTERNAL -H ldapi:/// rm -f "$tmp" To get the crypted password: slapcat -a '(cn=admin)' -o ldif-wrap=no | sed -ne 's/^userPassword:: //p;T;q' | base64 -d