#!/bin/bash
# 
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1
# 
# The contents of this file are subject to the Mozilla Public License
# Version 1.1 ("License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.zimbra.com/license
# 
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
# 
# The Original Code is: Zimbra Collaboration Suite Server.
# 
# The Initial Developer of the Original Code is Zimbra, Inc.
# Portions created by Zimbra are Copyright (C) 2005, 2006 Zimbra, Inc.
# All Rights Reserved.
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 

source `dirname $0`/../bin/zmshutil || exit 1

if [ "x$1" != "x" ]; then
	echo "Usage: $0"
	echo "	Use $0 to set up this server as an ldap replica"
	exit 1
fi

zmsetvars -f\
	zimbra_home \
	zimbra_server_hostname \
	ldap_master_url \
	ldap_port \
	ldap_root_password \
  ldap_replica_rid \
	zimbra_ldap_userdn

ldap_master_host=`echo ${ldap_master_url} | sed -e 's|ldaps*://\([^:]*\):*.*|\1|'`

verifyLdapInstalled() {
	echo -n "Looking for LDAP installation..."
	if [ ! -d ${zimbra_home}/openldap/etc ]; then
		echo "FAILED"
		echo "ERROR: openldap does not appear to be installed - exiting"
		exit 1
	fi
	echo "succeeded"
}

verifyLdap() {
	echo -n "Verifying ldap on ${ldap_master_url}..."
	LDS="${zimbra_home}/bin/ldapsearch";
	ARGS="-x -H ${ldap_master_url} -D ${zimbra_ldap_userdn} -w ${ldap_root_password}"
	OUTPUT=`$LDS $ARGS 2>&1`
	if [ $? -ne 0 ]; then
		echo "FAILED"
		echo "ERROR: Unable to verify ldap connection on ${ldap_master_url} - exiting"
    echo "$LDS $ARGS"
    echo $OUTPUT
		exit 1
	fi
	echo "succeeded"
}

enableSyncProv() {
	echo -n "Enabling sync provider..."
	sed -i .pre-replica -e '/syncprov/ s/#//g' ${zimbra_home}/conf/slapd.conf.in
	echo "succeeded"
}

createLdapConfig() {
	echo -n "Creating LDAP config in ${zimbra_home}/conf/slapd.conf..."
	root_sha=`${zimbra_home}/openldap/sbin/slappasswd -s ${ldap_root_password}`
	sed -e "s|^rootpw.*|rootpw ${root_sha}|" \
		${zimbra_home}/openldap/etc/openldap/slapd.conf > ${zimbra_home}/conf/slapd.conf.in
	grep -v syncprov ${zimbra_home}/conf/slapd.conf.in > /tmp/slapd.conf.in
	mv -f /tmp/slapd.conf.in ${zimbra_home}/conf/slapd.conf.in

	if [ $? -ne 0 ]; then
		echo "FAILED"
		echo "ERROR - LDAP config creation failed - exiting"
	fi

  if [ x"${ldap_replica_rid}" = "x" ]; then
    ldap_replica_rid=100
  fi

	if [ -f "/opt/zimbra/lib/conf/zimbra-ext.schema" ]; then
		plat=`/opt/zimbra/libexec/get_plat_tag.sh`
		if [ "x$plat" = "xMACOSX" -o "x$plat" = "xMACOSXx86" ]; then
			sed -e '\|/opt/zimbra/openldap/etc/openldap/schema/zimbra.schema| a\
				include "/opt/zimbra/lib/conf/zimbra-ext.schema"' ${zimbra_home}/conf/slapd.conf.in > /tmp/slapd.conf
		else
			sed -e '\|/opt/zimbra/openldap/etc/openldap/schema/zimbra.schema| a include "/opt/zimbra/lib/conf/zimbra-ext.schema"' ${zimbra_home}/conf/slapd.conf.in > /tmp/slapd.conf
		fi
		mv -f /tmp/slapd.conf ${zimbra_home}/conf/slapd.conf.in
	fi

	if [ $? -ne 0 ]; then
		echo "FAILED"
		echo "ERROR - LDAP config creation failed - exiting"
	fi

	cat >> ${zimbra_home}/conf/slapd.conf.in <<EOF
syncrepl rid=${ldap_replica_rid}
	provider=${ldap_master_url}
	retry="60 +"
	type=refreshAndPersist
	schemachecking=off
	updatedn="uid=zimbrareplication,cn=admins,cn=zimbra"
	searchbase=""
	bindmethod=simple
	binddn="uid=zimbra,cn=admins,cn=zimbra"
	credentials=${ldap_root_password}
updateref  ${ldap_master_url}
EOF

	/opt/zimbra/libexec/zmconfigure /opt/zimbra/conf/slapd.conf.in /opt/zimbra/conf/slapd.conf

	echo "succeeded"
}

