#!/bin/bash
PSTORAGE_ISCSI_LIB=/usr/libexec/vstorage-iscsi/vstorage_functions
ROOT=""
USER=""
PASSW=""
ARGS="${@}"
CMD=""

function do_cleanup {
        [ -z "$TMP_DIRS" -o -z "$ISCSI_ROOT" ] && return
        for dir in $TMP_DIRS; do
                parent=`dirname ${dir}`
                [ "$parent" = "$ISCSI_ROOT/tmp" -a -d "${dir}" ] && rm -rf "${dir}"
        done
}

function print_usage {
        exec 1>&2
	if [ "$CMD" = "account-create" ] ; then
		echo "Create new CHAP account."
        	echo "Usage:"
		echo " $CTL_TOOL account-create -u,--user=USER -p,--passw"
        	echo "Options:"
		echo "  -u,--user=NAME          Name for new account."
		echo "  -p,--passw              Read password from stdin."

	elif [ "$CMD" = "account-delete" ] ; then
		echo "Delete the specified CHAP account."
		echo "Usage:"
		echo " $CTL_TOOL account-delete -u,--user=USER"
		echo "Options:"
		echo "  -u,--user=NAME          Name for new account."
	elif [ "$CMD" = "account-list" ]; then
		echo "List existing CHAP accounts."
		echo "Usage:"
		echo " $CTL_TOOL account-list [-u,--user=USER]"
		echo "Options:"
		echo "  -u,--user=NAME          Print iSCSI targets linked to specified account."
	elif [ "$CMD" = "account-set" ] ; then
		echo "Change password for the specified account."
		echo "Usage:"
		echo " $CTL_TOOL account-set -u,--user=USER -p,--passw"
		echo "Options:"
		echo "  -u,--user=NAME          Name of existing account."
		echo "  -p,--passw              Read password from stdin."
	fi
	        echo " "
        exit 1
}

function ask_password {
	echo -n "Enter password:"
	read -s passw
	echo " "
	if [ -z "$passw" ]; then
		echo "Entered empty password."
		exit 1
	fi
	echo -n "Verify password:"
	read -s verify
	echo " "
	if [ "$passw"  != "$verify" ] ; then
		echo "Entered different passwords."
		exit 1
	fi

	PASSW="$passw"
}

function parse_args {

        if [ ${#} -eq 0 ]; then
                echo "Command not specified" 1>&2
                exit 1
        fi
        CMD="${1}"; shift
        if [ "$CMD" != "account-list" -a "$CMD" != "account-set" -a "$CMD" != "account-delete" -a "$CMD" != "account-create" ] ; then
                echo "Unknown command '$CMD'" 1>&2
                exit 1
        fi

        while [ "${#}" -gt 0 ]; do
                case "${1}" in
			"-r"|"--root")
				[ -z "${2}" ] && print_usage
				ROOT="${2}"
				shift
				shift
				;;
                        "-u"|"--user")
				[ -z "${2}" ] && print_usage
				USER="${2}"
				shift
				shift
				;;
                        "-p"|"--passw")
				PASSW="$(< /dev/stdin)"
				shift
				shift
				;;
			"-h"|"--help")
				print_usage
				;;
                        *)
                                echo "Unknown option '${1}'." 1>&2
                                print_usage
                                ;;
                esac
        done
}

function do_account_set {
	if [ -z "$USER" ] ; then
		echo "Name for new account (-u,--user) must be specified." 1>&2
		exit 1
	fi


	[ -z "$PASSW" ] && ask_password

	if [ ! -d "$ISCSI_ROOT/accounts" ] ; then
		echo "Directory $ISCSI_ROOT/accounts does not exist." 1>&2
		exit 1
	fi

	if [ ! -d "$ISCSI_ROOT/accounts/$USER" ] ; then
		echo "Account '$USER' does not exist" 1>&2
		exit 1
	fi

        echo "$PASSW" | dd of="$ISCSI_ROOT/accounts/$USER/auth" conv=fsync >/dev/null 2>&1
        if [ $? -ne 0 ] ; then
                echo "Unable save password." 1>&2
                exit 3
        fi

	exit 0
}

