#!/bin/bash

#====================================================================
# CLI script for OpenLDAP
# (http://www.openldap.org).
# 
# chkconfig: 2345 27 73
# description: OpenLDAP
#
# Copyright (C) 2017 David COUTADEUR
# Copyright (C) 2008 Jonathan CLARKE
# Copyright (C) 2007 Olivier LI-KIANG-CHEONG
# Copyright (C) 2007 Thomas CHEMINEAU
# Copyright (C) 2005 Sebastien BAHLOUL 
# Copyright (C) 2005 Raphael OUAZANA 
# Copyright (C) 2005 Clement OUDOT
# Copyright (C) 2010-2021 LTB-project.org
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# GPL License: http://www.gnu.org/licenses/gpl.txt
#
#====================================================================

#====================================================================
# Version
#====================================================================
VERSION="2.9"

#====================================================================
# CLI configuration file, for overloading every variable below
#====================================================================
PROG_NAME=`basename $0 | sed 's/^[KS][0-9][0-9]//'` # For nice messages
CLI_CONF_FILE=/usr/local/openldap/etc/openldap/${PROG_NAME}.conf


#====================================================================
# Default parameters (unless /usr/local/openldap/etc/openldap/{script_name}.conf)
#====================================================================
# IP and port to listen (use wildcard * in IP to listen on all interfaces)
IP="*"
SSLIP="*"
PORT="389"
SSLPORT="636"
LDAPI_SOCKETDIR=""
LDAPI_SOCKETURL=""

# OpenLDAP directory and files
SLAPD_PATH="/usr/local/openldap"
SLAPD_PID_FILE="$SLAPD_PATH/var/run/slapd.pid"
SLAPD_CONF="$SLAPD_PATH/etc/openldap/slapd.conf"
SLAPD_CONF_DIR=""
SLAPD_SERVICES="ldap://$IP:$PORT ldaps://$SSLIP:$SSLPORT"
SLAPD_PARAMS=""
SLAPD_BIN="$SLAPD_PATH/libexec/slapd"
SLAPD_USER=""
SLAPD_GROUP=""
SLAPD_SYSLOG_LOCAL_USER="local4"
SLAPD_MODULEDIR="$SLAPD_PATH/libexec/openldap"

DATA_PATH="$SLAPD_PATH/var/openldap-data"

SLAPADD_BIN="$SLAPD_PATH/sbin/slapadd"
SLAPADD_PARAMS="-q"
SLAPCAT_BIN="$SLAPD_PATH/sbin/slapcat"
SLAPCAT_PARAMS="-o ldif-wrap=no"
SLAPINDEX_BIN="$SLAPD_PATH/sbin/slapindex"
SLAPTEST_BIN="$SLAPD_PATH/sbin/slaptest"
LDAPSEARCH_BIN="${SLAPD_PATH}/bin/ldapsearch"

# Backup
BACKUP_AT_SHUTDOWN="1"
BACKUP_PATH="/tmp/openldap"
BACKUP_SUFFIX="`date +%Y%m%d%H%M%S`.ldif"
BACKUP_COMPRESS_EXT="" # gz, bz2, ...
BACKUP_COMPRESS_BIN="" # /bin/gzip, /bin/bzip2, ...
BACKUP_UNCOMPRESS_BIN="" # /bin/gunzip, /bin/bunzip2, ...

# Other
TIMEOUT="60"      # Max time to stop process
FD_LIMIT="2048"   # Max file descriptor
DEBUG_LEVEL="256" # Debug loglevel
UMASK="umask"
MASK="0027"

SLAPD_VERSION="2.5" # OpenLDAP version: major.minor (don't include .patch)
OS=`uname -s`   # To adapt message printing
MYUID=`id -u`     # For UNIX compatibility => modify this command
MYGID=`id -g`     # For UNIX compatibility => modify this command
declare -A PROVIDER

# Return functions' value
RETVAL=""

#====================================================================
# Message function
#====================================================================
message() {
	# $1: syslog level
	# $2: message

	# Log to syslog
	logger -p "$SLAPD_SYSLOG_LOCAL_USER.$1" -t $PROG_NAME -i "$2"

	# Output to console
	if [ "$1" = "alert" ]
	then
		echo "$PROG_NAME: $2">&2
	else
		echo "$PROG_NAME: $2">&1
	fi
}

#====================================================================
# Specific functions
#====================================================================

get_confvalues() {
	# $1: parameter
	# $RETVAL: list of values

        # Search in conffile or backconfig
	if [ -n "$SLAPD_CONF_DIR" ]; then
        case $1 in
	directory)
		backconfig_get_values "olcDbDirectory"
	;;
	suffix)
		backconfig_get_values "olcSuffix" "(|(objectclass=olcBdbConfig)(objectclass=olcHdbConfig)(objectclass=olcMdbConfig))"
	;;
        *)
		RETVAL=""
	;;
	esac
        else
		conffile_get_values $1
	fi
}

conffile_get_values() {
	# $1: parameter in slapd.conf
	# $RETVAL: list of values

	list=`sed "s/\r//" $SLAPD_CONF | grep "^$1[[:space:]]" | grep -v '^#' | sed "s/$1[[:space:]]*//" | sed "s/ /#20/g"| sed -e 's/"//g'`

	if [ "$list" ]; then
		RETVAL="$list"
	else
		RETVAL=""
	fi
}

backconfig_get_values() {
	# $1: parameter
	# $2: LDAP filter (optional)
	# $RETVAL: list of returned values

	if [ -z "$SLAPD_CONF_DIR" -o ! -d "$SLAPD_CONF_DIR" ]
	then
		message "alert" "[ALERT] Could not parse configuration directory"
		RETVAL=""
		return
	fi

	slapcat_cmd="$SLAPCAT_BIN $SLAPCAT_PARAMS -F $SLAPD_CONF_DIR -b cn=config"
	if [ -n "$2" ]
	then
		if [ -n "$SU" ]; then
			slapcat_cmd="$slapcat_cmd -a '$2'"
		else
			slapcat_cmd="$slapcat_cmd -a $2"
		fi
	fi
	if [ -z "$SU" ]
	then
		list=$( $slapcat_cmd | grep "^$1:" | sed "s/$1: //" | sed "s/ /#20/g" )
	else
		list=$( $SU "$slapcat_cmd" | grep "^$1:" | sed "s/$1: //" | sed "s/ /#20/g" )
	fi

	if [ -n "$list" ]; then
		RETVAL="$list"
	else
		RETVAL=""
	fi
}

syncrepl_get_value() {
	# $1: syncrepl value
	# $2: parameter in syncrepl value
	# $RETVAL: value

	syncrepl=$1
	parameter=$2

	# Check if parameter value is surrounded with quotes
	echo "$syncrepl" | grep -e $parameter'="' > /dev/null
	noquotes=$?

	if [ $noquotes -gt 0 ]
	then
		RETVAL=$( echo "$syncrepl" | sed -e 's/.*'$parameter'[ \t]*=[ \t]*\([^ \t]\+\).*$/\1/' | sed -e 's/["]//g' | sed -e "s/[']//g")
	else
		RETVAL=$( echo "$syncrepl" | sed -e 's/.*'$parameter'[ \t]*=[ \t]*"\([^"\t]\+\)".*$/\1/' | sed -e 's/["]//g' | sed -e "s/[']//g");
	fi
}

#====================================================================
# Load specific parameters
#====================================================================
if [ -f ${CLI_CONF_FILE} ]
then
	. ${CLI_CONF_FILE}
	message "info" "[INFO] Using ${CLI_CONF_FILE} for configuration"
else
	message "info" "[INFO] Using built-in configuration - this may cause some problems"
fi

# Use systemd to manage the service if it's present
_use_systemctl=0

# When systemd runs a shell script, bash sets PPID to 1 (init)
if [ $PPID -ne 1 ] && \
    # This variable lets the user disable systemd redirection
    [ -z "$SYSTEMCTL_SKIP_REDIRECT" ] && \
    # This tests whether systemd is currently managing the systemd
    [ -d /run/systemd/system ] && \
    # This variable is set when systemd >=232 runs a service
    # We need this test in case systemd does not run the slapd-cli script
    # directly (PPID>1) but runs it through /etc/init.d/slapd
    [ -z "$INVOCATION_ID" ]  ;
then
	SYSTEMD_SERVICE_NAME=slapd-ltb
	SYSTEMD_LLOAD_SERVICE_NAME=lload-ltb
	_use_systemctl=1
fi

if [ "$SLAPD_USER" = "" ] ; then
	PS_COMMAND_PID="ps -o pid -e"
	PS_COMMAND_CMD="ps -o cmd -e"
else
	PS_COMMAND_PID="ps -o pid -u $SLAPD_USER"
	PS_COMMAND_CMD="ps -o cmd -u $SLAPD_USER"
fi


#====================================================================
# Initiate 'su' command
#====================================================================
if [ "$SLAPD_USER" -a $MYUID -eq 0 ]
then
	SU="su -s /bin/bash - $SLAPD_USER -c "
fi

#====================================================================
# Initial checks
#====================================================================

# Make sure the pidfile directory exists with correct permissions
piddir=`dirname "$SLAPD_PID_FILE"`
if [ ! -d "$piddir" ]; then
	mkdir -p "$piddir"
	[ -z "$SLAPD_USER" ] || chown -R "$SLAPD_USER" "$piddir"
	[ -z "$SLAPD_GROUP" ] || chgrp -R "$SLAPD_GROUP" "$piddir"
fi

