#!/bin/sh

exec > /tmp/checkpassword 2>&1; printenv; set -x
CKPASSREPLY=$1

# TMP file creation and cleanup
dnresult=$(mktemp -t $(basename $0)); authresult=$(mktemp -t $(basename $0))
cleanup () { rm -f "$dnresult" "$authresult"; exit; }
trap 'cleanup' 0 1 2 3 4 6 7 8 10 11 12 14 15 24 25

cfgvalue() {
	echo $(cut -d= -f2-)
}
ldapvalue() {
	awk '{FS=": "; print $2}'
}

# Dovecot-style LDAP configuration, containing a single "hosts", a "base", "dn" and "dnpass"
cfg=/usr/local/etc/dovecot/on2it-ldap-users.cfg
  srv=$(grep "^hosts[[:space:]]*=[[:space:]]*" "$cfg" | cfgvalue)
  base=$(grep "^base[[:space:]]*=[[:space:]]*" "$cfg" | cfgvalue)
  dn=$(grep "^dn[[:space:]]*=[[:space:]]*" "$cfg" | cfgvalue)
  dnpass=$(grep "^dnpass[[:space:]]*=[[:space:]]*" "$cfg" | cfgvalue)
LDAPSEARCH="/usr/local/bin/ldapsearch -o ldif-wrap=no -x -LLL -E pr=200/noprompt -H ldap://$srv -b $base -s sub"

# Read username and pass, null-separated on fd 3
input=$(tr "\0" "\1" 0<&3)
username=$(echo $input | awk '{FS = "\1" ; print $1}')
userpass=$(echo $input | awk '{FS = "\1" ; print $2}')

# Obtain DN using authenticated bind
if ${LDAPSEARCH} -D "$dn" -w "$dnpass" "(&(ObjectClass=person)(sAMAccountName=$username))" DN > "$dnresult" ; then
	logger -t checkpassword -p mail.info "successful authenticated bind and DN($username) lookup"
else
	logger -t checkpassword -p mail.err "internal error looking up DN($username)"
	exit 111
fi
DN=$(grep -i '^DN:' "$dnresult" | ldapvalue)
if [ "${DN}" ] ; then
	logger -t checkpassword -p mail.info "DN($username) is $DN"
else
	logger -t checkpassword -p mail.warning "DN($username) not found"
	exit 3
fi
if ${LDAPSEARCH} -D "$DN" -w "$userpass" sAMAccountName=$username sAMAccountName > "$authresult" ; then
	logger -t checkpassword -p mail.info "$username authenticated"
else
	logger -t checkpassword -p mail.warning "$username authentication failed"
	exit 1
fi
HOME=$(grep -i '^sAMAccountName:' "$authresult" | ldapvalue)
USER=${HOME}
AUTHORIZED=2
userdb_uid=1000
userdb_gid=1000
EXTRA="userdb_uid userdb_gid"

exec ${CKPASSREPLY}
