#!/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=$(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=$(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=$(mktemp -d -t ldap.$$.XXXXXXXXXX)

    printf "installing OpenLDAP"
    if is_ubuntu; then
        # Ubuntu automatically starts LDAP so no need to call start_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=$(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

    pip_install ldappool

    rm -rf $tmp_ldap_dir
}

# 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

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