createReplicaUser() {
	echo -n "Setting up replication ldap user..."

	touch /opt/zimbra/openldap-data/DB_CONFIG

	root_sha=`${zimbra_home}/openldap/sbin/slappasswd -s ${ldap_root_password}`
	
	cat > /tmp/replicauser.ldif <<EOF
dn: uid=zimbrareplication,cn=admins,cn=zimbra
uid: zimbrareplication
objectclass: zimbraAccount
objectclass: organizationalPerson
cn: zimbrareplication
sn: zimbrareplication
zimbraAccountStatus: active
zimbraIsAdminAccount: TRUE
zimbraId: e0fafd89-1360-11d9-8661-000a95d98ef3
description: The zimbra replication account
userPassword: ${root_sha}
EOF

	${zimbra_home}/openldap/bin/ldapadd -w ${ldap_root_password} -D ${zimbra_ldap_userdn} \
		-x -f /tmp/replicauser.ldif -H ${ldap_master_url} > /dev/null 2>&1

	# Ignore failures, user may already exist?
	echo "succeeded"
	
	/bin/rm -f /tmp/replicauser.ldif
}

enableLdapService() {
	echo -n "Enabling LDAP service on ${zimbra_server_hostname}..."
	SERVICES=`/opt/zimbra/bin/zmprov -l gs ${zimbra_server_hostname} | sed -ne '/^zimbraServiceEnabled/ s/zimbraServiceEnabled: //p'`
	echo $SERVICES | grep -q ldap
	if [ $? -ne 0 ]; then
		echo -n "..."
		NEWSERVICES="zimbraServiceEnabled ldap"
		for s in $SERVICES; do
			NEWSERVICES="$NEWSERVICES zimbraServiceEnabled $s"
		done
		/opt/zimbra/bin/zmprov -l ms ${zimbra_server_hostname} $NEWSERVICES
	fi
	echo "succeeded"
}

stopRemoteZimbra() {
	echo -n "Shutting down Zimbra Services on ${ldap_master_host}..."
	echo "HOST:${ldap_master_host} shutdown" | ${zimbra_home}/libexec/zmrc ${ldap_master_host} \
		> /dev/null 2>&1

	if [ $? -ne 0 ]; then
		echo "FAILED"
		echo "Remote shutdown failed - exiting"
		exit 1
	fi
	echo "done"
}

stopZimbra() {
	echo -n "Shutting down Zimbra Services on ${zimbra_server_hostname}..."
	zmcontrol stop > /dev/null 2>&1
	echo "done"
}

replicateLdap() {
	echo -n "Replicating ldap data from ${ldap_master_host}..."
	echo -n "Copying data..."
	echo "HOST:${ldap_master_host} slapcat" | ${zimbra_home}/libexec/zmrc ${ldap_master_host} | \
		grep -v STARTCMD | grep -v ENDCMD > /tmp/repl.ldif

	if [ $? -ne 0 ]; then
		echo "FAILED"
		echo "Ldap replication failed - exiting"
		exit 1
	fi

	echo -n "Writing data..."

	${zimbra_home}/openldap/sbin/slapadd -w -f ${zimbra_home}/conf/slapd.conf -l /tmp/repl.ldif
	if [ $? -ne 0 ]; then
		echo "FAILED"
		echo "Ldap replication failed - exiting"
		exit 1
	fi

	#/bin/rm -f /tmp/repl.ldif
	echo "succeeded"
}

updateLdapHost() {
	echo -n "Setting ldap_url on ${zimbra_server_hostname}...";
  if [ ${ldap_port} = 636 ]; then
    proto="ldaps"
  else 
    proto="ldap"
  fi
	zmlocalconfig -e ldap_url="${proto}://${zimbra_server_hostname}:${ldap_port} ${ldap_master_url}"
	echo "done"
}

startRemoteZimbra() {
	echo -n "Starting remote Zimbra Services on ${ldap_master_host}..."
	echo "HOST:${ldap_master_host} startup" | ${zimbra_home}/libexec/zmrc ${ldap_master_host} \
		> /dev/null 2>&1

	if [ $? -ne 0 ]; then
		echo "FAILED"
		echo "Remote startup failed - exiting"
		exit 1
	fi
	echo "done"
}

startLdap() {
	echo -n "Starting LDAP on ${zimbra_server_hostname}..."
	${zimbra_home}/bin/ldap start > /dev/null 2>&1
	echo "done"
}

if [ $ldap_master_host = $zimbra_server_hostname ]; then
	enableSyncProv
	${zimbra_home}/bin/ldap stop
	sleep 5;
	${zimbra_home}/bin/ldap start
	exit 0
fi

verifyLdapInstalled
verifyLdap
createLdapConfig
createReplicaUser
enableLdapService
#stopZimbra
#stopRemoteZimbra
#replicateLdap
updateLdapHost
#startRemoteZimbra
zmsetvars -f ldap_url
startLdap
