#!/bin/bash

# Some easy means to start/stop the mail spool
if [ -x /etc/init.d/exim ] ; then
  MTAINIT=/etc/init.d/exim
elif [ -x /etc/init.d/exim4 ] ; then
  MTAINIT=/etc/init.d/exim4
else
  echo "error: unknown MTA, exiting..."
  exit 9
fi


copy_example_DB_CONFIG() {
#function to set a DB_CONFIG, ripped from slapd.postinst
# Copy an example DB_CONFIG file
# copy_example_DB_CONFIG <directory>
        local directory srcdir

        directory="$1"
        srcdir="/usr/share/slapd"

        if ! [ -f "${directory}/DB_CONFIG" ] && [ -d "$directory" ]; then
                cp $srcdir/DB_CONFIG "${directory}/DB_CONFIG"
        fi
}


# Init tree
init_ldap () {
  rm -f /var/lib/ldap/*
  copy_example_DB_CONFIG /var/lib/ldap


  if [ -f /etc/shadow ] ; then
      FILE=/etc/shadow
  else
      FILE=/etc/passwd
  fi
  ROOTPWDHASH=`grep ^root: < $FILE | cut -d':' -f2`

  HOSTNAME=`hostname -s`
  echo "info: Fetching SMB local SID from hostname '$HOSTNAME'."
  SAMBASID=`net getlocalsid $HOSTNAME 2>/dev/null | awk '{ print $6; }'`

  if [ -z "$SAMBASID" ] ; then
      echo "error: unable to fetch Samba SID"
      exit 1
  fi

  # Generate Samba_passwd
  SAMBAPWD=$(slappasswd -g -h {CLEARTEXT})
  # Generate hashed samba password
  SAMBAPWDHASH=$(slappasswd -u -s $SAMBAPWD)
  
  ## Create and distribute a random password and
  ## its hash for the ldap gosa-admin account:
  GOSAPWD=`slappasswd -g -h {CLEARTEXT}`
  GOSAPWDHASH=`slappasswd -s $GOSAPWD -h {SSHA}`
  GOSACONFDIR="/etc/gosa/"
  GOSACONF="gosa.conf"
  GOSAADMINDN=$(awk '/dn: uid=super-admin,/ { print $2 }' /etc/ldap/gosa.ldif)
  GOSAADMINDN64=$(echo -n "$GOSAADMINDN" | base64 -w0)
  ADMINROLEDN=$(awk '/dn: cn=admin-role,/ { print $2 }' /etc/ldap/gosa.ldif)
  ADMINROLEDN64=$(echo -n "$ADMINROLEDN" | base64 -w0)
  JRADMINROLEDN=$(awk '/dn: cn=jradmin-role,/ { print $2 }' /etc/ldap/gosa.ldif)
  JRADMINROLEDN64=$(echo -n "$JRADMINROLEDN" | base64 -w0)
  TEACHERSDN=$(awk '/dn: cn=teachers,/ { print $2 }' /etc/ldap/gosa.ldif)
  TEACHERSDN64=$(echo -n "$TEACHERSDN" | base64 -w0)

  ## query debconf data base for time zone and locale:
  AREA=`debconf-show tzdata | grep "^* tzdata/Areas:" | \
      sed "s/.*:[[:space:]]*\([[:alpha:]]*\)$/\1/"`
  ZONE=`debconf-show tzdata | grep "^* tzdata/Zones/$AREA:" | \
      sed "s/.*:[[:space:]]*\([[:alpha:]]*\)$/\1/"`
  TIMEZONE=$AREA/$ZONE
  LANGUAGE=`debconf-show locales | grep "^* locales/default_environment_locale:" | \
      sed "s/.*:[[:space:]]*\([^[:space:]]*\)$/\1/"`

  ## FIXME: make sure gosa.conf is in place if it is missing:
  if [ -f $GOSACONFDIR$GOSACONF ] && grep -q \$GOSAPWD $GOSACONFDIR$GOSACONF ; then
      sed -i "s:\$GOSAPWD:$GOSAPWD:g" $GOSACONFDIR$GOSACONF
      sed -i "s:\$TIMEZONE:$TIMEZONE:g" $GOSACONFDIR$GOSACONF
      sed -i "s:\$LANGUAGE:$LANGUAGE:g" $GOSACONFDIR$GOSACONF
      rm -f $GOSACONFDIR/gosa.random_secret
      chown root:www-data $GOSACONFDIR$GOSACONF
      chmod 0640 $GOSACONFDIR$GOSACONF
      ## FIXME: run gosa-encrypt-passwords 
  else
      mkdir -p $GOSACONFDIR
      touch $GOSACONFDIR/gosa.random_secret
      chmod 0600 $GOSACONFDIR/gosa.random_secret
      cat > $GOSACONFDIR/gosa.random_secret <<EOF
## The gosa configuration file "$GOSACONFDIR$GOSACONF" has
## been missing during bootstrap of the ldap database or 
## does not contain the string \$GOSAPWD.
## The password used by the gosa-admin in ldap is: 
##                 $GOSAPWD
## Make sure to use this password in "$GOSACONFDIR$GOSACONF".
## Finally, run 'gosa-encrypt-passwords' if anything 
## works fine and remove this file.
EOF
  fi

  ## Create and distribute a random password and its hash
  ## for the kdc service accounts kadmin and kdc-service:
  KDCPWD=`slappasswd -g -h {CLEARTEXT}`
  KDCPWDHASH=`slappasswd -s $KDCPWD -h {SSHA}`
  KDCCONFDIR="/etc/krb5kdc/"
  KEYFILE="service.keyfile"
  ## convert to {HEX} encoding:
  KDCPWDHEX=`echo $KDCPWD | xxd -g0 -ps | sed "s/0a$//"`
  KRB_CONT_DN=`awk '/dn: cn=kerberos,/ { print $2 }' /etc/ldap/krb5.ldif`

  mkdir -p $KDCCONFDIR
  touch $KDCCONFDIR$KEYFILE
  chmod 0600 $KDCCONFDIR$KEYFILE
  cat > $KDCCONFDIR$KEYFILE <<EOF
cn=kdc-service,$KRB_CONT_DN#{HEX}$KDCPWDHEX
cn=kadmin-service,$KRB_CONT_DN#{HEX}$KDCPWDHEX
EOF

  ## bootstrap ldap with passwords inserted:

  for ldif in \
    /etc/ldap/root.ldif \
    /etc/ldap/ipnetworks.ldif \
    /etc/ldap/netgroup.ldif \
    /etc/ldap/autofs.ldif \
    /etc/ldap/samba.ldif \
    /etc/ldap/sudo.ldif \
    /etc/ldap/gosa.ldif \
    /etc/ldap/gosa-server.ldif \
    /etc/ldap/ltsp.ldif \
    /etc/ldap/krb5.ldif

## removed for gosa-sever to work: 
#    /etc/ldap/dhcp.ldif \
#    /etc/ldap/dhcp_hosts.ldif \
#    /etc/ldap/dns_skole.ldif \
#    /etc/ldap/dns_ranges.ldif \

  do
      if cat $ldif | sed -e "s:\$ROOTPWDHASH:$ROOTPWDHASH:" \
	-e "s:\$SAMBASID:$SAMBASID:" \
	-e "s:\$SAMBAPWDHASH:$SAMBAPWDHASH:" \
	-e "s:\$GOSAPWDHASH:$GOSAPWDHASH:" \
	-e "s:\$GOSAADMINDN64:$GOSAADMINDN64:" \
	-e "s:\$ADMINROLEDN64:$ADMINROLEDN64:" \
	-e "s:\$JRADMINROLEDN64:$JRADMINROLEDN64:" \
	-e "s:\$TEACHERSDN64:$TEACHERSDN64:" \
	-e "s:\$KDCPWDHASH:$KDCPWDHASH:" \
	  | /usr/sbin/slapadd ; then
	  echo "info: added '$ldif' to ldap database."
      else
	  echo "error: Unable to load '$ldif'"
	  exit 1
      fi
  done
  # Migrate to new style LDAP configuration first.  Required since
  # slapd version 2.4.23-4.
  # A better way is to convert our configuration to slapd.d config and
  # include those files in the package.
  # Disabled after openldap in squeeze (since 2.4.23-5) no longer
  # require slapd.d config.
  if false && [ ! -d /etc/ldap/slapd.d ] ; then
    echo "info: migrating SLAPD configuration to slapd.d format"
    mkdir /etc/ldap/slapd.d
    slapd -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d
    /etc/init.d/slapd stop
    chown -R openldap:openldap /etc/ldap/slapd.d
    # In case the init.d script fail to stop the service (which it
    # does when testing 2010-09-07).
    killall slapd
  fi
}

set -e

# Create ldap-tree on the initial install
$MTAINIT stop

# Check if slapd is running.  Use pidfile to avoid detecting the wrong
# daemon when running in a chroot.
if [ -f /var/run/slapd/slapd.pid ] &&
  kill -0 $(cat /var/run/slapd/slapd.pid) ; then
  RESTARTSLAPD=true
  /etc/init.d/slapd stop

  # Make sure slapd is really stopped
  SLAPPIDS=$(pidof slapd || /bin/true)
  if [ "$SLAPPIDS" ] ; then
    echo -n "warning: slapd is still running, trying to TERM it"
    for SLAPPID in $SLAPPIDS ; do
      kill $SLAPPID || /bin/true
    done
  fi

  # Not sure why, but it seem like slapd takes some time to shut down
  LOOP=0
  while [ $LOOP -lt 10 ] ; do
    SLAPPIDS=$(pidof slapd || /bin/true)
    if [ "$SLAPPIDS" ] ; then
      LOOP=$(($LOOP + 1))
      sleep 1
      echo -n "."
    else
	LOOP=10
    fi
  done
  echo

  if [ "$SLAPPIDS" ] ; then
    echo -n "error: slapd is still running, I'll KILL it"
    for SLAPPID in $SLAPPIDS ; do
      kill -9 $SLAPPID || /bin/true
    done
  fi

  # Not sure why, but it seem like slapd takes some time to shut down
  LOOP=0
  while [ $LOOP -lt 10 ] ; do
    SLAPPIDS=$(pidof slapd || /bin/true)
    if [ "$SLAPPIDS" ] ; then
      LOOP=$(($LOOP + 1))
      sleep 1
      echo -n "."
    else
	LOOP=10
    fi
  done
  echo
  if [ "$SLAPPIDS" ] ; then
    echo "error: Critical: slapd is still running, I'm giving up"
    exit 9
  fi
fi

if slapcat 2> /dev/null | grep -q "dn: cn=all-hosts" ; then
  echo "info: found existing data (cn=all-hosts): skipping initalization"
  echo "info: use rm /var/lib/ldap/__db* /var/lib/ldap/*.bdb to reinitialize"
else
  init_ldap

  #in Etch and Lenny, the database must be owned by openldap
  if getent passwd openldap | grep  -q openldap ; then
     chown -R openldap:openldap /var/lib/ldap
  fi

  # Store samba pw for later use
  smbpasswd -w $SAMBAPWD

# Instead of registering unix groups in samba like this
#   net groupmap add unixgroup=teachers \
#        type=domain ntgroup="teachers" \
#        comment="All teachers in the institution"
# we add the sambaSID attribute to LDAP objects when they are created,
# with static RID part.

  ## initialize Kerberos KDC, use gosa-admin account to access ldap:
  if [ -x /usr/share/debian-edu-config/tools/kerberos-kdc-init ] ; then
      if /usr/share/debian-edu-config/tools/kerberos-kdc-init $GOSAPWD ; then
          :
      else
          echo "error: critical: setting up Kerberos failed"
      fi
  fi
fi

# Restart ldap server if we stopped it and it aint already running
SLAPPIDS=$(pidof slapd || /bin/true)
if [ true = "$RESTARTSLAPD" ] && [ -z "$SLAPPIDS" ] ; then
  /etc/init.d/slapd start
fi

chown mail.mail /var/lib/maildirs/
$MTAINIT start

## restart Kerberos KDC and admin server:
/etc/init.d/krb5-kdc restart
/etc/init.d/krb5-admin-server restart