# Rights to execute binaries
for i in "$SLAPD_BIN" "$SLAPCAT_BIN" "$SLAPINDEX_BIN" "$SLAPTEST_BIN" "$LDAPSEARCH_BIN"
do
	if [ ! -x $i ]
	then
		message "alert" "[ALERT] Can't execute $i"
		exit 1
	fi
done

# Rights to read configuration
if [ "$SLAPD_CONF" -a ! -r "$SLAPD_CONF" ]
then
	message "alert" "[ALERT] Can't read $SLAPD_CONF"
	exit 1
fi

# Is there a configuration directory ?
if [ "$SLAPD_CONF_DIR" -a ! -w "$SLAPD_CONF_DIR" ]
then
	message "alert" "[ALERT] Can't write to configuration directory $SLAPD_CONF_DIR"
	exit 1
fi

# Are you root (for port < 1024)?
if [ $PORT -lt 1024 -a $MYUID -ne 0 ]
then
	message "alert" "[ALERT] Only root can launch OpenLDAP on port $PORT"
	exit 1
fi

# Create LDAPI socket
if [ "$LDAPI_SOCKETDIR" -a ! -r "$LDAPI_SOCKETDIR" ]
then
    message "info" "[INFO] Create LDAPI socket dir $LDAPI_SOCKETDIR"
    mkdir -p "$LDAPI_SOCKETDIR"
    [ -z "$SLAPD_USER" ] || chown -R "$SLAPD_USER" "$LDAPI_SOCKETDIR"
    [ -z "$SLAPD_GROUP" ] || chgrp -R "$SLAPD_GROUP" "$LDAPI_SOCKETDIR"
fi

#====================================================================
# Functions
#====================================================================

display_usage() {
	bold=$(tput bold)
	normal=$(tput sgr0)
	printf "%s\n" "${bold}Usage: $0 action [optional arguments]${normal}"
	printf "%s\n" " action is a keyword between:"
	printf "%s\n" "  - ${bold}start${normal}: start the slapd server"
	printf "%s\n" "  - ${bold}stop${normal}: stop the slapd server"
	printf "%s\n" "  - ${bold}forcestop${normal}: kill the slapd server if it can't stop"
	printf "%s\n" "  - ${bold}restart${normal}: restart the slapd server"
	printf "%s\n" "  - ${bold}debug${normal}: start the slapd server in debug mode (stay attached)"
	printf "%s\n" "  - ${bold}force-restart${normal}: forcestop + start"
	printf "%s\n" "  - ${bold}status${normal}: get the status of currently running slapd server"
	printf "%s\n" "  - ${bold}configtest${normal}: test configuration syntax"
	printf "%s\n" "  - ${bold}reindex${normal}: index or reindex database"
	printf "%s\n" "  - ${bold}backup${normal}: backup the data"
	printf "%s\n" "  - ${bold}restore${normal}: restore the data"
	printf "%s\n" "  - ${bold}backupconfig${normal}: backup the configuration"
	printf "%s\n" "  - ${bold}restoreconfig${normal}: restore the configuration"
	printf "%s\n" "  - ${bold}checksync${normal}: check the synchronization state of the current instance to every provider found in configuration"
	printf "%s\n" "  - ${bold}importflatconfigtemplate${normal}: import the flat template configuration file, after setting the variables"
	printf "%s\n" "  - ${bold}importldifconfigtemplate${normal}: import the ldif template configuration file, after setting the variables"
	printf "%s\n" "  - ${bold}convertconfig inputfile.conf outputfile.ldif${normal}: convert the input slapd configuration file into the equivalent ldif configuration"
	printf "%s\n" "  - ${bold}buildconfigtemplate inputfile.ldif outputfile.ldif${normal}: Get the input ldif configuration file and transform it into a template configuration"
	printf "%s\n" "  - ${bold}importdatatemplate${normal}: import the template data file, after setting the variables"
	printf "%s\n" "  - ${bold}lloadstart${normal}: start the load-balancer"
	printf "%s\n" "  - ${bold}lloadstop${normal}: stop the load-balancer"
	printf "%s\n" "  - ${bold}lloadstatus${normal}: get the status of currently running load-balancer"
	printf "\n"

}


start_slapd() {

	# $1: debug level

	# Exit 0 if slapd is already running
	# LSB compliance
	slapd_status

	if [ $? -eq 0 ]
	then 
		message "info" "[OK] OpenLDAP is already running"
		exit 0
	fi   

	# Start message
	message "info" "[INFO] Launching OpenLDAP..."

	# File descriptor limit, only for root
	if [ $MYUID -eq 0 ]
	then
		ulimit -n $FD_LIMIT
		if [ $? -eq 0 ]
		then
			message "info" "[OK] File descriptor limit set to $FD_LIMIT"
		else
			message "warning" "[WARNING] Fail to set file descriptor limit to $FD_LIMIT, going to next step"
		fi
	else
		message "info" "[INFO] File descriptor limit not modified (require root privileges)"
	fi

	# Parameters
	if [ "$SLAPD_CONF_DIR" ]
	then
		SLAPD_PARAMS="$SLAPD_PARAMS -F $SLAPD_CONF_DIR"
	elif [ "$SLAPD_CONF" ]
	then
		SLAPD_PARAMS="$SLAPD_PARAMS -f $SLAPD_CONF"
	fi

	if [  "$SLAPD_USER" -a $MYUID -eq 0 ]
	then
		SLAPD_PARAMS="$SLAPD_PARAMS -u $SLAPD_USER"
	fi

	if [ "$SLAPD_GROUP" -a $MYGID -eq 0 ]
	then
		SLAPD_PARAMS="$SLAPD_PARAMS -g $SLAPD_GROUP"
	fi

	if [ "$SLAPD_SYSLOG_LOCAL_USER" ]
	then
		SLAPD_PARAMS="$SLAPD_PARAMS -l $SLAPD_SYSLOG_LOCAL_USER" 
	fi

	# It's time to start slapd

	if [ -n "$1" ]; then
		$SLAPD_BIN -h "$SLAPD_SERVICES" $SLAPD_PARAMS -d $1
	else
		if [ $_use_systemctl -eq 1 ] ; then
			systemctl start "$SYSTEMD_SERVICE_NAME"
		else
			$SLAPD_BIN -h "$SLAPD_SERVICES" $SLAPD_PARAMS
		fi
		sleep 1

		# Presence of PID file
		if [ ! -r $SLAPD_PID_FILE ]
		then
			message "alert" "[ALERT] No PID file for OpenLDAP"
			exit 1
		fi

		# Is slapd launched?
		PID=`cat $SLAPD_PID_FILE`
		if [ ! -e /proc/$PID ]
		then
			message "alert" "[ALERT] OpenLDAP not running"
			exit 1
		else
			message "info" "[OK] OpenLDAP started"
		fi
	fi
}

stop_slapd() {
	# Stop message
	message "info" "[INFO] Halting OpenLDAP..."

	# Presence of PID file
	if [ ! -r $SLAPD_PID_FILE ]
	then
		message "info" "[INFO] Can't read PID file, to stop OpenLDAP try: $0 forcestop"
		return 1
	else
		if [ $_use_systemctl -eq 1 ] ; then
			systemctl stop "$SYSTEMD_SERVICE_NAME"
			message "info" "[OK] OpenLDAP stopped"
		else
			PID=`cat $SLAPD_PID_FILE`
			if [ $( ${PS_COMMAND_PID} | grep "${PID}" | wc -l ) -eq 0 ] ; then
				message "info" "[OK] OpenLDAP already stopped"
				exit 0
			fi
			kill -INT $PID
			# Waiting loop
			i=0
			while [ -e /proc/$PID ]
			do
				if [ $i -eq $TIMEOUT ]
				then
					# Timeout
					message "alert" "[ALERT] OpenLDAP still running (PID $PID), try: $0 forcestop"
					exit 1
				fi
				i=`expr $i + 1`
				sleep 1
			done

			message "info" "[OK] OpenLDAP stopped after $i seconds"
		fi

	fi

	# Backup if necessary
	if [ $BACKUP_AT_SHUTDOWN -eq 1 ]
	then
		backup
	else
		message "info" "[INFO] No data backup done"
	fi
}

start_lload() {

	# $1: debug level

	# Exit 0 if lload is already running
	# LSB compliance
	lload_status

	if [ $? -eq 0 ]
	then 
		message "info" "[OK] lload is already running"
		exit 0
	fi   

	# Start message
	message "info" "[INFO] Launching OpenLDAP..."

	# File descriptor limit, only for root
	if [ $MYUID -eq 0 ]
	then
		ulimit -n $FD_LIMIT
		if [ $? -eq 0 ]
		then
			message "info" "[OK] File descriptor limit set to $FD_LIMIT"
		else
			message "warning" "[WARNING] Fail to set file descriptor limit to $FD_LIMIT, going to next step"
		fi
	else
		message "info" "[INFO] File descriptor limit not modified (require root privileges)"
	fi

	# Parameters
	if [ "$LLOAD_CONF_DIR" ]
	then
		LLOAD_PARAMS="$LLOAD_PARAMS -F $LLOAD_CONF_DIR"
	elif [ "$LLOAD_CONF" ]
	then
		LLOAD_PARAMS="$LLOAD_PARAMS -f $LLOAD_CONF"
	fi

	if [  "$SLAPD_USER" -a $MYUID -eq 0 ]
	then
		LLOAD_PARAMS="$LLOAD_PARAMS -u $SLAPD_USER"
	fi

	if [ "$SLAPD_GROUP" -a $MYGID -eq 0 ]
	then
		LLOAD_PARAMS="$LLOAD_PARAMS -g $SLAPD_GROUP"
	fi

	if [ "$SLAPD_SYSLOG_LOCAL_USER" ]
	then
		LLOAD_PARAMS="$LLOAD_PARAMS -l $SLAPD_SYSLOG_LOCAL_USER" 
	fi

	# It's time to start lload

	if [ -n "$1" ]; then
		$SLAPD_BIN -h "$LLOAD_SERVICES" $LLOAD_PARAMS -d $1
	else
		if [ $_use_systemctl -eq 1 ] ; then
			systemctl start "$SYSTEMD_LLOAD_SERVICE_NAME"
		else
			$SLAPD_BIN -h "$LLOAD_SERVICES" $LLOAD_PARAMS
		fi
		sleep 1

		# Presence of PID file
		if [ ! -r $LLOAD_PID_FILE ]
		then
			message "alert" "[ALERT] No PID file for lload"
			exit 1
		fi

		# Is lload launched?
		PID=`cat $LLOAD_PID_FILE`
		if [ ! -e /proc/$PID ]
		then
			message "alert" "[ALERT] lload not running"
			exit 1
		else
			message "info" "[OK] lload started"
		fi
	fi
}

