#!/bin/sh
#
# This script is executed within the debian-installer environment when
# pre-pkgsel.d is executed, which is executed before tasksel is
# started.

set -e

. /usr/share/debconf/confmodule

log() {
    logger -t debian-edu-config-pre-pkgsel "$@"
}

error() {
    logger -t debian-edu-config-pre-pkgsel "error: $*"
}

# FIXME Rewrite function/subsystem to allow IP numbers and subnet
# information to be configured at install time.
configure_network() {
# Write a functional /target/etc/network/interfaces
    if [ -z "$PROFILE" ]; then
	PROFILE=Workstation
    fi

    # Default hostname is 'localhost'
    HOSTNAME=localhost

    # Default DNS server is tjener.intern
    NAMESERVER=10.0.2.2

    DNSDOMAIN=intern
    MAILNAME=postoffice.intern

    interfaces=/target/etc/network/interfaces

    # Should it get the information from the netcfg package instead?
    eth0=dhcp
    autoeth0="auto eth0"
    eth1=dhcp
    autoeth1=

    # Hm, what if both server and workstation is choosen?  Choose the
    # server config for eth0.
    for value in `echo $PROFILE |sed 's/ /-/g' | sed 's/,-/ /g'`; do
	case $value in
	    Roaming-Workstation)
		# Configure network-manager to connect to eth0 by
		# default, to be able to look up user information in
		# LDAP.
		eth0=none
		autoeth0=""
		eth1=none
		autoeth1=""
		DNSDOMAIN=
		MAILNAME=
		HOSTNAME=
		eth0uuid=$(chroot /target uuid)
		mkdir -p /target/etc/NetworkManager/system-connections
		cat > /target/etc/NetworkManager/system-connections/eth0 <<EOF
[connection]
id=eth0
uuid=$eth0uuid
type=ethernet

[ipv6]
method=auto

[ipv4]
method=auto
EOF
		;;
	    Standalone)
 	        # Leave network configuration to network-manager on
 	        # Standalone
		eth0=none
		autoeth0=""
		eth1=none
		autoeth1=""
		DNSDOMAIN=
		MAILNAME=
		HOSTNAME=
		;;
	    Workstation)
   	        # Use this unless Server also was choosen.
		if [ -z "$eth0" ] ; then
		    eth0=none
		    autoeth0=""
		    eth1=none
		    autoeth1=""
		fi
		;;
	    Main-Server)
 	        # Override for workstations combining as servers
		eth0=10.0.2.2:255.0.0.0:10.255.255.255:10.0.0.1
		HOSTNAME=tjener.intern
		NAMESERVER=127.0.0.1
		autoeth0="auto eth0"
		;;
	    LTSP-Server)
 	        # Use this unless Server also was choosen.
		if [ -z "$eth0" ] ; then
		    eth0=none
		    autoeth0=""
		fi
		eth1=192.168.0.254:255.255.255.0:192.168.0.255:none
		autoeth1="auto eth1"
		;;
	esac
    done
  
    # Every host need the loopback interface
    cat > $interfaces <<EOF
# Created by debian-edu-profile during the Debian installation.
#
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback
EOF
    if [ "$DNSDOMAIN" ] && [ "$NAMESERVER" = "127.0.0.1" ] ; then
	cat >> $interfaces <<EOF
    dns-search $DNSDOMAIN
    dns-nameservers $NAMESERVER
EOF
    fi

    for interface in eth0 eth1 ; do
	eval "ifinfo=\$$interface"
	eval "ifauto=\$auto$interface"
	log "setting up network interface $interface using $ifinfo"
	case $ifinfo in
	    dhcp)
		cat >> $interfaces <<EOF

$ifauto
iface $interface inet dhcp
EOF

		;;
	    [0-9]*)
	        address=`echo $ifinfo | cut -d: -f1`
		netmask=`echo $ifinfo | cut -d: -f2`
		broadcast=`echo $ifinfo | cut -d: -f3`
		gateway=`echo $ifinfo | cut -d: -f4`
		cat >> $interfaces <<EOF

