#!/usr/share/ucs-test/runner bash
# shellcheck shell=bash
## desc: "Creating a shared printer and printing from smbclient and lp with special characters in printer name"
## exposure: dangerous
## packages:
##  - univention-samba | univention-samba4
##  - univention-printserver
## roles:
## - domaincontroller_master
## - domaincontroller_backup
## - domaincontroller_slave
## - memberserver
# shellcheck source=../../lib/user.sh
. "$TESTLIBPATH/user.sh" || exit 137
# shellcheck source=../../lib/random.sh
. "$TESTLIBPATH/random.sh" || exit 137

#create user
echo "----Create user"
SAMBA="true"
MAIL="false"
KERBEROS="true"
PERSON="false"
POSIX="true"

username="$(user_randomname)"
#printername="$(random_chars 5)"'"'"$(random_chars 5)"  # lp fails with " in the name (Permission denied)
printername="$(random_chars 10)"
#sambaprintername="$(random_chars 12)"'" '"$(random_chars 46)"
sambaprintername="$(random_chars 12) $(random_chars 46)"
password=univention

eval "$(ucr shell)"

printsharebasedn="cn=shares,$ldap_base"
printerdn="cn=$printername,$printsharebasedn"

if ! [ -x /bin/nc.openbsd ]; then
	apt-get install -y netcat-openbsd
fi

trap '
user_remove "$username"
rm -rf "/tmp/$printername" "/tmp/$sambaprintername"
udm-test shares/printer remove --dn="$printerdn"
ucr unset directory/manager/web/modules/shares/printer/properties/name/syntax directory/manager/web/modules/shares/printer/properties/sambaName/syntax
wait_for_replication_and_postrun
if [ -n "$nc_pid" ] && [ "$nc_pid" = "$(pgrep -x nc)" ]; then
	kill "$nc_pid" >/dev/null 2>&1
	if [ "$nc_pid" = "$(pgrep -x nc)" ]; then
		echo "netcat PID $nc_pid did not terminate, sending KILL"
		kill -9 "$nc_pid" >/dev/null 2>&1
	fi
fi
' INT TERM EXIT

ucr set directory/manager/web/modules/shares/printer/properties/name/syntax=string directory/manager/web/modules/shares/printer/properties/sambaName/syntax=string
user_create "$username" || fail_fast 1 "Could not create user $username."

#create printer
echo "----create printer"

printercreated="$(udm-test shares/printer create \
	--position "$printsharebasedn" \
	--set "name=$printername" \
	--set "sambaName=$sambaprintername" \
	--set "spoolHost=$hostname.$domainname" \
	--set "uri=socket:// 127.0.0.1:12346" \
	--set "model=None" || fail_fast 1 "Could not create printer")"
echo "$printercreated"
printerdn="$(echo "$printercreated" | grep 'Object created:' | sed 's/Object created: //g')"

wait_for_replication_and_postrun

## look for printer and user
echo "----Testing wether printer share '$sambaprintername' and user '$username' have been created"
i=0
while ! output="$(smbclient "//localhost/$sambaprintername" -U "$username%$password" -c "exit" 2>&1)"
do
        echo '.'
        let i=$i+1
        if [ $i = 20 ]; then
		if echo "$output" | grep NT_STATUS_ACCESS_DENIED; then
			fail_fast 1 "User was not provided 20 seconds after creation"
		else
			fail_fast 1 "Samba did not provide the printer share 20 seconds after creation"
		fi
        fi
        sleep 1
done

#create input file
tmp_filename="$(mktemp)"
echo "----Creating cups input file $tmp_filename"
echo "$(uname -a)" > "$tmp_filename"

#create output socket
nc -l 12346 > "/tmp/$printername" &
nc_pid=$!

## initiate print
echo "initiate print"
i=0
while ! lp -d "$printername" -U "$username" "$tmp_filename"
do
	echo "lp -d \"$printername\" -U \"$username\" \"$tmp_filename\""
	let i=$i+1
	if [ $i = 20 ]; then
		fail_fast 1 "CUPS: Initiate printing has not been successful."
	fi
	sleep 1
done
rm "$tmp_filename"

## check output
echo "check output"
i=0
while ! grep -q "$(uname -a)" "/tmp/$printername"
do
	let i=$i+1
	if [ $i = 20 ]; then
		fail_fast 1 "CUPS: Nothing has been printed to the output file."
	fi
	sleep 1
done

kill "$nc_pid" >/dev/null 2>&1
if [ "$nc_pid" = "$(pgrep -x nc)" ]; then
	echo "netcat PID $nc_pid didn't terminate, sending KILL"
	kill -9 "$nc_pid" >/dev/null 2>&1
fi

# SAME for samba!
tmp_filename="$(mktemp)"
echo "----Creating samba input file $tmp_filename"
echo "$(uname -a)" > "$tmp_filename"

#create output socket
nc -l 12346 > "/tmp/$sambaprintername" &
nc_pid=$!

## initiate print
echo "initiate print"
i=0
## Important: Wait.. Otherwise, if ONE too early attempt fails, then it seems to get cached for about 5 min.
sleep 10
while ! smbclient -U"$username%$password" "//$hostname.$domainname/$sambaprintername" -c "print \"$tmp_filename\""
do
	let i=$i+1
	echo "SAMBA: Initiate printing has not been successful on attempt $i"
	echo "smbclient -U\"$username%$password\" \"//$hostname.$domainname/$sambaprintername\" -c \"print \\\"$tmp_filename\\\"\""
	if [ $i = 3 ]; then
		fail_fast 1 "SAMBA: Initiate printing has not been successful."
	fi
	sleep 300
done
rm "$tmp_filename"

## check output
echo "check output"
i=0
while ! grep -q "$(uname -a)" "/tmp/$sambaprintername"
do
	let i=$i+1
	if [ $i = 20 ]; then
		fail_fast 1 "SAMBA: Nothing has been printed to the output file."
	fi
	sleep 1
done

kill "$nc_pid" >/dev/null 2>&1
if [ "$nc_pid" = "$(pgrep -x nc)" ]; then
	echo "netcat PID $nc_pid didn't terminate, sending KILL"
	kill -9 "$nc_pid" >/dev/null 2>&1
fi

exit $RETVAL
