#!/bin/bash
#
# Univention Directory Replication
#  re-synchronize the local LDAP directory
#
# Copyright 2001-2014 Univention GmbH
#
# http://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <http://www.gnu.org/licenses/>.
# Univention LDAP Listener replication module

eval "$(univention-config-registry shell)"
export faileddns=`tempfile`



display_header() {
        echo ""
        echo "univention-directory-replication-resync: Resync local LDAP using a failed.ldif"
        echo "copyright (c) 2001-@%@copyright_lastyear@%@ Univention GmbH, Germany"
		echo "usage: $0 <failed.ldif>"
        echo ""
}


base64decode()
{
	export IFS=''
	cat << EOF | python - $1
import base64,sys
x=sys.argv[1]
print base64.decodestring(x)
EOF
}

getdns()
{
	export IFS=''
	cat $1 | ldapsearch-wrapper | grep '^dn:' | sort -u | {
		while
			read i
		do
			if echo $i | grep '^dn:: '>/dev/null
			then
				base64decode `echo "$i"| sed 's/^dn:: //g'`
			else
				echo "$i"| sed 's/^dn: //g'
			fi
		done
	}
}

if [ -z "$1" ] || [ "$1" = "-h" -o "$1" = "--help" ]; then
	display_header
	exit 1
fi

if ! pidof slapd > /dev/null 2>&1
	then
	echo "No slapd-process found, resync is not possible."
	echo "run /etc/init.d/slapd start"
	exit 1
fi

if ! test -f $1
	then
	echo "Input $1 is no regular file"
	exit 1
fi

date >> /var/log/univention/ldap-replication-resync.log
echo "Try to sync changes stored in $1 into local LDAP" | tee -a /var/log/univention/ldap-replication-resync.log
sv down univention-directory-listener
echo -n "waiting for listener-shutdown "
while ! sv status univention-directory-listener | grep ^down: >/dev/null
  do sleep 1
  echo -n " ."
done
echo " shutdown done"

echo "replay stored changes ..."
if ldapmodify -x -w`cat /etc/ldap/rootpw.conf |cut -d'"' -f 2` -D "cn=update,${ldap_base}" -c -S"${faileddns}" -f "$1" >> /var/log/univention/ldap-replication-resync.log 2>&1
then
	echo ""
	d=`date +%F-%X`
	echo "Restored modifies sucessfuly, the ldif-file will be moved to /tmp/replayed.ldif_$d"
	rm "${faileddns}"
	if [ ! -d /var/lib/univention-directory-replication ]; then
		mkdir -p /var/lib/univention-directory-replication; chmod -R 700 /var/lib/univention-directory-replication
	fi
	mv $1 "/var/lib/univention-directory-replication/replayed.ldif_$d"; chmod 600 "/var/lib/univention-directory-replication/replayed.ldif_$d"
	/etc/init.d/univention-directory-listener start
	exit 0
else
	echo "some DNs have failed and have to be synced manually:"
	getdns "${faileddns}"
	echo ""
	echo "You can find the failed modifications in ${faileddns}"
	echo "Check them for being sync with the master-LDAP, then delete $1 and start the listener again typing:"
	echo "/etc/init.d/univention-directory-listener start"
	exit 1
fi