stop_lload() {
	# Stop message
	message "info" "[INFO] Halting lload..."

	# Presence of PID file
	if [ ! -r $LLOAD_PID_FILE ]
	then
		message "info" "[INFO] Can't read PID file, try to stop lload manually"
		return 1
	else
		if [ $_use_systemctl -eq 1 ] ; then
			systemctl stop "$SYSTEMD_LLOAD_SERVICE_NAME"
			message "info" "[OK] lload stopped"
		else
			PID=`cat $LLOAD_PID_FILE`
			if [ $( ${PS_COMMAND_PID} | grep "${PID}" | wc -l ) -eq 0 ] ; then
				message "info" "[OK] lload already stopped"
				exit 0
			fi
			kill -INT $PID
			# Waiting loop
			i=0
			while [ -e /proc/$PID ]
			do
				if [ $i -eq $TIMEOUT ]
				then
					# Timeout
					message "alert" "[ALERT] lload still running (PID $PID), try to stop lload manually"
					exit 1
				fi
				i=`expr $i + 1`
				sleep 1
			done

			message "info" "[OK] lload stopped after $i seconds"
		fi

	fi
}

lload_status() {
	if [ $_use_systemctl -eq 1 ]
	then
		if systemctl --quiet is-active "$SYSTEMD_LLOAD_SERVICE_NAME"
		then
			return 0
		else
			return 1
		fi
	fi

	# Return 0 if lload is running, 1 if slapd is stopped, 2 if we can't say
	if [ ! -r $LLOAD_PID_FILE ]
	then
		# Escape special characters into $LLOAD_SERVICES
		lload_services="`echo "$LLOAD_SERVICES" | sed 's/\*/\\\*/g'`"

		# Check if any slapd process are running
		if [ `${PS_COMMAND_CMD} | grep $SLAPD_BIN | grep "$lload_services" | grep -v grep | wc -l` -eq 0 ]
		then
			return 1
		else
			return 2
		fi
	else
		PID=`cat $LLOAD_PID_FILE`
	fi

	if [ ! -e /proc/$PID ]
	then
		return 1
	else
		return 0
	fi
}

display_lload_status() {

	# Print script version
	message "info" "[INFO] LDAP Tool Box slapd-cli script version $VERSION" 

	# Get status
	lload_status

	status=$?

	if [ $status -eq 0 ]
	then
		PID=`cat $LLOAD_PID_FILE`

		message "info" "[INFO] Process lload is running (PID $PID)"
		VER="$( slapd_version )"
		if [ "${VER}" != "" ] ; then
			message "info" "[INFO] Detected OpenLDAP version: $( slapd_version )"
		fi
		message "info" "[INFO] Listening to services $LLOAD_SERVICES"

		CPU=`ps -p $PID -o %cpu=`
		MEM=`ps -p $PID -o %mem=`

		message "info" "[INFO] lload process usage: $CPU% CPU / $MEM% MEM"


	fi

	if [ $status -eq 1 ]
	then
		message "info" "[INFO] Process lload is not running"
	fi

	if [ $status -eq 2 ]
	then
		message "info" "[INFO] Unable to determine lload status"
	fi

	exit $status
}

forcestop() {
	# Stop message
	message "info" "[INFO] Killing OpenLDAP with force..."

	# Presence of PID file
	if [ ! -r $SLAPD_PID_FILE ]
	then
		# Escape special characters into $SLAPD_SERVICES
		slapd_services="`echo "$SLAPD_SERVICES" | sed 's/\*/\\\*/g'`"

		# Check if any slapd process are running
		if [ `${PS_COMMAND_CMD} | grep $SLAPD_BIN | grep "$slapd_services" | grep -v grep | wc -l` -eq 0 ]
		then
			message "info" "[INFO] Found no OpenLDAP process running with $SLAPD_SERVICES"
		else
			# Try a killall
			/usr/bin/killall -KILL $SLAPD_BIN

			if [ $? -eq 0 ]
			then
				message "info" "[OK] All OpenLDAP process killed with force"
			else
				message "alert" "[ALERT] Unable to kill OpenLDAP with force"
				exit 1
			fi
		fi
	else
		PID=`cat $SLAPD_PID_FILE`
		if [ $( ${PS_COMMAND_PID} | grep "${PID}" | wc -l ) -eq 0 ] ; then
			message "info" "[OK] OpenLDAP already stopped"
			exit 0
		fi
		kill -KILL $PID

		if [ $? -eq 0 ]
		then
			message "info" "[OK] OpenLDAP process killed with force (PID $PID)"
		else
			message "alert" "[ALERT] Unable to kill OpenLDAP with force (PID $PID)"
			exit 1
		fi
	fi
}

slapd_status() {
	if [ $_use_systemctl -eq 1 ]
	then
		if systemctl --quiet is-active "$SYSTEMD_SERVICE_NAME"
		then
			return 0
		else
			return 1
		fi
	fi

	# Return 0 if slapd is running, 1 if slapd is stopped, 2 if we can't say
	if [ ! -r $SLAPD_PID_FILE ]
	then
		# Escape special characters into $SLAPD_SERVICES
		slapd_services="`echo "$SLAPD_SERVICES" | sed 's/\*/\\\*/g'`"

		# Check if any slapd process are running
		if [ `${PS_COMMAND_CMD} | grep $SLAPD_BIN | grep "$slapd_services" | grep -v grep | wc -l` -eq 0 ]
		then
			return 1
		else
			return 2
		fi
	else
		PID=`cat $SLAPD_PID_FILE`
	fi

	if [ ! -e /proc/$PID ]
	then
		return 1
	else
		return 0
	fi
}

# Try to get slapd version by searching in cn=monitor as anonymous
# else, get it by launching slapd process with -V
slapd_version() {
	# Assume service is opened at ldapi:///, and external authentication as root is allowed
	HOST="ldapi://${LDAPI_SOCKETURL}"
	BASE="cn=monitor"
	ATTR="monitoredInfo"
	SCOPE="base"

	# test if SLAPD_SERVICES contains an ldapi:/// listening port
	if echo "${SLAPD_SERVICES}" | grep -q 'ldapi:' ; then
		VERSION=$( ${LDAPSEARCH_BIN} -Y EXTERNAL -H "${HOST}" -b "${BASE}" -s "${SCOPE}" -LLL "${ATTR}" 2>/dev/null| grep "${ATTR}" )
	fi

	if [ "${VERSION}" = "" ] ; then
		if [ ! -z ${SLAPD_BIN+x} ] && [ "${SLAPD_BIN}" != "" ] ; then
			VERSION="$( ${SLAPD_BIN} -V 2>&1 | grep 'OpenLDAP' )"
		fi
	fi
	VERSION=$( printf "%s" "${VERSION}" | sed -e 's/^.*\(slapd .*(.*)\).*$/\1/' )
	printf "%s" "${VERSION}"
}

display_status() {

	# Print script version
	message "info" "[INFO] LDAP Tool Box slapd-cli script version $VERSION" 

	# Get status
	slapd_status

	status=$?

	if [ $status -eq 0 ]
	then
		PID=`cat $SLAPD_PID_FILE`

		message "info" "[INFO] Process OpenLDAP is running (PID $PID)"
		VER="$( slapd_version )"
		if [ "${VER}" != "" ] ; then
			message "info" "[INFO] Detected OpenLDAP version: $( slapd_version )"
		fi
		message "info" "[INFO] Listening to services $SLAPD_SERVICES"

		CPU=`ps -p $PID -o %cpu=`
		MEM=`ps -p $PID -o %mem=`

		message "info" "[INFO] Process usage: $CPU% CPU / $MEM% MEM"


	fi

	if [ $status -eq 1 ]
	then
		message "info" "[INFO] Process OpenLDAP is not running"
	fi

	if [ $status -eq 2 ]
	then
		message "info" "[INFO] Unable to determine OpenLDAP status"
	fi

	# Get detected suffix
	get_confvalues "directory"
	dbdirs=$RETVAL
	get_confvalues "suffix"
	dbsufs=$RETVAL

	if [ ! -z "$dbdirs" -o ! -z "$dbsufs" ]
	then
		i=1
		for dbdir in $dbdirs
		do
			# Table is not allowed, so we use awk
			suf=`echo $dbsufs | awk -v j="$i" 'BEGIN{OFS=" "} {print $j}'`
			sufprint=`echo $suf | sed "s/#20/ /"`
			if [ ! -z $suf ]
			then
				message "info" "[INFO] Detected suffix: $sufprint"
			fi
			i=`expr $i + 1`
		done
	fi

	exit $status
}

