#!/bin/bash
#
# postinst script for linuxmuster-base
# thomas@linuxmuster.net
# 20190328
# GPL v3
#

# see: dh_installdeb(1)

set -e

# summary of how this script can be called:
#        * <postinst> `configure' <most-recently-configured-version>
#        * <old-postinst> `abort-upgrade' <new version>
#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
#          <new-version>
#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
#          <failed-install-package> <version> `removing'
#          <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
#

# read setup values from debconf
read_values(){

 echo "Reading values from debconf ..."

 for i in country state location schoolname servername domainname workgroup fwconfig \
          smtprelay sambasid internsubrange iface_lan serverexternname subnetting; do
  eval $i="$(echo "get linuxmuster-base/$i" | debconf-communicate | awk '{ print $2 }')"
 done

 # compute additional values
 internsub=`echo $serverip | awk -F. '{ print $2 }'`
 serverrev_short=1.1.$internsub
 ipcoprev_short=254.1.$internsub
 basedn="dc=`echo $domainname|sed 's/\./,dc=/g'`"
 srvnetip=10.$internsub.1.0
 srvnetgw=10.$internsub.1.253
 srvnetbc="$(ipcalc -b "$srvnetip/$subnetmask" | grep ^Broadcast | awk '{ print $2 }')"

 # update serverexternname
 if [ -z "$serverexternname" ]; then
  serverexternname="$servername.$domainname"
  echo "set linuxmuster-base/serverexternname $serverexternname" | debconf-communicate
 fi

} # read_values

# write new network.settings file
write_networksettings(){

 echo "Updating $NETWORKSETTINGS ..."

 (
 cat <<EOF
# linuxmuster.net settings
servername="$servername"
serverip="$serverip"
ipcopip="$ipcopip"
domainname="$domainname"
serverexternname="$serverexternname"
fwconfig="$fwconfig"
internalnet="$internalnet"
broadcast="$broadcast"
ipcopblue="$ipcopblue"
ipcoporange="$ipcoporange"
ipcopovpn="$ipcopovpn"
basedn="$basedn"
smtprelay="$smtprelay"
iface_lan="$iface_lan"
admin="$ADMINISTRATOR"
schoolname="$schoolname"
location="$location"
state="$state"
country="$country"
imaging="linbo"
subnetting="$subnetting"
srvnetip="$srvnetip"
srvnetgw="$srvnetgw"
srvnetbc="$srvnetbc"
EOF
 ) > "$NETWORKSETTINGS"
 chmod 755 "$NETWORKSETTINGS"

} # write_networksettings


