#!/usr/bin/env sh
set -e
set -x

BASE_PATH=$( cd "`dirname $0`/../test/fixtures/openldap" && pwd )
SEED_PATH=$( cd "`dirname $0`/../test/fixtures"          && pwd )

dpkg -s slapd time ldap-utils gnutls-bin ssl-cert > /dev/null ||\
  DEBIAN_FRONTEND=noninteractive apt-get update  -y --force-yes && \
  DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes slapd time ldap-utils gnutls-bin ssl-cert

/etc/init.d/slapd stop

TMPDIR=$(mktemp -d)
cd $TMPDIR

# Delete data and reconfigure.
cp -v /var/lib/ldap/DB_CONFIG ./DB_CONFIG
rm -rf /etc/ldap/slapd.d/*
rm -rf /var/lib/ldap/*
cp -v ./DB_CONFIG /var/lib/ldap/DB_CONFIG
slapadd -F /etc/ldap/slapd.d -b "cn=config" -l $BASE_PATH/slapd.conf.ldif
# Load memberof and ref-int overlays and configure them.
slapadd -F /etc/ldap/slapd.d -b "cn=config" -l $BASE_PATH/memberof.ldif
# Load retcode overlay and configure
slapadd -F /etc/ldap/slapd.d -b "cn=config" -l $BASE_PATH/retcode.ldif

# Add base domain.
slapadd -F /etc/ldap/slapd.d <<EOM
dn: dc=rubyldap,dc=com
objectClass: top
objectClass: domain
dc: rubyldap
EOM

chown -R openldap.openldap /etc/ldap/slapd.d
chown -R openldap.openldap /var/lib/ldap

/etc/init.d/slapd start

# Import seed data.
# NOTE: use ldapadd in order for memberOf and refint to apply, instead of:
# cat $SEED_PATH/seed.ldif | slapadd -F /etc/ldap/slapd.d
/usr/bin/time ldapadd -x -D "cn=admin,dc=rubyldap,dc=com" -w passworD1 \
             -h localhost -p 389 \
             -f $SEED_PATH/seed.ldif

rm -rf $TMPDIR

# SSL
export CA_CERT="/usr/local/share/ca-certificates/rubyldap-ca.crt"
export CA_KEY="/etc/ssl/private/rubyldap-ca.key"

# The self-signed fixture CA cert & key are generated by
# `script/generate-fiuxture-ca` and checked into version control.
# You shouldn't need to muck with these unless you're writing more
# TLS/SSL integration tests, and need special magic values in the cert.

cp "${SEED_PATH}/ca/cacert.pem" "${CA_CERT}"
cp "${SEED_PATH}/ca/cakey.pem"  "${CA_KEY}"

# actually add the fixture CA to the system store
update-ca-certificates

# Make a private key for the server:
certtool --generate-privkey \
  --bits 1024 \
  --outfile /etc/ssl/private/ldap01_slapd_key.pem

sh -c "cat > /etc/ssl/ldap01.info <<EOF
organization = Example Company
cn = ldap01.example.com
dns_name = ldap01.example.com
dns_name = ldap02.example.com
dns_name = localhost
tls_www_server
encryption_key
signing_key
expiration_days = 3650
EOF"

# The integration server may be accessed by IP address, in which case
# we want some of the IPs included in the cert. We skip loopback (127.0.0.1)
# because that's the IP we use in the integration test for cert name mismatches.
ADDRS=$(ifconfig -a | grep 'inet addr:' | cut -f 2 -d : | cut -f 1 -d ' ')
for ip in $ADDRS; do
  if [ "x$ip" = 'x127.0.0.1' ]; then continue; fi
  echo "ip_address = $ip" >> /etc/ssl/ldap01.info
done

# Create the server certificate
certtool --generate-certificate \
  --load-privkey /etc/ssl/private/ldap01_slapd_key.pem \
  --load-ca-certificate "${CA_CERT}" \
  --load-ca-privkey "${CA_KEY}" \
  --template /etc/ssl/ldap01.info \
  --outfile /etc/ssl/certs/ldap01_slapd_cert.pem

ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF | true
dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: ${CA_CERT}
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap01_slapd_cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap01_slapd_key.pem
EOF

# LDAP over TLS/SSL (ldaps://) is deprecated in favour of StartTLS. The latter
# refers to an existing LDAP session (listening on TCP port 389) becoming
# protected by TLS/SSL whereas LDAPS, like HTTPS, is a distinct
# encrypted-from-the-start protocol that operates over TCP port 636. But we
# enable it for testing here.
sed -i -e 's|^SLAPD_SERVICES="\(.*\)"|SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"|' /etc/default/slapd

adduser openldap ssl-cert
chgrp ssl-cert /etc/ssl/private/ldap01_slapd_key.pem
chmod g+r /etc/ssl/private/ldap01_slapd_key.pem
chmod o-r /etc/ssl/private/ldap01_slapd_key.pem

# Drop packets on a secondary port used to specific timeout tests
iptables -A INPUT -p tcp -j DROP --dport 8389

# Forward a port for Vagrant
iptables -t nat -A PREROUTING -p tcp --dport 9389 -j REDIRECT --to-port 389

# fix up /etc/hosts for cert validation
grep ldap01 /etc/hosts || echo "127.0.0.1 ldap01.example.com" >> /etc/hosts
grep ldap02 /etc/hosts || echo "127.0.0.1 ldap02.example.com" >> /etc/hosts
grep bogus /etc/hosts  || echo "127.0.0.1 bogus.example.com" >> /etc/hosts

service slapd restart
