#!/bin/sh
@%@UCRWARNING=# @%@
# pidfile: /var/run/slapd/slapd.pid
### BEGIN INIT INFO
# Provides:			 slapd
# 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 standalone server (Lightweight Directory Access Protocol)
### END INIT INFO
#
# Written by Miquel van Smoorenburg <miquels@drinkel.ow.org>.
# Modified for Debian GNU/Linux by Ian Murdock <imurdock@gnu.ai.mit.edu>.
# Modified for Debian by Christoph Lameter <clameter@debian.org>
# Modified for OpenLDAP by Ben Collins <bcollins@debian.org>
# Modified for UCS by Univention <packages@univention.de>


PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAEMON=/usr/sbin/slapd
SLAPDCONF=/etc/ldap/slapd.conf

. /lib/lsb/init-functions

getpid ()
{
	# Bug #50616: without further args, pgrep would find any slapd process,
	# including those in docker containers. We care about only that one
	# process that is a direct child of PID 1. We also added that
	# restriction to start-stop-daemon. Should this script get an overhaul,
	# we need to keep docker processes in mind. Granted, pidfile should
	# work better.
	pgrep -f "^$DAEMON" -P 1
}

exit_if_start_is_running ()
{
	local pid
	pid=$(pgrep -cf "^/bin/sh /etc/init.d/slapd start$")
	if [ -n "$pid" ] && [ "$pid" -gt 1 ]; then
		log_action_msg "WARNING: Another /etc/init.d/slapd start is already in progress."
		exit 1
	fi
}

check_subschema ()
{
	tmpfile=`mktemp`
	res=1
	count=0
	while [ $res != 0 ] ; do
		ldapsearch -x -H ldapi:/// -s base -b cn=Subschema 'objectClass=subschema' objectClasses attributeTypes matchingRules matchingRuleUse dITStructureRules dITContentRules nameForms ldapSyntaxes >$tmpfile
		res=$?
		if [ $res != 0 ]; then
			count=$((count+1))
			if [ $count -ge 5 ]; then
				echo "Failed to search schema"
				exit 1
			fi
			sleep 2
		fi
	done
@!@
if configRegistry.is_true('ldap/schema/export'):
    print('\tcp $tmpfile /var/www/ldap-schema.txt')
    print('\tchmod a+r /var/www/ldap-schema.txt')
@!@
	md5=`md5sum $tmpfile | awk '{print $1}'`
	rm -f "$tmpfile"

	if [ ! -d /var/lib/univention-ldap/schema ]; then
		mkdir /var/lib/univention-ldap/schema
	fi
	if [ ! -e /var/lib/univention-ldap/schema/md5 ]; then
		touch /var/lib/univention-ldap/schema/md5
	fi
	md5_old=`cat /var/lib/univention-ldap/schema/md5`
	if [ "$md5" != "$md5_old" ]; then
		if [ ! -d /var/lib/univention-ldap/schema/id ]; then
			mkdir /var/lib/univention-ldap/schema/id
		fi
		if [ ! -e /var/lib/univention-ldap/schema/id/id ]; then
			touch /var/lib/univention-ldap/schema/id/id
		fi
		id=`cat /var/lib/univention-ldap/schema/id/id`
		if [ -z "$id" ]; then
			id=0
		fi
		id=$((id+1))
		echo "$md5" >/var/lib/univention-ldap/schema/md5
		echo "$id" >/var/lib/univention-ldap/schema/id/id
		chown listener /var/lib/univention-ldap/schema/id/id
	else
		id=`cat /var/lib/univention-ldap/schema/id/id`
		if [ -z "$id" ]; then
			echo "1" >/var/lib/univention-ldap/schema/id/id
			chown listener /var/lib/univention-ldap/schema/id/id
		fi
	fi
}


if [ -f "$SLAPDCONF" ]; then
	pidfile=`grep ^pidfile $SLAPDCONF | awk '{print $2}'`
	if [ -z "$pidfile" ]; then
		pidfile="/var/run/slapd/slapd.pid"
	fi
	pidfiledir="$(dirname $pidfile)"
	test ! -e "$pidfiledir" && mkdir -p "$pidfiledir"
else
	exit 0
fi

test -f $DAEMON || exit 0

case "$1" in
  start)
	# check ucr autostart setting
	if [ -f "/usr/share/univention-config-registry/init-autostart.lib" ]; then
		. "/usr/share/univention-config-registry/init-autostart.lib"
		check_autostart ldap ldap/autostart
	fi
	# check that no slapd is running
	if ! start-stop-daemon --start --ppid 1 --quiet --exec $DAEMON --test > /dev/null; then
		log_action_msg "LDAP server already running"
		exit 0
	fi
	logger "/etc/init.d/slapd $1 (pid: $$, ppid:$(ps -p $PPID -o pid= -o comm=))"
	log_action_begin_msg "Starting ldap server(s): slapd "

@!@
uris = ['ldapi:///']
for p in configRegistry.get('slapd/port', '7389').split(','):
    uris.append('ldap://:%s/' % p)
for p in configRegistry.get('slapd/port/ldaps', '7636').split(','):
    uris.append('ldaps://:%s/' % p)
print('\turis="%s"' % ' '.join(uris))
if configRegistry.get('ldap/maxopenfiles'):
    print('\t\tulimit -n %s' % configRegistry['ldap/maxopenfiles'])
