Bug 47455 - Document / replace /etc/ldap.secret
Document / replace /etc/ldap.secret
Status: NEW
Product: UCS
Classification: Unclassified
Component: LDAP
UCS 4.4
Other Linux
: P5 normal with 2 votes (vote)
: ---
Assigned To: UCS maintainers
UCS maintainers
Depends on:
  Show dependency treegraph
Reported: 2018-08-06 07:35 CEST by Philipp Hahn
Modified: 2023-07-28 13:03 CEST (History)
4 users (show)

See Also:
What kind of report is it?: Security Issue
What type of bug is this?: ---
Who will be affected by this bug?: ---
How will those affected feel about the bug?: ---
User Pain:
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional): Security
Max CVSS v3 score:


Note You need to log in before you can comment on or make changes to this bug.
Description Philipp Hahn univentionstaff 2018-08-06 07:35:25 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
Comment 1 Arvid Requate univentionstaff 2018-08-06 13:29:41 CEST
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.
Comment 2 Philipp Hahn univentionstaff 2022-02-23 12:50:20 CET
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
 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