#!/bin/sh -e
#
# Univention Directory Notifier
#  Replicate one DN
#
# SPDX-FileCopyrightText: 2012-2026 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only

eval "$(ucr shell)"

usage()
{
	echo "Usage: $0 --dn <ldap dn> [--force]"
	echo
	echo "The given LDAP DN will be re-replicated by the Univention Directory Notifier to all UCS systems in this UCS domain. This tool must be run on the Primary Directory Node."
	echo
	echo "  --force    Continue even if the object does not exist in LDAP."
	echo
	echo "Warning: This tool will stop the OpenLDAP and the Notifier daemon."
	echo
}

if [ "$server_role" != "domaincontroller_master" ]; then
	echo "Abort: This tool must be run on the Primary Directory Node!" >&2
	exit 1
fi

if [ ! -e /var/lib/univention-ldap/notify/transaction ]; then
	echo "Abort: /var/lib/univention-ldap/notify/transaction was not found." >&2
	exit 1
fi

dn=""
FORCE=0

while [ "$#" -gt 0 ]; do
	case "$1" in
		--dn)
			[ "$#" -ge 2 ] || { usage >&2; exit 1; }
			dn="$2"
			shift 2
			;;
		--force)
			FORCE=1
			shift
			;;
		*)
			usage >&2
			exit 1
			;;
	esac
done

if [ -z "$dn" ]; then
	usage >&2
	exit 1
fi

if ! slapdn -f /etc/ldap/slapd.conf "$dn" > /dev/null 2>&1; then
	echo "Error: Skip due to invalid DN syntax: $dn" >&2
	exit 1
fi

if ! univention-ldapsearch -LLLA -b "$dn" -s base dn >/dev/null 2>&1; then
	if [ "$FORCE" = 1 ]; then
		echo "Warning: \"$dn\" does not exist in LDAP, continuing as requested." >&2
	else
		echo "Abort: \"$dn\" does not exist in LDAP. Use --force to replicate anyway." >&2
		exit 1
	fi
fi

RESTART_NOTIFIER=0
if pidof univention-directory-notifier >/dev/null ; then
	echo -n "Stopping notifier: "
	RESTART_NOTIFIER=1
	systemctl stop univention-directory-notifier
	sleep 1
	if pidof univention-directory-notifier >/dev/null ; then
		echo "failed"
		echo "Abort: Failed to stop the notifier daemon. Please check stop the daemon manually and try again." >&2
		exit 1
	fi
	echo "done"
fi

RESTART_SLAPD=0
if pidof slapd >/dev/null ; then
	echo -n "Stopping slapd: "
	RESTART_SLAPD=1
	/etc/init.d/slapd stop >/dev/null
	sleep 1
	if pidof slapd >/dev/null ; then
		echo "failed"
		echo "Abort: Failed to stop the OpenLDAP daemon. Please check stop the daemon manually and try again." >&2
		exit 1
	fi
	echo "done"
fi


echo -n "Write $dn to listener file: "
id="$(tail -n 1 /var/lib/univention-ldap/notify/transaction | awk '{print $1}')"

last_line="$(tail -n 1 /var/lib/univention-ldap/listener/listener)"
if [ -n "$last_line" ]; then
	id_listener="$(tail -n 1 /var/lib/univention-ldap/listener/listener | awk '{print $1}')"
fi

if [ -n "$id_listener" ] && [ "$id_listener" -gt "$id" ]; then
	nextid=$((id_listener+1))
else
	nextid=$((id+1))
fi

echo "$nextid $dn m" >>/var/lib/univention-ldap/listener/listener
echo -n "$nextid" >/var/lib/univention-ldap/last_id
echo "done"

rc=0

if [ "$RESTART_NOTIFIER" = 1 ]; then
	echo -n "Starting notifier: "
	systemctl start univention-directory-notifier >/dev/null || rc=1
	echo "done"
fi

if [ "$RESTART_SLAPD" = 1 ]; then
	echo -n "Starting slapd: "
	/etc/init.d/slapd start >/dev/null || rc=1
	echo "done"
fi

exit $rc