case "$1" in

 configure)

  # read linuxmuster defaults
  . /usr/share/linuxmuster/config/dist.conf

  # ensure all german locales are configured
  locale-gen de_DE.UTF-8 de_DE de_DE@euro

  # make configs executable so that perl scripts can source it
  for i in $DISTCONF $BACKUPCONF $DEFAULTCONF; do
   [ -e "$i" ] && chmod 755 "$i"
  done

  # only root may use helperfunctions.sh
  chmod 600 $HELPERFUNCTIONS

  # check all necessary dirs and create them if needed
  for i in $PREEXECD $POSTEXECD $NETLOGONDIR $PROGSDIR $PROGSRWDIR $CDSDIR $BACKUPDIR $BACKUPMNTPOINT $LOGINCACHE $LOGDIR; do
   [ -d "$i" ] || mkdir -p $i
  done

  # create necessary files
  for i in $WIMPORTDATA $BLOCKEDHOSTSINTERNET $BLOCKEDHOSTSINTRANET $UNFILTEREDHOSTS; do
   [ -e "$i" ] || touch "$i"
  done

  # dummy dhcpd.conf
  if [ ! -f "$DHCPDCONF" ]; then
   [ -d "${DHCPDCONF%/*}" ] || mkdir -p ${DHCPDCONF%/*}
   touch $DHCPDCONF
  fi

  # add startup scripts to runlevels
  update-rc.d linuxmuster-base defaults

  # change default shell to /bin/bash
  echo "Changing default shell to /bin/bash!"
  ln -sf bash /bin/sh
  chsh -s /bin/bash

  # exit if linuxmuster.net is not configured yet
  [ -e "$INSTALLED" ] || exit 0

  if ! . $HELPERFUNCTIONS; then
   echo "Cannot read $HELPERFUNCTIONS!"
   exit 1
  fi

  if ! id $ADMINISTRATOR &> /dev/null; then
   echo "LDAP-Service is not running! Skipping package configuration."
   echo "Please do this manually by invoking"
   echo "# dpkg-reconfigure linuxmuster-base"
   echo "after you have fixed this issue."
   exit 0
  fi

  # messages for config file headers
  message1="Do not change this file! It will be overwritten!"
  message2="This configuration file was automatically created by linuxmuster-base!"
  message3="Last Modification: `date`"

  # read setup values from debconf
  read_values

  # test if fwconfig is valid
  case $fwconfig in
   ipfire|custom) ;;
   ipcop) echo "IPCop is no longer supported. Please change to IPFire ASAP!" ;;
   *) fwconfig=custom
      echo "set linuxmuster-base/fwconfig $fwconfig" | debconf-communicate
      ;;
  esac

  # update network.settings
  grep -q ^srvnetip "$NETWORKSETTINGS" || write_networksettings

  # patch samba
  [ -s "$SMBCONFTEMPLATE" ] && sed -e "s/@@message1@@/${message1}/g
          s/@@message2@@/${message2}/g
          s/@@message3@@/${message3}/g
          s/@@serverip@@/${serverip}/g
          s/@@internmask@@/${INTERNMASK}/g
          s/@@workgroup@@/${workgroup}/g
          s/@@domadmin@@/${DOMADMIN}/g
          s/@@administrator@@/${ADMINISTRATOR}/g
          s/@@domadmins@@/${DOMADMINS}/g
          s/@@teachersgroup@@/${TEACHERSGROUP}/g
          s/@@basedn@@/${basedn}/g" $SMBCONFTEMPLATE > /etc/samba/smb.conf

  # provide new sources.list
  repo="archive.linuxmuster.net"
  lmnlist_current="/etc/apt/sources.list.d/lmn.list"
  if ! grep -q "$repo" "$lmnlist_current"; then
    echo "Updating linuxmuster.net repo address."
    lmnlist_new="$DATADIR/lmn.list"
    cp "$lmnlist_new" "$lmnlist_current"
  fi

  # openldap permissions
  conf=/etc/ldap/slapd.conf
  chown root:openldap ${conf}*
  chmod 640 ${conf}*
  # repair ldaps
  conf=/etc/default/slapd ; backup=false
  if ! grep ^SLAPD_SERVICES $conf | grep -q ldaps; then
   echo "Fixing ldaps in $conf."
   cp $conf $conf.dpkg-old
   backup=true
   cp $STATICTPLDIR/$conf $conf
   slapd_reload=yes
  fi
  if ! grep -q ^"SLAPD_OPTIONS=\"\-4\"" $conf; then
   echo "Disabling IPv6 support in $conf."
   [ "$backup" = "false" ] && cp $conf $conf.dpkg-old
   cp $STATICTPLDIR/$conf $conf
   slapd_reload=yes
  fi

  # extraschueler.txt, extrakurse.txt
  for i in extraschueler.txt extrakurse.txt entfernen.txt sperrklassen.txt; do
   [ -e "/etc/sophomorix/user/$i" ] || cp $STATICTPLDIR/etc/sophomorix/user/$i /etc/sophomorix/user
  done

  # create localized links in certain samba share folders (temporary workaround until sophomorix does the job)
  chmod 755 "$SHAREHOME"
  chmod 1775 "$TASKSCACHE"
  for d in "$SHAREHOME" "$TASKSCACHE"; do
   # remove obsolete links
   for i in Lehrkräfte Prüfungen Räume; do
    [ -L "$d/$i" ] && rm "$d/$i"
   done
   for i in "Klassen classes" "Kollegium teachers" "Projekte projects" "Räume rooms" "Schule school"; do
    # no link for teachers in tasks
    [ "$d" = "$TASKSCACHE" -a "$i" = "Kollegium teachers" ] && continue
    # no link for rooms in share
    [ "$d" = "$SHAREHOME" -a "$i" = "Räume rooms" ] && continue
    lnk="$d/$(echo $i | awk '{ print $1 }')"
    src="$(echo $i | awk '{ print $2 }')"
    [ ! -L "$lnk" -a -e "$d/$src" ] && ln -sf "$src" "$lnk"
   done
  done

  # adding win7 netlogon example files.
  if ! grep -q replace.vbs "$NETLOGONDIR/common.bat"; then
   [ -e "$NETLOGONDIR/common.bat.win7" ] || cp "$STATICTPLDIR/$NETLOGONDIR/common.bat" "$NETLOGONDIR/common.bat.win7"
  fi
  [ -e "$NETLOGONDIR/replace.vbs" ] || cp "$STATICTPLDIR/$NETLOGONDIR/replace.vbs" "$NETLOGONDIR"

  # provide teachers.bat if not yet there
  tpldir="$DYNTPLDIR/17_admins"
  tpl="$tpldir/login.bat"
  conf="$(cat $tpl.target)"
  if ! grep -q 'teachers.bat' "$conf"; then
   echo "Providing new netlogon script teachers.bat."
   sed -e "s|@@servername@@|$servername|g" "$tpl" > "$conf"
   tpl="$tpldir/teachers.bat"
   conf="$(cat $tpl.target)"
   sed -e "s|@@servername@@|$servername|g" "$tpl" > "$conf"
  fi
  # reparing permissions in netlogondir
  echo "Repairing permissions in $NETLOGONDIR ..."
  find $NETLOGONDIR/ -type f -exec chmod 664 '{}' \;
  find $NETLOGONDIR/ -type d -exec chmod 775 '{}' \;
  chown $ADMINISTRATOR:$DOMADMINS $NETLOGONDIR -R
  # see #466
  chown $ADMINISTRATOR:$DOMADMINS $SAMBAHOME
  chown $ADMINISTRATOR:$DOMADMINS $SAMBAHOME/*
  chmod 775 $SAMBAHOME/*

  # remove stale obsolete registry-patches link in administrator's home
  find "$ADMINSHOME/$ADMINISTRATOR" -xtype l -name registry-patches -exec rm '{}' \;

  # linbo administrative user
  service slapd status | grep -q "is running" && slapd_running="yes"
  pg_running="$(service postgresql status | awk -F\: '{ print $2 }' | awk '{ print $1 }')"
  if [ -n "$slapd_running" -a -n "$pg_running" ]; then
   if ! check_id linbo &>/dev/null; then
    linbopasswd=`grep ^linbo /etc/rsyncd.secrets | awk -F\: '{ print $2 }'`
    if [ -n "$linbopasswd" ]; then
     echo "Creating linbo user ..."
     sophomorix-useradd --administrator linbo --unix-group $ADMINGROUP --shell /bin/false --gecos "LINBO Administrator" &> /dev/null || true
     sophomorix-passwd --user linbo --pass $linbopasswd &> /dev/null || true
     smbldap-usermod -H '[UX         ]' linbo || true
    fi
   fi
  else
   echo "slapd and/or postgresql not running! Skipping linbo user check!"
  fi

  # creating ldap.secret links
  [ -s /etc/ldap.secret ] || echo $(grep ^rootpw /etc/ldap/slapd.conf | awk '{ print $2 }') > /etc/ldap.secret
  for i in pam_ldap libnss-ldap; do
   rm -f /etc/$i.secret
   ln -s ldap.secret /etc/$i.secret
  done
  chmod 600 /etc/*.secret

  # refresh samba admin passwd (see #80)
  smbpasswd -w "$(cat /etc/ldap.secret)"

  # provide sophomorix-bind-mount scripts if missing (see #80)
  for i in preexec postexec; do
   case "$i" in
    pre*) conf="$PREEXECD/sophomorix-root-$i"
          param="--login" ;;
    pos*) conf="$POSTEXECD/sophomorix-root-$i"
          param="--logout" ;;
   esac
   if [ ! -s "$conf" ]; then
    echo "Writing $conf."
    cat > "$conf" <<EOF
#!/bin/bash
sophomorix-bind --quick $param --host \$HOSTNAME --user \$USERNAME --homedir \$HOMEDIR
EOF
    chmod +x "$conf"
   fi
  done

  # expand allow-query list in named.conf.options (#18)
  conf=/etc/bind/named.conf.options
  searchstr="allow-query { $internalnet/$INTERNBITMASK; $ipcopblue.0/24; $ipcoporange.0/24; $ipcopovpn.0/24; };"
  if ! grep -q "$searchstr" $conf; then
    echo "Backing up $conf to $conf.dpkg-bak."
    cp $conf $conf.dpkg-bak
    echo "Expanding allow-query list in $conf (#18)."
    sed -e "s|\tallow-query.*|\t$searchstr|" -i $conf
    bind_reload=yes
  fi
  # fix firewall hostname resolution for nagios checks (see #81)
  if [ "$fwconfig" != "ipcop" ]; then
   searchstr="ipcop"
   conf=/etc/bind/db.linuxmuster
   if grep -q ^"$searchstr" "$conf"; then
    echo "Backing up $conf to $conf.dpkg-bak."
    cp $conf $conf.dpkg-bak
    echo "Removing $searchstr from $conf."
    sed -e "/^$searchstr/d" -i $conf
    bind_reload=yes
   fi
  fi

  # update turba's sources.php (closes #83 & #184)
  tpl="$DYNTPLDIR/21_horde3/turba2.sources.php"
  conf="$(cat $tpl.target)"
  searchstr="* 22.04.2013"
  if (! grep -q "$searchstr" "$conf" || grep -q @@ "$conf"); then
   echo "Backing up $conf to $conf.dpkg-bak."
   cp $conf $conf.dpkg-bak
   echo "Fixing turba's sources.php."
   sed -e "s|@@schoolname@@|$schoolname|
           s|@@basedn@@|$basedn|" "$tpl" > "$conf"
   chown root:www-data "$conf"
   chmod 440 "$conf"
  fi

  # update gollem configs
  confdir="/etc/horde/gollem"
  conf="$confdir/prefs.php"
  searchstr='* 19.02.2013'
  if ! grep -q "$searchstr" "$conf"; then
   echo "Fixing gollem's $(basename $conf)."
   cp "${STATICTPLDIR}${conf}" "$conf"
   chown root:www-data "$conf"
   chmod 440 "$conf"
  fi
  conf="$confdir/backends.php"
  searchstr='* 27.01.2014'
  if ! grep -q "$searchstr" "$conf"; then
   echo "Fixing gollem's $(basename $conf)."
   cp "${STATICTPLDIR}${conf}" "$conf"
   chown root:www-data "$conf"
   chmod 440 "$conf"
  fi

  # repair permissions for horde log dir (closes #82)
  [ -e /var/log/horde ] && chown www-data:www-data /var/log/horde -R

  # fix cups configuration (closes #101)
  conf="/etc/cups/cupsd.conf"
  tpl="${STATICTPLDIR}${conf}"
  if ! grep -q ^"BrowseAddress 10.*" "$conf"; then
   echo "Fixing $conf ..."
   cp "$conf" "${conf}.dpkg-bak"
   cp "$tpl" "$conf"
   cups_reload=yes
  fi
  conf="/etc/cups/cups-files.conf"
  tpl="${STATICTPLDIR}${conf}"
  if [ ! -e "$conf" ]; then
   echo "Creating $conf ..."
   cp "$conf" "${conf}.dpkg-bak"
   cp "$tpl" "$conf"
   cups_reload=yes
  fi

  # adding apparmor profile for linuxmuster (see #156)
  dir="/etc/apparmor.d/tunables/home.d"
  conf="$dir/linuxmuster"
  if [ ! -s "$conf" ]; then
   echo "Adding apparmor profile for linuxmuster.net ..."
   tpl="${STATICTPLDIR}${conf}"
   mkdir -p "$dir"
   cp "$tpl" "$conf"
   [ -s "/etc/init.d/apparmor" ] && apparmor_reload=yes
  fi

  # fix horde/ingo's sieve configuration (closes #102)
  searchstr="/* 16.03.2013"
  conf="/etc/horde/ingo1/backends.php"
  if ! grep -q "$searchstr" "$conf"; then
   echo "Fixing horde/ingo's sieve configuration ..."
   cp "$conf" "${conf}.dpkg-bak"
   tpl="${STATICTPLDIR}${conf}"
   cp "$tpl" "$conf"
   chown root:www-data "$conf"
   chmod 440 "$conf"
  fi

  # add allowusermoves to imapd.conf (see #216)
  searchstr="# 27.01.2014"
  conf="/etc/imapd.conf"
  if ! grep -q "$searchstr" "$conf"; then
   echo "Adding allowusermoves option to imapd.conf ..."
   cp "$conf" "${conf}.dpkg-bak"
   tpl="${STATICTPLDIR}${conf}"
   cp "$tpl" "$conf"
   cyrus_reload=yes
  fi

  # rename old shit
  conf_old=/etc/php5/conf.d/paedml.ini
  if [ -e "$conf_old" ]; then
   conf=/etc/php5/conf.d/linuxmuster.ini
   mv "$conf_old" "$conf"
  fi

  # convert macs to ips for ip based internal firewall
  for conf in $BLOCKEDHOSTSINTRANET $UNFILTEREDHOSTS; do
   searchstr="$(head -1 $conf)"
   if validmac "$searchstr"; then
    echo "Converting macs to ips in $conf."
    macs="$(cat $conf)"
    rm $conf
    touch $conf
    for i in $macs; do
     if validip "$i"; then
      echo "$i" >> $conf
     else
      get_ip "$i"
      echo "$RET" >> $conf
     fi
    done
    fwint_reload=yes
   fi
  done

  # check for obsolete mac based iptables rules file
  IPTRULES="$CACHEDIR/iptables"
  if [ -e "$IPTRULES" ]; then
   grep -q mac-source "$IPTRULES" && fwint_reload=yes
  fi

  # dhcpd.conf update
  echo "DHCP configuration update"
  conf="/etc/dhcp/dhcpd.conf"
  # according to subnetting
  if [ "$subnetting" = "true" ]; then
   dhcpbc="$srvnetbc"
   dhcpmask="$SUBNETMASK"
  else
   dhcpbc="$broadcast"
   dhcpmask="$INTERNMASK"
  fi
  # patch the according template
  tpl="$DYNTPLDIR/05_dhcp/$(basename "$conf")"
  cp "$conf" "${conf}.dpkg-bak"
  sed -e "s/@@servername@@/${servername}/g
          s/@@domainname@@/${domainname}/g
          s/@@serverip@@/${serverip}/g
          s/@@ipcopip@@/${ipcopip}/g
          s/@@dhcpbc@@/${dhcpbc}/g
          s/@@internsub@@/${internsub}/g
          s/@@internalnet@@/${internalnet}/g
          s/@@dhcpmask@@/${dhcpmask}/g" "$tpl" > "$conf"
  # patch dhcp host definitions if necessary, deprecated
  #if grep -q extensions-path "${conf}.linuxmuster"; then
  # sed -e 's/extensions-path \"/pxelinux.configfile \"pxelinux.cfg\//g' -i "${conf}.linuxmuster"
  #fi
  # remove free range if subnetting is set
  [ "$subnetting" = "true" ] && removefrom_file "$conf" "$BEGINSTR" "$ENDSTR"
  # provide custom file
  conf="/etc/dhcp/dhcpd.conf.custom"
  [ -e "$conf" ] || cp "$STATICTPLDIR/$conf" "$conf"
  dhcp_reload=yes

  # withdraw access rights for room on /home/share
  if [ ! -e "$ROOM_SHARE_ACLS" ]; then
   "$SCRIPTSDIR/room_share_acl.sh" --deny || true
  fi

  # fix apache SSLv3 usage
  conf="/etc/apache2/mods-available/ssl.conf"
  searchstr="\-SSLv3"
  if ! grep ^SSLProtocol "$conf" | grep -q "$searchstr"; then
   echo "Disabling SSLv3 in apache's ssl.conf."
   cp "$conf" "${conf}.dpkg-bak"
   sed "/^SSLProtocol/ s/$/ ${searchstr/\\/}/" -i "$conf"
  fi

  # create missing ecdsa ssh keys (#498)
  rootkey="/root/.ssh/id_ecdsa"
  hostkey="/etc/ssh/ssh_host_ecdsa_key"
  for i in $rootkey $hostkey; do
   if [ ! -e "$i" ]; then
    echo -n "Creating ssh key $i ... "
    ssh-keygen -N "" -q -t ecdsa -f "$i"
    echo "Done!"
    ssh_reload="yes"
   fi
  done

  # updating release information
  echo "$DISTNAME $DISTFULLVERSION / Codename $CODENAME" > /etc/issue
  cp /etc/issue /etc/issue.net

  # remove upgrade-notice to 14.04 and make it not come back (closes #355)
  conf="/etc/update-manager/release-upgrades"
  if [ -s "$conf" ]; then
   echo "Disabling release upgrade announcements."
   cp "$conf" "${conf}.dpkg-bak"
   sed -e "s/^Prompt=lts$/Prompt=never/" -i "$conf"
  fi
  rm -f /var/lib/update-notifier/release-upgrade-available

  # reload services
  apache2ctl graceful || true
  reload smbd || true
  [ -n "$ssh_reload" ] && service ssh reload
  [ -n "$apparmor_reload" ] && service apparmor restart
  [ -n "$cups_reload" ] && reload cups
  [ -n "$cyrus_reload" ] && service cyrus-imapd reload
  [ -n "$nagios_reload" ] && service nagios3 restart
  [ -n "$bind_reload" ] && service bind9 force-reload
  if [ -n "$dhcp_reload" ]; then
   if status isc-dhcp-server | grep -q running; then
    reload isc-dhcp-server
   else
    start isc-dhcp-server
   fi
  fi
  [ -n "$slapd_reload" ] && /etc/init.d/slapd restart
  [ -n "$postgres_reload" ] && /etc/init.d/postgresql reload
  [ -n "$fwint_reload" ] && /etc/init.d/linuxmuster-base reload

  # add config patches
  run-parts "$ADDTPLDIR"

  # remove obsolete config dirs
  for i in 03_dhcp3-server 01_network; do
   conf="$DYNTPLDIR/$i"
   [ -e "$conf" ] && rm -rf "$conf"
  done

  # notify if upgrade is necessary
  if [ -n "$upgrade" ]; then
   echo "NOTE!"
   echo "Be sure to make a dist-upgrade very soon!"
  fi
  # notify if reboot is necessary
  if [ -n "$reboot" ]; then
   echo "IMPORTANT!"
   echo "You have to REBOOT the server to make the changes effective!"
  fi
 ;;

 abort-upgrade|abort-remove|abort-deconfigure)
 ;;

 *)
  echo "postinst called with unknown argument \`$1'" >&2
  exit 1
 ;;

esac

# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.

#DEBHELPER#

exit 0
