#!/bin/sh

set -e

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

# set an option in the configuration file to the specified value
cfg_set()
{
  parameter="$1"
  value="$2"
  # make matching of spaces better in parameter
  # this is complicated becase of the "base [map] dn" keyword
  param_re=`echo "$parameter" | sed 's#^#[[:space:]]*#;s#[[:space:]][[:space:]]*#[[:space:]][[:space:]]*#g'`
  # lines to not match
  nomatch_re="^$param_re[[:space:]][[:space:]]*\(aliases\|ethers\|group\|hosts\|netgroup\|networks\|passwd\|protocols\|rpc\|services\|shadow\)"
  # check if the parameter is defined
  line=`sed -n '/'"$nomatch_re"'/n;/^'"$param_re"'[[:space:]]/p' "$CONFFILE" | head -n 1`
  if [ -z "$line" ]
  then
    # check if the parameter is commented out
    param_re="#$param_re"
    nomatch_re="^$param_re[[:space:]][[:space:]]*\(aliases\|ethers\|group\|hosts\|netgroup\|networks\|passwd\|protocols\|rpc\|services\|shadow\)"
    line=`sed -n '/'"$nomatch_re"'/n;/^'"$param_re"'[[:space:]]/p' "$CONFFILE" | head -n 1`
  fi
  # decide what to do
  if [ -z "$line" ]
  then
    # just append a new line
    echo "$parameter $value" >> $CONFFILE
  else
    # escape line to replace
    replace=`echo "$line" | sed 's#\\\#\\\\\\\#g;s#\([.*+?^$|]\)#\\\\\1#g'`
    # escape value (parameter doesn't have any special stuff)
    value=`echo "$value" | sed 's#\\\#\\\\\\\#g;s#|#\\\|#g;s#&#\\\&#g'`
    # replace the first occurrence of the line
    sed -i '1,\|^'"$replace"'$| s|^'"$replace"'$|'"$parameter"' '"$value"'|i' "$CONFFILE"
  fi
  # we're done
  return 0
}

# disable options in the configuration file by commenting them out
cfg_disable()
{
  for parameter in $@
  do
    # handle bindpw option specially by removing value from config first
    if [ "$parameter" = "bindpw" ] && grep -i -q "^bindpw " $CONFFILE
    then
      cfg_set bindpw "*removed*"
    fi
    # make matching of spaces better in parameter
    param_re=`echo "$parameter" | sed 's#^#[[:space:]]*#;s#[[:space:]][[:space:]]*#[[:space:]][[:space:]]*#g'`
    # lines to not match
    nomatch_re="^$param_re[[:space:]][[:space:]]*\(aliases\|ethers\|group\|hosts\|netgroup\|networks\|passwd\|protocols\|rpc\|services\|shadow\)"
    # comment out the option
    sed -i '/'"$nomatch_re"'/n;s/^'"$param_re"'[[:space:]].*$/#&/i' "$CONFFILE"
    # we're done
  done
  return 0
}

# set the list of uris
cfg_uris()
{
  uris="$1"
  # escape all uri directives
  sed -i 's/^uri /_uri_ /i' $CONFFILE
  # set the uri options
  echo "$uris" | sed 's/  */\n/g' | while read uri
  do
    if grep -qi '^_uri_ ' $CONFFILE
    then
      # escape uri for use in regexp replacement
      uri=`echo "$uri" | sed 's#\\\#\\\\\\\#g;s#|#\\\|#g;s#&#\\\&#g'`
      # replace the first occurrence of _uri_
      sed -i '1,/^_uri_ / s|^_uri_ .*$|uri '"$uri"'|i' "$CONFFILE"
    else
      # append new uri
      echo "uri $uri" >> $CONFFILE
    fi
  done
  # comment out the remaining escaped uris
  sed -i 's/^_uri_ /#uri /' $CONFFILE
}

# create a default configuration file if nothing exists yet
create_config()
{
  if [ ! -e "$CONFFILE" ]
  then
    # check if the file with the old name exists
    if [ -e "$OCONFFILE" ]
    then
      # copy the existing file
      cp -p $OCONFFILE $CONFFILE
      # fix reference to manual page
      sed -i 's/nss-ldapd/nslcd/' $CONFFILE
    else
      # create a simple configuration file from this template
      cat > "$CONFFILE" << EOM
# $CONFFILE
# nslcd configuration file. See nslcd.conf(5)
# for details.

# The user and group nslcd should run as.
uid nslcd
gid nslcd

# The location at which the LDAP server(s) should be reachable.
uri ldap://localhost/

# The search base that will be used for all queries.
base dc=example,dc=net

# The LDAP protocol version to use.
#ldap_version 3

# The DN to bind with for normal lookups.
#binddn cn=annonymous,dc=example,dc=net
#bindpw secret

# The DN used for password modifications by root.
#rootpwmoddn cn=admin,dc=example,dc=com

# SSL options
#ssl off
#tls_reqcert never

# The search scope.
#scope sub

EOM
      # fix permissions
      chmod 640 "$CONFFILE"
      chown root:nslcd "$CONFFILE"
    fi
  fi
  # we're done
  return 0
}

