#!/bin/bash
#
# Univention Corporate Client
#  set root password in ucc images
#
# Copyright (C) 2012-2016 Univention GmbH
#
# http://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <http://www.gnu.org/licenses/>.

trap "clean_up" EXIT SIGINT SIGTERM SIGKILL

clean_up () {
	if [ -n "$mountDir" ]; then
		umount "$mountDir"
		if [ $? -eq 0 ]; then
			rm -r "$mountDir"
		else
			echo "umount of $mountDir failed, please umount manually" | STDERR
			exit 1
		fi
	fi
}

function STDERR () {
	cat - 1>&2
}

usage () {
	echo "$(basename $0): set root password in ucc image"
	echo ""
	echo "USAGE:"
	echo "  $(basename $0) -i FILE [OPTIONS]"
	echo ""
	echo "OPTIONS:"
	echo "  -i FILE"
	echo "     the ucc image file"
	echo "  -p"
	echo "     ask for the password interactively"
	echo "  -h"
	echo "     show this message"
}

IMAGE=""
ASK_PASSWORD=false

# options
while getopts 'i:ph' OPTION; do
	case "$OPTION" in
		i)
			IMAGE="$OPTARG"
			;;
		p)
			ASK_PASSWORD=true
			;;
		h)
			usage
			exit 0
			;;
		*)
			usage 
			;;
	esac
done

# test
if [ ! -e "$IMAGE" ]; then
	echo "No image file given" | STDERR
	exit 1
fi
if ! file -b "$IMAGE" | grep -q UUID=; then
	echo "$IMAGE is not a valid ucc image" | STDERR
	exit 1
fi

# is image already mounted?
imageUUID="$(blkid -s UUID -o value "$IMAGE")"
if [ -z "$imageUUID" ]; then
	echo "failed to get uuid from image $IMAGE" | STDERR
fi
for loop in $(more /etc/mtab | grep '/dev/loop'| awk '{print $1}'); do
	if [ -b "$loop" ]; then
		uuid="$(blkid -s UUID -o value "$loop")" 
		if [ -n "$uuid" -a "$imageUUID" = "$uuid" ]; then
			echo "image $IMAGE seems to be mounted on $loop" | STDERR
			exit 1
		fi
	fi
done

# get password
if $ASK_PASSWORD; then
	# ask for password
	read -s -p "Password:" password
	echo ""
	read -s -p "Verify password:" passwordV2
	echo ""
	if [ ! "$password" = "$passwordV2" ]; then
		echo "Sorry, passwords do not match." | STDERR
		exit 1
	fi
	password="$(mkpasswd -H sha-512 "$password")"
else
	# get password from /etc/shadow
	password="$(cat /etc/shadow 2>/dev/null | grep ^root: | awk -F : '{print $2}')"
fi
if [ -z "$password" ]; then
	echo "no password to set" | STDERR
	exit 1
fi

# do it
mountDir="$(mktemp -d)"
mount -o loop "$IMAGE" "$mountDir"
chroot "$mountDir" usermod -p "$password" root
if [ ! $? -eq 0 ]; then
	"failed to set root password in $IMAGE" | STDERR
	exit 1
fi

exit 0