@!@		start-stop-daemon --start --ppid 1 --quiet \
			--exec $DAEMON -- -h "${uris}" -f "${SLAPDCONF}"
	rvalue=$?
	fail_msg=""
	# Bug #33993
	if [ "i686" = "$(uname -m)" ]; then
		for i in $(seq 1 3); do
			[ $rvalue -eq 0 ] && break
			sleep 1
			start-stop-daemon --start --ppid 1 --quiet --exec $DAEMON -- -h "${uris}" -f "${SLAPDCONF}"
			rvalue=$?
		done
		[ $rvalue -ne 0 ] && fail_msg="slapd start failed, check if ldap/database/mdb/maxsize is supported on this architecture"
	fi
	log_action_end_msg $rvalue "$fail_msg"
	if [ $rvalue != 0 ]; then
		exit_if_start_is_running
		[ -e /usr/sbin/slapschema ] && log_action_msg $(/usr/sbin/slapschema -f /etc/ldap/slapd.conf 2>&1)
		exit $rvalue
	fi

	test -e /var/run/slapd/ldapi && ln -sf /var/run/slapd/ldapi /var/run/ldapi

@!@
if configRegistry['ldap/server/type'] == "master":
    print('\tlog_action_begin_msg "Checking Schema ID: "')
    print('\tcheck_subschema 2>&1')
    print('\tlog_action_end_msg 0')
@!@

	if [ -e /var/lib/univention-directory-replication/failed.ldif ]; then
		log_action_begin_msg "Found failed.ldif. Importing "
		test -x /usr/sbin/univention-directory-replication-resync && /usr/sbin/univention-directory-replication-resync /var/lib/univention-directory-replication/failed.ldif >>/var/log/univention/listener.log 2>&1
		if [ $? = 0 ]; then
			log_action_end_msg 0
		else
			log_action_end_msg 1
			log_action_msg "Please check /var/log/univention/listener.log"
			exit 1
		fi
	fi

	;;
  stop)
	logger "/etc/init.d/slapd $1 (pid: $$, ppid:$(ps -p $PPID -o pid= -o comm=))"
	log_action_begin_msg "Stopping ldap server(s): slapd "
	## first try with pidfile
	start-stop-daemon --stop --ppid 1 --quiet --oknodo --retry 10 \
		--pidfile "$pidfile" -v | sed -rn 's/.*, (retry #|refused to die)/\1/p' \
		| while read line; do log_action_cont_msg "$line"; done
	## check process (instead of [ $? -eq 2 ])
	pid=$(getpid)
	if [ -n "$pid" ]; then
		log_action_end_msg 1
		## try via executable name
		log_action_begin_msg "Slapd still running ($pid), terminating via executable name"
		start-stop-daemon --stop --ppid 1 --quiet --oknodo --retry 10 \
			--exec $DAEMON -v | sed -rn 's/.*, (retry #|refused to die)/\1/p' \
			| while read line; do log_action_cont_msg "$line"; done
		rm -f "$pidfile"
	fi
	log_action_end_msg 0
	;;
  restart|force-reload)
	logger "/etc/init.d/slapd $1 (pid: $$, ppid:$(ps -p $PPID -o pid= -o comm=))"
	log_action_msg "Restarting ldap server(s)"
	$0 stop
	$0 start
	;;
  force-stop)
	logger "/etc/init.d/slapd $1 (pid: $$, ppid:$(ps -p $PPID -o pid= -o comm=))"
	log_action_begin_msg "Stopping ldap servers (forced) "
	start-stop-daemon --stop --ppid 1 --quiet --oknodo --retry forever/KILL \
		--exec $DAEMON
	rm -f "$pidfile"
	log_action_end_msg 0
	;;
  crestart)
	logger "/etc/init.d/slapd $1 (pid: $$, ppid:$(ps -p $PPID -o pid= -o comm=))"
	if pidof slapd > /dev/null 2>&1
	then
		$0 restart
	else
		log_action_msg "No slapd process found, no restart needed"
	fi
	;;
  graceful-stop)
	$0 stop
	# logger "/etc/init.d/slapd $1 (pid: $$, ppid:$(ps -p $PPID -o pid= -o comm=))"
	# log_action_begin_msg "Sending HUP to ldap server(s): slapd "
	# signal_plan="HUP/10/TERM/5/KILL/1"
	# ## first try with pidfile
	# start-stop-daemon --stop --ppid 1 --quiet --oknodo --retry "$signal_plan" \
	# 	--pidfile "$pidfile" -v | sed -rn 's/.*, (retry #|refused to die)/\1/p' \
	# 	| while read line; do log_action_cont_msg "$line"; done
	# ## check process (instead of [ $? -eq 2 ])
	# pid=$(getpid)
	# if [ -n "$pid" ]; then
	# 	log_action_end_msg 1
	# 	## try via executable name
	# 	log_action_begin_msg "Slapd still running ($pid), sending HUP via executable name"
	# 	start-stop-daemon --stop --ppid 1 --quiet --oknodo --retry "$signal_plan" \
	# 		--exec $DAEMON -v | sed -rn 's/.*, (retry #|refused to die)/\1/p' \
	# 		| while read line; do log_action_cont_msg "$line"; done
	# 	rm -f "$pidfile"
	# fi
	# log_action_end_msg 0
	;;
  graceful-restart)
	$0 restart
	# logger "/etc/init.d/slapd $1 (pid: $$, ppid:$(ps -p $PPID -o pid= -o comm=))"
	# log_action_msg "Initiating graceful reload of ldap server(s)"
	# $0 graceful-stop
	# $0 start
	;;
  *)
	echo "Usage: $0 {start|stop|restart|force-stop|crestart|graceful-stop|graceful-restart}"
	exit 1
	;;
esac

exit 0