configtest() {
	# Start message
	message "info" "[INFO] Launching OpenLDAP configuration test..."

	SLAPTEST_PARAMS="-u"	

	if [ "$SLAPD_CONF_DIR" ]
	then
		SLAPTEST_PARAMS="$SLAPTEST_PARAMS -F $SLAPD_CONF_DIR"
	elif [ "$SLAPD_CONF" ]
	then
		SLAPTEST_PARAMS="$SLAPTEST_PARAMS -f $SLAPD_CONF"
	fi

	# slaptest
	$SLAPTEST_BIN $SLAPTEST_PARAMS > /dev/null 2>&1

	if [ $? -eq 0 ]
	then
		message "info" "[OK] OpenLDAP configuration test successful"
	else
		message "alert" "[ALERT] OpenLDAP configuration test failed"
		exit 1
	fi
}

reindex() {
	# Start message
	message "info" "[INFO] Launching OpenLDAP database reindexing..."

	if [ "$SLAPD_CONF_DIR" ]
	then
		SLAPINDEX_PARAMS="-F $SLAPD_CONF_DIR"
	elif [ "$SLAPD_CONF" ]
	then
		SLAPINDEX_PARAMS="-f $SLAPD_CONF"
	fi

	# slapd must be stopped
	slapd_status

	if [ $? -ne 1 ]
	then
		message "alert" "[ALERT] OpenLDAP is running or was not correctly shut down, aborting reindexing"
		exit 1
	else
		# slapindex
		if [ -z "$SU" ]
		then
			$SLAPINDEX_BIN $SLAPINDEX_PARAMS
		else
			$SU "$SLAPINDEX_BIN $SLAPINDEX_PARAMS"
		fi

		if [ $? -eq 0 ]
		then
			message "info" "[OK] OpenLDAP database reindexing successful"
		else
			message "alert" "[ALERT] OpenLDAP database reindexing failed"
			exit 1
		fi
	fi
}

backup() {
	# Start message
	message "info" "[INFO] Launching OpenLDAP database backup..."

	# Backup directory
	mkdir -p "$BACKUP_PATH"

	if [ "$SLAPD_CONF_DIR" ]
	then
		SLAPCAT_PARAMS="$SLAPCAT_PARAMS -F $SLAPD_CONF_DIR"
	elif [ "$SLAPD_CONF" ]
	then
		SLAPCAT_PARAMS="$SLAPCAT_PARAMS -f $SLAPD_CONF"
	fi

	# Do backup for all databases
	dbdirs="$DATA_PATH"
	get_confvalues "suffix"
	dbsufs=$RETVAL

	if [ "$DATA_PATH" = "auto" ]
	then
		get_confvalues "directory"
		dbdirs=$RETVAL

		if [ -z "$dbdirs" -o -z "$dbsufs" ]
		then
			message "alert" "[ALERT] No database directories found"
			exit 1
		fi
	fi

	i=1
	for dbdir in $dbdirs
	do
		# Table is not allowed, so we use awk
		suf=`echo $dbsufs | awk -v j="$i" 'BEGIN{OFS=" "} {print $j}'`

		if [ -z $suf ]; then
			message "info" "[INFO] No suffix for $dbdir"
		else
			sufprint=`echo $suf | sed "s/#20/ /"`
			dir=`basename $dbdir`
			file="$BACKUP_PATH/$dir-$BACKUP_SUFFIX"

			if [ ! -d "${dbdir}" ] || [ -z "$( ls -A ${dbdir} )" ]; then
				message "info" "[INFO] No data in ${dbdir}, don't do any backup"
				continue
			fi

			# slapcat
			if [ -z "$SU" ]
			then
				$UMASK $MASK && $SLAPCAT_BIN -b "$sufprint" $SLAPCAT_PARAMS -l "$file"
				ret=$?
			else
				$SU "$UMASK $MASK && $SLAPCAT_BIN -b \"$sufprint\" $SLAPCAT_PARAMS > \"$file\""
				ret=$?
			fi

			# alert
			if [ $ret -ne 0 ]
			then
				message "alert" "[ALERT] OpenLDAP database backup failed"
				exit 1
			fi

			# compress
			if [ -z $BACKUP_COMPRESS_EXT ]
			then
				message "info" "[OK] data saved in $file"
			else
				if [ -z "$SU" ]
				then
					$UMASK $MASK && $BACKUP_COMPRESS_BIN "$file"
				else
					$SU "$UMASK $MASK && $BACKUP_COMPRESS_BIN $file"
				fi

				# alert
				if [ $? -ne 0 ]
				then
					message "alert" "[ALERT] OpenLDAP database backup compression failed"
					exit 1
				fi
				message "info" "[OK] Data saved in ${file}.$BACKUP_COMPRESS_EXT"
			fi
		fi

		i=`expr $i + 1`
	done

}

backupconfig() {
	# Start message
	message "info" "[INFO] Launching OpenLDAP configuration backup..."

	# Backup directory
	mkdir -p "$BACKUP_PATH"

	file=""

	if [ "$SLAPD_CONF_DIR" ]
	then
		file="$BACKUP_PATH/config-$BACKUP_SUFFIX"

		# slapcat
		if [ -z "$SU" ]
		then
			$UMASK $MASK && $SLAPCAT_BIN $SLAPCAT_PARAMS -n0 -F $SLAPD_CONF_DIR -l "$file"
			ret=$?
		else
			$SU "$UMASK $MASK && $SLAPCAT_BIN $SLAPCAT_PARAMS -n0 -F $SLAPD_CONF_DIR > \"$file\""
			ret=$?
		fi

	elif [ "$SLAPD_CONF" ]
	then
		file="$BACKUP_PATH/slapd-`date +%Y%m%d%H%M%S`.conf"
		cp $SLAPD_CONF $file
		ret=$?
	fi

	# alert
	if [ $ret -ne 0 ]
	then
		message "alert" "[ALERT] OpenLDAP configuration backup failed"
		exit 1
	fi

	message "info" "[OK] Configuration saved in $file"

}

restore() {
	# Start message
	message "info" "[INFO] Launching OpenLDAP database restore..."

	if [ "$SLAPD_CONF_DIR" ]
	then
		SLAPADD_PARAMS="$SLAPADD_PARAMS -F $SLAPD_CONF_DIR"
	elif [ "$SLAPD_CONF" ]
	then
		SLAPADD_PARAMS="$SLAPADD_PARAMS -f $SLAPD_CONF"
	fi

	# Do restore for all databases
	dbdirs="$DATA_PATH"
	get_confvalues "suffix"
	dbsufs=$RETVAL

	if [ "$DATA_PATH" = "auto" ]
	then
		get_confvalues "directory"
		dbdirs=$RETVAL

		if [ -z "$dbdirs" -o -z "$dbsufs" ]
		then
			message "alert" "[ALERT] No database directories found"
			exit 1
		fi
	fi

	i=1
	for dbdir in $dbdirs
	do
		# Table is not allowed, so we use awk
		suf=`echo $dbsufs | awk -v j="$i" 'BEGIN{OFS=" "} {print $j}'`

		if [ -z $suf ]; then
			message "info" "[INFO] No suffix for $dbdir"
		else
			sufprint=`echo $suf | sed "s/#20/ /"`
			dir=`basename $dbdir`

			# Get the most recent backup for this database
			file=`ls -1t "$BACKUP_PATH/$dir-"* 2>/dev/null | head -1`
			
			if [ -z $file ]; then
				message "info" "[INFO] No backup file for $sufprint, skipping..."
			else
				message "info" "[INFO] Restore file $file for $sufprint"

				# uncompress
				if [ "$BACKUP_COMPRESS_EXT" ]
				then
					if [ -z "$SU" ]
					then
						$BACKUP_UNCOMPRESS_BIN "$file"
					else
						$SU "$BACKUP_UNCOMPRESS_BIN $file"
					fi

					# alert
					if [ $? -ne 0 ]
					then
						message "alert" "[ALERT] OpenLDAP database backup uncompression failed"
						exit 1
					fi

					file=${file%\.*}
				fi

				SLAPADD_PARAMS="$SLAPADD_PARAMS -l $file"

				# Delete current data
				if [ -z "$SU" ]
				then
					rm -rf "$dbdir/"*
				else
					$SU "rm -rf $dbdir/"*
				fi

				# Import backup
				if [ -z "$SU" ]
				then
					$SLAPADD_BIN -b "$sufprint" $SLAPADD_PARAMS
				else
					$SU "$SLAPADD_BIN -b \"$sufprint\" $SLAPADD_PARAMS"
				fi
				
				# alert
				if [ $? -ne 0 ]
				then
					message "alert" "[ALERT] OpenLDAP database restore failed for $sufprint"
					exit 1
				fi
				message "info" "[OK] Data restored for $sufprint"

				# compress backup again if needed
				if [ "$BACKUP_COMPRESS_EXT" ]
				then
					if [ -z "$SU" ]
					then
						$BACKUP_COMPRESS_BIN "$file"
					else
						$SU "$BACKUP_COMPRESS_BIN $file"
					fi

					# alert
					if [ $? -ne 0 ]
						then
						message "alert" "[ALERT] OpenLDAP database backup compression failed"
						exit 1
					fi
				fi
			fi
		fi
		i=`expr $i + 1`
	done

}

