File root.obscpio of Package opensuse-openldap-image
07070100000000000081ED00000000000000000000000166BC4E6600003A61000000000000000000000000000000000000001300000000root/entrypoint.sh#!/bin/bash
DEBUG=${DEBUG:-"0"}
[ "${DEBUG}" = "1" ] && set -x
export PATH=/usr/sbin:/sbin:${PATH}
LDAP_NOFILE=${LDAP_NOFILE:-1024}
LDAP_PORT=${LDAP_PORT:-389}
LDAPS_PORT=${LDAPS_PORT:-636}
LDAPI_URL=${LDAPI_URL:-"ldapi:///"}
LDAP_UID=${LDAP_UID:-""}
LDAP_GID=${LDAP_GID:-""}
LDAP_BACKEND=${LDAP_BACKEND:-"mdb"}
SLAPD_LOG_LEVEL=${SLAPD_LOG_LEVEL:-0}
SLAPD_CONF=${SLAPD_CONF:-"/etc/openldap/slapd.d"}
SLAPD_RUN_DIR=${SLAPD_RUN_DIR:-"/run/slapd"}
SLAPD_SLP_REG=${SLAPD_SLP_REG:-"-o slp=off"}
# Default values for new database
LDAP_ORGANIZATION=${LDAP_ORGANIZATION:-"Example Inc."}
LDAP_DOMAIN=${LDAP_DOMAIN:-"example.org"}
LDAP_BASE_DN=${LDAP_BASE_DN:-""}
# TLS
LDAP_TLS=${LDAP_TLS:-"1"}
LDAP_TLS_CA_CRT=${LDAP_TLS_CA_CRT:-"/etc/openldap/certs/openldap-ca.crt"}
LDAP_TLS_CA_KEY=${LDAP_TLS_CA_KEA:-"/etc/openldap/certs/openldap-ca.key"}
LDAP_TLS_CRT=${LDAP_TLS_CRT:-"/etc/openldap/certs/tls.crt"}
LDAP_TLS_KEY=${LDAP_TLS_KEY:-"/etc/openldap/certs/tls.key"}
LDAP_TLS_DH_PARAM=${LDAP_TLS_DH_PARAM:-"/etc/openldap/certs/dhparam.pem"}
LDAP_TLS_ENFORCE=${LDAP_TLS_ENFORCE:-"0"}
LDAP_TLS_CIPHER_SUITE=${LDAP_TLS_CIPHER_SUITE:-"HIGH:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.3:!SSLv3:!SSLv2:!ADH"}
LDAP_TLS_VERIFY_CLIENT=${LDAP_TLS_VERIFY_CLIENT:-try}
# For mailserver setup
SETUP_FOR_MAILSERVER=${SETUP_FOR_MAILSERVER:-0}
setup_timezone() {
if [ -n "$TZ" ]; then
TZ_FILE="/usr/share/zoneinfo/$TZ"
if [ -f "$TZ_FILE" ]; then
echo "Setting container timezone to: $TZ"
ln -snf "$TZ_FILE" /etc/localtime
else
echo "Cannot set timezone \"$TZ\": timezone does not exist."
fi
fi
}
init_ldap_url() {
test -n "${LDAP_URL}" && return
if [ -n "${OPENLDAP_START_LDAP}" ]; then
case "$OPENLDAP_START_LDAP" in
[Yy][Ee][Ss])
if [ -n "$OPENLDAP_LDAP_INTERFACES" ]
then
for iface in $OPENLDAP_LDAP_INTERFACES ;do
LDAP_URL="$LDAP_URL ldap://$iface"
done
else
LDAP_URL="ldap:///"
fi
;;
esac
else
local FQDN
FQDN="$(/bin/hostname -f)"
LDAP_URL="ldap://$FQDN:$LDAP_PORT"
fi
}
init_ldaps_url() {
test -n "${LDAPS_URL}" && return
if [ -n "${OPENLDAP_START_LDAPS}" ]; then
case "$OPENLDAP_START_LDAPS" in
[Yy][Ee][Ss])
if [ -n "$OPENLDAP_LDAP_INTERFACES" ]
then
for iface in $OPENLDAP_LDAPS_INTERFACES ;do
LDAPS_URL="$LDAPS_URL ldaps://$iface"
done
else
LDAPS_URL="ldaps:///"
fi
;;
esac
else
local FQDN
FQDN="$(/bin/hostname -f)"
LDAPS_URL="ldaps://$FQDN:$LDAPS_PORT"
fi
}
setup_ldap_uidgid() {
CUR_LDAP_UID=$(id -u ldap)
CUR_LDAP_GID=$(id -g ldap)
LDAP_UIDGID_CHANGED=false
if [ -n "${LDAP_UID}" ] && [ "$LDAP_UID" != "$CUR_LDAP_UID" ]; then
echo "Current ldap UID (${CUR_LDAP_UID}) does not match LDAP_UID (${LDAP_UID}), adjusting..."
LDAP_UIDGID_CHANGED=true
fi
if [ -n "${LDAP_GID}" ] && [ "$LDAP_GID" != "$CUR_USER_GID" ]; then
echo "Current ldap GID (${CUR_LDAP_GID}) does not match LDAP_GID (${LDAP_GID}), adjusting..."
LDAP_UIDGID_CHANGED=true
fi
if [ "${LDAP_UIDGID_CHANGED}" = "true" ]; then
test -z "${LDAP_UID}" && LDAP_UID=${CUR_LDAP_UID}
test -z "${LDAP_GID}" && LDAP_GID=${CUR_LDAP_GID}
if [ -x /usr/sbin/usermod ] && [ -x /usr/sbin/groupmod ]; then
groupmod -o -g "$LDAP_GID" ldap
usermod -o -u "$LDAP_UID" -g "$LDAP_GID" ldap
else
sed -i -e "s|:${CUR_LDAP_UID}:${CUR_LDAP_GID}:|:${LDAP_UID}:${LDAP_GID}:|g" /etc/passwd
sed -i -e "s|:${CUR_LDAP_GID}:|:${LDAP_GID}:|g" /etc/group
fi
fi
echo 'OpenLDAP GID/UID'
echo "User uid: $(id -u ldap)"
echo "User gid: $(id -g ldap)"
echo "uid/gid changed: ${LDAP_UIDGID_CHANGED}"
# Fix permissions
chown -R ldap:ldap /var/lib/ldap
chown -R ldap:ldap /etc/openldap
}
init_slapd() {
CNT_VAR="$(ls /var/lib/ldap)"
CNT_ETC="$(ls /etc/openldap/slapd.d)"
# Do nothing if we have a config file or a database
if [ -n "${CNT_VAR}" ] && [ -n "$CNT_ETC" ]; then
return
elif [ -z "${CNT_VAR}" ] && [ -n "$CNT_ETC" ]; then
echo "ERROR: the database directory (/var/lib/ldap) is empty but not the config directory (/etc/openldap/slapd.d)" >&2
exit 1
elif [ -n "${CNT_VAR}" ] && [ -z "$CNT_ETC" ]; then
echo "ERROR: the config directory (/etc/openldap/slapd.d) is empty but not the database directory (/var/lib/ldap)" >&2
exit 1
fi
# Helper functions
function get_ldap_base_dn() {
# if LDAP_BASE_DN is empty set value from LDAP_DOMAIN
if [ -z "$LDAP_BASE_DN" ]; then
IFS='.' read -ra LDAP_BASE_DN_TABLE <<< "$LDAP_DOMAIN"
for i in "${LDAP_BASE_DN_TABLE[@]}"; do
EXT="dc=$i,"
LDAP_BASE_DN=$LDAP_BASE_DN$EXT
done
LDAP_BASE_DN=${LDAP_BASE_DN::-1}
fi
}
function init_slapd_d() {
local initldif failed
echo "Creating initial slapd configuration... "
# Create the slapd.d directory.
rm -rf "${SLAPD_CONF}/cn=config" "${SLAPD_CONF}/cn=config.ldif"
mkdir -p "${SLAPD_CONF}"
initldif=$(mktemp -t slapadd.XXXXXX)
sed -e "s|@SUFFIX@|${LDAP_BASE_DN}|g" \
-e "s|@PASSWORD@|${LDAP_ADMIN_PASSWORD}|g" \
/entrypoint/slapd.init.ldif > "${initldif}"
slapadd -F "${SLAPD_CONF}" -b "cn=config" \
-l "${initldif}" || failed=1
if [ "$failed" ]; then
rm -f "${initldif}"
echo "Loading initial configuration failed!" >&2
exit 1
fi
rm -f "${initldif}"
}
function create_new_directory() {
local dc
dc="$(echo "${LDAP_DOMAIN}" | sed 's/^\.//; s/\..*$//')"
echo "Creating LDAP directory... " >&2
initldif=$(mktemp -t slapadd.XXXXXX)
cat <<-EOF > "${initldif}"
dn: ${LDAP_BASE_DN}
objectClass: top
objectClass: dcObject
objectClass: organization
o: ${LDAP_ORGANIZATION}
dc: $dc
dn: cn=admin,${LDAP_BASE_DN}
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword: ${LDAP_ADMIN_PASSWORD}
EOF
slapadd -F "${SLAPD_CONF}" -b "${LDAP_BASE_DN}" \
-l "${initldif}" || failed=1
if [ "$failed" ]; then
rm -f "${initldif}"
echo "Loading initial configuration failed!" >&2
exit 1
fi
rm -f "${initldif}"
}
function is_new_schema() {
local COUNT
COUNT=$(ldapsearch -Q -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config cn | grep -c "}$1,")
if [ "$COUNT" -eq 0 ]; then
echo 1
else
echo 0
fi
}
function adjust_ldif_file() {
local LDIF_FILE
LDIF_FILE="$1"
sed -i "s|@LDAP_BASE_DN@|${LDAP_BASE_DN}|g" "${LDIF_FILE}"
sed -i "s|@LDAP_BACKEND@|${LDAP_BACKEND}|g" "${LDIF_FILE}"
sed -i "s|@LDAP_DOMAIN@|${LDAP_DOMAIN}|g" "${LDIF_FILE}"
if [ -n "${MAIL_ACCOUNT_READER_PASSWORD}" ]; then
sed -i "s|@MAIL_ACCOUNT_READER_PASSWORD@|${MAIL_ACCOUNT_READER_PASSWORD}|g" "${LDIF_FILE}"
fi
}
function ldap_add_or_modify() {
local failed
local LDIF_FILE=$1
echo "Processing file ${LDIF_FILE}"
adjust_ldif_file "${LDIF_FILE}"
if grep -iq changetype "${LDIF_FILE}" ; then
ldapmodify -Y EXTERNAL -Q -H ldapi:/// -D "cn=admin,${LDAP_BASE_DN}" -w "${LDAP_ADMIN_PASSWORD}" -f "${LDIF_FILE}" || failed=1
if [ "$failed" ]; then
echo "ERROR: ldapmodify failed!"
exit 1
fi
else
ldapadd -Y EXTERNAL -Q -H ldapi:/// -D "cn=admin,${LDAP_BASE_DN}" -w "$LDAP_ADMIN_PASSWORD" -f "${LDIF_FILE}" || failed=1
if [ "$failed" ]; then
echo "ERROR: ldapadd failed!"
exit 1
fi
fi
}
function setup_tls() {
if [ "${LDAP_TLS}" != "1" ]; then
return
fi
echo "Add TLS config..."
mkdir -p /etc/openldap/certs
/common-scripts/ssl-helper "$LDAP_TLS_CRT" "$LDAP_TLS_KEY" "$LDAP_TLS_CA_CRT" "$LDAP_TLS_CA_KEY"
# make sure slapd is allowed to read it the files
chown ldap:ldap "$LDAP_TLS_CRT" "$LDAP_TLS_KEY"
# create DHParamFile if not found
if [ ! -f "${LDAP_TLS_DH_PARAM}" ]; then
openssl genpkey -genparam -algorithm DH \
-out "${LDAP_TLS_DH_PARAM}" \
-pkeyopt dh_paramgen_prime_len:2048
chmod 600 "${LDAP_TLS_DH_PARAM}"
chown ldap:ldap "${LDAP_TLS_DH_PARAM}"
fi
# adapt tls ldif
sed -i "s|@LDAP_TLS_CA_CRT_PATH@|${LDAP_TLS_CA_CRT}|g" /entrypoint/tls/enable.ldif
sed -i "s|@LDAP_TLS_CRT_PATH@|${LDAP_TLS_CRT}|g" /entrypoint/tls/enable.ldif
sed -i "s|@LDAP_TLS_KEY_PATH@|${LDAP_TLS_KEY}|g" /entrypoint/tls/enable.ldif
sed -i "s|@LDAP_TLS_DH_PARAM_PATH@|${LDAP_TLS_DH_PARAM}|g" /entrypoint/tls/enable.ldif
sed -i "s|@LDAP_TLS_CIPHER_SUITE@|${LDAP_TLS_CIPHER_SUITE}|g" /entrypoint/tls/enable.ldif
sed -i "s|@LDAP_TLS_VERIFY_CLIENT@|${LDAP_TLS_VERIFY_CLIENT}|g" /entrypoint/tls/enable.ldif
ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f /entrypoint/tls/enable.ldif
# enforce TLS
if [ "${LDAP_TLS_ENFORCE}" = "1" ]; then
echo "Enforce TLS..."
ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f /entrypoint/tls/enforce-enable.ldif
fi
# stop OpenLDAP
echo "Stopping temporary OpenLDAP slapd daemon..."
SLAPD_PID=$(cat /run/slapd/slapd.pid)
kill -15 "$SLAPD_PID"
while [ -e /proc/"$SLAPD_PID" ]; do sleep 1; done # wait until slapd is terminated
}
echo "Database and config directory are empty..."
echo "Init new ldap server..."
file_env 'LDAP_ADMIN_PASSWORD'
if [ -z "${LDAP_ADMIN_PASSWORD}" ]; then
echo "LDAP admin password (LDAP_ADMIN_PASSWORD) not set!" >&2
exit 1
fi
file_env 'LDAP_CONFIG_PASSWORD'
if [ -z "${LDAP_CONFIG_PASSWORD}" ]; then
echo "LDAP config password (LDAP_CONFIG_PASSWORD) not set!" >&2
exit 1
fi
get_ldap_base_dn
init_slapd_d
create_new_directory
chown -R ldap:ldap "${SLAPD_CONF}"
chown -R ldap:ldap /var/lib/ldap
# start slapd for further initialization work
# (No double quote for SLAPD_SLP_REG)
# shellcheck disable=SC2086
/usr/sbin/slapd -d "${SLAPD_LOG_LEVEL}" -u ldap -g ldap \
-h "ldapi:///" ${SLAPD_SLP_REG} &
echo "Waiting for OpenLDAP to start..."
while [ ! -e /run/slapd/slapd.pid ]; do sleep 1; done
echo "Add bootstrap schemas..."
# add ppolicy schema
ldapadd -c -Y EXTERNAL -Q -H ldapi:/// -f /etc/openldap/schema/ppolicy.ldif
mkdir -p /entrypoint/schema/custom
mkdir -p /entrypoint/ldif/custom
# Seed ldif if a path is specified
file_env 'LDAP_SEED_LDIF_PATH'
if [ -n "${LDAP_SEED_LDIF_PATH}" ]; then
cp -R "${LDAP_SEED_LDIF_PATH}"/*.ldif /entrypoint/ldif/custom/
fi
# Seed schema if a path is specified
file_env 'LDAP_SEED_SCHEMA_PATH'
if [ -n "${LDAP_SEED_SCHEMA_PATH}" ]; then
cp -R "${LDAP_SEED_SCHEMA_PATH}"/*.schema /entrypoint/schema/custom/
fi
# convert schemas to ldif
for f in $(find /entrypoint/schema -name \*.schema -type f); do
ldif_file="$(basename "${f}" .schema).ldif"
schema_dir=$(dirname "${f}")
schema2ldif "${f}" > "${schema_dir}/${ldif_file}"
done
for f in $(find entrypoint/schema -name \*.ldif -type f); do
echo "Processing file ${f}"
# add schema if not already exists
SCHEMA=$(basename "${f}" .ldif)
ADD_SCHEMA=$(is_new_schema "$SCHEMA")
if [ "$ADD_SCHEMA" -eq 1 ]; then
ldapadd -c -Y EXTERNAL -Q -H ldapi:/// -f "$f"
else
echo "schema ${f} already exists"
fi
done
# set config password
LDAP_CONFIG_PASSWORD_ENCRYPTED=$(slappasswd -s "$LDAP_CONFIG_PASSWORD")
sed -i -e "s|@LDAP_CONFIG_PASSWORD_ENCRYPTED@|${LDAP_CONFIG_PASSWORD_ENCRYPTED}|g" /entrypoint/ldif/set-config-password.ldif
ldap_add_or_modify /entrypoint/ldif/set-config-password.ldif
rm -f /entrypoint/ldif/set-config-password.ldif
ldap_add_or_modify /entrypoint/ldif/security.ldif
rm -f /entrypoint/ldif/security.ldif
ldap_add_or_modify /entrypoint/ldif/memberOf.ldif
ldap_add_or_modify /entrypoint/ldif/refint.ldif
ldap_add_or_modify /entrypoint/ldif/postfix.ldif
ldap_add_or_modify /entrypoint/ldif/index.ldif
# process config files (*.ldif) in custom directory
echo "Add image bootstrap ldif..."
for f in $(find /entrypoint/ldif/custom -mindepth 1 -maxdepth 1 -type f -name \*.ldif | sort); do
ldap_add_or_modify "$f"
done
if [ "${SETUP_FOR_MAILSERVER}" = "1" ]; then
echo "Setup for mailserver..."
file_env 'MAIL_ACCOUNT_READER_PASSWORD'
if [ -z "${MAIL_ACCOUNT_READER_PASSWORD}" ]; then
echo "Password for mail account reader (MAIL_ACCOUNT_READER_PASSWORD) not set!" >&2
exit 1
fi
for f in /entrypoint/ldif/mailserver/*.ldif ; do
ldap_add_or_modify "$f"
done
else
for f in /entrypoint/ldif/mailserver/*.ldif ; do
echo "Adjusting $f"
adjust_ldif_file "$f"
done
fi
# Check or create certificates
setup_tls
}
# ldap client config
setup_ldap_conf() {
if [ "${LDAP_TLS}" = "1" ]; then
echo "Configure ldap client TLS configuration..."
echo "TLS_CACERT ${LDAP_TLS_CA_CRT}" >> /etc/openldap/ldap.conf
echo "TLS_REQCERT ${LDAP_TLS_VERIFY_CLIENT}" >> /etc/openldap/ldap.conf
[[ -f "$HOME/.ldaprc" ]] && rm -f "$HOME/.ldaprc"
echo "TLS_CERT ${LDAP_TLS_CRT}" > "$HOME/.ldaprc"
echo "TLS_KEY ${LDAP_TLS_KEY}" >> "$HOME/.ldaprc"
fi
}
# usage: file_env VAR [DEFAULT]
# ie: file_env 'LDAP_ADMIN_PASSWORD' 'example'
# (will allow for "$LDAP_ADMIN_PASSWORD_FILE" to fill in the value of
# "$LDAP_ADMIN_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
var="$1"
fileVar="${var}_FILE"
def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
val="$def"
if [ "${!var:-}" ]; then
val="${!var}"
elif [ "${!fileVar:-}" ]; then
val="$(< "${!fileVar}")"
fi
export "$var"="$val"
unset "$fileVar"
}
# if command starts with an option, prepend slapd
if [ "${1:0:1}" = '-' ]; then
set -- /usr/sbin/slapd "$@"
fi
# shellcheck disable=SC1091
test -f /etc/sysconfig/openldap && . /etc/sysconfig/openldap
# Reduce maximum number of number of open file descriptors
# see https://github.com/docker/docker/issues/8231
ulimit -n "$LDAP_NOFILE"
# Generic setup
setup_timezone
setup_ldap_uidgid
echo "Updating certificate store..."
update-ca-certificates
if [ "$1" = '/usr/sbin/slapd' ]; then
if [ ! -d "$SLAPD_RUN_DIR" ]; then
mkdir -p "$SLAPD_RUN_DIR"
chown -R ldap:ldap "$SLAPD_RUN_DIR"
fi
# slapd specific initialization
init_ldap_url
init_ldaps_url
init_slapd
setup_ldap_conf
echo "Starting OpenLDAP server"
# (No double quote for SLAPD_SLP_REG)
# shellcheck disable=SC2086
exec /usr/sbin/slapd -d "${SLAPD_LOG_LEVEL}" -u ldap -g ldap \
-h "$LDAP_URL $LDAPS_URL $LDAPI_URL" ${SLAPD_SLP_REG}
else
setup_ldap_conf
exec "$@"
fi
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!30 blocks