#!/bin/bash
# =============================================================================
# change_admin_password.sh
# Changes the LDAP admin (rootDN) password and verifies it took effect.
#
# Usage: change_admin_password.sh [new_password]
#   With an argument:    uses that as the new password.
#   With no argument:    generates a random password and prints it.
# =============================================================================

LDAP_DOMAIN="${LDAP_DOMAIN:-cohesive.net}"
DC="dc=$(echo "$LDAP_DOMAIN" | cut -d '.' -f 1),dc=$(echo "$LDAP_DOMAIN" | cut -d '.' -f 2)"
ADMIN_DN="cn=admin,${DC}"

if [[ $EUID -ne 0 ]]; then
  echo "ERROR: This script must be run as root (needs ldapi:/// EXTERNAL auth)."
  exit 1
fi

# --- Get the new password -----------------------------------------------------
GENERATED=false
if [[ $# -ge 1 ]]; then
  NEW_PASSWORD="$1"
else
  # Generate a random 20-character alphanumeric password.
  NEW_PASSWORD=$(openssl rand -base64 24 | tr -dc 'A-Za-z0-9' | head -c 20)
  GENERATED=true
fi

if [[ -z "$NEW_PASSWORD" ]]; then
  echo "ERROR: Password cannot be empty."
  exit 1
fi

# --- Confirm slapd is running ---------------------------------------------
if ! pgrep -x slapd > /dev/null; then
  echo "ERROR: slapd is not running. Start it first."
  exit 1
fi

# --- Change the password ----------------------------------------------------
echo "Changing password for ${ADMIN_DN}..."
HASH=$(slappasswd -s "$NEW_PASSWORD")

if cat <<EOF | ldapmodify -Y EXTERNAL -H ldapi:/// 2>&1
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: ${HASH}
EOF
then
  echo "ldapmodify command completed."
else
  echo "FAILED: ldapmodify returned an error - password was not changed."
  exit 1
fi

# --- Verify the new password actually works ---------------------------------
# NOTE: uses ldapi:/// (local unix socket), NOT the default ldap://localhost:389.
# Plain LDAP (389) may be disabled if LDAPS has been turned on via
# setup_ldaps.sh - but ldapi:/// is always present in SLAPD_SERVICES
# regardless of whether plain LDAP or LDAPS is active, so it's the one
# transport this script can rely on for verification.
echo "Verifying new password..."
if ldapsearch -x -H ldapi:/// -D "$ADMIN_DN" -w "$NEW_PASSWORD" -b "$DC" -s base dn >/dev/null 2>&1; then
  echo "SUCCESS: Password changed and verified for ${ADMIN_DN}."
  if [[ "$GENERATED" == true ]]; then
    echo "New password: ${NEW_PASSWORD}"
  fi
  exit 0
else
  echo "FAILED: Password change did not take effect - verification bind failed."
  exit 1
fi