#!/usr/local/bin/cbsd
#v12.0.4
MYARG="mode"
MYOPTARG="fromfile jname login fullname group uid secgroup shell pw epw"
MYDESC="Add user to jail"
ADDHELP="mode can be: remove, add, show\n\
pw - plain password, or\n\
epw - encrypted password\n"

. ${subrdir}/nc.subr

. ${cbsdinit}

. ${system}

_MYDIR=$( /usr/bin/dirname `${REALPATH_CMD} $0` )
SERVICE="adduser"

f_getvar()
{
	local __var_to_get="$1" __var_to_set="$2"
	[ "$__var_to_set" ] || local value
	eval [ \"\${$__var_to_get+set}\" ]
	local __retval=$?
	eval ${__var_to_set:-value}=\"\${$__var_to_get}\"
	[ "$__var_to_set" ] || { [ "$value" ] && echo "$value"; }
	return $__retval
}


check_jaildir()
{
	local check_file="${path}/etc/master.passwd ${path}/etc/passwd ${path}/etc/group ${path}/usr/sbin/pw"
	local _i
	local ret=0

	for _i in ${check_file}; do
		[ ! -f "${_i}" ] && echo ${_i} && ret=1
	done

	return ${ret}
}

# not for multiple action
getpw()
{
	local _oldmodes=$( /bin/stty -g ) _try=0
	pw=""
	_try=0

	while [ ${_try} -ne 3 ]; do
		printf "${BOLD}Enter password:${N0_COLOR}"
		while [ -z "${npw}" ]; do
			#/bin/stty -echo
			read npw
			/bin/stty ${_oldmodes}
		done

		printf "\n${BOLD}Re-enter password: ${N0_COLOR}"
		while [ -z "${tpw}" ]; do
			/bin/stty -echo
			read tpw
			/bin/stty ${_oldmodes}
		done

		[ "${tpw}" = "${npw}" ] && pw="${npw}" && break

		printf "\n${N1_COLOR}Wrong password${N0_COLOR}\n"
		unset npw tpw
		_try=$(( _try + 1 ))
	done

	/bin/stty ${_oldmodes}
	echo
}

# must be filled:
# mandatory: login, pw
# opt: uid, fullname, group, secgroup, shell
c_adduser()
{
	local _res _ret

	[ -z "${login}" ] && ${ECHO} "${N2_COLOR}login= ${N1_COLOR} is mandatory${N0_COLOR}" && return 1

	_res=$( ${exec_cmd} user show ${login} 2>&1)
	case $? in
		0)
			${ECHO} "${N1_COLOR}Already exist: ${N0_COLOR}${_res}"
			return 1
			;;
		67)
			;;
		*)
			${ECHO} "${N1_COLOR}Error: ${N0_COLOR}${_res}"
			return 1
			;;
	esac

	if [ -z "${pw}" -a -z "${fromfile}" ]; then
		[ -z "${epw}" ] && getpw
	fi
	[ -z "${pw}" -a -z "${epw}" ] && err 1 "${N2_COLOR}pw= ${N1_COLOR}or ${N2_COLOR}epw= ${N1_COLOR} is mandatory${N0_COLOR}"
	ADDON=""
	[ -n "$uid" ] && ADDON="${ADDON} -u ${uid}"
	[ -n "$fullname" ] && ADDON="${ADDON} -c \"${fullname}\""
	[ -n "$group" ] && ADDON="${ADDON} -g ${group}"
	[ -n "$secgroup" ] && ADDON="${ADDON} -G ${secgroup}"

	if [ -n "$shell" ]; then
		ADDON="${ADDON} -s ${shell}"
	else
		ADDON="${ADDON} -s /bin/csh"
	fi

	if [ "${emulator}" != "jail" -a -n "${emulator}" -a "${emulator}" != "bhyve" ]; then
		. ${subrdir}/emulator.subr
		init_usermode_emul
		CHROOT_EXEC="/usr/sbin/chroot ${path} /bin/${emulator}"
	else
		CHROOT_EXEC="/usr/sbin/chroot ${path}"
	fi

	#echo "$CHROOT_EXEC /bin/sh  : pw useradd $login $ADDON"

	${CHROOT_EXEC} /bin/sh <<EOF