auto $interface
iface $interface inet static
    address $address
    netmask $netmask
    broadcast $broadcast
EOF
		if [ none != "$gateway" ] ; then
		    cat >> $interfaces <<EOF
    gateway $gateway
EOF
		fi
		cat >> $interfaces <<EOF
# The commented lines below is to be used if a DHCP server is in use
#iface $interface inet dhcp
EOF
		;;
	    *)
	        # Nothing to do?
	        ;;
	esac
    done
    (
	echo "127.0.0.1       localhost.localdomain localhost" 
	echo "::1             localhost       ip6-localhost ip6-loopback"
	echo "fe00::0         ip6-localnet"
	echo "ff00::0         ip6-mcastprefix"
	echo "ff02::1         ip6-allnodes"
	echo "ff02::2         ip6-allrouters"
	echo "ff02::3         ip6-allhosts"
    ) > /target/etc/hosts

    if [ ! -z "$HOSTNAME" ] ; then
        echo "$HOSTNAME" > /target/etc/hostname
        in-target /bin/hostname "$HOSTNAME"
    fi

    # Update hostname based on reverse DNS entry of current IP or
    # generate from MAC address, unless installing main-server.
    if echo $PROFILE | grep -q Main-Server ; then
	:
    elif [ -x /target/usr/sbin/update-hostname-from-ip ] ; then
	in-target /usr/sbin/update-hostname-from-ip -m || true
    fi

    # Avoid hardcoding entries on the clients, to make sure IP address
    # range can be changed on the clients by changing DHCP
    # configuration on the server.
    if [ "tjener.intern" = "$HOSTNAME" ] ; then
	(
	    echo
	    echo "10.0.2.2        tjener.intern tjener" 
	) >> /target/etc/hosts
    fi

    # Set /etc/mailname if it is missing
    if [ "$MAILNAME" ] && [ ! -f /target/etc/mailname ] ; then
	echo "$MAILNAME" > /target/etc/mailname
    fi

    # Make sure that the interfaces are there for the cfengine run if
    # network isn't already configured
    if route | grep -q default ; then
	log "Not restarting network, as it seem to be up already."
    else
	log "Restarting network to prepare for cfengine run."
	# Redirecting fd 3 as a workaround for skolelinux bug #1229.
	# make sure the redirecting happen inside the chroot, as
	# in-target need to talk to debconf.
	in-target /bin/sh -c "/etc/init.d/networking start 3> /dev/null" || true
	touch /tmp/debian-edu-nonetwork
    fi
}

# Make sure required information is available after user-setup run its
# finish-install hook.
set_kerberos_ldap_passwords() {
    if db_get passwd/root-password-crypted && [ "$RET" ] ; then
	log "No clear text root password, unable to pass it on to Kerberos/LDAP."
    else
	log "Fetching password for Kerberos KDC and LDAP." 1>&2
	db_get passwd/root-password
	ROOTPWD="$RET"

	log "Fetching info for first user." 1>&2
	
	if db_get passwd/username && [ "$RET" ] ; then
	    FIRSTUSERNAME="$RET"
	else
	    FIRSTUSERNAME="localadmin"
	fi
	if db_get passwd/user-fullname && [ "$RET" ] ; then
	    FIRSTUSERGECOS="$RET"
	else
	    FIRSTUSERGECOS="LDAP initial admin user"
	fi
	if db_get passwd/user-password && [ "$RET" ] ; then
	    FIRSTUSERPWD="$RET"
	else
	    FIRSTUSERPWD="$ROOTPWD"
	fi

	file=/tmp/passwords-preseed
	cat > $file <<EOF
debian-edu-config debian-edu-config/kdc-password password $ROOTPWD
debian-edu-config debian-edu-config/kdc-password-again password $ROOTPWD
debian-edu-config debian-edu-config/ldap-password password $ROOTPWD
debian-edu-config debian-edu-config/ldap-password-again password $ROOTPWD
debian-edu-config debian-edu-config/first-user-name string $FIRSTUSERNAME
debian-edu-config debian-edu-config/first-user-fullname string $FIRSTUSERGECOS
debian-edu-config debian-edu-config/first-user-password password $FIRSTUSERPWD
EOF
	# Pass user and password information into the target
	cat $file | LANG=C chroot /target debconf-set-selections || \
	    error "Failed to load preseed values from $file."
	rm $file
    fi
}

