#!/bin/sh set -e # Source utility functions . /scripts/utils.sh # LDAPI socket URL - must use URL-encoded path for Alpine LDAPI_SOCKET="ldapi://%2Frun%2Fopenldap%2Fldapi" export LDAPI_SOCKET # Validate required environment variables if [ -z "$LDAP_DOMAIN" ]; then log_error "LDAP_DOMAIN is required" exit 1 fi if [ -z "$LDAP_ORGANISATION" ]; then log_error "LDAP_ORGANISATION is required" exit 1 fi if [ -z "$LDAP_ADMIN_PASSWORD" ]; then log_error "LDAP_ADMIN_PASSWORD is required" exit 1 fi # Generate base DN from domain if not provided if [ -z "$LDAP_BASE_DN" ]; then LDAP_BASE_DN=$(echo "$LDAP_DOMAIN" | sed 's/^/dc=/; s/\./,dc=/g') fi export LDAP_BASE_DN # Extract DC component for base entry LDAP_DC=$(echo "$LDAP_DOMAIN" | cut -d'.' -f1) export LDAP_DC # Set defaults for optional variables export LDAP_CONFIG_PASSWORD="${LDAP_CONFIG_PASSWORD:-$(generate_password)}" export LDAP_TLS_ENABLED="${LDAP_TLS_ENABLED:-true}" export LDAP_TLS_CERT_FILE="${LDAP_TLS_CERT_FILE:-/certs/ldap.crt}" export LDAP_TLS_KEY_FILE="${LDAP_TLS_KEY_FILE:-/certs/ldap.key}" export LDAP_TLS_CA_FILE="${LDAP_TLS_CA_FILE:-/certs/ca.crt}" export LDAP_TLS_VERIFY_CLIENT="${LDAP_TLS_VERIFY_CLIENT:-try}" export LDAP_LOG_LEVEL="${LDAP_LOG_LEVEL:-256}" export LDAP_READONLY="${LDAP_READONLY:-false}" # Replication settings export LDAP_REPLICATION_ENABLED="${LDAP_REPLICATION_ENABLED:-false}" export LDAP_SERVER_ID="${LDAP_SERVER_ID:-1}" export LDAP_REPLICATION_HOSTS="${LDAP_REPLICATION_HOSTS:-}" export LDAP_BOOTSTRAP_PRIMARY="${LDAP_BOOTSTRAP_PRIMARY:-false}" log_info "OpenLDAP Container Starting" log_info "Domain: $LDAP_DOMAIN" log_info "Base DN: $LDAP_BASE_DN" log_info "Organisation: $LDAP_ORGANISATION" # Check if already initialized if [ ! -f /var/lib/openldap/openldap-data/data.mdb ]; then log_info "First run - initializing OpenLDAP..." # Initialize cn=config (always needed) /scripts/init-config.sh # Load schemas in order (always needed) /scripts/init-schemas.sh # Configure overlays (always needed) /scripts/init-overlays.sh # Determine if we should initialize DIT or replicate from peer # If replication is enabled and we're not the bootstrap primary, skip DIT init if [ "$LDAP_REPLICATION_ENABLED" = "true" ] && [ "$LDAP_BOOTSTRAP_PRIMARY" != "true" ]; then log_info "Replication enabled - this server will sync DIT from peers" log_info "Skipping local DIT initialization..." else # Create base DIT /scripts/init-dit.sh # Configure ACLs /scripts/init-acls.sh # Create service accounts if requested if [ "$LDAP_CREATE_SERVICE_ACCOUNTS" = "true" ]; then /scripts/init-services.sh fi # Process custom LDIF files if present if [ -d /ldif/custom ] && [ "$(ls -A /ldif/custom 2>/dev/null)" ]; then log_info "Processing custom LDIF files..." for ldif in /ldif/custom/*.ldif; do if [ -f "$ldif" ]; then log_info "Loading: $ldif" ldapadd -x -H "$LDAPI_SOCKET" -D "cn=admin,$LDAP_BASE_DN" -w "$LDAP_ADMIN_PASSWORD" -f "$ldif" || \ log_warn "Failed to load $ldif (may already exist)" fi done fi fi log_info "Initialization complete." else log_info "Database exists - starting normally." fi # Ensure proper ownership chown -R ldap:ldap /var/lib/openldap chown -R ldap:ldap /etc/openldap/slapd.d chown -R ldap:ldap /run/openldap # Build slapd arguments SLAPD_URLS="ldap:/// $LDAPI_SOCKET" if [ "$LDAP_TLS_ENABLED" = "true" ]; then if [ -f "$LDAP_TLS_CERT_FILE" ] && [ -f "$LDAP_TLS_KEY_FILE" ]; then SLAPD_URLS="ldap:/// ldaps:/// $LDAPI_SOCKET" log_info "TLS enabled - listening on ldaps://" else log_warn "TLS enabled but certificates not found - skipping ldaps://" fi fi log_info "Starting slapd with URLs: $SLAPD_URLS" # If replication is enabled, start slapd in background first to configure replication if [ "$LDAP_REPLICATION_ENABLED" = "true" ]; then log_info "Starting slapd in background for replication configuration..." /usr/sbin/slapd -h "$SLAPD_URLS" \ -F /etc/openldap/slapd.d \ -u ldap -g ldap & SLAPD_PID=$! # Wait for slapd to be ready log_info "Waiting for slapd to be ready..." sleep 2 for i in $(seq 1 30); do if ldapsearch -x -H ldap://localhost -b "" -s base "objectClass=*" >/dev/null 2>&1; then log_info "slapd is ready" break fi sleep 1 done # Configure replication /scripts/init-replication.sh # Stop background slapd gracefully log_info "Restarting slapd in foreground mode..." kill $SLAPD_PID 2>/dev/null || true wait $SLAPD_PID 2>/dev/null || true sleep 1 fi # Start slapd in foreground (final) exec /usr/sbin/slapd -h "$SLAPD_URLS" \ -F /etc/openldap/slapd.d \ -u ldap -g ldap \ -d "${LDAP_LOG_LEVEL}"