#!/bin/sh

set -e

# DEBIAN_FRONTEND=noninteractive apt --yes install adduser slapd ldap-utils sssd cron sudo man-db procps vim whiptail
# slappasswd -s kkkk

TESTNR="04"
BASEDIR="$(pwd)/debian/tests"
COMMONDIR="${BASEDIR}/common"
DIR="${BASEDIR}/${TESTNR}"
PATH="/bin:/usr/bin:/sbin:/usr/sbin"
ACCTA="testuser1"
ACCTB="testuser2"
PASSWD="test${TESTNR}23456"
HOMEDIRA="/home/${ACCTA}"
HOMEDIRB="/home/${ACCTB}"
LDIFDIR="${DIR}/ldif"
SSSDCONF="/etc/sssd/sssd.conf"

trap '
  kill $(pidof slapd) 2>/dev/null || true
  kill $(pidof sssd) 2>/dev/null || true
' 0 INT QUIT ABRT PIPE TERM

# openssl req -x509 -days 365 -nodes -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem --subj "/C=DE/CN=emptysid86.zugschlus.de"

< ${LDIFDIR}/debconf debconf-set-selections
printf "clean up ldap database ... "
rm -rf /var/lib/ldap/*.mdb
printf "move configuration in place ... "
mkdir -p /etc/ldap /etc/sssd
cp ${LDIFDIR}/server_*.pem /etc/ldap/
cp ${LDIFDIR}/ldap.conf /etc/ldap/
chown openldap:openldap /etc/ldap/server_*.pem
chmod 600 /etc/ldap/server_key.pem
cp ${LDIFDIR}/sssd.conf /etc/sssd
chown root:root /etc/sssd/sssd.conf
chmod 600 /etc/sssd/sssd.conf
cp ${LDIFDIR}/slapd-default /etc/default/slapd
echo "slapd: [::1]" >> /etc/hosts.allow
printf "reconfigure slapd ... "
DEBIAN_FRONTEND=noninteractive dpkg-reconfigure -pcritical slapd 2>/dev/null
kill $(pidof slapd) 2>/dev/null || true
sleep 1
printf "start slapd ... "
slapd -h "ldaps:/// ldapi:///" -g openldap -u openldap -F /etc/ldap/slapd.d
# ldapsearch -x -LLL -s base -b "" namingContexts should work here
printf "set LDAP passwords"
ldapmodify -Y external -H ldapi:/// -f ${LDIFDIR}/tls.ldif 2>/dev/null
ldapmodify -Y external -H ldapi:/// -f ${LDIFDIR}/adminpw.ldif 2>/dev/null
ldapmodify -Y external -H ldapi:/// -f ${LDIFDIR}/adminpw-example-com.ldif 2>/dev/null
printf "add users and groups OUs ..."
ldapadd -x -D "cn=admin,dc=example,dc=com" -w ldappw -f ${LDIFDIR}/sss-ous.ldif 2>/dev/null
printf "add users ..."

printf "sssd.conf ...\n"
cp ${LDIFDIR}/sssd.conf "${SSSDCONF}"

printf "sudoers file ...\n"A
mkdir -p /etc/sudoers.d/
mv ${LDIFDIR}/ldapsudoers /etc/sudoers.d/
chown root:root "${SSSDCONF}" /etc/sudoers.d/ /etc/sudoers.d/*
chmod 755 /etc/sudoers.d/
chmod 600 "${SSSDCONF}" /etc/sudoers.d/*
kill $(pidof sssd) 2>/dev/null || true
sleep 1
sssd --logger=files -D

for user in testuser1 testuser2; do
  ldapadd -x -D "cn=admin,dc=example,dc=com" -w ldappw -f ${LDIFDIR}/${user}.ldif 2>/dev/null
  mkdir -p /home/${user}
  chown ${user}:nogroup /home/${user}
done
ldapadd -x -D "cn=admin,dc=example,dc=com" -w ldappw -f ${LDIFDIR}/ldapsudoers.ldif 2>/dev/null
# ldapsearch -x -D "cn=admin,dc=example,dc=com" -w ldappw -b "dc=example,dc=com" -s sub "(objectclass=*)" should work here.

printf "========= test %s\.1: account group member, correct password\n" "${TESTNR}"
RET=0
printf "trying %s with correct password\n" "${ACCTA}"
su - "${ACCTA}" -c "${COMMONDIR}/asuser ${PASSWD}" || RET=$?
printf "%s with correct password, return value %s\n" "${ACCTA}" "${RET}"
if [ "$(cat ${HOMEDIRA}/stdout)" != "0" ]; then
  printf >&2 "id -u did not give 0\n"
  printf >&2 "stdout:\n"
  cat >&2 ${HOMEDIRA}/stdout
  printf >&2 "stderr:\n"
  cat >&2 ${HOMEDIRA}/stderr
  printf >&2 "exit code %s\n" "${RET}"
  printf >&2 "exit 1\n" "${RET}"
  exit 1
fi

printf "========= test %s\.2: account group member, wrong password\n" "${TESTNR}"
rm -f "${HOMEDIRA}/std*"
RET=0
printf "trying %s with wrong password\n" "${ACCTA}"
su - "${ACCTA}" -c "${COMMONDIR}/asuser wrongpasswd" || RET=$?
printf "%s with wrong password, return value %s\n" "${ACCTA}" "${RET}"
head -n-0 ${HOMEDIRA}/stdout ${HOMEDIRA}/stderr
printf -- "\n-------\n"
for string in "[sudo] password for ${ACCTA}" "Sorry, try again" "sudo: no password was provided" "sudo: 1 incorrect password attempt"; do
  if ! grep -F "${string}" ${HOMEDIRA}/stderr; then
    printf "%s missing in stderr output\n" "${string}"
    printf >&2 "stdout:\n"
    cat >&2 ${HOMEDIRA}/stdout
    printf >&2 "stderr:\n"
    cat >&2 ${HOMEDIRA}/stderr
    printf >&2 "\nexit code %s\n" "${RET}"
    printf >&2 -- "------\n exit 1\n"
    exit 1
  fi
done

printf "========= test %s\.3: account not group member, correct password\n" "${TESTNR}"
printf "trying %s (no sudo membership) with correct password\n" "${ACCTB}"
su - "${ACCTB}" -c "${COMMONDIR}/asuser ${PASSWD}" || RET=$?
printf "%s with correct password, return value %s\n" "${ACCTB}" "${RET}"
head -n-0 ${HOMEDIRB}/stdout ${HOMEDIRB}/stderr
printf -- "\n-------\n"
for string in "[sudo] password for ${ACCTB}: ${ACCTB} is not in the sudoers file." ; do
  if ! grep -q -F "${string}" ${HOMEDIRB}/stderr; then
    printf "%s missing in stderr output\n" "${string}"
    printf >&2 "stdout:\n"
    cat >&2 ${HOMEDIRB}/stdout
    printf >&2 "stderr:\n"
    cat >&2 ${HOMEDIRB}/stderr
    printf >&2 "\nexit code %s\n" "${RET}"
    printf >&2 -- "------\n exit 1\n"
    exit 1
  fi
done

printf "test series sucessful, exit 0\n"
exit 0