function do_create_account {

	if [ -z "$USER" ] ; then
		echo "Name for new account (-u,--user) must be specified." 1>&2
		exit 1
	fi

	[ -z "$PASSW" ] && ask_password

	if [ ! -d "$ISCSI_ROOT/accounts" ] ; then
		echo "Directory $ISCSI_ROOT/accounts does not exist." 1>&2
		exit 1
	fi

	if [ -d "$ISCSI_ROOT/accounts/$USER" ] ; then
		echo "Account '$USER' already exist" 1>&2
		exit 1
	fi

	tmp=`mktemp -d ${ISCSI_ROOT}/tmp/new-account.XXXXXXXX`
        if [ $? -ne 0 ] ; then
                echo "Can't create temporary directory." 1>&2
                exit 2
	fi

	TMP_DIRS="${TMP_DIRS} ${tmp}"
	mkdir -p "${tmp}/$USER"
	is_root_on_vstorage || pcs_iscsi_set_storage_attr "${tmp}/$USER" "mds-storage=1" || exit 2

	echo "$PASSW" | dd of="$tmp/$USER/auth" conv=fsync >/dev/null 2>&1
	if [ $? -ne 0 ] ; then
		echo "Unable save password." 1>&2
		exit 3
        fi

	mv "$tmp/$USER" "${ISCSI_ROOT}/accounts" >/dev/null
	if [ $? -ne 0 ] ; then
		echo "Failed to create account." 1>&2
		exit 4
	fi

	exit 0
}

function do_delete_account {
	if [ -z "$USER" ] ; then
		echo "Name of account to delete (-u,--user) must be specified." 1>&2
		exit 1
	fi

	if [ ! -d "$ISCSI_ROOT/accounts" ] ; then
		echo "Directory $ISCSI_ROOT/accounts does not exist." 1>&2
		exit 1
	fi

	if [ ! -d "$ISCSI_ROOT/accounts/$USER" ] ; then
		echo "Account '$USER' does not exist." 1>&2
		exit 1
	fi

	# check target assigned to this account
	targets=""
        ls -d $ISCSI_ROOT/iqn*[pv]storage* 2>/dev/null | while read path
        do
		[ ! -L "$path/control/account" ] && continue
		account=`/bin/readlink "$path/control/account"`
		[ -z "$account" -o `basename "$account" ` != "$USER" ] && continue
		targets="$account $targets"
        done

	if [ -n "$target" ] ; then
		echo "Unable to delete account '$USER', this account used by some targets." 1>&2
		exit 2
	fi

        tmp=`mktemp -d ${ISCSI_ROOT}/tmp/removed-account.XXXXXXXX`
        if [ $? -ne 0 ] ; then
                echo "Can't create temporary directory." 1>&2
                exit 3
        fi
        TMP_DIRS="${TMP_DIRS} ${tmp}"
	mv "$ISCSI_ROOT/accounts/$USER"	"$tmp/$USER" >/dev/null
	if [ $? -ne 0 ]; then
		echo "Failed to delete account '$USER'" 1>&2
		exit 4
	fi
	exit 0
}

function do_list_accounts {
	if [ -z "$USER" ]; then
		ls $ISCSI_ROOT/accounts 2>/dev/null
		exit 0
	fi

	if [ ! -d "$ISCSI_ROOT/accounts/$USER" ] ; then
		echo "Unable find account '$USER' in $ISCSI_ROOT." 1>&2
		exit 1
	fi

        ls -d $ISCSI_ROOT/iqn*[pv]storage* 2>/dev/null | while read path
        do
		[ ! -L "$path/control/account" ] && continue
		account=`/bin/readlink "$path/control/account"`
		[ -z "$account" -o `basename "$account" ` != "$USER" ] && continue
		echo `basename $path`
        done
	exit 0
}

if [ ! -x $PSTORAGE_ISCSI_LIB ] ; then
	echo "Unable find executable $PSTORAGE_ISCSI_LIB" 1>&2
	exit 1
fi

source $PSTORAGE_ISCSI_LIB
[ -f $ISCSI_ETC/config ] && source $ISCSI_ETC/config

parse_args $ARGS

ISCSI_ROOT=`pcs_iscsi_get_root "${ROOT}"`
pcs_iscsi_check_root
mkdir -p "$ISCSI_ROOT/accounts"
trap do_cleanup EXIT
case "${CMD}" in
                "account-create")
			do_create_account
                        ;;
		"account-list")
			do_list_accounts
			;;
		"account-delete")
			do_delete_account
			;;
		"account-set")
			do_account_set

esac
exit $RET