${PW_CMD} useradd ${login} ${ADDON} -m
EOF
	_ret=$?

	if [ -n "${pw}" ]; then
		${CHROOT_EXEC} /bin/sh <<EOF
echo "${pw}" | ${PW_CMD} mod user ${login} -h 0 -
EOF
	elif [ -n "${epw}" ]; then
		${CHROOT_EXEC} /bin/sh <<EOF
/usr/bin/chpass -p '${epw}' ${login}
EOF
	fi

	return ${_ret}
}

# must be filled:
# mandatory: login
remove()
{
	local _ret _res
	_res=$( ${exec_cmd} user del ${login} )
	_ret=$?
	if [ ${_ret} -eq 0 ]; then
		${ECHO} "${N2_COLOR}user delete successfull${N0_COLOR}"
	else
		echo "${_res}"
	fi
	return ${_ret}
}

# -n "name of the tools" - show <name> in Info string, e.g: -n jexec, -n "pkg install" ...
# -o uniq_name_of_the_task (one world)
adduser_multi_init()
{
	local _jname

	while getopts "c:n:o:" opt; do
		case "${opt}" in
			c) cmd="${OPTARG}" ;;
			n) _multiple_consumer_name="${OPTARG}" ;;
			o) task_owner="${OPTARG}" ;;
		esac
		shift $(($OPTIND - 1))
	done

	[ -z "${task_owner}" ] && err 1 "${N1_COLOR}multiple_processing_spawn: empty -o multiple_task_owner${N0_COLOR}"

	. ${subrdir}/multiple.subr
	${ECHO} "${N1_COLOR}Hint: Press ${N2_COLOR}'Ctrl+t'${N1_COLOR} to see last logfile line for active task${N0_COLOR}" 1>&2
	task_id=
	task_id_cur=
	task_owner="${task_owner}"
	# spawn command for all jail
	for _jname in ${jail_list}; do
		task_id_cur=$( task mode=new logfile=${tmpdir}/${task_owner}.${_jname}.log.$$ client_id=${_jname} autoflush=0 owner=${task_owner} /usr/bin/env NOCOLOR=1 /usr/local/bin/cbsd adduser jname=${_jname} ${cmd} 2>/dev/null )
		sleep 0.1               # dont brute taskdb
		if ! is_number "${task_id_cur}"; then
			task_id="${task_id} ${task_id_cur}"
		fi
	done

	multiple_task_id_all=$( echo ${task_id} | ${TR_CMD} " " "," )
	sleep 0.5
	multiple_processing_spawn -o ${task_owner} -n "${_multiple_consumer_name}"
}

# MAIN
emulator="jail" # for jname_is_multiple
jail_list=
jname_is_multiple

# MAIN for multiple jails
if [ -n "${jail_list}" ]; then
	# multiple
	if [ -n "${jail_list}" ]; then
		JLIST="${jail_list}"
	fi

	task_owner="adduser_multiple_query"
	_args=

	# trim for jname= in "$*"
	for i in $*; do
		prefix=
		prefix=$( substr --pos=0 --len=6 --str="${i}" )
		[ "${prefix}" = "jname=" ] && continue
		if [ -n "${_args}" ]; then
			_args="${_args} ${i}"
		else
			_args="${i}"
		fi
	done

	case "${mode}" in
		add)
			[ -z "${pw}" -a -z "${epw}" ] && err 1 "${N2_COLOR}pw= ${N1_COLOR}or ${N2_COLOR}epw=${N1_COLOR} is mandatory for multiple operation${N0_COLOR}"
			task_owner="adduser_multiple_add"
			adduser_multi_init -c "${_args}" -o ${task_owner} -n "adduser add"
			;;
		remove)
			[ -z "${login}" ] && err 1 "${N2_COLOR}login= ${N1_COLOR} is mandatory${N0_COLOR}"
			task_owner="adduser_multiple_remove"
			adduser_multi_init -c "${_args}" -o ${task_owner} -n "adduser remove"
			;;
		show)
			[ -z "${login}" ] && err 1 "${N2_COLOR}login= ${N1_COLOR} is mandatory${N0_COLOR}"
			task_owner="adduser_multiple_show"
			adduser_multi_init -c "${_args}" -o ${task_owner} -n "adduser show"
			;;
	esac

	err 0 "${N1_COLOR}Multiple adduser: ${N2_COLOR}done${N0_COLOR}"