# update a configuration parameter, based on the debconf key
update_config()
{
  debconf_param="$1"
  cfg_param="$2"
  # update configuration option based on debconf value
  db_get "$debconf_param"
  if [ -n "$RET" ]
  then
    cfg_set "$cfg_param" "$RET"
  else
    cfg_disable "$cfg_param"
  fi
}

# real functions begin here
if [ "$1" = "configure" ]
then
  # get configuration data from debconf
  . /usr/share/debconf/confmodule
  # check if the nslcd user exists
  if getent passwd nslcd >/dev/null
  then
    :
  else
    # create nslcd user and group
    adduser --system --group --home /var/run/nslcd/ \
            --gecos "nslcd name service LDAP connection daemon" \
            --no-create-home \
            nslcd
    # add uid/gid options to the config file if it exists
    # (this is when we're upgrading)
    if [ -f "$CONFFILE" ]
    then
      echo "Adding uid and gid options to $CONFFILE..." >&2
      echo "# automatically added on upgrade of nslcd package" >> "$CONFFILE"
      cfg_set uid nslcd
      cfg_set gid nslcd
    fi
  fi
  # create a default configuration
  create_config
  # rename tls_checkpeer to tls_reqcert
  if grep -qi '^tls_checkpeer[[:space:]]' $CONFFILE
  then
    echo "Renaming tls_checkpeer to tls_reqcert in $CONFFILE..." >&2
    sed -i 's/^tls_checkpeer[[:space:]]/tls_reqcert /' "$CONFFILE"
  fi
  # rename reconnect_maxsleeptime to reconnect_retrytime
  if grep -qi '^reconnect_maxsleeptime[[:space:]]' $CONFFILE
  then
    echo "Renaming reconnect_maxsleeptime to reconnect_retrytime in $CONFFILE..." >&2
    sed -i 's/^reconnect_maxsleeptime[[:space:]]/reconnect_retrytime /' "$CONFFILE"
  fi
  # set server uri
  db_get nslcd/ldap-uris
  cfg_uris "$RET"
  # update some options
  update_config nslcd/ldap-base base
  db_get nslcd/ldap-auth-type
  authtype="$RET"
  case "$authtype" in
  simple)
    update_config nslcd/ldap-binddn binddn
    update_config nslcd/ldap-bindpw bindpw
    cfg_disable sasl_mech sasl_realm sasl_authcid sasl_authzid sasl_secprops krb5_ccname
    ;;
  SASL)
    update_config nslcd/ldap-sasl-mech sasl_mech
    update_config nslcd/ldap-sasl-realm sasl_realm
    # RFC4313 if SASL, binddn should be disabled
    cfg_disable binddn
    db_get nslcd/ldap-sasl-mech
    saslmech="$RET"
    case "$saslmech" in
    GSSAPI)
      update_config nslcd/ldap-sasl-krb5-ccname krb5_ccname
      cfg_disable sasl_authcid
      ;;
    *)
      update_config nslcd/ldap-sasl-authcid sasl_authcid
      update_config nslcd/ldap-bindpw bindpw
      cfg_disable krb5_ccname
      ;;
    esac
    update_config nslcd/ldap-sasl-authzid sasl_authzid
    update_config nslcd/ldap-sasl-secprops sasl_secprops
    ;;
  none)
    cfg_disable binddn bindpw
    cfg_disable sasl_mech sasl_realm sasl_authcid sasl_authzid sasl_secprops krb5_ccname
  esac
  update_config nslcd/ldap-reqcert tls_reqcert
  # remove password from database
  db_set nslcd/ldap-bindpw ""
  # set ssl option
  db_get nslcd/ldap-starttls
  if [ "$RET" = "true" ]
  then
    cfg_set ssl "start_tls"
  elif grep -qi '^ssl[[:space:]]*start_*tls' $CONFFILE
  then
    cfg_disable ssl
  fi
  # we're done
  db_stop
  # fix permissions of configfile if upgrading from an old version
  if dpkg --compare-versions "$2" lt-nl "0.6.7.1"
  then
    echo "Fixing permissions of $CONFFILE"
    chmod 640 "$CONFFILE"
    chown root:nslcd "$CONFFILE"
  fi
fi

#DEBHELPER#

exit 0