#!/bin/sh
### BEGIN INIT INFO
# Provides:          slapd-instances
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: OpenLDAP multiple instances server (Lightweight Directory Access Protocol)
### END INIT INFO

# Specify path variable
PATH=/sbin:/usr/sbin:/bin:/usr/bin

. /lib/lsb/init-functions

# Kill me on all errors
set -e

INSTANCES_CONFIG="/etc/default/slapd-instances-config"

valuef() {
        value=$( grep "${1}=" ${INSTANCES_CONFIG} | grep -v '#'\
                | awk -F "\"" '{ print $2 }')
        echo ${value}
}

NUM_INSTANCES=$( valuef "num_instances" )

SLAPD_USER=$( valuef "SLAPD_USER" )
SLAPD_GROUP=$( valuef "SLAPD_GROUP" )
SLAPD_LOGDIR=$( valuef "SLAPD_LOGDIR" )


# Set the paths to slapd as a variable so that someone who really
# wants to can override the path in /etc/default/slapd.
SLAPD=/opt/symas/lib/slapd

# Stop processing if slapd is not there
[ -x $SLAPD ] || exit 1

# debconf may have this file descriptor open and it makes things work a bit
# more reliably if we redirect it as a matter of course.  db_stop will take
# care of this, but this won't hurt.
exec 3>/dev/null



# Stop processing if the config file is not there
check_if_config_file_present() {
    if [ ! -r "$SLAPD_CONF" ]; then
        log_warning_msg "No configuration file was found for slapd-instance-${INSTANCE} at $SLAPD_CONF."
        [ "x$1" = xstop ] && exit 0 || exit 1
    fi
}



# Make sure the pidfile provided and pidfile directory exists with correct
# permissions
ensure_correct_piddir() {
    if [ -z "$SLAPD_PIDFILE" ]; then
        log_failure_msg "The pidfile for slapd has not been specified"
        exit 1
    fi
    piddir=`dirname "$SLAPD_PIDFILE"`
    if [ ! -d "$piddir" ]; then
    	mkdir -p "$piddir"
    fi
    [ -z "$SLAPD_USER" ] || chown -R "$SLAPD_USER" "$piddir"
    [ -z "$SLAPD_GROUP" ] || chgrp -R "$SLAPD_GROUP" "$piddir"
}


# Make sure that data directory is present annd with correct permissions
ensure_correct_datadir() {
    if [ ! -d "$SLAPD_DATADIR" ]; then
        mkdir -p "$SLAPD_DATADIR"
    fi
    [ -z "$SLAPD_USER" ] || chown -R "$SLAPD_USER" "$SLAPD_DATADIR"
    [ -z "$SLAPD_GROUP" ] || chgrp -R "$SLAPD_GROUP" "$SLAPD_DATADIR"
}


# Make sure that log directory is present annd with correct permissions
ensure_correct_logdir() {
    if [ ! -d "$SLAPD_LOGDIR" ]; then
        mkdir -p "$SLAPD_LOGDIR"
    fi
    if [ ! -d "$SLAPD_LOGDIR" ]; then
        mkdir -p "$SLAPD_LOGDIR"
        [ -z "$SLAPD_USER" ] || chown -R "$SLAPD_USER" "$SLAPD_LOGDIR"
        [ -z "$SLAPD_GROUP" ] || chgrp -R "$SLAPD_GROUP" "$SLAPD_LOGDIR"
    fi
}


# Pass the user and group to run under to slapd
add_user_group_to_slapd_options() {
    if [ "$SLAPD_USER" ]; then
        SLAPD_OPTIONS="-u $SLAPD_USER $SLAPD_OPTIONS"
    fi

    if [ "$SLAPD_GROUP" ]; then
        SLAPD_OPTIONS="-g $SLAPD_GROUP $SLAPD_OPTIONS"
    fi
}

# Tell the user that something went wrong and give some hints for
# resolving the problem.
report_failure() {
	log_end_msg 1
	if [ -n "$reason" ]; then
		log_failure_msg "$reason"
	else
		log_failure_msg "The operation failed but no output was produced."

		if [ -n "$SLAPD_OPTIONS" -o \
		     -n "$SLAPD_SERVICES" ]; then
			if [ -z "$SLAPD_SERVICES" ]; then
				if [ -n "$SLAPD_OPTIONS" ]; then
					log_failure_msg "Command line used: slapd $SLAPD_OPTIONS"
				fi
			else
				log_failure_msg "Command line used: slapd -h '$SLAPD_SERVICES' $SLAPD_OPTIONS"
			fi
		fi
	fi
}