fi

[ -n "${jname}" ] && shift # skip for jname


if [ -z "${jname}" ]; then
	data=""
	exec_cmd="/usr/sbin/pw"
else
	# push original jname to temporary variable for extract after fromfile action
	origjname="${jname}"
	. ${subrdir}/rcconf.subr

	[ $? -eq 1 ] &&  err 1 "${N1_COLOR}No such jail: ${N2_COLOR}${jname}${N0_COLOR}"

	[ $baserw -eq 1 ] && path=$data

	if [ ${jid} -eq 0 ]; then
		set -e
		. ${_MYDIR}/bsdconf.subr
		set +e
		. ${subrdir}/universe.subr
		readconf buildworld.conf
		init_target_arch
		init_srcdir
		init_basedir
		init_kerneldir
		prepare_jail
	fi

	if [ "${emulator}" != "jail" -a -n "${emulator}" -a "${emulator}" != "bhyve" ]; then
		. ${subrdir}/emulator.subr
		init_usermode_emul
		CHROOT_EXEC="/usr/sbin/chroot ${path} /bin/${emulator}"
	else
		CHROOT_EXEC="/usr/sbin/chroot ${path}"
	fi

	exec_cmd="${CHROOT_EXEC} /usr/sbin/pw"
	check_jaildir

	if [ $? -eq 1 ]; then
		echo "bad data dir"
		exit 1
	fi
fi


if [ -r "${fromfile}" ]; then
	. ${fromfile}

	if [ -n "${origjname}" ]; then
		# extract after fromfile original jname if exist
		jname="${origjname}"
		. ${subrdir}/rcconf.subr
	fi

	[ $baserw -eq 1 ] && path=$data
	[ -z "${user_add}" ] && exit 0

	for i in ${user_add}; do
		unset login epw pw fullname secgroup group shell res err
		login="${i}"

		f_getvar user_pw_${i} pw
		f_getvar user_pw_${i}_crypt epw
		f_getvar user_gecos_${i} fullname
		f_getvar user_uid_${i} uid
		f_getvar user_gid_${i} gid
		f_getvar user_home_${i} home
		f_getvar user_shell_${i} shell
		f_getvar user_member_groups_${i} secgroup

		case "${mode}" in
			"add")
				res=$( c_adduser )
				ret=$?
				;;
			"remove")
				res=$( remove )
				ret=$?
				;;
			"show")
				res=$( show )
				ret=$?
				;;
		esac
		[ ${ret} -ne 0 ] && ${ECHO} "${res}" && continue
	done
	exit 0
fi

case "${mode}" in
	remove)
		res=$( ${exec_cmd} user show ${login} 2>&1)
		err=$?
		case ${err} in
			0)
				;;
			*)
				err 1 "${N1_COLOR}Error: ${N0_COLOR}${res}"
				;;
		esac
		res=$( remove )
		err=$?
		;;
	add)
		res=$( c_adduser )
		err=$?
		;;
	show)
		[ -z "${login}" ] && err 1 "${N2_COLOR}login= ${N1_COLOR}is mandatory${N0_COLOR}"
		res=$( ${exec_cmd} user show ${login} )
		err=$?
		;;
esac

err ${err} "${res}"
