#! /bin/sh 

set -e

# Make the version we are upgrading from globally available
OLD_VERSION="Webmin-Ldap-Upgrade-"`date +%Y-%m-%d-%H-%M-%S`

# Source the init script configuration
if [ -f "/etc/default/slapd" ]; then
  . /etc/default/slapd
fi

# Load the default location of the slapd config file
if [ -z "$SLAPD_CONF" ]; then
  SLAPD_CONF="/etc/ldap/slapd.conf"
fi

# slapd supports continuation lines in the slapd.conf. Continuation lines 
# start with spaces and are merged with the preceding line. This function
# uses perl to merge physical lines into logical lines as seen by the 
# slapd config parser.
merge_logical_lines() {
  perl -pe 'BEGIN { undef $/ }; s/\n(?!\n)\s+/ /g;' 
}

# Directory names are whitespace-sensitive, but suffixes are not.  Discard
# whitespace, so we can create cleaner backup directory names.
canonical_suffix() {
  eval echo $1 | sed -e 's/[[:space:]]+//g'
}

# Check if upgrading a database in the named backend is supported by
# our scripts.
supported_backend() {
  case "$1" in ldbm|bdb) return 0; esac
  return 1
}

# Print out the information about one database
write_database_info() {
  backend=$1
  suffix=$2
  directory=$3

  if supported_backend "$backend"; then
    # If no directory was given use the compiled in value
    if [ -z "$directory" ]; then
      # TODO: This should be somewhere in /var - needs tweaking of 
      # configure.options
      directory=/usr/share/ldap/openldap-data
    fi
    echo $backend '"'$suffix'"' '"'$directory'"'
  else
    echo "Warning: Backend $backend not supported by automatic upgrade." >&2
  fi
}

# Get the list of configured databases from the slapd configuration file
get_database_list() {
  (merge_logical_lines < $SLAPD_CONF && echo database) | \
    while read command data; do
      case $command in
      database)
        # Write information about previous database section if any
        if [ -n "$backend" ] && [ -n "$suffix" ]; then
	  write_database_info "$backend" "$suffix" "$directory"
	fi
	backend=$data
	suffix=""
	directory=""
        ;;
      suffix)
        suffix=`canonical_suffix "$data"`
        ;;
      directory)
        directory=`eval echo $data`
        ;;
      esac
    done
}

ldif_dump_wanted() {
  return 0
}

# Ask for the filename of the dump file
# XXX: Currently just uses /var/backups/ldap/$OLD_VERSION/slapd-${suffix}-slapcat.ldif
ldif_dump_location() {
  local suffix=$1
  echo "/var/backups/ldap/$OLD_VERSION/slapd-${suffix}-slapcat.ldif"
}

# Create directory for dump file
create_ldif_dump_location() {
  # Make our backup directory if it does not exist already
  if [ -d /var/backups/ldap ]; then
    chmod 700 /var/backups/ldap
  else
    mkdir -p -m 700 /var/backups/ldap
  fi
  mkdir -p -m 700 /var/backups/ldap/$OLD_VERSION/
}


# Check if the preinst slapcat worked or not, if not, go ahead and
# attempt to slapcat here with the new version of slapcat
export_database() {
  suffix="$1"
  location="$2"

  if [ ! -e "$location" ]; then
    echo -n "  Dumping directory to $location with new slapcat... "
    slapcat -b "$suffix" > "$location" || SLAPCAT_FAIL=1
    if [ "$SLAPCAT_FAIL" = "1" ]; then
      echo "failed"
      rm -f "$location"
#      db_input high slapd/upgrade_slapcat_failure || true
    else
      echo "done"
    fi
  fi
}

# Fix the directory when upgrading from before 2.1 and the root
# dn has no structural objectclass
fix_ldif() {
  location="$1"
  fixed_location="$2"

  # We should now have a valid ldif file, created either in the
  # preinst or above.  If we don't, then the user has been
  # notified and just give up.

  if [ -e "$location" ]; then
    organization=$(echo "db_get shared/organization" | debconf-communicate)
    echo $organisation
    if [ -z "$organization" ]; then organization=Unknown; fi
    /usr/share/webmin/ldap-users/fix_ldif $CommandLineOptions -f -o "$organization" < "$location" > "$fixed_location"
  fi
}

move_old_database_directory_away() {
  suffix=$1
  directory=$2

  if [ -n "$directory" ]; then
    echo -n "  Moving old database files to /var/backups/ldap/$OLD_VERSION/... "
    mkdir -p "/var/backups/ldap/$OLD_VERSION/$suffix"
    mv "$directory"/* "/var/backups/ldap/$OLD_VERSION/$suffix/"
    echo "done"
  fi
}

# If a dump file from the old version exists we want to recreate the
# directory from it
import_database() {
  suffix="$1"
  location="$2"

  if [ -e "$location" ]; then
    echo -n "  Recreating directory from $location... "
    SLAPADD_FAIL=0
#   slapadd -b "$suffix" -u -l "$location" || SLAPADD_FAIL=1
    if [ "$SLAPADD_FAIL" = "1" ]; then
      echo "failed"
    else
      slapadd -cb "$suffix" -l "$location"
      echo "done"
    fi
  fi
}

# MAIN

/etc/init.d/slapd stop
CommandLineOptions="$@"
get_database_list | while read backend suffix directory
  do
  suffix=`eval echo $suffix`
  directory=`eval echo $directory`
  echo "Processing directory $suffix..."
  
  location=`ldif_dump_location "$suffix"`
    # XXX: to be truly idempotent, we should make sure we don't try to
    # overwrite this ldif file on a second pass after already having
    # moved some of the files aside below.
  
  if [ ! -f "/var/lib/slapd/upgrade_2.0-$suffix" ]; then
      if ldif_dump_wanted; then
	  create_ldif_dump_location
	  export_database "$suffix" "$location"
	  fix_ldif  "$location" "${location}.fixed"
      fi
      move_old_database_directory_away "$suffix" "$directory"
  fi
  import_database "$suffix" "${location}.fixed"
  
  # Since this is actually a subshell, we need to explicitly
  # call exit: otherwise, the errors won't be caught, and the rm command
  # below gets run!
done || exit $?
  

# Automatically added by dh_installinit
if [ -x "/etc/init.d/slapd" ]; then
    if [ -x /usr/sbin/invoke-rc.d ]; then
       	invoke-rc.d slapd start
    else
	/etc/init.d/slapd start
    fi
fi
# End automatically added section


rm -f /var/lib/slapd/upgrade_2.0-*

