# 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:
