#! /bin/sh
# $OpenLDAP$
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
##
## Copyright 2016-2021 Ondřej Kuzník, Symas Corp.
## Copyright 1998-2024 The OpenLDAP Foundation.
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted only as authorized by the OpenLDAP
## Public License.
##
## A copy of this license is available in the file LICENSE in the
## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.

echo "running defines.sh"
. $SRCDIR/scripts/defines.sh

if test $WITH_TLS = no ; then
    echo "TLS support not available, test skipped"
    exit 0
fi

if test $REMOTEAUTH = remoteauthno; then
    echo "RemoteAuth overlay not available, test skipped"
    exit 0
fi

mkdir -p $TESTDIR $DBDIR1 $DBDIR2 $TESTDIR/confdir
cp -r $DATADIR/tls $TESTDIR

. $CONFFILTER < $DATADIR/remoteauth/default_domain > $TESTDIR/default_domain

. $CONFFILTER $BACKEND < $TLSCONF > $CONF1

$SLAPPASSWD -g -n >$CONFIGPWF
echo "database config" >>$CONF1
echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >>$CONF1
echo "TLSCACertificateFile $TESTDIR/tls/ca/certs/testsuiteCA.crt" >>$CONF1

$SLAPD -Tt -n 0 -f $CONF1 -F $TESTDIR/confdir -d $LVL > $LOG1 2>&1
RC=$?
if test $RC != 0 ; then
    echo "slaptest failed ($RC)!"
    exit $RC
fi

echo -n "Running slapadd to build slapd database... "
$SLAPADD -F $TESTDIR/confdir -l $LDIFORDERED
RC=$?
if test $RC != 0 ; then
    echo "slapadd failed ($RC)!"
    exit $RC
fi

echo "DB tweaks..."
$SLAPMODIFY -F $TESTDIR/confdir >>$LOG1 2>&1 <<EOMODS
dn: $MELLIOTDN
changetype: modify
add: o
o: self
-
replace: seeAlso
seeAlso: $BJORNSDN

dn: $JOHNDDN
changetype: modify
replace: seeAlso
seeAlso: $BJORNSDN
EOMODS
RC=$?
if test $RC != 0 ; then
    echo "slapmodify failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi

echo "Starting slapd on TCP/IP port $PORT1 for configuration..."
$SLAPD -F $TESTDIR/confdir -h $URI1 -d $LVL >> $LOG1 2>&1 &
REMOTEAUTH_PID=$!
if test $WAIT != 0 ; then
    echo REMOTEAUTH_PID $REMOTEAUTH_PID
    read foo
fi
KILLPIDS="$REMOTEAUTH_PID"

sleep $SLEEP0

for i in 0 1 2 3 4 5; do
    $LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \
        'objectclass=*' > /dev/null 2>&1
    RC=$?
    if test $RC = 0 ; then
        break
    fi
    echo "Waiting ${SLEEP1} seconds for slapd to start..."
    sleep ${SLEEP1}
done

if [ "$REMOTEAUTH" = remoteauthmod ]; then
$LDAPADD -D cn=config -H $URI1 -y $CONFIGPWF \
    >> $TESTOUT 2>&1 <<EOMOD
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulePath: $TESTWD/../servers/slapd/overlays
olcModuleLoad: remoteauth.la
EOMOD
RC=$?
if test $RC != 0 ; then
    echo "ldapmodify failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi
fi

echo "Loading test remoteauth configuration..."
. $CONFFILTER $BACKEND < $DATADIR/remoteauth/config.ldif | \
$LDAPADD -v -D cn=config -H $URI1 -y $CONFIGPWF \
    >> $TESTOUT 2>&1
RC=$?
if test $RC != 0 ; then
    echo "ldapadd failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi

echo -n "Preparing second server on $URI2 and $SURIP3... "
. $CONFFILTER $BACKEND < $TLSCONF | sed -e "s,$DBDIR1,$DBDIR2," > $CONF2

echo -n "loading data... "
$SLAPADD -f $CONF2 -l $LDIFORDERED
RC=$?
if test $RC != 0 ; then
    echo "slapadd failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi

echo -n "tweaking DB contents... "
$SLAPMODIFY -f $CONF2 >>$LOG2 2>&1 <<EOMODS
dn: $BJORNSDN
changetype: modify
replace: userPassword
userPassword: bjorn2
EOMODS
RC=$?
if test $RC != 0 ; then
    echo "slapmodify failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi

echo "starting up... "
$SLAPD -f $CONF2 -h "$URI2 $SURIP3" -d $LVL > $LOG2 2>&1 &
BACKEND_PID=$!
if test $WAIT != 0 ; then
    echo BACKEND_PID $BACKEND_PID
    read foo
fi
KILLPIDS="$KILLPIDS $BACKEND_PID"

for i in 0 1 2 3 4 5; do
    $LDAPSEARCH -s base -b "$MONITOR" -H $URI2 \
        'objectclass=*' > /dev/null 2>&1
    RC=$?
    if test $RC = 0 ; then
        break
    fi
    echo "Waiting ${SLEEP1} seconds for slapd to start..."
    sleep ${SLEEP1}
done

if test $RC != 0 ; then
    echo "failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi

. $CONFFILTER $BACKEND < $TLSCONF > $CONF1

echo "TLSCACertificateFile $TESTDIR/tls/ca/certs/testsuiteCA.crt" >>$CONF1
echo "database config" >>$CONF1
echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >>$CONF1

# We check basic remoteauth operation and generated configuration in these
# circumstances:
# 1. configured online through cn=config (what we set up above)
# 2. the server from 1. restarted (loading from cn=config on startup)
# 3. configured and started through a slapd.conf
#
# All of the above should present the same behaviour and cn=config output

echo "Saving generated config before server restart..."
echo "# search output from dynamically configured server..." >> $SERVER1OUT
$LDAPSEARCH -D cn=config -H $URI1 -y $CONFIGPWF \
    -b "olcOverlay={0}remoteauth,olcDatabase={1}$BACKEND,cn=config" \
    >> $SERVER1OUT 2>&1
RC=$?
if test $RC != 0 ; then
    echo "ldapsearch failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi

echo -n "Checking bind handling... "

$LDAPWHOAMI -H $URI1 -x -D "$BJORNSDN" -w bjorn >/dev/null
RC=$?
if test $RC != 0 ; then
    echo "ldapwhoami failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi
echo -n "1 "

$LDAPWHOAMI -H $URI1 -x -D "$JOHNDDN" -w bjorn2 >/dev/null
RC=$?
if test $RC != 0 ; then
    echo "ldapwhoami failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi
echo -n "2 "

$LDAPWHOAMI -H $URI1 -x -D "$MELLIOTDN" -w bjorn >/dev/null
RC=$?
if test $RC != 0 ; then
    echo "ldapwhoami failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi
echo -n "3 "

echo "ok"

echo "Stopping slapd on TCP/IP port $PORT1..."
kill -HUP $REMOTEAUTH_PID
KILLPIDS="$BACKEND_PID"
sleep $SLEEP0
echo "Starting slapd on TCP/IP port $PORT1..."
$SLAPD -F $TESTDIR/confdir -h $URI1 -d $LVL >> $LOG1 2>&1 &
REMOTEAUTH_PID=$!
if test $WAIT != 0 ; then
    echo REMOTEAUTH_PID $REMOTEAUTH_PID
    read foo
fi
KILLPIDS="$KILLPIDS $REMOTEAUTH_PID"

sleep $SLEEP0

for i in 0 1 2 3 4 5; do
    $LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \
        'objectclass=*' > /dev/null 2>&1
    RC=$?
    if test $RC = 0 ; then
        break
    fi
    echo "Waiting ${SLEEP1} seconds for slapd to start..."
    sleep ${SLEEP1}
done

echo "Saving generated config after server restart..."
echo "# search output from dynamically configured server after restart..." >> $SERVER2OUT
$LDAPSEARCH -D cn=config -H $URI1 -y $CONFIGPWF \
    -b "olcOverlay={0}remoteauth,olcDatabase={1}$BACKEND,cn=config" \
    >> $SERVER2OUT 2>&1
RC=$?
if test $RC != 0 ; then
    echo "ldapsearch failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi

echo -n "Checking bind handling... "

$LDAPWHOAMI -H $URI1 -x -D "$BJORNSDN" -w bjorn >/dev/null
RC=$?
if test $RC != 0 ; then
    echo "ldapwhoami failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi
echo -n "1 "

$LDAPWHOAMI -H $URI1 -x -D "$JOHNDDN" -w bjorn2 >/dev/null
RC=$?
if test $RC != 0 ; then
    echo "ldapwhoami failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi
