#!/bin/sh

set -e

CONFFILE="/etc/nss-ldapd.conf"

# source debconf library.
. /usr/share/debconf/confmodule
db_version 2.0
db_capb backup

# set title
db_title "Configuring libnss-ldapd"

#
# This is the fist part of the script. In this part an attempt
# is made to get or guess the current configuration. This information
# is later on used to prompt the user and to provide a sensible
# default.
#

# check the system (non-LDAP configuration files) for some
# reasonable defaults
parsesys()
{
  # guess domain based on system information
  domain=`hostname --domain` || true
  [ -z "$domain" ] && domain=`hostname --nis | grep '\.'` || true
  [ -z "$domain" ] && domain=`hostname --fqdn | sed -n 's/^[^.]*\.//p'` || true
  [ -z "$domain" ] && domain=`sed -n 's/^ *\(domain\|search\) *\([^ ]*\) *$/\2/p' /etc/resolv.conf | head -n 1` || true
  if [ -n "$domain" ]
  then
    # set search base
    searchbase=`echo "$domain" | sed 's/^/dc=/;s/\./,dc=/'` || true
    db_set libnss-ldapd/ldap-base "$searchbase"
  fi
  # guess ldap server
  server=`getent hosts ldap` || true
  [ -z "$server" ] && server=`getent hosts dirhost` || true
  if [ -n "$domain" ] && [ -z "$server" ]
  then
    server=`getent hosts ldap."$domain"` || true
    [ -z "$server" ] && server=`getent hosts dirhost."$domain"` || true
  fi
  if [ -n "$server" ]
  then
    # extract ip address from host entry and quote ipv6 address
    ip=`echo $server | sed 's/[[:space:]].*//;s/^\(.*:.*\)$/[\1]/'`
    db_set libnss-ldapd/ldap-uris "ldap://$ip/"
  fi
}

# parse a LDAP-like configuration file
parsecfg()
{
  cfgfile="$1"
  # check existance
  [ -f "$cfgfile" ] || return 0
  # find uri/host/port combo
  uris=`sed -n 's/^uri[[:space:]]*//ip' "$cfgfile"`
  if [ -z "$uris" ]
  then
    hosts=`sed -n 's/^host[[:space:]]*//ip' "$cfgfile"`
    port=`sed -n 's/^port[[:space:]]*//ip' "$cfgfile"`
    for host in $hosts
    do
      if [ -z "$port" ] || (echo "$host" | grep -q ':' )
      then
        uris="$uris ldap://$host/"
      else
        uris="$uris ldap://$host:$port/"
      fi
    done
  fi
  [ -n "$uris" ] && db_set libnss-ldapd/ldap-uris "$uris"
  # find base config
  searchbase=`sed -n 's/^base[[:space:]]*//ip' "$cfgfile"`
  [ -n "$searchbase" ] && db_set libnss-ldapd/ldap-base "$searchbase"
  # find ldap_version
  ldapversion=`sed -n 's/^ldap_version[[:space:]]*//ip' "$cfgfile"`
  [ -n "$searchbase" ] && db_set libnss-ldapd/ldap-version "$ldapversion"
  # find binddb
  binddn=`sed -n 's/^binddn[[:space:]]*//ip' "$cfgfile"`
  [ -n "$binddn" ] && db_set libnss-ldapd/ldap-binddn "$binddn"
  # find bindpw
  bindpw=`sed -n 's/^bindpw[[:space:]]*//ip' "$cfgfile"`
  [ -n "$bindpw" ] && db_set libnss-ldapd/ldap-bindpw "$bindpw"
  # find rootbinddb
  rootbinddn=`sed -n 's/^rootbinddn[[:space:]]*//ip' "$cfgfile"`
  [ -n "$rootbinddn" ] && db_set libnss-ldapd/ldap-rootbinddn "$rootbinddn"
  # find rootbindpw
  rootbindpw=`sed -n 's/^rootbindpw[[:space:]]*//ip' "$cfgfile"`
  [ -n "$rootbindpw" ] && db_set libnss-ldapd/ldap-rootbindpw "$rootbindpw"
  # we're done
  return 0
}

# parse /etc/nsswitch.conf and see which services have ldap specified
parsensswitch()
{
  # find name services that currently use LDAP
  configured=`sed -n 's/^\([^[:space:]]*\):.*[[:space:]]ldap\([[:space:]].*\)\?/\1/p' /etc/nsswitch.conf`
  # separate by commas
  configured=`echo $configured | sed 's/ /, /g'`
  # store configured services
  db_set libnss-ldapd/nsswitch "$configured"
  # we're done
  return 0
}

# clear some settings in case they are not set in the config
db_set libnss-ldapd/ldap-binddn ""
db_set libnss-ldapd/ldap-bindpw ""
db_set libnss-ldapd/ldap-rootbinddn ""
db_set libnss-ldapd/ldap-rootbindpw ""

# fill our defaults with the current configuration if available
# and fall back to guessing the config from some other system files
if [ -f "$CONFFILE" ]
then
  # parse current configuration
  parsecfg "$CONFFILE"
else
  # newer found values override older values
  parsesys
  parsecfg /etc/ldap/ldap.conf
  parsecfg /etc/pam_ldap.conf
  parsecfg /etc/libnss-ldap.conf
fi
# check /etc/nsswitch.conf
parsensswitch

#
# This is the second part of the script. In this part the configurable
# settings will be presented to the user for approval. The postinst
# will finaly perform the actual modifications.
#

state="server"
while [ "$state" != "done" ]
do
  case "$state" in
  server)
    # ask about server configuration
    db_input high libnss-ldapd/ldap-uris || true
    db_input high libnss-ldapd/ldap-base || true
    db_input low libnss-ldapd/ldap-version || true
    # ask the questions, go to the next question or exit
    state="binddn"
    db_go || exit 1
    # TODO: add error checking on options
    ;;
  binddn)
    # ask for login information
    db_input medium libnss-ldapd/ldap-binddn || true
    # ask the question, go to the next question or back
    state="bindpw"
    db_go || state="server"
    # TODO: if answer is empty also clear passwd
    ;;
  bindpw)
    # only ask question if we have a binddn
    db_get libnss-ldapd/ldap-binddn
    if [ -n "$RET" ]
    then
      # ask for login information
      db_input medium libnss-ldapd/ldap-bindpw || true
    fi
    # ask the question, go to the next question or back
    state="rootbinddn"
    db_go || state="binddn"
    ;;
  rootbinddn)
    # ask for login information
    db_input medium libnss-ldapd/ldap-rootbinddn || true
    # ask the question, go to the next question or back
    state="rootbindpw"
    db_go || state="bindpw"
    # TODO: if answer is empty also clear passwd
    ;;
  rootbindpw)
    # only ask question if we have a rootbinddn
    db_get libnss-ldapd/ldap-rootbinddn
    if [ -n "$RET" ]
    then
      # ask for login information
      db_input medium libnss-ldapd/ldap-rootbindpw || true
    fi
    # ask the question, go to the next question or back
    state="nsswitch"
    db_go || state="rootbinddn"
    ;;
  nsswitch)
    # ask for which nsswitch options to configure
    db_capb multiselect
    db_input high libnss-ldapd/nsswitch || true
    state="done"
    db_go || state="rootbindpw"
    ;;
  esac
done

exit 0