restoreconfig() {
	# Start message
	message "info" "[INFO] Launching OpenLDAP configuration restore..."

	if [ "$SLAPD_CONF_DIR" ]
	then
		# Get the most recent backup of cn=config
		file=`ls -1t "$BACKUP_PATH/config-"* 2>/dev/null | head -1`

		if [ -z $file ]; then
			message "info" "[INFO] No configuration backup found, skipping..."
		else
			message "info" "[INFO] Restore configuration file $file"

			# Delete current data
			if [ -z "$SU" ]
			then
				rm -rf "$SLAPD_CONF_DIR/"*
			else
				$SU "rm -rf $SLAPD_CONF_DIR/"*
			fi

			# Import backup
			if [ -z "$SU" ]
			then
				$SLAPADD_BIN -n0 -F $SLAPD_CONF_DIR -l $file
			else
				$SU "$SLAPADD_BIN -n0 -F $SLAPD_CONF_DIR -l $file"
			fi
		fi

	elif [ "$SLAPD_CONF" ]
	then
		# Get the most recent backup of slapd.conf
		file=`ls -1t "$BACKUP_PATH/slapd-"*.conf 2>/dev/null | head -1`

		if [ -z $file ]; then
			message "info" "[INFO] No configuration backup found, skipping..."
		else
			message "info" "[INFO] Restore configuration file $file"
			cp -f $file $SLAPD_CONF		
		fi
	fi

	# alert
	if [ $? -ne 0 ]
	then
		message "alert" "[ALERT] OpenLDAP configuration restore failed"
		exit 1
	fi
	message "info" "[OK] Configuration restored"
}

get_provider_config() {
	i=0
	if [ "$SLAPD_CONF_DIR" ]
	then
		# get all file in a DUMP variable
		DUMP="$( $SLAPCAT_BIN -n0 -F "$SLAPD_CONF_DIR" -o ldif-wrap=no )"
		# parse DUMP variable for getting providers
		SUF=""
		while read -r LINE
		do
			if printf "$LINE" | grep -q -P '^olcSuffix:[ \t]+' ; then
				SUF="$( printf "$LINE" | sed -e 's/^olcSuffix:[ \t]\+//' -e 's/"//g' )"
			fi
			if printf "$LINE" | grep -q -P '^olcSyncrepl:[ \t]+' ; then
				# add detected provider to the list of detected providers for this suffix (\n separated)
				PROVIDER[${SUF}]="${PROVIDER[$SUF]}\n$( printf "${LINE}" | sed -e 's/olcSyncrepl:[ \t]\+{*[0-9]*}*//' )"
				# remove starting \n
				PROVIDER[${SUF}]="$( printf "${PROVIDER[${SUF}]}" | sed -e ':a;N;$!ba;s/^\n//g' )"
			fi
		done <<< "${DUMP}"

	elif [ "$SLAPD_CONF" ]
	then
		# get all file in a DUMP variable
		DUMP=""
		while IFS= read -r LINE
		do
			# unwrap file (ie, join lines that begins with space or tab
			if printf "$LINE" | grep -q -P '^[ \t]+' ; then
				# remove starting space or tab
				LINE=$( printf "${LINE}" | sed -e 's/^[ \t]\+//g' )
				DUMP=$( printf "${DUMP} ${LINE}" )
			else
				DUMP=$( printf "${DUMP}\n${LINE}" )
			fi
		done < "$SLAPD_CONF"
		# parse DUMP variable for getting providers
		SUF=""
		while read -r LINE
		do
			if printf "$LINE" | grep -q -P '^suffix[ \t]+' ; then
				SUF="$( printf "$LINE" | sed -e 's/^suffix[ \t]\+//' -e 's/"//g' )"
			fi
			if printf "$LINE" | grep -q -P '^syncrepl[ \t]+' ; then
				# add detected provider to the list of detected providers for this suffix (\n separated)
				PROVIDER[${SUF}]="${PROVIDER[$SUF]}\n$( printf "${LINE}" | sed -e 's/syncrepl[ \t]\+//' )"
				# remove starting \n
				PROVIDER[${SUF}]="$( printf "${PROVIDER[${SUF}]}" | sed -e ':a;N;$!ba;s/^\n//g' )"
			fi
		done <<< "${DUMP}"
	fi
	for key in "${!PROVIDER[@]}"; do
		printf "Suffix: ${key}\n"
		printf "detected providers:\n${PROVIDER[$key]}\n\n"
	done
}


