#!/bin/bash
#
# lib/ldap
# Functions to control the installation and configuration of **ldap**

# ``lib/keystone`` calls the entry points in this order:
#
# - install_ldap()

# Save trace setting
_XTRACE_LDAP=$(set +o | grep xtrace)
set +o xtrace


LDAP_DOMAIN=${LDAP_DOMAIN:-openstack.org}
# Make an array of domain components
DC=(${LDAP_DOMAIN/./ })

# Leftmost domain component used in top-level entry
LDAP_BASE_DC=${DC[0]}

# Build the base DN
dn=""
for dc in ${DC[*]}; do
    dn="$dn,dc=$dc"
done
LDAP_BASE_DN=${dn#,}

LDAP_MANAGER_DN="${LDAP_MANAGER_DN:-cn=Manager,${LDAP_BASE_DN}}"
LDAP_URL=${LDAP_URL:-ldap://localhost}

LDAP_SERVICE_NAME=slapd

if is_ubuntu; then
    LDAP_OLCDB_NUMBER=1
    LDAP_ROOTPW_COMMAND=replace
elif is_fedora; then
    LDAP_OLCDB_NUMBER=2
    LDAP_ROOTPW_COMMAND=add
elif is_suse; then
    # SUSE has slappasswd in /usr/sbin/
    PATH=$PATH:/usr/sbin/
    LDAP_OLCDB_NUMBER=1
    LDAP_ROOTPW_COMMAND=add
    LDAP_SERVICE_NAME=ldap
fi


# Functions
# ---------

# Perform common variable substitutions on the data files
# _ldap_varsubst file
function _ldap_varsubst {
    local infile=$1
    local slappass=$2
    sed -e "
        s|\${LDAP_OLCDB_NUMBER}|$LDAP_OLCDB_NUMBER|
        s|\${SLAPPASS}|$slappass|
        s|\${LDAP_ROOTPW_COMMAND}|$LDAP_ROOTPW_COMMAND|
        s|\${BASE_DC}|$LDAP_BASE_DC|
        s|\${BASE_DN}|$LDAP_BASE_DN|
        s|\${MANAGER_DN}|$LDAP_MANAGER_DN|
    " $infile
}

# clean_ldap() - Remove ldap server
function cleanup_ldap {
    uninstall_package $(get_packages ldap)
    if is_ubuntu; then
        uninstall_package slapd ldap-utils libslp1
        sudo rm -rf /etc/ldap/ldap.conf /var/lib/ldap
    elif is_fedora; then
        sudo rm -rf /etc/openldap /var/lib/ldap
    elif is_suse; then
        sudo rm -rf /var/lib/ldap
    fi
}

# init_ldap
# init_ldap() - Initialize databases, etc.
function init_ldap {
    local keystone_ldif

    local tmp_ldap_dir
    tmp_ldap_dir=$(mktemp -d -t ldap.$$.XXXXXXXXXX)

    # Remove data but not schemas
    clear_ldap_state

    # Add our top level ldap nodes
    if ldapsearch -x -w $LDAP_PASSWORD -D "$LDAP_MANAGER_DN" -H $LDAP_URL -b "$LDAP_BASE_DN" | grep -q "Success"; then
        printf "LDAP already configured for $LDAP_BASE_DC\n"
    else
        printf "Configuring LDAP for $LDAP_BASE_DC\n"
        # If BASE_DN is changed, the user may override the default file
        if [[ -r $FILES/ldap/${LDAP_BASE_DC}.ldif.in ]]; then
            local keystone_ldif=${LDAP_BASE_DC}.ldif
        else
            local keystone_ldif=keystone.ldif
        fi
        _ldap_varsubst $FILES/ldap/${keystone_ldif}.in >$tmp_ldap_dir/${keystone_ldif}
        if [[ -r $tmp_ldap_dir/${keystone_ldif} ]]; then
            ldapadd -x -w $LDAP_PASSWORD -D "$LDAP_MANAGER_DN" -H $LDAP_URL -c -f $tmp_ldap_dir/${keystone_ldif}
        fi
    fi

    rm -rf $tmp_ldap_dir
}

# install_ldap
# install_ldap() - Collect source and prepare
function install_ldap {
    echo "Installing LDAP inside function"
    echo "os_VENDOR is $os_VENDOR"

    local tmp_ldap_dir
    tmp_ldap_dir=$(mktemp -d -t ldap.$$.XXXXXXXXXX)

    printf "installing OpenLDAP"
    if is_ubuntu; then
        configure_ldap
    elif is_fedora; then
        start_ldap
    elif is_suse; then
        _ldap_varsubst $FILES/ldap/suse-base-config.ldif.in >$tmp_ldap_dir/suse-base-config.ldif
        sudo slapadd -F /etc/openldap/slapd.d/ -bcn=config -l $tmp_ldap_dir/suse-base-config.ldif
        sudo sed -i '/^OPENLDAP_START_LDAPI=/s/"no"/"yes"/g' /etc/sysconfig/openldap
        start_ldap
    fi

    echo "LDAP_PASSWORD is $LDAP_PASSWORD"
    local slappass
    slappass=$(slappasswd -s $LDAP_PASSWORD)
    printf "LDAP secret is $slappass\n"

    # Create manager.ldif and add to olcdb
    _ldap_varsubst $FILES/ldap/manager.ldif.in $slappass >$tmp_ldap_dir/manager.ldif
    sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f $tmp_ldap_dir/manager.ldif

    # On fedora we need to manually add cosine and inetorgperson schemas
    if is_fedora; then
        sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
        sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
    fi

    rm -rf $tmp_ldap_dir
}

# configure_ldap() - Configure LDAP - reconfigure slapd
function configure_ldap {
    sudo debconf-set-selections <<EOF
    slapd slapd/internal/generated_adminpw password $LDAP_PASSWORD
    slapd slapd/internal/adminpw password $LDAP_PASSWORD
    slapd slapd/password2 password $LDAP_PASSWORD
    slapd slapd/password1 password $LDAP_PASSWORD
    slapd slapd/dump_database_destdir string /var/backups/slapd-VERSION
    slapd slapd/domain string Users
    slapd shared/organization string $LDAP_DOMAIN
    slapd slapd/backend string HDB
    slapd slapd/purge_database boolean true
    slapd slapd/move_old_database boolean true
    slapd slapd/allow_ldap_v2 boolean false
    slapd slapd/no_configuration boolean false
    slapd slapd/dump_database select when needed
EOF
    sudo apt-get install -y slapd ldap-utils
    sudo dpkg-reconfigure -f noninteractive $LDAP_SERVICE_NAME
}

# start_ldap() - Start LDAP
function start_ldap {
    sudo service $LDAP_SERVICE_NAME restart
}

# stop_ldap() - Stop LDAP
function stop_ldap {
    sudo service $LDAP_SERVICE_NAME stop
}

# clear_ldap_state() - Clear LDAP State
function clear_ldap_state {
    ldapdelete -x -w $LDAP_PASSWORD -D "$LDAP_MANAGER_DN" -H $LDAP_URL -r "$LDAP_BASE_DN" || :
}

# Restore xtrace
$_XTRACE_LDAP

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End: