#!/bin/sh set -e . /scripts/utils.sh # Skip if replication not enabled if [ "$LDAP_REPLICATION_ENABLED" != "true" ]; then log_info "Replication not enabled, skipping..." exit 0 fi # Validate required variables if [ -z "$LDAP_SERVER_ID" ]; then log_error "LDAP_SERVER_ID is required for replication" exit 1 fi if [ -z "$LDAP_REPLICATION_HOSTS" ]; then log_error "LDAP_REPLICATION_HOSTS is required for replication" exit 1 fi # Use admin credentials for replication if not specified LDAP_REPLICATION_DN="${LDAP_REPLICATION_DN:-cn=admin,$LDAP_BASE_DN}" LDAP_REPLICATION_PASSWORD="${LDAP_REPLICATION_PASSWORD:-$LDAP_ADMIN_PASSWORD}" log_info "Configuring multi-master replication..." log_info "Server ID: $LDAP_SERVER_ID" log_info "Replication hosts: $LDAP_REPLICATION_HOSTS" # Wait for slapd to be ready wait_for_slapd 30 "$LDAPI_SOCKET" # Configure serverID in cn=config log_info "Setting serverID..." cat > /tmp/repl-serverid.ldif << EOF dn: cn=config changetype: modify replace: olcServerID olcServerID: ${LDAP_SERVER_ID} EOF ldapmodify -Y EXTERNAL -H "$LDAPI_SOCKET" -f /tmp/repl-serverid.ldif 2>/dev/null || \ log_warn "ServerID may already be set" # Configure syncprov overlay on the database log_info "Configuring syncprov overlay..." cat > /tmp/repl-syncprov.ldif << EOF dn: olcOverlay=syncprov,olcDatabase={1}mdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov olcSpCheckpoint: 100 10 olcSpSessionlog: 100 EOF ldapmodify -Y EXTERNAL -H "$LDAPI_SOCKET" -f /tmp/repl-syncprov.ldif 2>/dev/null || \ log_warn "syncprov overlay may already exist" # Build syncrepl configuration for each peer # Format: LDAP_REPLICATION_HOSTS="ldap://server1.example.com,ldap://server2.example.com" REPLICA_NUM=0 SYNCREPL_CONFIG="" # Parse the comma-separated list of hosts OLD_IFS="$IFS" IFS=',' for host in $LDAP_REPLICATION_HOSTS; do REPLICA_NUM=$((REPLICA_NUM + 1)) # Trim whitespace host=$(echo "$host" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') log_info "Adding replication peer $REPLICA_NUM: $host" SYNCREPL_CONFIG="${SYNCREPL_CONFIG} olcSyncRepl: rid=$(printf '%03d' $REPLICA_NUM) provider=${host} bindmethod=simple binddn=\"${LDAP_REPLICATION_DN}\" credentials=${LDAP_REPLICATION_PASSWORD} searchbase=\"${LDAP_BASE_DN}\" scope=sub schemachecking=on type=refreshAndPersist retry=\"60 +\" timeout=1" done IFS="$OLD_IFS" # Configure syncrepl and mirrormode on the database log_info "Configuring syncrepl and mirrormode..." cat > /tmp/repl-syncrepl.ldif << EOF dn: olcDatabase={1}mdb,cn=config changetype: modify replace: olcSyncRepl ${SYNCREPL_CONFIG} - replace: olcMirrorMode olcMirrorMode: TRUE EOF ldapmodify -Y EXTERNAL -H "$LDAPI_SOCKET" -f /tmp/repl-syncrepl.ldif || { log_error "Failed to configure syncrepl" cat /tmp/repl-syncrepl.ldif exit 1 } # Add additional indexes for replication log_info "Adding replication indexes..." cat > /tmp/repl-indexes.ldif << EOF dn: olcDatabase={1}mdb,cn=config changetype: modify add: olcDbIndex olcDbIndex: entryCSN eq - add: olcDbIndex olcDbIndex: entryUUID eq EOF ldapmodify -Y EXTERNAL -H "$LDAPI_SOCKET" -f /tmp/repl-indexes.ldif 2>/dev/null || \ log_warn "Indexes may already exist" # Cleanup rm -f /tmp/repl-*.ldif log_info "Multi-master replication configured successfully" log_info "This server (ID=$LDAP_SERVER_ID) will replicate with $REPLICA_NUM peer(s)"