# Start the slapd daemon and capture the error message if any to
# $reason.
start_slapd() {
    PRELOAD_STMT="LD_PRELOAD=\$SOL_PRELOAD;export LD_PRELOAD"
    eval $PRELOAD_STMT
	if [ -z "$SLAPD_SERVICES" ]; then
		reason="`start-stop-daemon --start --quiet --oknodo \
		    --background \
			--pidfile "$SLAPD_PIDFILE" \
			--exec $SLAPD -- -f $SLAPD_CONF $SLAPD_OPTIONS 2>&1`"
	else
		reason="`start-stop-daemon --start --quiet --oknodo \
		    --background \
			--pidfile "$SLAPD_PIDFILE" \
			--exec $SLAPD -- -f $SLAPD_CONF -h \"$SLAPD_SERVICES\" $SLAPD_OPTIONS 2>&1`"
	fi

	# Backward compatibility with OpenLDAP 2.1 client libraries.
	if [ ! -h /var/run/ldapi ] && [ ! -e /var/run/ldapi ] ; then
		ln -s slapd/ldapi /var/run/ldapi
	fi
}

# Stop the slapd daemon and capture the error message (if any) to
# $reason.
stop_slapd() {
	reason="`start-stop-daemon --stop --quiet --oknodo --retry TERM/10 \
		--pidfile "$SLAPD_PIDFILE" \
		--exec $SLAPD 2>&1`"
}

# Start the OpenLDAP daemons
start_ldap() {
	trap 'report_failure' 0
	log_daemon_msg "Starting OpenLDAP" "slapd-instance-${INSTANCE}"
	start_slapd
	trap "-" 0
	log_end_msg 0
}

# Stop the OpenLDAP daemons
stop_ldap() {
	trap 'report_failure' 0
	log_daemon_msg "Stopping OpenLDAP" "slapd-instance-${INSTANCE}"
	stop_slapd
	trap "-" 0
	log_end_msg 0
}

case "$1" in
  start)
        echo "Starting all ${NUM_INSTANCES} slapd instances..."
        ensure_correct_logdir
        for INSTANCE in $(seq 1 ${NUM_INSTANCES})
        do
            SLAPD_CONF=$( valuef "ins${INSTANCE}_SLAPD_CONF" )
            SLAPD_PIDFILE=$( valuef "ins${INSTANCE}_SLAPD_PIDFILE" )
            SLAPD_DATADIR=$( valuef "ins${INSTANCE}_SLAPD_DATADIR" )
            SLAPD_SERVICES=$( valuef "ins${INSTANCE}_SLAPD_SERVICES" )
            SLAPD_OPTIONS=$( valuef "ins${INSTANCE}_SLAPD_OPTIONS" )
            check_if_config_file_present
            ensure_correct_piddir
            ensure_correct_datadir
            ensure_correct_logdir
            add_user_group_to_slapd_options
  	    start_ldap
        done
        ;;
  stop)
        echo "Stopping all ${NUM_INSTANCES} slapd instances..."
        for INSTANCE in $(seq 1 ${NUM_INSTANCES})
        do
            SLAPD_CONF=$( valuef "ins${INSTANCE}_SLAPD_CONF" )
            SLAPD_PIDFILE=$( valuef "ins${INSTANCE}_SLAPD_PIDFILE" )
            SLAPD_SERVICES=$( valuef "ins${INSTANCE}_SLAPD_SERVICES" )
            SLAPD_OPTIONS=$( valuef "ins${INSTANCE}_SLAPD_OPTIONS" )
            stop_ldap
        done
  	;;
  restart|force-reload)
        echo "Restarting all ${NUM_INSTANCES} slapd instances..."
        for INSTANCE in $(seq 1 ${NUM_INSTANCES})
        do
            SLAPD_CONF=$( valuef "ins${INSTANCE}_SLAPD_CONF" )
            SLAPD_PIDFILE=$( valuef "ins${INSTANCE}_SLAPD_PIDFILE" )
            SLAPD_DATADIR=$( valuef "ins${INSTANCE}_SLAPD_DATADIR" )
            SLAPD_SERVICES=$( valuef "ins${INSTANCE}_SLAPD_SERVICES" )
            SLAPD_OPTIONS=$( valuef "ins${INSTANCE}_SLAPD_OPTIONS" )
            stop_ldap
            start_ldap
        done
	;;
  status)
        for INSTANCE in $(seq 1 ${NUM_INSTANCES})
        do
            SLAPD_PIDFILE=$( valuef "ins${INSTANCE}_SLAPD_PIDFILE" )
	    status_of_proc -p $SLAPD_PIDFILE $SLAPD slapd-instance-${INSTANCE}
        done
	;;
  *)
  	echo "Usage: $0 {start|stop|restart|force-reload|status}"
	exit 1
	;;
esac
