#!/bin/ksh
#
# OSSTech OpenLDAP slapd service
#
# chkconfig: - 27 73
# chkconfig.solaris: 2 70 40
# chkconfig.aix: 2 270 40
# chkconfig.debian: 2345 19 80
# description: LDAP stands for Lightweight Directory Access Protocol, used \
#              for implementing the industry standard directory services.
#
### BEGIN INIT INFO
# Provides:		osstech-slapd osstech-ldap
# Required-Start:	$network $local_fs osstech-svscan
# Required-Stop:	$network $local_fs osstech-svscan
# Should-Start:		$syslog
# Should-Stop:		$syslog
# Default-Start:	2 3 4 5
# Default-Stop:		0 1 6
### END INIT INFO

. "/opt/osstech/etc/sv/svinit" || exit 1

sv_name="slapd"
slapd_conf_file_default="/opt/osstech/etc/openldap/slapd.conf"
slapd_conf_dir_default="/opt/osstech/etc/openldap/slapd.d"
slapd_user_default="ldap"
slaptest_cmd="/opt/osstech/sbin/slaptest"
slapindex_cmd="/opt/osstech/sbin/slapindex"

## Check if slapd-config(5) (cn=config backend) is used or not
function slapd_config_backend_p {
  [[ -f $1/cn=config.ldif ]]
}

function ldifunwrap {
  sed \
    -n \
    '1 {h; $ !d}; $ {x; s/\n //g; p}; /^ / {H; d}; /^ /! {x; s/\n //g; p}' \
    "$@" \
  ;
}

if slapd_config_backend_p "$slapd_conf_dir_default"; then
  slapd_conf_default="$slapd_conf_dir_default"
else
  slapd_conf_default="$slapd_conf_file_default"
fi

## ======================================================================

function sv_configtest {
  typeset sv_dir=$(sv_dir "$1"); shift

  typeset slapd_conf=$(sv_env "$sv_dir" CONFIGFILE || echo "$slapd_conf_default")
  typeset slapd_user=$(sv_env "$sv_dir" USER || echo "$slapd_user_default")
  typeset slapd_group=$(sv_env "$sv_dir" GROUP)

  typeset db_dir= db_file= slaptest_opts=
  {
    if slapd_config_backend_p "$slapd_conf"; then
      ldifunwrap "$slapd_conf"/cn=config/olcDatabase=*db.ldif \
      |sed -n 's/^olcDbDirectory: //p' \
      ;
    else
      sed -n \
	-e 's/[ 	]*$//' \
	-e 's/^[ 	]*directory[ 	]\{1,\}"*\([^"]*\)"*$/\1/p' \
	"$slapd_conf" \
      ;
    fi
  } \
  |while read -r db_dir; do
    if [ ! -d "$db_dir" ]; then
      (umask 0027; mkdir "$db_dir") && chown "$slapd_user${slapd_group:+:$slapd_group}" "$db_dir" \
	|| {
	  echo_n "Checking configuration files for ${sv_dir##*/}: "; failure; echo
	  return 6
	}
      slaptest_opts=-u
      continue
    fi
    if [ ! -s $db_dir/id2entry.* ]; then
      slaptest_opts=-u
    fi
    find "$db_dir" \
      ! -user "$slapd_user" \
      \( \
	-name "*.dbb" -o \
	-name "*.gdbm" -o \
	-name "*.bdb" -o \
	-name "__db.*" -o \
	-name "log.*" -o \
	-name alock \
      \) \
    |while read -r db_file; do
      echo_n "$db_file is not owned by \"$slapd_user\" "; warning; echo
    done
  done

  typeset tls_file=
  {
    if slapd_config_backend_p "$slapd_conf"; then
      ldifunwrap "$slapd_conf"/cn=config.ldif \
      |sed -n 's/^olcTLS[A-Za-z]*File: //p' \
      ;
    else
      awk '$1~/^TLS[A-Za-z]*File$/ {print $2}' "$slapd_conf"
    fi
  } \
  |while read -r tls_file; do
    if ! setuidgid "$slapd_user" test -r $tls_file; then
      echo_n "$tls_file is not readable by \"$slapd_user\" "; warning; echo
    fi
  done

  typeset slaptest_out= slaptest_ret=
  typeset slapd_conf_opt="-f"
  if slapd_config_backend_p "$slapd_conf"; then
    slapd_conf_opt="-F"
  fi
  slaptest_out=$(
    setuidgid "$slapd_user" \
      "$slaptest_cmd" \
	"$slapd_conf_opt" "$slapd_conf" \
	$slaptest_opts \
      2>&1 \
    ;
  )
  slaptest_ret=$?
  if [ $slaptest_ret -eq 0 ]; then
    if echo "$slaptest_out" |grep -v "config file testing succeeded" >/dev/null; then
      echo_n "Checking configuration files for ${sv_dir##*/}: "; warning; echo
      echo "$slaptest_out"
    fi
  fi
  if [ $slaptest_ret -ne 0 ]; then
    echo_n "Checking configuration files for ${sv_dir##*/}: "; failure; echo
    echo "$slaptest_out"
    return 6
  fi

  if [ -x /sbin/portrelease ]; then
    /sbin/portrelease osstech-slapd
    /sbin/portrelease slapd
  fi

  return 0
}

function sv_index {
  typeset sv_dir=$(sv_dir "$1"); shift

  typeset slapd_conf=$(sv_env "$sv_dir" CONFIGFILE || echo "$slapd_conf_default")
  typeset slapd_user=$(sv_env "$sv_dir" USER || echo "$slapd_user_default")

  typeset slapd_conf_opt="-f"
  if slapd_config_backend_p "$slapd_conf"; then
    slapd_conf_opt="-F"
  fi

  {
    if slapd_config_backend_p "$slapd_conf"; then
      ldifunwrap "$slapd_conf"/cn=config/olcDatabase=*db.ldif \
      |sed -n 's/^olcSuffix: //p' \
      ;
    else
      sed -n \
	-e 's/[ 	]*$//' \
	-e 's/^[ 	]*suffix[ 	]\{1,\}"*\([^"]*\)"*$/\1/p' \
	"$slapd_conf" \
      ;
    fi
  } \
  |while read -r db_suffix; do
    echo_n "Regenerating index data for $db_suffix: "
    slapindex_out=$(
      setuidgid "$slapd_user" \
	"$slapindex_cmd" \
	  "$slapd_conf_opt" "$slapd_conf" \
	  -b "$db_suffix" \
	2>&1 \
      ;
    )
    slapindex_ret=$?
    if [ $slapindex_ret -ne 0 ]; then
       failure; echo
      echo "$slapindex_out"
      return 6
    fi
    success; echo
  done
}

sv_init "$sv_name" ${1+"$@"}