create_initial_localadmin_user() {
    LOCAL_USER_ID="localadmin"
    LOCAL_USER_GECOS="Local Administrator"
    LOCAL_USER_UIDNUMBER="500"
    LOCAL_USER_PRIMGIDNUMBER="500"

    LOCAL_USER_INGROUPS="$LOCAL_USER_INGROUPS adm sudo"

    if db_get passwd/root-password-crypted && [ "$RET" ] ; then
	log "No clear text root password, unable to use it for creating the initial local user"
    else
	# retrieve root password
	db_get passwd/root-password
	LOCAL_USER_PASSWD=$RET
	# create initial local user
	in-target /usr/sbin/addgroup --gid $LOCAL_USER_PRIMGIDNUMBER $LOCAL_USER_ID 1>&2 || true
	in-target /usr/sbin/adduser --gid $LOCAL_USER_PRIMGIDNUMBER \
		--firstuid $LOCAL_USER_UIDNUMBER \
		--home /home/$LOCAL_USER_ID \
		--shell /bin/bash \
		--disabled-login \
		--gecos "$LOCAL_USER_GECOS" $LOCAL_USER_ID 1>&2 || true
	# add initial local user to some standard system groups
	for group in ${LOCAL_USER_INGROUPS}; do
		in-target /usr/sbin/adduser $LOCAL_USER_ID $group 1>&2 || true
	done
	# set password (batch mode)
	in-target /bin/sh -c "echo ${LOCAL_USER_ID}:${LOCAL_USER_PASSWD} | /usr/sbin/chpasswd" 1>&2 || true
    fi
}

# Work around grub bug #712907 (see also bug #763580) by preseeding
# grub-installer/choose_device to the disk used by /target/boot
# This fix it for the most common case.
# FIXME remember to remove this code when the bug is fixed
workaround_grub_issue() {
    log "checking if grub workaround for bug #712907 should be activated."
    bootdev=$(grep /target/boot /proc/mounts | cut -d" " -f1)
    grubdev=$(echo $bootdev | sed -rn 's/^(\/dev\/.*d.)[0-9].*$/\1/p')

    # Only override if it is set to manual or do not have a value,
    # otherwise we assume someone is preseeding it to the value they
    # want.
    db_get grub-installer/choose_bootdev || true
    if [ "$RET" ] && [ "manual" != "$RET" ]; then
	log "not overriding grub-installer/choose_bootdev to $grubdev, its value was '$RET'"
	return
    fi

    case "$bootdev" in
	/dev/sd*|/dev/vd*|/dev/hd*|/dev/xvd*)
	    log "overriding grub-installer/choose_bootdev, setting it to $grubdev"
	    db_set grub-installer/choose_bootdev "$grubdev" || true
	    ;;
    esac
}

workaround_grub_issue

db_get debian-edu-install/profile
PROFILE="$RET"

# Modify tasksel tests so the normal Debian desktop profiles are not
# installed.
in-target /usr/lib/education-tasks/edu-tasksel-setup setup

edu-etcvcs commit

# Configure network also on DVDs to make sure cfengine find a working
# network.
configure_network

edu-etcvcs commit

for p in $(echo $PROFILE | tr , " ") ; do
    case $p in
	# Only do this for the networked tasks, not for standalone
	Main-Server|Workstation|Roaming-Workstation|LTSP-Server|Minimal)
	    set_kerberos_ldap_passwords
	    #create_initial_localadmin_user
	    in-target /usr/share/debian-edu-config/tools/preseed-ldap-kerberos
	    in-target /usr/share/debian-edu-config/tools/preseed-sitesummary

	    # Tell user-setup to not create a user, needed on
	    # Main-Server to be able to create the user in LDAP.
	    db_set passwd/make-user boolean false
	    ;;
    esac
done
