#!/bin/sh name="${__target_host}" manager_dn=$(cat "${__object}/parameter/manager-dn") manager_password_hash=$(cat "${__object}/parameter/manager-password-hash") serverid=$(cat "${__object}/parameter/serverid") suffix=$(cat "${__object}/parameter/suffix") slapd_modules=$(cat "${__object}/parameter/module" 2>/dev/null || true) schemas=$(cat "${__object}/parameter/schema") slapd_urls=$(tr '\n' ' ' < "${__object}/parameter/slapd-url") tls_cipher_suite=$(cat "${__object}/parameter/tls-cipher-suite" 2>/dev/null || true) extra_config=$(cat "${__object}/parameter/extra-config" || true) os="$(cat "${__global}/explorer/os")" # Setup OS-dependent vars CONF_OWNER="root" CONF_GROUP="root" case "${os}" in freebsd) PKGS="openldap-server" ETC="/usr/local/etc" SLAPD_DIR="/usr/local/etc/openldap" SLAPD_DATA_DIR="/var/db/openldap-data" SLAPD_RUN_DIR="/var/run/openldap" SLAPD_MODULE_PATH="/usr/local/libexec/openldap" SLAPD_MODULE_TYPE="la" if [ -z "${slapd_modules}" ]; then # It looks like ppolicy and syncprov must be compiled slapd_modules="back_mdb back_monitor" fi CONF_OWNER="ldap" CONF_GROUP="ldap" if [ -z "${tls_cipher_suite}" ]; then # TODO: research default for FreeBSD. 'NORMAL' appears to not work tls_cipher_suite="HIGH:MEDIUM:+SSLv2" fi ;; debian|ubuntu|devuan) PKGS="slapd ldap-utils" ETC="/etc" SLAPD_DIR="/etc/ldap" SLAPD_DATA_DIR="/var/lib/ldap" SLAPD_RUN_DIR="/var/run/slapd" SLAPD_MODULE_PATH="/usr/lib/ldap" SLAPD_MODULE_TYPE="la" if [ -z "${slapd_modules}" ]; then slapd_modules="back_mdb ppolicy syncprov back_monitor" fi CONF_OWNER="openldap" CONF_GROUP="openldap" if [ -z "${tls_cipher_suite}" ]; then tls_cipher_suite="NORMAL" fi ;; alpine) PKGS="openldap openldap-clients" ETC="/etc" SLAPD_DIR="/etc/openldap" SLAPD_DATA_DIR="/var/lib/openldap" SLAPD_RUN_DIR="/var/run/openldap" SLAPD_MODULE_PATH="/usr/lib/openldap" SLAPD_MODULE_TYPE="so" if [ -z "${slapd_modules}" ]; then slapd_modules="back_mdb ppolicy syncprov back_monitor" PKGS="$PKGS openldap-back-mdb openldap-back-monitor openldap-overlay-all" fi CONF_OWNER="ldap" CONF_GROUP="$SLAPD_USER" if [ -z "${tls_cipher_suite}" ]; then tls_cipher_suite="DEFAULT" fi ;; *) echo "Don't know the openldap defaults for: $os" >&2 exit 1 ;; esac PKG_MAIN=$(echo "${PKGS}" | awk '{print $1;}') # Determine if __letsencrypt_cert is to be used and setup vars accordingly if [ -f "${__object}/parameter/tls-cert" ]; then tls_cert=$(cat "${__object}/parameter/tls-cert") if [ ! -f "${__object}/parameter/tls-privkey" ]; then echo "When tls-cert is defined, tls-privkey is also required." >&2 exit 1 fi tls_privkey=$(cat "${__object}/parameter/tls-privkey") if [ ! -f "${__object}/parameter/tls-ca" ]; then echo "When tls-cert is defined, tls-ca is also required." >&2 exit 1 fi tls_ca=$(cat "${__object}/parameter/tls-ca") _skip_letsencrypt_cert="YES" else if [ ! -f "${__object}/parameter/admin-email" ]; then echo "When using __letsencrypt_cert, admin-email is also required." >&2 exit 1 fi admin_email=$(cat "${__object}/parameter/admin-email") tls_cert="${SLAPD_DIR}/sasl2/cert.pem" tls_privkey="${SLAPD_DIR}/sasl2/privkey.pem" tls_ca="${SLAPD_DIR}/sasl2/chain.pem" fi mkdir "${__object}/files" ldapconf="${__object}/files/ldapconf" replication="" if [ -f "${__object}/parameter/replicate" ]; then replication=yes if [ ! -f "${__object}/parameter/syncrepl-searchbase" ]; then echo "Requiring the searchbase for replication" >&2 exit 1 fi syncrepl_searchbase=$(cat "${__object}/parameter/syncrepl-searchbase") if [ ! -f "${__object}/parameter/syncrepl-credentials" ]; then echo "Requiring credentials for replication" >&2 exit 1 fi syncrepl_credentials=$(cat "${__object}/parameter/syncrepl-credentials") if [ ! -f "${__object}/parameter/syncrepl-host" ]; then echo "Requiring host(s) for replication" >&2 exit 1 fi syncrepl_hosts=$(cat "${__object}/parameter/syncrepl-host") fi # Install required packages for pkg in ${PKGS}; do __package "${pkg}" done require="__package/${PKG_MAIN}" __start_on_boot slapd # Setup -h flag for the listeners. See man slapd (-h flag). case "${os}" in freebsd) require="__start_on_boot/slapd" __key_value \ --file "/etc/rc.conf" \ --key "slapd_flags" \ --value "\"-h '${slapd_urls}'\"" \ --delimiter "=" \ --comment "# LDAP Listener URLs" \ "${__target_host}__slapd_flags" ;; debian|ubuntu|devuan) require="__package/${PKG_MAIN}" __line rm_slapd_conf \ --file ${ETC}/default/slapd \ --regex 'SLAPD_CONF=.*' \ --state absent require="__package/${PKG_MAIN}" __line rm_slapd_services \ --file ${ETC}/default/slapd \ --regex 'SLAPD_SERVICES=.*' \ --state absent require="__line/rm_slapd_conf" __line add_slapd_conf \ --file ${ETC}/default/slapd \ --line "SLAPD_CONF=${SLAPD_DIR}/slapd.conf" \ --state present require="__line/rm_slapd_services" __line add_slapd_services \ --file ${ETC}/default/slapd \ --line "SLAPD_SERVICES=\"${slapd_urls}\"" \ --state present ;; alpine) require="__package/${PKG_MAIN}" __line add_slapd_services \ --file ${ETC}/conf.d/slapd \ --line "command_args=\"-h '${slapd_urls}'\"" \ --state present ;; *) # Nothing to do here, move on. ;; esac if [ -z "${_skip_letsencrypt_cert}" ]; then if [ -f "${__object}/parameter/staging" ]; then staging="--staging" else staging="" fi # shellcheck disable=SC2086 __directory ${SLAPD_DIR}/sasl2 require="__directory/${SLAPD_DIR}/sasl2" __letsencrypt_cert "${name}" \ --admin-email "${admin_email}" \ --renew-hook "cp ${ETC}/letsencrypt/live/${name}/*.pem ${SLAPD_DIR}/sasl2 && chown -R ${CONF_OWNER}:${CONF_GROUP} ${SLAPD_DIR}/sasl2 && service slapd restart" \ --automatic-renewal "${staging}" fi require="__package/${PKG_MAIN}" __directory ${SLAPD_DIR}/slapd.d --state absent if [ -z "${_skip_letsencrypt_cert}" ]; then require="__package/${PKG_MAIN} __letsencrypt_cert/${name}" \ __file "${SLAPD_DIR}/slapd.conf" --owner "${CONF_OWNER}" --group "${CONF_GROUP}" --mode 644 \ --source "${ldapconf}" else require="__package/${PKG_MAIN}" \ __file "${SLAPD_DIR}/slapd.conf" --owner "${CONF_OWNER}" --group "${CONF_GROUP}" --mode 644 \ --source "${ldapconf}" fi # Start slapd.conf cat << EOF > "${ldapconf}" pidfile ${SLAPD_RUN_DIR}/slapd.pid argsfile ${SLAPD_RUN_DIR}/slapd.args TLSCipherSuite ${tls_cipher_suite} TLSCertificateFile ${tls_cert} TLSCertificateKeyFile ${tls_privkey} TLSCACertificateFile ${tls_ca} disallow bind_anon require bind security tls=1 EOF # Add specified schemas for schema in ${schemas}; do echo "include ${SLAPD_DIR}/schema/${schema}.schema" >> "${ldapconf}" done # Add specified modules echo "modulepath ${SLAPD_MODULE_PATH}" >> "${ldapconf}" for module in ${slapd_modules}; do echo "moduleload ${module}.${SLAPD_MODULE_TYPE}" >> "${ldapconf}" done # Rest of the config cat << EOF >> "${ldapconf}" loglevel 1024 database mdb maxsize 1073741824 suffix "${suffix}" directory ${SLAPD_DATA_DIR} rootdn "${manager_dn}" rootpw "${manager_password_hash}" index objectClass eq,pres index ou,cn,mail,surname,givenname eq,pres,sub index uidNumber,gidNumber,loginShell eq,pres index uid,memberUid eq,pres,sub index nisMapName,nisMapEntry eq,pres,sub index entryCSN,entryUUID eq ${extra_config} serverid ${serverid} EOF # Setup replication if [ "${replication}" ]; then rid=1; for syncrepl in ${syncrepl_hosts}; do cat <> "${ldapconf}" syncrepl rid=${rid} provider=ldap://${syncrepl} bindmethod=simple starttls=yes binddn="${manager_dn}" credentials=${syncrepl_credentials} searchbase="${syncrepl_searchbase}" type=refreshAndPersist retry="5 + 5 +" interval=00:00:00:05 EOF rid=$((rid + 1)) done cat <> "${ldapconf}" mirrormode true overlay syncprov syncprov-checkpoint 100 5 syncprov-sessionlog 100 database monitor limits dn.exact="${manager_dn}" time=unlimited size=unlimited EOF fi