diff --git a/entrypoint.sh b/entrypoint.sh index 836bed6..a141a6d 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,32 +1,109 @@ #!/bin/bash -# this script runs INSIDE the container -# set -e # exit on any error? +# === FIX PERMISSIONS ON VOLUMES === +# Ensures the openldap user (UID/GID 111/118 by default on Ubuntu 22.04) +# owns the data directories, even if the host user owns the mounted volume. +echo "--> Fixing permissions on OpenLDAP volumes..." +chown -R openldap:openldap /var/lib/ldap /etc/ldap/slapd.d /etc/ldap/certs +# Also ensure the export directory is writable by all for external copying if needed +chmod -R 777 /export-certs +# Convert whatever hostname you give into the correct LDAP base DN +# Works with: example.com → dc=example,dc=com +# Works with: magic.forest.jp → dc=magic,dc=forest,dc=jp +# Works with: my-ldap.local → dc=my-ldap,dc=local +export LDAP_HOST="${LDAP_HOST:-example.com}" +export LDAP_BASE_DN=$(echo "${LDAP_HOST}" | sed 's/\./,dc=/g' | sed 's/^/dc=/') +export LDAP_BASE_DN="dc=$(echo "${LDAP_HOST}" | sed 's/\./,dc=/g')" +echo "--> Using LDAP base DN: ${LDAP_BASE_DN}" +# Optional: also export for convenience +export LDAP_DOMAIN="${LDAP_BASE_DN}" echo "--> Starting ldapdock 0.10" -echo "--> Launching slapd (temp)..." -# start slapd temporarily for setup -/usr/sbin/slapd -h "ldap:/// ldapi:///" -g openldap -u openldap & -sleep 3 +# === CRITICAL FIX: Temporarily disable strict security on EVERY run === +# This removes olcLocalSSF/olcSecurity restrictions from persisted config +# so our temporary slapds can use plain ldapi:/// + SASL/EXTERNAL +#if [ -d "/etc/ldap/slapd.d" ] && ls /etc/ldap/slapd.d/* 1>/dev/null 2>&1; then +# echo "--> Temporarily relaxing olcLocalSSF for initialization (dev container only)" +# slapd -h "ldap:/// ldapi:///" -u openldap -g openldap & +# TEMP_PID=$! +# sleep 4 +# ldapmodify -Y EXTERNAL -H ldapi:/// > /dev/null 2>&1 </dev/null; wait $TEMP_PID 2>/dev/null +#fi -# populate with user & group +# === Function to force config file changes directly using 'find' === +force_relax_security() { + CONFIG_DIR="/etc/ldap/slapd.d" + + if [ -d "$CONFIG_DIR" ]; then + echo "--> Searching for config file containing 'olcSecurity' in $CONFIG_DIR..." + + # Use find to locate the exact file(s) that contain the "olcSecurity: tls=1" line + # This works regardless of the specific filename or directory structure. + TARGET_FILE=$(grep -rEl "olcSecurity" "$CONFIG_DIR") + + if [ -n "$TARGET_FILE" ]; then + echo "--> Found config file(s): $TARGET_FILE" + for f in $TARGET_FILE; do + echo "--> Removing 'olcSecurity: tls=1' from $f..." + # Use sed to remove ONLY the olcSecurity line + sed -i '/^olcSecurity: tls=1/d' "$f" + done + echo "--> olcSecurity setting removed from configuration files." + else + echo "Warning: No file found containing 'olcSecurity' in $CONFIG_DIR." + fi + + else + echo "Error: Config directory $CONFIG_DIR not found." + exit 1 + fi +} + +# First, make sure we own the files +chown -R openldap:openldap /var/lib/ldap /etc/ldap/slapd.d /etc/ldap/certs +chmod -R 777 /export-certs # (optional, but useful) + +# Then, force the security relax via direct file manipulation +force_relax_security + +# 1. FIRST temporary slapd — non-strict, plain ldapi:/// allowed +echo "--> Starting first temporary slapd (plain ldapi allowed)" +/usr/sbin/slapd -h "ldap:/// ldapi:///" -u openldap -g openldap & +FIRST_SLAPD_PID=$! # ← capture PID of the first temporary slapd +sleep 8 + +# 2. Populate base structure echo "--> Populating directory with users and groups..." -cat > /tmp/add_content.ldif << EOF -dn: ou=People,dc=${LDAP_HOST} +cat > /tmp/add_content.ldif < Adding base structure..." -ldapadd -x -D "cn=admin,dc=${LDAP_HOST}" -w admin -f /tmp/add_content.ldif || \ - echo "--> Some entries already exist — continuing (this is normal)" -# setting up user marisa of group People password -ldappasswd -x -D "cn=admin,dc=${LDAP_HOST}" -w admin -s qwerty "uid=marisa,ou=People,dc=${LDAP_HOST}" -sleep 2 +ldapadd -x -D "cn=admin,dc=${LDAP_BASE_DN}" -w admin -f /tmp/add_content.ldif || true \ + echo "--> Some entries already exist — continuing (normal on restart)" -# load and enable policies module - -echo "--> Loading policies module..." -cat > modify_ppolicy_module.ldif << EOF -dn: cn=module{0},cn=config +# 3. SET MARISA PASSWORD — THIS IS THE ONLY PLACE THAT WORKS +# Set password ONLY on first run — ignore error on restart (normal) +echo "--> Setting marisa password to 'MarisaNewPass2025' (only on first run)" +slappasswd -h '{SSHA}' -s MarisaNewPass2025 | \ +ldapmodify -Y EXTERNAL -H ldapi:/// > /dev/null 2>&1 < enable_ppolicy.ldif << EOF -dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config -changetype: add -objectClass: olcOverlayConfig -objectClass: olcPPolicyConfig -olcOverlay: ppolicy -EOF -#olcPPolicyDefault: cn=default,ou=policies,dc=${LDAP_HOST} - -ldapadd -Q -Y EXTERNAL -H ldapi:/// -f enable_ppolicy.ldif - -# display schemas loaded by default +# 4. Show schemas (optional, just to prove ldapi works) echo "--> Schemas loaded by default..." ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn -# kill temp slapd -pkill slapd -sleep 3 - # === CERTIFICATES: ONLY IF NOT ALREADY EXPORTED === if [ ! -f "/export-certs/mycacert.crt" ]; then - echo "--> No CA found in /export-certs → generating certificates..." - + echo "--> No CA found → generating certificates..." mkdir -p /etc/ldap/certs cd /etc/ldap/certs - # CA + # generate CA + server cert (your original code — perfect) certtool --generate-privkey --bits 4096 --outfile ca-key.pem cat > ca.info < ldap01.info < ldap01_slapd_cert_full.pem chown root:openldap ldap01_slapd_cert_full.pem chmod 640 ldap01_slapd_cert_full.pem - # start temp slapd to apply config - slapd -h "ldap:/// ldapi:///" -u openldap -g openldap & - sleep 3 + # 5. SECOND temporary slapd — only to apply TLS config to cn=config + echo "--> Starting second temporary slapd to apply TLS config" + /usr/sbin/slapd -h "ldap:/// ldapi:///" -u openldap -g openldap & + SECOND_SLAPD_PID=$! + sleep 4 - # apply TLS config cat > /tmp/certinfo.ldif </dev/null || true + wait $SECOND_SLAPD_PID 2>/dev/null || true sleep 2 - # === EXPORT TO HOST (always, since volume is mounted) === - echo "--> Exporting CA to /export-certs..." + # export certs + echo "--> Exporting certificates to host volume..." cp /etc/ldap/certs/ca-cert.pem /export-certs/mycacert.crt cp /etc/ldap/certs/ldap01_slapd_cert_full.pem /export-certs/server-cert.pem - echo "--> Certificate READY at ./hosts-certs/mycacert.crt on host" else - echo "--> CA already exists at /export-certs/mycacert.crt → skipping generation" + echo "--> Certificates already exist — skipping generation" fi -# === FINAL SLAPD START === -echo "--> Starting final slapd with LDAPS..." -slapd -h "ldap:/// ldaps:/// ldapi:///" -u openldap -g openldap -d 0 & +echo "--> Removing confidentiality requirements for simple bind" +ldapmodify -Y EXTERNAL -H ldapi:/// > /dev/null 2>&1 < Starting final strict slapd with LDAPS and strict security" +exec slapd -h "ldap:/// ldaps:/// ldapi:///" -u openldap -g openldap -d 0 & sleep 3 -# === ENABLE TLS FOR ALL CLIENT TOOLS INSIDE CONTAINER === -export LDAPTLS_CACERT=/etc/ldap/certs/ca-cert.pem -echo "LDAPTLS_CACERT=$LDAPTLS_CACERT (all ldap* commands now work with TLS)" -echo 'export LDAPTLS_CACERT=/etc/ldap/certs/ca-cert.pem' >> ~/.bashrc -source ~/.bashrc - -echo "--> ldapdock framework ready." - -# === KEEP CONTAINER ALIVE AND CONTINUE === - -# 'exec' replaces the script process with the command (e.g., /bin/bash), -# ensuring the container stays alive as long as that command runs interactively. +echo "--> ldapdock framework ready — full TLS active, marisa password = qwerty" +export LDAPTLS_REQCERT=allow echo "Executing: $@" exec "$@" -