#!/usr/bin/env bash
#
# Copyright (C) 2003 VA Linux Systems Japan, K.K.
#
# LICENSE NOTICE
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#

# Usage:
#    update-ultrapossum <configure|remove>
#

# $Id: update-server,v 1.46 2004/07/01 19:16:58 taru Exp $

set -e

eval `ultrapossum-config init`

tmp=`tempfile`
trap "rm -f $tmp; eval `ultrapossum-config term`" 0

configure_slapd() {
  progress "Configuring OpenLDAP for $TYPE... "

  install -d $CONFDIR

  add_startmark "##" "SCHEMA" > $tmp
  $MODULEDIR/server/apps schema >> $tmp
  add_endmark "##" "SCHEMA" >> $tmp

  add_end_vaconf $SLAPDCONF $tmp "SCHEMA"

  cp /dev/null $ULTRAPOSSUM_SLAPD_CONF
  cp /dev/null $ULTRAPOSSUM_MASTER_SLAPD_CONF
  chmod 640 $ULTRAPOSSUM_SLAPD_CONF $ULTRAPOSSUM_MASTER_SLAPD_CONF

  $MODULEDIR/server/slapd.sh $ULTRAPOSSUM_SLAPD_CONFIN slave \
	  > $ULTRAPOSSUM_SLAPD_CONF
  $MODULEDIR/server/slapd.sh $ULTRAPOSSUM_SLAPD_CONFIN master \
    	> $ULTRAPOSSUM_MASTER_SLAPD_CONF

  add_startmark "##" "DB" > $tmp
  echo "include	$ULTRAPOSSUM_SLAPD_CONF" >> $tmp
  add_endmark "##" "DB" >> $tmp

  add_end_vaconf $SLAPDCONF $tmp "DB"

  if test `uname` = "SunOS"; then
    grep -v pidfile < $SLAPDCONF > $SLAPDMASTERCONF
    echo "pidfile $SLAPD_PIDFILE" >> $SLAPDMASTERCONF
  else
    sed "s!^pidfile[[:space:]][[:space:]]*.*!pidfile $SLAPD_PIDFILE!" \
  	< $SLAPDCONF > $SLAPDMASTERCONF
  fi

  add_startmark "##" "DB" > $tmp
  echo "include	$ULTRAPOSSUM_MASTER_SLAPD_CONF" >> $tmp
  add_endmark "##" "DB" >> $tmp
  add_end_vaconf $SLAPDMASTERCONF $tmp "DB"

  oldmark=$ULTRAPOSSUMMARK
  for mark in `grep "## " $SLAPDMASTERCONF | grep -- "-DB START" | sed 's/.* \(.*\)\-DB.*/\1/'`
  do
    ULTRAPOSSUMMARK=$mark
    project=`echo $mark | sed 's/ULTRAPOSSUM\(.*\)/\1/'`
    add_startmark "##" "DB" > $tmp
    echo "include       $CONFDIR/$project/ultrapossum.master.conf" >> $tmp
    add_endmark "##" "DB" >> $tmp
    add_end_vaconf $SLAPDMASTERCONF $tmp "DB"
  done
  ULTRAPOSSUMMARK=$oldmark

  cp /dev/null $ULTRAPOSSUMLDIF
  chmod 640 $ULTRAPOSSUMLDIF
  $MODULEDIR/server/ldif.sh > $ULTRAPOSSUMLDIF

  cp /dev/null $APPSLDIF
  chmod 640 $APPSLDIF
  $MODULEDIR/server/apps ldif > $APPSLDIF

  ULTRAPOSSUM_INDEX=`egrep '^index' $ULTRAPOSSUM_MASTER_SLAPD_CONF 2> /dev/null | tr '\n' ' '`

  progress "Configuring OpenLDAP for $TYPE... done"

  if test -f "$ULTRAPOSSUM_INIT_LDIF_IN"; then
    progress "Configuring initial LDIF... "
    sed -e "s/#SUFFIX#/$SUFFIX/" < $ULTRAPOSSUM_INIT_LDIF_IN > $INITLDIF
    progress "Configuring initial LDIF... done"
  else
    /bin/rm -f $INITLDIF
  fi

  install -d `dirname $SLURPD_PIDFILE`
  if ! test -d "`dirname $CHROOTDIRECTORY$SLAPD_PIDFILE`"; then
    progress "Creating `dirname $CHROOTDIRECTORY$SLAPD_PIDFILE` for pidfile... "
    install -d `dirname $CHROOTDIRECTORY$SLAPD_PIDFILE`
    progress "Creating `dirname $CHROOTDIRECTORY$SLAPD_PIDFILE` for pidfile... done"
  fi

  if test "x$CHROOTDIRECTORY" != "x"; then
    if /bin/ls "$DIRECTORY" > /dev/null 2> /dev/null; then
      if ! test -L "$DIRECTORY"; then
        # $DIRECTORY must be a link to $CHROOTDIRECTORY$DIRECTORY
        progress "Moving $SUFFIX under $CHROOTDIRECTORY... "
	install -d $CHROOTDIRECTORY/`dirname $DIRECTORY`
	/bin/mv $DIRECTORY $CHROOTDIRECTORY/`dirname $DIRECTORY`
        progress "Moving $SUFFIX under $CHROOTDIRECTORY... done"
        #$DIRECTORY exist but $CHROOTDIRECTORY$DIRECTORY not exist
        progress "Linking $SUFFIX under $CHROOTDIRECTORY... "
        /bin/ln -sf $CHROOTDIRECTORY$DIRECTORY $DIRECTORY
        progress "Linking $SUFFIX under $CHROOTDIRECTORY... done"
      fi
      if ! /bin/ls -L "$DIRECTORY" > /dev/null 2> /dev/null; then
        progress "Removing dereferenced link '$DIRECTORY'... "
        /bin/rm "$DIRECTORY"
        progress "Removing dereferenced link '$DIRECTORY'... done"
      fi
    elif test -d "$CHROOTDIRECTORY$DIRECTORY"; then
      # $CHROOTDIRECTORY$DIRECTORY exist but $DIRECTORY not exist
      progress "Linking $SUFFIX under $CHROOTDIRECTORY... "
      /bin/ln -sf $CHROOTDIRECTORY$DIRECTORY $DIRECTORY
      progress "Linking $SUFFIX under $CHROOTDIRECTORY... done"
    fi
  fi

  if ! test -e "$DIRECTORY"; then
      $MODULEDIR/server/createdb.sh
  else
    index_old=`getvalue $DIRECTORY/ultrapossum-environ ULTRAPOSSUM_INDEX`
    if test "x$ULTRAPOSSUM_INDEX" != "x$index_old"; then
      if test "`$MODULEDIR/server/startup status`" = "running"; then
        echo "W: index configuration is changed while server is running" 1>&2
      else
        progress "Indexing database... "
        ( $SLAPINDEX -v -f $SLAPDMASTERCONF -b $SUFFIX || echo "ERROR" ) |
	egrep '00$|ERROR$' | while read line
	do
	  if test "x$line" = "xERROR"; then
	    exit 1
	  fi
          v=`echo $line | sed 's/.*id=0*\(.*\)/\1/'`
          progress "Indexing database... $v"
        done || exit 1
	create_environ
        progress "Indexing database... done"
      fi
    fi
  fi

  if test "x$HOST" = "x$MASTER"; then
    if test "x$SLURPDSLAVES" = "x"; then
      if test -f "$RPLDIR/$HOST/replica/slurpd.replog" ||
          test -f "$REPLOGFILE"
      then
        progress "Removing replog... "
        /bin/rm -f $RPLDIR/$HOST/replica/slurpd.replog 2> /dev/null
        /bin/rm -f $REPLOGFILE 2> /dev/null
        progress "Removing replog... done"
      fi
      /bin/rm -f $DIRECTORY/*.ldif 2> /dev/null
    else
      /bin/ls $DIRECTORY/*.ldif 2> /dev/null | while read f
      do
        b=`basename $f .ldif`
        if ! include $b "$SLURPDSLAVES"; then
          if test -f $RPLDIR/$HOST/replica/slurpd.replog; then
            egrep -v "^replica: $b" $RPLDIR/$HOST/replica/slurpd.replog > $RPLDIR/$HOST/replica/slurpd.replog.tmp
            mv $RPLDIR/$HOST/replica/slurpd.replog.tmp $RPLDIR/$HOST/replica/slurpd.replog
          fi
          progress "Removing obsolete LDIF for $b... "
          /bin/rm -f $f
          progress "Removing obsolete LDIF for $b... done"
        fi
      done
    fi

    for host in $SLURPDSLAVES
    do
      if ! test -f "$DIRECTORY/$host.ldif"; then
        progress "Creating $host LDIF... "
        touch $DIRECTORY/$host.ldifT
        chmod 640 $DIRECTORY/$host.ldifT
        $SLAPCAT -b $SUFFIX -f $SLAPDMASTERCONF >  $DIRECTORY/$host.ldifT
        mv $DIRECTORY/$host.ldifT $DIRECTORY/$host.ldif
        progress "Creating $host LDIF... done"
      fi
    done
  fi

}

sanity_check() {
  sanity_error=0
  # ad-hoc: this must be common sanity check not update-server
  if test "x$SUFFIX" = "x"; then
      echo "E: SUFFIX must not be empty." 1>&2
      exit 1
  fi
  if test "x$DBDIRECTORY" = "x"; then
      echo "E: DBDIRECTORY must not be empty." 1>&2
      exit 1
  fi
  if test -f $SLAPDCONF; then
    if ! grep "^pidfile" $SLAPDCONF > /dev/null; then
      echo "E: no pidfile directive found in $SLAPDCONF" 1>&2
      exit 1
    fi
    # FIXME: this is not correct
    if test "x`grep suffix $SLAPDCONF | awk -F' ' '{print $2;}' | tr -d '\"' | egrep -v '^#'`" = "x$SUFFIX"; then
      echo "E: You have already configured $SUFFIX other than UltraPossum in $SLAPDCONF" 1>&2
      exit 1
    fi
  else
    echo "E: $SLAPDCONF not found... You have to install it first." 1>&2
    sanity_error=1
  fi
  if test "x$TYPE" = "xclient"; then
    echo "E: $HOST not found neither MASTER or SLAVES" 1>&2
    exit 1
  fi
  if ! test -f "$ULTRAPOSSUM_SLAPD_CONFIN"; then
    echo "E: backend '$SLAPD_BACKEND_DB_TYPE' not supported" 1>&2
    exit 1
  fi
  if test "x$SYNCBACKUPS" != "x" && test "x$SLAPD_PROVIDES_SYNCBACKUP" = "x"
  then
    echo "E: can't detect slapd supports syncbackup." 1>&2
    exit 1
  fi
  if test "x$CHROOTDIRECTORY" != "x"; then
    egrep "^directory" $SLAPDCONF | awk -F' ' '{print $2;}' | while read d
    do
      if ! test -d "$CHROOTDIRECTORY$d"; then
        echo "E: $d not found in chroot defined in $SLAPDCONF" 1>&2
	exit 1
      fi
    done
  fi
  if test -e "$DIRECTORY"; then
    if test -f "$DIRECTORY/ultrapossum-environ"; then
      val=`getvalue $DIRECTORY/ultrapossum-environ SUFFIX`
      if test "x$val" != "x$SUFFIX"; then
        echo "E: db directory holds another namingContext: $val in $DIRECTORY" 1>&2
        exit 1
      fi
      val=`getvalue $DIRECTORY/ultrapossum-environ SLAPD_BACKEND_DB_TYPE`
      if test "x$val" != "x$SLAPD_BACKEND_DB_TYPE"; then
        echo "E: db directory holds another backend type: $val in $DIRECTORY" 1>&2
        exit 1
      fi
    else
      echo "W: db directory already exists: $DIRECTORY" 1>&2
    fi
  fi
  if test "$sanity_error" != "0"; then
    exit 1
  fi
}

configure() {
  sanity_check
  if test "x`$MODULEDIR/server/startup status`" = "xrunning"; then
    oSLURPDSLAVES=$SLURPDSLAVES
    eval `$MODULEDIR/server/runtime SLURPDSLAVES`
    if test "x$oSLURPDSLAVES" != "x$SLURPDSLAVES"; then
      echo "E: Slurpd settings are changed but UltraPossum server running... You have to stop it" 1>&2
      exit 1
    fi
    SLURPDSLAVES=$oSLURPDSLAVES
  fi
  configure_slapd
  if test "x$SLAVES" != "x"; then
    $MODULEDIR/server/sshman keygen fetchldif
    $MODULEDIR/server/sshman auth
  fi
}

remove() {
  /bin/rm -f $ULTRAPOSSUMLDIF $ULTRAPOSSUM_SLAPD_CONF
  /bin/rm -f $APPSLDIF $SLAPDMASTERCONF $INITLDIF
  /bin/rm -f $ULTRAPOSSUM_MASTER_SLAPD_CONF
  if test -f "$SLAPDCONF"; then
    strip_vaconf $SLAPDCONF "SCHEMA"
    strip_vaconf $SLAPDCONF "DB"
  fi
  if test "x$SLAVES" = "x"; then
    /bin/rm -rf $SSHKEYDIR/fetchldif/
  fi
  $MODULEDIR/server/sshman unauth
}

case "x$1" in
	xconfigure)
		configure
		ultrapossum-config set .status ULTRAPOSSUM_MODULE_SERVER=installed
		/bin/rm -f $CONFSTATUS
	;;
	xremove)
		remove
		ultrapossum-config remove .status ULTRAPOSSUM_MODULE_SERVER
		/bin/rm -f $CONFSTATUS
	;;
	xsanity)
		sanity_check
	;;
	x)
		echo "Usage: $0 <configure|remove|sanity>" 1>&2
		exit 1
	;;
	x*)
		echo "Unknown argument: $1" 1>&2
		exit 1
	;;
esac