check_sync() {
	message "info" "[INFO] Checking synchronization..."
	get_provider_config
	RES=0 # result OK by default (if nothing to check, sync=OK)

	# Is there any provider configuration?
	if [[ ${#PROVIDER[@]} -eq "0" ]]; then
		message "info" "[OK] No provider found in configuration - sync status not checked"
		exit $RES
	fi

	for SUFFIX in "${!PROVIDER[@]}"; do

		# Parse PROVIDERS
		while IFS= read -r PROV
		do
			# get provider config parameters
			syncrepl_get_value "${PROV}" "provider"
			PHOST=$RETVAL
			syncrepl_get_value "${PROV}" "binddn"
			PBINDDN=$RETVAL
			syncrepl_get_value "${PROV}" "credentials"
			PBINDPW=$RETVAL
			syncrepl_get_value "${PROV}" "searchbase"
			PBASEDN=$RETVAL
			echo "Checking contextCSN for suffix ${SUFFIX} on remote host ${PHOST}"
			# Get remote provider contextCSN (one contextCSN per line)
			CONTEXTCSN=$( ${LDAPSEARCH_BIN} -x -H "${PHOST}" -D "${PBINDDN}" -w "${PBINDPW}" -b "${PBASEDN}" -o nettimeout=5 -s base contextCSN -LLL 2>/dev/null )

			# Checking status of previous command
			if [ $? -ne 0 ]; then
				echo "    ERROR: search on remote host impossible!"
				let "RES=-1"
				break
			fi
			CONTEXTCSN=$( echo "$CONTEXTCSN" | grep contextCSN | sed -e 's/^contextCSN: //i' )

			# get local contextCSN
			if [ "$SLAPD_CONF_DIR" ]; then
				localContextCSN=$( $SLAPCAT_BIN -b $SUFFIX -F "$SLAPD_CONF_DIR" -o ldif-wrap=no 2>/dev/null | head -n 100 | sed -e '/^$/,$d' | grep 'contextCSN' | sed -e 's/^contextCSN: //' )
			elif [ "$SLAPD_CONF" ]; then
				localContextCSN=$( $SLAPCAT_BIN -b $SUFFIX -f "$SLAPD_CONF" -o ldif-wrap=no 2>/dev/null | head -n 100 | sed -e '/^$/,$d' | grep 'contextCSN' | sed -e 's/^contextCSN: //' )
			else
				echo "No acceptable configuration found"
				exit 1
			fi

			# compare contextCSN values
			# for each provider contextCSN
			for CSN in $CONTEXTCSN; do
				#  identify sid part
				#  contextCSN = 20171128170017.708386Z#000000#001#000000
				#                                             ^^^
				SID=$( echo ${CSN} | sed -e 's/^.*\(#[0-9]\+#\)[^#]*$/\1/' )
				echo "  Checking SID ${SID}"

				#  check matching local slave ContextCSN
				if echo "$localContextCSN" | grep -q "$SID" ; then
					# get corresponding local slave contextCSN
					matchingLocalContextCSN=$( echo -e "$localContextCSN" | grep "$SID" )
					# Check if corresponding local slave contextCSN is identical to remote provider contextCSN
					if echo "$matchingLocalContextCSN" | grep -q "$CSN" ; then
						echo "    INFO: remote ($CSN) and local ($matchingLocalContextCSN) contextCSN found and synchronized"
					else
						echo "    ERROR: remote ($CSN) and local ($matchingLocalContextCSN) contextCSN found, but not synchronized!"
						let "RES=RES+1"
					fi
				else
					echo "    ERROR: no matching local contextCSN ($localContextCSN) found for remote ($CSN) contextCSN!"
					let "RES=RES+1"
				fi
			done

			# return result (OK|KO)
		done <<< "${PROVIDER[$SUFFIX]}"
		if [[ "$RES" -eq "0" ]]; then
			message "info" "[OK] Local directory synchronized to every declared provider"
		elif [[ "$RES" -eq "-1" ]]; then
			message "error" "[KO] Error while checking synchronization"
		else
			message "error" "[KO] Local directory not synchronized to one of its declared providers"
		fi
	done
	exit $RES
}


# escape special chars in value
escape_value()
{
	VALUE="$1"

	# escape ampersand (&)
	if printf "%s" $VALUE | grep -q -F '&'; then
		VALUE=$( printf "%s" "$VALUE" | sed -e 's/\&/\\\&/g' )
	fi

	# escape slash (/)
	if printf "%s" $VALUE | grep -q -F '/'; then
		VALUE=$( printf "%s" "$VALUE" | sed -e 's/\//\\\//g' )
	fi

	# escape line-feed (\n)
	if printf "%s" $VALUE | grep -q -F '\n'; then
		VALUE=$( printf "%s" "$VALUE" | sed -e 's/\\n/\\\\n/g' )
	fi

	printf "%s" "$VALUE"
}


# replace a pattern by a value in the given data file
replace_pattern()
{
	PATTERN="$1"
	VALUE="$2"
	FILE="$3"

	PATTERN=$( escape_value "$PATTERN" )
	VALUE=$( escape_value "$VALUE" )

	if [ ! -z ${PATTERN+x} ] && [ ! -z ${VALUE+x} ] && [ ! -z ${FILE+x} ]; then
		if [ "${PATTERN}" != "" ] && [ "${VALUE}" != "" ] && [ "${FILE}" != "" ]; then
			sed -i -e "s/${PATTERN}/${VALUE}/g" ${FILE}
		fi
	fi

}

# compute hash for given password
compute_hash()
{
	PASS="$1"

	$SLAPD_PATH/sbin/slappasswd -o module-path="${SLAPD_MODULEDIR}" -o module-load="argon2" -h "{ARGON2}" -s "${PASS}"
}


import_flat_config_template() {
	message "info" "[INFO] Import flat configuration..."

	if [ -z ${SLAPD_CONF+x} ] || [ "${SLAPD_CONF}" = "" ]; then
		message "alert" "[ALERT] No SLAPD_CONF defined. You should set this variable to the directory hosting the configuration"
		exit 1;
	fi


	if [ ! -z "$( ls -A ${SLAPD_CONF} 2>/dev/null )" ] ; then
		message "info" "[INFO] Configuration data found, launch configuration backup"
		cp -a "${SLAPD_CONF}" "$BACKUP_PATH/slapd-`date +%Y%m%d%H%M%S`.conf"
	fi

	if [ -z ${CONFIG_FLAT_TEMPLATE_FILE+x} ] || [ "${CONFIG_FLAT_TEMPLATE_FILE}" = "" ]; then
		message "alert" "[ALERT] No CONFIG_FLAT_TEMPLATE_FILE defined."
	fi

	# Prepare template for replacement
	CONFIG_TEMPLATE_PATH="${CLI_CONF_FILE%/*}/${CONFIG_FLAT_TEMPLATE_FILE}"
	if [ -f ${CONFIG_TEMPLATE_PATH} ]
	then
		message "info" "[INFO] Using ${CONFIG_TEMPLATE_PATH} as template"
	else
		message "error" "[ERROR] No data template found at ${CONFIG_TEMPLATE_PATH}"
		exit 1
	fi

	CONFIG_FILE_PATH="${SLAPD_CONF}"
	cp -f ${CONFIG_TEMPLATE_PATH} ${CONFIG_FILE_PATH}
	chown $SLAPD_USER:$SLAPD_GROUP ${CONFIG_FILE_PATH}
	chmod 640 ${CONFIG_FILE_PATH}

	replace_pattern "CONFIG_FQDN" "${CONFIG_FQDN}" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_LOGLEVEL" "${CONFIG_LOGLEVEL}" "${CONFIG_FILE_PATH}"
	if [ "${SLAPD_VERSION}" = "2.6" ] || [ "${SLAPD_VERSION}" = "2.7" ]; then
		replace_pattern "CONFIG_LOGFILE" "${CONFIG_LOGFILE}" "${CONFIG_FILE_PATH}"
	fi
	replace_pattern "CONFIG_MANAGERROOTDN" "${CONFIG_MANAGERROOTDN}" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_MANAGERROOTPW" "$( compute_hash ${CONFIG_MANAGERROOTPW} )" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_CONFIGROOTDN" "${CONFIG_CONFIGROOTDN}" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_CONFIGROOTPW" "$( compute_hash ${CONFIG_CONFIGROOTPW} )" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_MONITORROOTDN" "${CONFIG_MONITORROOTDN}" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_MONITORROOTPW" "$( compute_hash ${CONFIG_MONITORROOTPW} )" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_SUFFIX" "${CONFIG_SUFFIX}" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_DATADIR" "${CONFIG_DATADIR}" "${CONFIG_FILE_PATH}"

}


import_ldif_config_template() {
	message "info" "[INFO] Import ldif configuration..."

	if [ -z ${SLAPD_CONF_DIR+x} ] || [ "${SLAPD_CONF_DIR}" = "" ]; then
		message "alert" "[ALERT] No SLAPD_CONF_DIR defined. You should set this variable to the directory hosting the configuration"
		exit 1;
	fi


	if [ ! -z "$( ls -A ${SLAPD_CONF_DIR} )" ] ; then
		message "info" "[INFO] Configuration data found, launch configuration backup"
		backupconfig
	fi

	if [ -z ${CONFIG_LDIF_TEMPLATE_FILE+x} ] || [ "${CONFIG_LDIF_TEMPLATE_FILE}" = "" ]; then
		message "alert" "[ALERT] No CONFIG_LDIF_TEMPLATE_FILE defined."
	fi

	# Prepare template for replacement
	CONFIG_TEMPLATE_PATH="${CLI_CONF_FILE%/*}/${CONFIG_LDIF_TEMPLATE_FILE}"
	if [ -f ${CONFIG_TEMPLATE_PATH} ]
	then
		message "info" "[INFO] Using ${CONFIG_TEMPLATE_PATH} as template"
	else
		message "error" "[ERROR] No data template found at ${CONFIG_TEMPLATE_PATH}"
		exit 1
	fi

	CONFIG_FILE_PATH="${CONFIG_TEMPLATE_PATH%.ldif}-filled.ldif"
	cp -f ${CONFIG_TEMPLATE_PATH} ${CONFIG_FILE_PATH}
	chown $SLAPD_USER:$SLAPD_GROUP ${CONFIG_FILE_PATH}
	chmod 640 ${CONFIG_FILE_PATH}

	replace_pattern "CONFIG_FQDN" "${CONFIG_FQDN}" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_LOGLEVEL" "${CONFIG_LOGLEVEL}" "${CONFIG_FILE_PATH}"
	if [ "${SLAPD_VERSION}" = "2.6" ] || [ "${SLAPD_VERSION}" = "2.7" ]; then
		replace_pattern "CONFIG_LOGFILE" "${CONFIG_LOGFILE}" "${CONFIG_FILE_PATH}"
	fi
	replace_pattern "CONFIG_MANAGERROOTDN" "${CONFIG_MANAGERROOTDN}" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_MANAGERROOTPW" "$( compute_hash ${CONFIG_MANAGERROOTPW} )" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_CONFIGROOTDN" "${CONFIG_CONFIGROOTDN}" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_CONFIGROOTPW" "$( compute_hash ${CONFIG_CONFIGROOTPW} )" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_MONITORROOTDN" "${CONFIG_MONITORROOTDN}" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_MONITORROOTPW" "$( compute_hash ${CONFIG_MONITORROOTPW} )" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_SUFFIX" "${CONFIG_SUFFIX}" "${CONFIG_FILE_PATH}"
	replace_pattern "CONFIG_DATADIR" "${CONFIG_DATADIR}" "${CONFIG_FILE_PATH}"
	if [ ! -z ${SLAPD_CONF+x} ] && [ "${SLAPD_CONF}" != "" ]; then
		replace_pattern "^olcConfigFile: .*$" "olcConfigFile: ${SLAPD_CONF}" "${CONFIG_FILE_PATH}"
	fi
	if [ ! -z ${SLAPD_CONF_DIR+x} ] && [ "${SLAPD_CONF_DIR}" != "" ]; then
		replace_pattern "^olcConfigDir: .*$" "olcConfigDir: ${SLAPD_CONF_DIR}" "${CONFIG_FILE_PATH}"
	fi


	# Delete current data
	message "info" "[INFO] Delete configuration data in ${SLAPD_CONF_DIR}"
	if [ -z "$SU" ]
	then
		rm -rf "${SLAPD_CONF_DIR}/"*
	else
		$SU "rm -rf ${SLAPD_CONF_DIR}/"*
	fi

	# Import backup
	message "info" "[INFO] Importing configuration data from ${CONFIG_FILE_PATH}"
	SLAPADD_PARAMS="$SLAPADD_PARAMS -n0 -F $SLAPD_CONF_DIR -l ${CONFIG_FILE_PATH}"
	if [ -z "$SU" ]
	then
		$SLAPADD_BIN $SLAPADD_PARAMS
	else
		$SU "$SLAPADD_BIN $SLAPADD_PARAMS"
	fi
	rm "${CONFIG_FILE_PATH}"

}


convert_config() {
	message "info" "[INFO] Convert configuration from flat .conf to .ldif..."

	TMP_CONF_DIR="/tmp/slapd.d-tmp"

	if [ $# -ne 2 ] ; then
		message "alert" "[ALERT] Missing argument: you need to supply flat and ldif configuration filenames"
		exit 1
	fi
	if [ ! -f ${1} ] ; then
		message "alert" "[ALERT] flat input configuration file does not exist"
		exit 2
	fi
	if [ -e ${2} ] ; then
		message "alert" "[ALERT] ldif output configuration file already exist"
		exit 3
	fi
	message "info" "[INFO] Convert configuration from ${1} flat configuration to ${2} ldif configuration..."

	rm -rf ${TMP_CONF_DIR}
	mkdir -p ${TMP_CONF_DIR}

	# import configuration into the temporary configuration directory
	SLAPTEST_PARAMS=" -n0 -F ${TMP_CONF_DIR} -f ${1}"
	$SLAPTEST_BIN $SLAPTEST_PARAMS > /dev/null 2>&1

	if [ $? -ne 0 ] ; then
		message "alert" "[ALERT] conversion failed during import"
		rm -rf "${TMP_CONF_DIR}"
		exit 4
	fi

	# export configuration in ldif
	$SLAPCAT_BIN $SLAPCAT_PARAMS -n0 -F ${TMP_CONF_DIR} -l "$2"
	if [ $? -ne 0 ] ; then
		message "alert" "[ALERT] conversion failed during export"
		rm -rf "${TMP_CONF_DIR}"
		exit 5
	fi

	# remove temporary configuration directory
	rm -rf "${TMP_CONF_DIR}"

	# remove operational attributes
	OPATTRS="structuralObjectClass
		entryUUID
		creatorsName
		createTimestamp
		entryCSN
		modifiersName
		modifyTimestamp"

	for A in ${OPATTRS} ; do
		sed -i -e "/^${A}: /d" "${2}"
	done

	# remove "cn=schema,cn=config" content, which is useless.
	# the content of this entry is automatically generated by slapd in memory at startup
	sed -i -e '/dn: cn=schema,cn=config/,/^$/{/^\(dn: \|objectClass: \|cn: \|$\)/!d;}' ${2}

	if [ ! -z ${SLAPD_CONF+x} ] && [ "${SLAPD_CONF}" != "" ]; then
		replace_pattern "^olcConfigFile: .*$" "olcConfigFile: ${SLAPD_CONF}" "$2"
	fi
	if [ ! -z ${SLAPD_CONF_DIR+x} ] && [ "${SLAPD_CONF_DIR}" != "" ]; then
		replace_pattern "^olcConfigDir: .*$" "olcConfigDir: ${SLAPD_CONF_DIR}" "$2"
	fi

	message "info" "[INFO] Conversion succeeded"

}


build_config_template() {
	message "info" "[INFO] Build configuration template from given ldif file..."

	if [ $# -ne 2 ] ; then
		message "alert" "[ALERT] Missing argument: you need to supply input ldif configuration and output ldif template filenames"
		exit 1
	fi
	if [ ! -f ${1} ] ; then
		message "alert" "[ALERT] input ldif configuration file does not exist"
		exit 2
	fi
	if [ -e ${2} ] ; then
		message "alert" "[ALERT] output ldif template already exist"
		exit 3
	fi
	message "info" "[INFO] Convert ldif configuration ${1} to ldif template ${2}..."

	cp -a ${1} ${2}


	# remove operational attributes
	OPATTRS="structuralObjectClass
		entryUUID
		creatorsName
		createTimestamp
		entryCSN
		modifiersName
		modifyTimestamp"

	for A in ${OPATTRS} ; do
		sed -i -e "/^${A}: /d" "${2}"
	done

	# remove "cn=schema,cn=config" content, which is useless.
	# the content of this entry is automatically generated by slapd in memory at startup
	sed -i -e '/dn: cn=schema,cn=config/,/^$/{/^\(dn: \|objectClass: \|cn: \|$\)/!d;}' ${2}

	# remove every olcRootPW line
	sed -i -e "/^olcRootPW:.*$/d" "${2}"

	# set olcConfigFile and olcConfigDir if defined
	if [ ! -z ${SLAPD_CONF+x} ] && [ "${SLAPD_CONF}" != "" ]; then
		replace_pattern "^olcConfigFile: .*$" "olcConfigFile: ${SLAPD_CONF}" "$2"
	fi
	if [ ! -z ${SLAPD_CONF_DIR+x} ] && [ "${SLAPD_CONF_DIR}" != "" ]; then
		replace_pattern "^olcConfigDir: .*$" "olcConfigDir: ${SLAPD_CONF_DIR}" "$2"
	fi

	# replace olcRootDN and olcRootPW by the given placeholder for cn=config and for data base
	if [ ! -z ${CONFIG_MANAGERROOTDN+x} ] && [ "${CONFIG_MANAGERROOTDN}" != "" ]; then
		sed -i -e "s/^olcRootDN: ${CONFIG_MANAGERROOTDN}$/olcRootDN: CONFIG_MANAGERROOTDN\nolcRootPW: CONFIG_MANAGERROOTPW/" "$2"
	fi
	if [ ! -z ${CONFIG_CONFIGROOTDN+x} ] && [ "${CONFIG_CONFIGROOTDN}" != "" ]; then
		sed -i -e "s/^olcRootDN: ${CONFIG_CONFIGROOTDN}$/olcRootDN: CONFIG_CONFIGROOTDN\nolcRootPW: CONFIG_CONFIGROOTPW/" "$2"
	fi
	if [ ! -z ${CONFIG_MONITORROOTDN+x} ] && [ "${CONFIG_MONITORROOTDN}" != "" ]; then
		sed -i -e "s/^olcRootDN: ${CONFIG_MONITORROOTDN}$/olcRootDN: CONFIG_MONITORROOTDN\nolcRootPW: CONFIG_MONITORROOTPW/" "$2"
	fi

	# replace olcDbDirectory by the given placeholder
	if [ ! -z ${CONFIG_DATADIR+x} ] && [ "${CONFIG_DATADIR}" != "" ]; then
		replace_pattern "^olcDbDirectory: ${CONFIG_DATADIR}$" "olcDbDirectory: CONFIG_DATADIR" "$2"
	fi

	# replace olcLogLevel by the given placeholder
	replace_pattern "^olcLogLevel: .*$" "olcLogLevel: CONFIG_LOGLEVEL" "${2}"

	# replace olcLogFile by the given placeholder
	if [ "${SLAPD_VERSION}" = "2.6" ] || [ "${SLAPD_VERSION}" = "2.7" ]; then
		replace_pattern "^olcLogFile: .*$" "olcLogFile: CONFIG_LOGFILE" "${2}"
	fi

	# replace olcSaslHost by the given placeholder
	replace_pattern "^olcSaslHost: .*$" "olcSaslHost: CONFIG_FQDN" "${2}"

	# replace the suffix value by the given placeholder everywhere in the template
	if [ ! -z ${CONFIG_SUFFIX+x} ] && [ "${CONFIG_SUFFIX}" != "" ]; then
		replace_pattern "${CONFIG_SUFFIX}" "CONFIG_SUFFIX" "$2"
	fi

	message "info" "[INFO] Build configuration template succeeded"

}


import_data_template() {
	message "info" "[INFO] Import test data..."

	if [ -z ${DATA_TEMPLATE_FILE+x} ] || [ "${DATA_TEMPLATE_FILE}" = "" ]; then
		message "alert" "[ALERT] No DATA_TEMPLATE_FILE variable defined"
	fi



	# Prepare template for replacement
	DATA_TEMPLATE_PATH="${CLI_CONF_FILE%/*}/${DATA_TEMPLATE_FILE}"
	if [ -f ${DATA_TEMPLATE_PATH} ]
	then
		message "info" "[INFO] Using ${DATA_TEMPLATE_PATH} as template"
	else
		message "error" "[ERROR] No data template found at ${DATA_TEMPLATE_PATH}"
		exit 1
	fi

	DATA_FILE_PATH="${DATA_TEMPLATE_PATH%.ldif}-filled.ldif"
	cp -f ${DATA_TEMPLATE_PATH} ${DATA_FILE_PATH}
	chown $SLAPD_USER:$SLAPD_GROUP ${DATA_FILE_PATH}
	chmod 640 ${DATA_FILE_PATH}


	# Add new admins
	DATA_ADMINS=$( set | grep -E '^DATA_ADMIN_' | sed -e 's/^DATA_ADMIN_\([^_]\+\)_.*/\1/' | sort -u )
	for DATA_ADMIN in ${DATA_ADMINS}; do
		eval DATA_ADMIN_DN="\$DATA_ADMIN_${DATA_ADMIN}_DN"
		eval DATA_ADMIN_PW="\$DATA_ADMIN_${DATA_ADMIN}_PW"
		eval DATA_ADMIN_UID="\$DATA_ADMIN_${DATA_ADMIN}_UID"
		eval DATA_ADMIN_SN="\$DATA_ADMIN_${DATA_ADMIN}_SN"
		eval DATA_ADMIN_GN="\$DATA_ADMIN_${DATA_ADMIN}_GN"
		eval DATA_ADMIN_MAIL="\$DATA_ADMIN_${DATA_ADMIN}_MAIL"

		if [ "${DATA_ADMIN_PW}" != "" ] ; then
			DATA_ADMIN_PW_HASH="$( compute_hash ${DATA_ADMIN_PW} )"
		fi

		if [ "${DATA_ADMIN_DN}" != "" ] && [ "${DATA_ADMIN_PW_HASH}" != "" ] && [ "${DATA_ADMIN_UID}" != "" ] && [ "${DATA_ADMIN_SN}" != "" ] && [ "${DATA_ADMIN_GN}" != "" ] && [ "${DATA_ADMIN_MAIL}" != "" ] ; then
			message "info" "[INFO] Adding admin ${DATA_ADMIN}: uid=${DATA_ADMIN_UID}, gn=${DATA_ADMIN_GN}, sn=${DATA_ADMIN_SN}, mail=${DATA_ADMIN_MAIL}, pass=${DATA_ADMIN_PW_HASH}"
			printf "\n%s" "
dn: ${DATA_ADMIN_DN}
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
cn: ${DATA_ADMIN_GN} ${DATA_ADMIN_SN}
givenName: ${DATA_ADMIN_GN}
mail: ${DATA_ADMIN_MAIL}
sn: ${DATA_ADMIN_SN}
uid: ${DATA_ADMIN_UID}
userPassword: ${DATA_ADMIN_PW_HASH}
pwdPolicySubentry: cn=admin-policy,ou=ppolicies,DATA_SUFFIX
memberOf: cn=admin,ou=groups,DATA_SUFFIX" >> ${DATA_FILE_PATH}

			MEMBER="member: ${DATA_ADMIN_DN}
${MEMBER}"
		fi

	done


	# create new organizations and add people and groups branches inside
	if [ ! -z ${DATA_ORGANIZATIONS+x} ] ; then
		ORGS=${DATA_ORGANIZATIONS}, # adds final separator
		while [ ${ORGS} ]; do
			o="${ORGS%%,*}" # get current organization
			message "info" "[INFO] Adding organization ${o}"
			printf "\n%s" "
dn: ou=${o},${DATA_SUFFIX}
objectClass: organizationalUnit
objectClass: top
ou: ${o}

dn: ou=people,ou=${o},${DATA_SUFFIX}
objectClass: organizationalUnit
objectClass: top
ou: people

dn: ou=groups,ou=${o},${DATA_SUFFIX}
objectClass: organizationalUnit
objectClass: top
ou: groups

dn: cn=admin,ou=groups,ou=${o},${DATA_SUFFIX}
objectClass: groupOfNames
objectClass: top
cn: admin
$MEMBER" >> ${DATA_FILE_PATH}

			# Add corresponding memberOf
			for DATA_ADMIN in ${DATA_ADMINS}; do
				eval DATA_ADMIN_DN="\$DATA_ADMIN_${DATA_ADMIN}_DN"
				sed -i -e "/^dn: ${DATA_ADMIN_DN}/amemberOf: cn=admin,ou=groups,ou=${o},${DATA_SUFFIX}" ${DATA_FILE_PATH}
			done

			# remove current organization from list
			ORGS=${ORGS#*,};
		done;
	fi


	# Add admin group
	MEMBER="member: DATA_SERVICEACCOUNT_DN
${MEMBER}"
	printf "\n%s" "
dn: cn=admin,ou=groups,DATA_SUFFIX
objectClass: groupOfNames
objectClass: top
cn: admin
$MEMBER" >> ${DATA_FILE_PATH}


	# Add new users
	DATA_USERS=$( set | grep -E '^DATA_USER_' | sed -e 's/^DATA_USER_\([^_]\+\)_.*/\1/' | sort -u )
	for DATA_USER in ${DATA_USERS}; do
		eval DATA_USER_DN="\$DATA_USER_${DATA_USER}_DN"
		eval DATA_USER_PW="\$DATA_USER_${DATA_USER}_PW"
		eval DATA_USER_UID="\$DATA_USER_${DATA_USER}_UID"
		eval DATA_USER_SN="\$DATA_USER_${DATA_USER}_SN"
		eval DATA_USER_GN="\$DATA_USER_${DATA_USER}_GN"
		eval DATA_USER_MAIL="\$DATA_USER_${DATA_USER}_MAIL"

		if [ "${DATA_USER_PW}" != "" ] ; then
			DATA_USER_PW_HASH="$( compute_hash ${DATA_USER_PW} )"
		fi

		if [ "${DATA_USER_DN}" != "" ] && [ "${DATA_USER_PW_HASH}" != "" ] && [ "${DATA_USER_UID}" != "" ] && [ "${DATA_USER_SN}" != "" ] && [ "${DATA_USER_GN}" != "" ] && [ "${DATA_USER_MAIL}" != "" ] ; then
			message "info" "[INFO] Adding user ${DATA_USER}: uid=${DATA_USER_UID}, gn=${DATA_USER_GN}, sn=${DATA_USER_SN}, mail=${DATA_USER_MAIL}, pass=${DATA_USER_PW_HASH}"
			printf "\n%s" "
dn: ${DATA_USER_DN}
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
cn: ${DATA_USER_GN} ${DATA_USER_SN}
givenName: ${DATA_USER_GN}
mail: ${DATA_USER_MAIL}
sn: ${DATA_USER_SN}
uid: ${DATA_USER_UID}
userPassword: ${DATA_USER_PW_HASH}" >> ${DATA_FILE_PATH}


		fi

	done

	# Adapt LDAP suffix
	message "info" "[INFO] Using suffix ${DATA_SUFFIX}"
	replace_pattern "DATA_SUFFIX" "${DATA_SUFFIX}" "${DATA_FILE_PATH}"
	if [ ! -z ${DATA_SUFFIX+x} ] ; then
		DATA_RDNSUFFIX=${DATA_SUFFIX#*=} # remove dc= (front of DN)
		DATA_RDNSUFFIX=${DATA_RDNSUFFIX%%,*} # remove suffix (back of DN)
		replace_pattern "DATA_RDNSUFFIX" "${DATA_RDNSUFFIX}" "${DATA_FILE_PATH}"
	fi
	replace_pattern "DATA_ORGANIZATION" "${DATA_ORGANIZATION}" "${DATA_FILE_PATH}"

	# Adapt serviceaccount DN, RDN and password
	if [ ! -z ${DATA_SERVICEACCOUNT_DN+x} ] ; then
		DATA_SERVICEACCOUNT_RDN=${DATA_SERVICEACCOUNT_DN#*=} # remove cn= (front of DN)
		DATA_SERVICEACCOUNT_RDN=${DATA_SERVICEACCOUNT_RDN%%,*} # remove suffix (back of DN)
		message "info" "[INFO] Adding service account ${DATA_SERVICEACCOUNT_RDN}"
		replace_pattern "DATA_SERVICEACCOUNT_RDN" "${DATA_SERVICEACCOUNT_RDN}" "${DATA_FILE_PATH}"
		replace_pattern "DATA_SERVICEACCOUNT_DN" "${DATA_SERVICEACCOUNT_DN}" "${DATA_FILE_PATH}"
		replace_pattern "DATA_SERVICEACCOUNT_PW" "$( compute_hash ${DATA_SERVICEACCOUNT_PW} )" "${DATA_FILE_PATH}"
	fi


	# Prepare add command
	if [ "$SLAPD_CONF_DIR" ]
	then
		SLAPADD_PARAMS="$SLAPADD_PARAMS -F $SLAPD_CONF_DIR -l ${DATA_FILE_PATH}"
	elif [ "$SLAPD_CONF" ]
	then
		SLAPADD_PARAMS="$SLAPADD_PARAMS -f $SLAPD_CONF -l ${DATA_FILE_PATH}"
	fi

	# Get data directories
	dbdirs="$DATA_PATH"
	get_confvalues "suffix"
	dbsufs=$RETVAL

	if [ "$DATA_PATH" = "auto" ]
	then
		get_confvalues "directory"
		dbdirs=$RETVAL

		if [ -z "$dbdirs" -o -z "$dbsufs" ]
		then
			message "alert" "[ALERT] No database directories found"
			exit 1
		fi
	fi

	i=1
	dbdir=""
	for suf in $dbsufs ; do
		sufprint=$( echo $suf | sed "s/#20/ /" )
		if [ "$sufprint" = "${DATA_SUFFIX}" ] ; then
			dbdir=$( echo $dbdirs | awk -v j="$i" 'BEGIN{OFS=" "} {print $j}' )
			sufp=$( echo $suf | sed "s/#20/ /" )
		fi
		i=$( expr $i + 1 )
	done
	if [ -z $dbdir ]; then
		message "error" "[ERROR] No suffix configured for ${DATA_SUFFIX}"
		exit 1
	fi


	# Delete current data
	message "info" "[INFO] Delete data in $dbdir associated to suffix ${DATA_SUFFIX}"
	if [ -z "$SU" ]
	then
		rm -rf "$dbdir/"*
	else
		$SU "rm -rf $dbdir/"*
	fi

	# Import backup
	message "info" "[INFO] Importing data from ${DATA_FILE_PATH}"
	if [ -z "$SU" ]
	then
		$SLAPADD_BIN -b "$sufp" $SLAPADD_PARAMS
	else
		$SU "$SLAPADD_BIN -b \"$sufp\" $SLAPADD_PARAMS"
	fi

	# alert
	if [ $? -ne 0 ]
	then
		message "alert" "[ALERT] OpenLDAP database restore failed for $sufp"
		exit 1
	fi
	message "info" "[OK] Data restored for $sufp"

}

#====================================================================
# Action switch
#====================================================================
case $1 in
	start)
	configtest
	start_slapd
	;;
	stop)
	stop_slapd
	;;
	forcestop)
	forcestop
	;;
	restart)
	configtest
	stop_slapd
	start_slapd
	;;
	debug)
	stop_slapd
	start_slapd $DEBUG_LEVEL
	;;
	force-restart)
	configtest
	forcestop
	start_slapd
	;;
	status)
	display_status
	;;
	configtest)
	configtest
	;;
	reindex)
	reindex
	;;
	backup)
	backup
	;;
	restore)
	stop_slapd
	restore
	start_slapd
	;;
	backupconfig)
	backupconfig
	;;
	restoreconfig)
	stop_slapd
	restoreconfig
	configtest
	start_slapd
	;;
	checksync)
	check_sync
	;;
	importflatconfigtemplate)
	stop_slapd
	import_flat_config_template
	;;
	importldifconfigtemplate)
	stop_slapd
	import_ldif_config_template
	;;
	convertconfig)
	shift
	convert_config $*
	;;
	buildconfigtemplate)
	shift
	build_config_template $*
	;;
	importdatatemplate)
	backup
	stop_slapd
	import_data_template
	;;
	lloadstart)
	start_lload
	;;
	lloadstop)
	stop_lload
	;;
	lloadstatus)
	display_lload_status
	;;
	*)
	display_usage
	exit 1
	;;
esac

#====================================================================
# Exit
#====================================================================
exit 0

