mirror of
https://github.com/vegardit/docker-openldap.git
synced 2026-04-10 16:39:07 +02:00
564 lines
19 KiB
Bash
564 lines
19 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com)
|
|
# SPDX-FileContributor: Sebastian Thomschke
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
# SPDX-ArtifactOfProjectHomePage: https://github.com/vegardit/docker-openldap
|
|
|
|
# shellcheck disable=SC1091 # Not following: /opt/bash-init.sh was not specified as input
|
|
source /opt/bash-init.sh
|
|
|
|
#################################################
|
|
# print header
|
|
#################################################
|
|
cat <<'EOF'
|
|
___ _ ____ _ ____
|
|
/ _ \ _ __ ___ _ __ | | | _ \ / \ | _ \
|
|
| | | | '_ \ / _ \ '_ \| | | | | |/ _ \ | |_) |
|
|
| |_| | |_) | __/ | | | |___| |_| / ___ \| __/
|
|
\___/| .__/ \___|_| |_|_____|____/_/ \_\_|
|
|
|_|
|
|
|
|
EOF
|
|
|
|
cat /opt/build_info
|
|
echo
|
|
|
|
log INFO "Timezone is $(date +"%Z %z")"
|
|
|
|
|
|
#################################################
|
|
# load custom init script if specified
|
|
#################################################
|
|
if [[ -f ${INIT_SH_FILE:-} ]]; then
|
|
log INFO "Loading [$INIT_SH_FILE]..."
|
|
|
|
# shellcheck disable=SC1090 # ShellCheck can't follow non-constant source
|
|
source "$INIT_SH_FILE"
|
|
fi
|
|
|
|
|
|
# display slapd build info
|
|
slapd -VVV 2>&1 | log INFO || true
|
|
|
|
|
|
# Limit maximum number of open file descriptors otherwise slapd consumes two
|
|
# orders of magnitude more of RAM, see https://github.com/docker/docker/issues/8231
|
|
ulimit -n "$LDAP_NOFILE_LIMIT"
|
|
|
|
|
|
#################################################################
|
|
# Adjust UID/GID and file permissions based on env var config
|
|
#################################################################
|
|
if [[ -n ${LDAP_OPENLDAP_UID:-} ]]; then
|
|
effective_uid=$(id -u openldap)
|
|
if [[ $LDAP_OPENLDAP_UID != "$effective_uid" ]]; then
|
|
log INFO "Changing UID of openldap user from $effective_uid to $LDAP_OPENLDAP_UID..."
|
|
usermod -o -u "$LDAP_OPENLDAP_UID" openldap
|
|
fi
|
|
fi
|
|
if [[ -n ${LDAP_OPENLDAP_GID:-} ]]; then
|
|
effective_gid=$(id -g openldap)
|
|
if [[ $LDAP_OPENLDAP_GID != "$effective_gid" ]]; then
|
|
log INFO "Changing GID of openldap user from $effective_gid to $LDAP_OPENLDAP_GID..."
|
|
usermod -o -g "$LDAP_OPENLDAP_GID" openldap
|
|
fi
|
|
fi
|
|
chown -R openldap:openldap /etc/ldap
|
|
chown -R openldap:openldap /var/lib/ldap
|
|
chown -R openldap:openldap /var/lib/ldap_orig || true
|
|
mkdir -p /run/slapd
|
|
chown -R openldap:openldap /run/slapd
|
|
|
|
#################################################################
|
|
# Install TLS certificates if needed (must be before any slapd starts)
|
|
#################################################################
|
|
case "${LDAP_TLS_ENABLED:-}" in
|
|
true|false) ;;
|
|
auto) [[ -f $LDAP_TLS_CERT_FILE && -f $LDAP_TLS_KEY_FILE ]] && LDAP_TLS_ENABLED=true || LDAP_TLS_ENABLED=false ;;
|
|
*) log ERROR "LDAP_TLS_ENABLED must be auto|true|false"; exit 1 ;;
|
|
esac
|
|
|
|
if [[ $LDAP_TLS_ENABLED == true ]]; then
|
|
if ! [[ "$LDAP_TLS_SSF" =~ ^[0-9]+$ ]] || (( LDAP_TLS_SSF < 0 || LDAP_TLS_SSF > 256 )); then
|
|
log ERROR "LDAP_TLS_SSF must be an integer between 0 and 256 (got '$LDAP_TLS_SSF')"
|
|
exit 1
|
|
fi
|
|
|
|
case "${LDAP_LDAPS_ENABLED:-}" in
|
|
true|false) log INFO "LDAPS enabled (port 636): $LDAP_LDAPS_ENABLED";;
|
|
*) log ERROR "LDAP_LDAPS_ENABLED must be true|false"; exit 1 ;;
|
|
esac
|
|
|
|
case "${LDAP_TLS_VERIFY_CLIENT:-}" in
|
|
never|allow|try|demand) log INFO "TLS_VERIFY_CLIENT: $LDAP_TLS_VERIFY_CLIENT";;
|
|
*) log ERROR "LDAP_LDAPS_ENABLED must be true|false"; exit 1 ;;
|
|
esac
|
|
|
|
if [[ ! -f ${LDAP_TLS_KEY_FILE:-} ]]; then
|
|
log ERROR "TLS requested but LDAP_TLS_KEY_FILE [${LDAP_TLS_KEY_FILE:-}] not accessible"
|
|
exit 1
|
|
fi
|
|
if [[ ! -f ${LDAP_TLS_CERT_FILE:-} ]]; then
|
|
log ERROR "TLS requested but LDAP_TLS_CERT_FILE [${LDAP_TLS_CERT_FILE:-}] not accessible"
|
|
exit 1
|
|
fi
|
|
|
|
log INFO "Installing TLS certificates..."
|
|
install -d -o openldap -g openldap -m 0755 /etc/ldap/certs
|
|
install -o openldap -g openldap -m 0600 "$LDAP_TLS_KEY_FILE" /etc/ldap/certs/server.key
|
|
install -o openldap -g openldap -m 0644 "$LDAP_TLS_CERT_FILE" /etc/ldap/certs/server.crt
|
|
if [[ -f ${LDAP_TLS_CA_FILE:-} ]]; then
|
|
install -o openldap -g openldap -m 0644 "$LDAP_TLS_CA_FILE" /etc/ldap/certs/ca.crt
|
|
fi
|
|
fi
|
|
|
|
|
|
#################################################################
|
|
# Configure LDAP server on initial container launch or after version upgrade
|
|
#################################################################
|
|
function ldif() {
|
|
log INFO "---------------------------------------"
|
|
local action=$1 && shift
|
|
local file=${!#}
|
|
log INFO "Executing [ldap$action $file]..."
|
|
# shellcheck disable=SC2094 # Make sure not to read and write the same file in the same pipeline
|
|
local tmpfile
|
|
tmpfile=$(mktemp --suffix=.ldif /tmp/ldif.XXXXXX)
|
|
interpolate <"$file" >"$tmpfile"
|
|
"ldap$action" -H ldapi:/// "${@:1:${#}-1}" -f "$tmpfile" 2>&1 | log INFO
|
|
rm -f "$tmpfile"
|
|
}
|
|
|
|
function slapd() {
|
|
local cmd="${1:-}"
|
|
local -r RUNDIR="/run/slapd"
|
|
local -r LOGFILE="${SLAPD_LOG_FILE:-/tmp/slapd.log}"
|
|
local -r PIDFILE="${SLAPD_INIT_PIDFILE:-$RUNDIR/.init.pid}"
|
|
local -r URLS="ldap:/// ldapi:///${SLAPD_EXTRA_URLS:-}"
|
|
local -a dbg_opts=()
|
|
|
|
# Debug levels for init runs (independent from final exec)
|
|
# e.g. export SLAPD_INIT_LOG_LEVELS="stats config sync"
|
|
for lvl in ${SLAPD_INIT_LOG_LEVELS:-stats config}; do
|
|
dbg_opts+=(-d "$lvl")
|
|
done
|
|
|
|
case "$cmd" in
|
|
start)
|
|
log INFO "Starting slapd for init/migration..."
|
|
mkdir -p "$RUNDIR"
|
|
chown openldap:openldap "$RUNDIR"
|
|
chmod 770 "$RUNDIR"
|
|
|
|
# truncate previous log
|
|
: > "$LOGFILE"
|
|
|
|
# Run in foreground (because of -d ...) and capture logs; background with &
|
|
/usr/sbin/slapd \
|
|
"${dbg_opts[@]}" \
|
|
-h "$URLS" \
|
|
-u openldap \
|
|
-g openldap \
|
|
-F /etc/ldap/slapd.d \
|
|
> "$LOGFILE" 2>&1 &
|
|
local pid=$!
|
|
echo "$pid" > "$PIDFILE"
|
|
|
|
# Wait up to 10s for readiness via ldapi:///
|
|
for _ in {1..20}; do
|
|
if ldapwhoami -H ldapi:/// >/dev/null 2>&1; then
|
|
log INFO "slapd started (pid $pid)"
|
|
return 0
|
|
fi
|
|
sleep 0.5
|
|
done
|
|
|
|
log ERROR "Timeout waiting for slapd to become ready"
|
|
# Show immediate diagnostics
|
|
tail -n 80 "$LOGFILE" | log ERROR
|
|
return 1
|
|
;;
|
|
|
|
stop)
|
|
log INFO "Stopping slapd..."
|
|
local pid=""
|
|
if [[ -r "$PIDFILE" ]]; then
|
|
pid="$(cat "$PIDFILE" 2>/dev/null || true)"
|
|
fi
|
|
|
|
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
|
kill "$pid" 2>/dev/null || true
|
|
else
|
|
# Fallback: scan /proc for a foreground slapd we started
|
|
for p in /proc/[0-9]*; do
|
|
if [[ -r "$p/comm" ]] && [[ "$(cat "$p/comm")" == "slapd" ]]; then
|
|
pid="${p##*/}"
|
|
kill "$pid" 2>/dev/null || true
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Wait up to 10s for it to exit (ldapi should drop when slapd is gone)
|
|
for _ in {1..20}; do
|
|
if ! ldapwhoami -H ldapi:/// >/dev/null 2>&1; then
|
|
log INFO "slapd stopped"
|
|
rm -f "$PIDFILE"
|
|
return 0
|
|
fi
|
|
sleep 0.5
|
|
done
|
|
|
|
log WARN "Graceful stop timed out — dumping last log lines before forcing kill:"
|
|
tail -n 120 "$LOGFILE" | log WARN
|
|
|
|
# Force kill any remaining slapd processes
|
|
for p in /proc/[0-9]*; do
|
|
if [[ -r "$p/comm" ]] && [[ "$(cat "$p/comm")" == "slapd" ]]; then
|
|
kill -9 "${p##*/}" 2>/dev/null || true
|
|
fi
|
|
done
|
|
rm -f "$PIDFILE"
|
|
log INFO "slapd forced to stop"
|
|
;;
|
|
|
|
*)
|
|
log ERROR "Usage: slapd {start|stop}"
|
|
return 2
|
|
;;
|
|
esac
|
|
}
|
|
|
|
initialized_file=/etc/ldap/slapd.d/initialized
|
|
config_version="2.6"
|
|
if [ ! -e "$initialized_file" ]; then
|
|
log BOX "Applying initial configuration..."
|
|
function substr_before() {
|
|
# shellcheck disable=SC2295 # Expansions inside ${..} need to be quoted separately, otherwise they match as patterns
|
|
echo "${1%%${2}*}"
|
|
}
|
|
|
|
function str_replace() {
|
|
IFS= read -r -d $'\0' str
|
|
echo "${str/$1/$2}"
|
|
}
|
|
|
|
# interpolate variable placeholders in env vars starting with "LDAP_INIT_"
|
|
for name in ${!LDAP_INIT_*}; do
|
|
declare "${name}=$(echo "${!name}" | interpolate)"
|
|
done
|
|
|
|
# pre-populate folders in case they are empty
|
|
for folder in "/var/lib/ldap" "/etc/ldap/slapd.d"; do
|
|
if [[ $folder -ef "${folder}_orig" ]]; then
|
|
continue
|
|
fi
|
|
if [[ -z $(ls $folder) ]]; then
|
|
log INFO "Initializing [$folder]..."
|
|
cp -r --preserve=all ${folder}_orig/. $folder
|
|
fi
|
|
done
|
|
|
|
if [[ -z ${LDAP_INIT_ROOT_USER_DN:-} ]]; then
|
|
log ERROR "LDAP_INIT_ROOT_USER_DN variable is not set!"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z ${LDAP_INIT_ROOT_USER_PW:-} ]]; then
|
|
log ERROR "LDAP_INIT_ROOT_USER_PW variable is not set!"
|
|
exit 1
|
|
fi
|
|
|
|
# shellcheck disable=SC2034 # LDAP_INIT_ROOT_USER_PW_HASHED appears unused
|
|
LDAP_INIT_ROOT_USER_PW_HASHED=$(slappasswd -s "${LDAP_INIT_ROOT_USER_PW}")
|
|
# LDAP_INIT_ROOT_USER_PW_HASHED is referenced in /opt/ldifs/init_mdb_acls.ldif
|
|
|
|
if [[ ${LDAP_INIT_RFC2307BIS_SCHEMA:-} == 1 ]]; then
|
|
log INFO "Replacing NIS (RFC2307) schema with RFC2307bis schema..."
|
|
|
|
log INFO "Exporting initial slapd config..."
|
|
initial_sldapd_config=$(slapcat -n0)
|
|
|
|
log INFO "Delete initial slapd config..."
|
|
find /etc/ldap/slapd.d/ -type f -delete
|
|
|
|
log INFO "Create modified sldapd config file..."
|
|
{
|
|
# create ldif file where "{2}nis,cn=schema,cn=config" schema is replaced by "{2}rfc2307bis,cn=schema,cn=config"
|
|
# 1. add all schema entries before "dn: cn={2}nis,cn=schema,cn=config" from initial config to new config file
|
|
echo "${initial_sldapd_config%%dn: cn=\{2\}nis,cn=schema,cn=config*}"
|
|
# 2. add "dn: cn={2}rfc2307bis,cn=schema,cn=config" entry
|
|
sed 's/rfc2307bis/{2}rfc2307bis/g' /opt/ldifs/schema_rfc2307bis02.ldif
|
|
echo # add empty new line
|
|
# 3. add entry "dn: cn={3}inetorgperson,cn=schema,cn=config" and following entries from initial config to new config file
|
|
echo "dn: cn={3}inetorgperson,cn=schema,cn=config${initial_sldapd_config#*dn: cn=\{3\}inetorgperson,cn=schema,cn=config}"
|
|
} >/tmp/config.ldif
|
|
|
|
log INFO "Register modified slapd config with RFC2307bis schema..."
|
|
slapadd -F /etc/ldap/slapd.d -n 0 -l /tmp/config.ldif | log INFO
|
|
chown openldap:openldap -R /etc/ldap/slapd.d
|
|
fi
|
|
|
|
slapd start
|
|
|
|
ldif add -Y EXTERNAL /opt/ldifs/schema_sudo.ldif
|
|
ldif add -Y EXTERNAL /opt/ldifs/schema_ldapPublicKey.ldif
|
|
|
|
ldif modify -Y EXTERNAL /opt/ldifs/init_frontend.ldif
|
|
ldif add -Y EXTERNAL /opt/ldifs/init_module_memberof.ldif
|
|
ldif modify -Y EXTERNAL /opt/ldifs/init_mdb.ldif
|
|
ldif modify -Y EXTERNAL /opt/ldifs/init_mdb_acls.ldif
|
|
ldif modify -Y EXTERNAL /opt/ldifs/init_mdb_indexes.ldif
|
|
ldif add -Y EXTERNAL /opt/ldifs/init_module_unique.ldif
|
|
ldif add -Y EXTERNAL /opt/ldifs/init_module_ppolicy.ldif
|
|
|
|
if [[ ${LDAP_INIT_ALLOW_CONFIG_ACCESS:-false} == true ]]; then
|
|
ldif modify -Y EXTERNAL /opt/ldifs/init_config_admin_access.ldif
|
|
fi
|
|
|
|
# calculate LDAP_INIT_ORG_COMPUTED_ATTRS variable, referenced in init_org_tree.ldif
|
|
if [[ -z ${LDAP_INIT_ORG_ATTR_O:-} ]] && [[ ${LDAP_INIT_ORG_DN:-} =~ [oO]=([^,]*) ]]; then
|
|
# derive 'o:' from LDAP_INIT_ORG_DN if LDAP_INIT_ORG_ATTR_O is unset and "O=..." is present
|
|
# e.g. LDAP_INIT_ORG_DN="O=example.com" -> "o: example.com"
|
|
# e.g. LDAP_INIT_ORG_DN="O=Example,DC=example,DC=com" -> "o: Example"
|
|
LDAP_INIT_ORG_ATTR_O=${BASH_REMATCH[1]}
|
|
fi
|
|
if [[ $LDAP_INIT_ORG_DN =~ [dD][cC]=([^,]*) ]]; then
|
|
LDAP_INIT_ORG_ATTR_DC=${BASH_REMATCH[1]}
|
|
# derive 'o:' from LDAP_INIT_ORG_DN if LDAP_INIT_ORG_ATTR_O is unset and "DC=..." is present
|
|
if [[ -z ${LDAP_INIT_ORG_ATTR_O:-} ]]; then
|
|
# e.g. LDAP_INIT_ORG_DN="DC=example,DC=com" -> "o: example.com"
|
|
LDAP_INIT_ORG_ATTR_O=$(echo "$LDAP_INIT_ORG_DN" | grep -ioP 'DC=\K[^,]+' | paste -sd '.')
|
|
fi
|
|
# shellcheck disable=SC2034 # LDAP_INIT_ORG_COMPUTED_ATTRS appears unused
|
|
LDAP_INIT_ORG_COMPUTED_ATTRS="objectClass: dcObject
|
|
o: $LDAP_INIT_ORG_ATTR_O
|
|
dc: $LDAP_INIT_ORG_ATTR_DC"
|
|
elif [[ -n ${LDAP_INIT_ORG_ATTR_O:-} ]]; then
|
|
# shellcheck disable=SC2034 # LDAP_INIT_ORG_COMPUTED_ATTRS appears unused
|
|
LDAP_INIT_ORG_COMPUTED_ATTRS="o: $LDAP_INIT_ORG_ATTR_O"
|
|
else
|
|
log ERROR "Unable to derive required 'o' attribute of objectClass 'organization' from LDAP_INIT_ORG_DN='$LDAP_INIT_ORG_DN'"
|
|
exit 1
|
|
fi
|
|
|
|
ldif add -x -D "$LDAP_INIT_ROOT_USER_DN" -w "$LDAP_INIT_ROOT_USER_PW" /opt/ldifs/init_org_tree.ldif
|
|
ldif add -x -D "$LDAP_INIT_ROOT_USER_DN" -w "$LDAP_INIT_ROOT_USER_PW" /opt/ldifs/init_org_ppolicy.ldif
|
|
ldif add -x -D "$LDAP_INIT_ROOT_USER_DN" -w "$LDAP_INIT_ROOT_USER_PW" /opt/ldifs/init_org_entries.ldif
|
|
|
|
log INFO "---------------------------------------"
|
|
|
|
echo "$config_version" >"$initialized_file"
|
|
rm -f /tmp/*.ldif
|
|
|
|
log INFO "Creating LDAP backup at [$LDAP_BACKUP_FILE]..."
|
|
slapcat -n 1 -l "$LDAP_BACKUP_FILE" || true
|
|
|
|
slapd stop
|
|
|
|
else
|
|
# System is already initialized - check for migrations
|
|
last_version=$(cat "$initialized_file")
|
|
|
|
# Handle legacy format (just "1" means pre-versioning, treat as 2.5)
|
|
if [[ "$last_version" == "1" ]]; then
|
|
last_version="2.5"
|
|
fi
|
|
|
|
# Check if we need to migrate from 2.5 to 2.6
|
|
if [[ "$last_version" == "2.5" ]]; then
|
|
log BOX "Migrating config to OpenLDAP 2.6..."
|
|
|
|
slapd start
|
|
|
|
# Find the actual ppolicy overlay DN (it might have an index like {0}ppolicy)
|
|
ppolicy_dn=$(ldapsearch -H ldapi:/// -Y EXTERNAL -b "olcDatabase={1}mdb,cn=config" "(objectClass=olcPPolicyConfig)" dn 2>/dev/null | grep "^dn:" | head -1 | sed 's/^dn: //')
|
|
|
|
if [[ -z "$ppolicy_dn" ]]; then
|
|
log WARN "ppolicy overlay not found in configuration, skipping password policy migration"
|
|
else
|
|
log INFO "Found ppolicy overlay at: $ppolicy_dn"
|
|
|
|
# Check if ppolicy overlay already has the new configuration
|
|
if ldapsearch -H ldapi:/// -Y EXTERNAL -b "$ppolicy_dn" -s base "(objectClass=*)" olcPPolicyCheckModule 2>/dev/null | grep -q "olcPPolicyCheckModule"; then
|
|
log INFO "Password policy overlay already configured for 2.6, skipping migration"
|
|
else
|
|
# Check for legacy pwdCheckModule entries
|
|
has_legacy_config=false
|
|
if ldapsearch -H ldapi:/// -Y EXTERNAL -b "${LDAP_INIT_ORG_DN:-DC=example,DC=com}" "(pwdCheckModule=*)" pwdCheckModule 2>/dev/null | grep -q "pwdCheckModule"; then
|
|
has_legacy_config=true
|
|
log INFO "Found legacy pwdCheckModule configuration in password policy entries"
|
|
fi
|
|
|
|
# Add new overlay configuration
|
|
log INFO "Adding OpenLDAP 2.6 password policy overlay configuration..."
|
|
cat >/tmp/migrate_ppolicy_26.ldif <<EOF
|
|
dn: $ppolicy_dn
|
|
changetype: modify
|
|
add: olcPPolicyCheckModule
|
|
olcPPolicyCheckModule: /usr/lib/ldap/pqchecker.so
|
|
EOF
|
|
|
|
if ldapmodify -H ldapi:/// -Y EXTERNAL -f /tmp/migrate_ppolicy_26.ldif 2>&1 | log INFO; then
|
|
log INFO "Successfully migrated password policy overlay configuration"
|
|
if [[ $has_legacy_config == true ]]; then
|
|
log WARN "Legacy pwdCheckModule entries found in password policy entries."
|
|
log WARN "These are now ignored in OpenLDAP 2.6 and can be removed manually if desired."
|
|
log WARN "The password checking functionality is now handled by the overlay configuration."
|
|
fi
|
|
else
|
|
log ERROR "Failed to apply password policy overlay migration"
|
|
exit 1
|
|
fi
|
|
rm -f /tmp/migrate_ppolicy_26.ldif
|
|
fi
|
|
fi
|
|
|
|
# Update version in initialized file
|
|
echo "$config_version" > "$initialized_file"
|
|
|
|
# Stop LDAP server after migrations
|
|
slapd stop
|
|
|
|
log INFO "Configuration migration completed"
|
|
elif [[ "$last_version" != "$config_version" ]]; then
|
|
log WARN "Unknown configuration version: $last_version (expected: $config_version)"
|
|
log WARN "Skipping migrations - manual intervention may be required"
|
|
else
|
|
log INFO "Configuration is up to date (version: $config_version)"
|
|
fi
|
|
fi
|
|
|
|
echo "$LDAP_PPOLICY_PQCHECKER_RULE" >/etc/ldap/pqchecker/pqparams.dat
|
|
|
|
|
|
#################################################################
|
|
# TLS configuration
|
|
#################################################################
|
|
SLAPD_EXTRA_URLS=""
|
|
|
|
if [[ $LDAP_TLS_ENABLED == true ]]; then
|
|
log BOX "Enabling TLS support..."
|
|
|
|
# configure TLS key material
|
|
cat >/tmp/tls.ldif <<EOF
|
|
dn: cn=config
|
|
changetype: modify
|
|
replace: olcTLSCertificateFile
|
|
olcTLSCertificateFile: /etc/ldap/certs/server.crt
|
|
-
|
|
replace: olcTLSCertificateKeyFile
|
|
olcTLSCertificateKeyFile: /etc/ldap/certs/server.key
|
|
EOF
|
|
if [[ -f /etc/ldap/certs/ca.crt ]]; then
|
|
cat >>/tmp/tls.ldif <<EOF
|
|
-
|
|
replace: olcTLSCACertificateFile
|
|
olcTLSCACertificateFile: /etc/ldap/certs/ca.crt
|
|
EOF
|
|
fi
|
|
|
|
# client-cert policy
|
|
cat >>/tmp/tls.ldif <<EOF
|
|
-
|
|
replace: olcTLSVerifyClient
|
|
olcTLSVerifyClient: ${LDAP_TLS_VERIFY_CLIENT:-try}
|
|
EOF
|
|
|
|
# Minimum Security Strength Factor enforcement
|
|
if [[ $LDAP_TLS_SSF == 0 ]]; then
|
|
cat >>/tmp/tls.ldif <<EOF
|
|
-
|
|
replace: olcSecurity
|
|
olcSecurity: ssf=$LDAP_TLS_SSF
|
|
EOF
|
|
fi
|
|
|
|
# ldaps:// listener
|
|
if [[ $LDAP_LDAPS_ENABLED == true ]]; then
|
|
SLAPD_EXTRA_URLS=" ldaps:///"
|
|
fi
|
|
|
|
else
|
|
log BOX "Ensuring TLS support is disabled..."
|
|
cat >/tmp/tls.ldif <<EOF
|
|
dn: cn=config
|
|
changetype: modify
|
|
delete: olcTLSCertificateFile
|
|
-
|
|
delete: olcTLSCertificateKeyFile
|
|
-
|
|
delete: olcTLSCACertificateFile
|
|
-
|
|
delete: olcTLSVerifyClient
|
|
-
|
|
delete: olcSecurity
|
|
EOF
|
|
|
|
fi
|
|
|
|
# apply TLS configuration
|
|
slapd start
|
|
if [[ ${LDAP_TLS_ENABLED} == true ]]; then
|
|
ldif modify -Y EXTERNAL /tmp/tls.ldif
|
|
else
|
|
ldif modify -c -Y EXTERNAL /tmp/tls.ldif || true # ignore "ldap_modify: No such attribute (16)"
|
|
fi
|
|
|
|
rm -f /tmp/tls.ldif
|
|
|
|
slapd stop
|
|
|
|
|
|
#################################################################
|
|
# Configure background task for LDAP backup
|
|
#################################################################
|
|
if [[ -n ${LDAP_BACKUP_TIME:-} ]]; then
|
|
|
|
if [[ -z ${LDAP_BACKUP_FILE:-} ]]; then
|
|
log ERROR "LDAP_BACKUP_FILE variable is not set!"
|
|
exit 1
|
|
fi
|
|
|
|
log BOX "Configuring LDAP backup task to run daily: time=[${LDAP_BACKUP_TIME}] file=[$LDAP_BACKUP_FILE]..."
|
|
if [[ ! $LDAP_BACKUP_TIME =~ ^([01][0-9]|2[0-3]):[0-5][0-9]$ ]]; then
|
|
log ERROR "The configured value [$LDAP_BACKUP_TIME] for LDAP_BACKUP_TIME is not in the expected 24-hour format [hh:mm]!"
|
|
exit 1
|
|
fi
|
|
|
|
# testing if LDAP_BACKUP_FILE is writeable
|
|
touch "$LDAP_BACKUP_FILE"
|
|
|
|
function backup_ldap() {
|
|
while true; do
|
|
while [[ ${LDAP_BACKUP_TIME} != "$(date +%H:%M)" ]]; do
|
|
sleep 10s
|
|
done
|
|
log INFO "Creating periodic LDAP backup at [$LDAP_BACKUP_FILE]..."
|
|
slapcat -n 1 -l "$LDAP_BACKUP_FILE" || true
|
|
sleep 23h
|
|
done
|
|
}
|
|
|
|
backup_ldap &
|
|
fi
|
|
|
|
|
|
#################################################################
|
|
# Start LDAP service
|
|
#################################################################
|
|
log BOX "Starting OpenLDAP: slapd..."
|
|
|
|
# build an array of "-d <level>" for each level in LDAP_LOG_LEVELS
|
|
log_opts=()
|
|
for lvl in ${LDAP_LOG_LEVELS:-}; do
|
|
log_opts+=("-d" "$lvl")
|
|
done
|
|
|
|
exec /usr/sbin/slapd \
|
|
"${log_opts[@]}" \
|
|
-h "ldap:/// ldapi:///$SLAPD_EXTRA_URLS" \
|
|
-u openldap \
|
|
-g openldap \
|
|
-F /etc/ldap/slapd.d 2>&1 | log INFO
|