echo -n "2 "

$LDAPWHOAMI -H $URI1 -x -D "$MELLIOTDN" -w bjorn >/dev/null
RC=$?
if test $RC != 0 ; then
    echo "ldapwhoami failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi
echo -n "3 "

echo "ok"

echo "Stopping slapd on TCP/IP port $PORT1..."
kill -HUP $REMOTEAUTH_PID
KILLPIDS="$BACKEND_PID"
sleep $SLEEP0

echo "Testing slapd.conf support..."
sed -e "s,database.*monitor,\\
TLSCACertificateFile $TESTDIR/tls/ca/certs/testsuiteCA.crt\\
\\
#remoteauthmod#modulepath ../servers/slapd/overlays/\\
#remoteauthmod#moduleload remoteauth.la\\
include $TESTDIR/remoteauth.conf\\
\\
database monitor," $TLSCONF | . $CONFFILTER $BACKEND >$CONF1
echo "database config" >>$CONF1
echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >>$CONF1

. $CONFFILTER $BACKEND < $DATADIR/remoteauth/remoteauth.conf >$TESTDIR/remoteauth.conf

echo "Starting slapd on TCP/IP port $PORT1..."
$SLAPD -f $CONF1 -h $URI1 -d $LVL >> $LOG1 2>&1 &
REMOTEAUTH_PID=$!
if test $WAIT != 0 ; then
    echo REMOTEAUTH_PID $REMOTEAUTH_PID
    read foo
fi
KILLPIDS="$KILLPIDS $REMOTEAUTH_PID"

sleep $SLEEP0

for i in 0 1 2 3 4 5; do
    $LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \
        'objectclass=*' > /dev/null 2>&1
    RC=$?
    if test $RC = 0 ; then
        break
    fi
    echo "Waiting ${SLEEP1} seconds for slapd to start..."
    sleep ${SLEEP1}
done

echo "Saving generated config from a slapd.conf sourced server..."
echo "# search output from server running from slapd.conf..." >> $SERVER3OUT
$LDAPSEARCH -D cn=config -H $URI1 -y $CONFIGPWF \
    -b "olcOverlay={0}remoteauth,olcDatabase={1}$BACKEND,cn=config" \
    >> $SERVER3OUT 2>&1
RC=$?
if test $RC != 0 ; then
    echo "ldapsearch failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi

echo -n "Checking bind handling... "

$LDAPWHOAMI -H $URI1 -x -D "$BJORNSDN" -w bjorn >/dev/null
RC=$?
if test $RC != 0 ; then
    echo "ldapwhoami failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi
echo -n "1 "

$LDAPWHOAMI -H $URI1 -x -D "$JOHNDDN" -w bjorn2 >/dev/null
RC=$?
if test $RC != 0 ; then
    echo "ldapwhoami failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi
echo -n "2 "

$LDAPWHOAMI -H $URI1 -x -D "$MELLIOTDN" -w bjorn >/dev/null
RC=$?
if test $RC != 0 ; then
    echo "ldapwhoami failed ($RC)!"
    test $KILLSERVERS != no && kill -HUP $KILLPIDS
    exit $RC
fi
echo -n "3 "

echo "ok"

test $KILLSERVERS != no && kill -HUP $KILLPIDS

# LDIFFILTER doesn't (un)wrap long lines yet, so the result would differ
#. $CONFFILTER $BACKEND < $DATADIR/remoteauth/config.ldif \
#    | $LDIFFILTER -s a > $SERVER6FLT

# We've already filtered out the ordering markers, now sort the entries
echo "Filtering ldapsearch results..."
$LDIFFILTER -s a < $SERVER1OUT > $SERVER1FLT
$LDIFFILTER -s a < $SERVER2OUT > $SERVER2FLT
$LDIFFILTER -s a < $SERVER3OUT > $SERVER3FLT
echo "Filtering expected entries..."

echo "Comparing filter output..."
#$CMP $SERVER6FLT $SERVER1FLT > $CMPOUT && \
$CMP $SERVER1FLT $SERVER2FLT > $CMPOUT && \
$CMP $SERVER2FLT $SERVER3FLT > $CMPOUT

if test $? != 0 ; then
	echo "Comparison failed"
	exit 1
fi

echo ">>>>> Test succeeded"

test $KILLSERVERS != no && wait

exit 0
