#!/usr/share/ucs-test/runner bash
# shellcheck shell=bash
## desc: "Testing the sysvol replication"
## exposure: careful
## packages:
##  - univention-samba4
## roles:
## - domaincontroller_master
## - domaincontroller_backup
## - domaincontroller_slave
## tags:
##  - SKIP-UCSSCHOOL
##  - basic
##  - apptest

# shellcheck source=../../lib/base.sh
. "$TESTLIBPATH/base.sh" || exit 137
# shellcheck source=../../lib/undo.sh
. "$TESTLIBPATH/undo.sh" || exit 137
# shellcheck source=../../lib/shares.sh
. "$TESTLIBPATH/shares.sh" || exit 137
# shellcheck source=../../lib/random.sh
. "$TESTLIBPATH/random.sh" || exit 137
. /usr/share/univention-lib/ldap.sh || exit 137

set -x

check_domainadmin_credentials || fail_fast 77 "UCR variables for admin credentials are not set"
admin_account="$(ucs_convertDN2UID "$tests_domainadmin_account")"

determine_neighbour_s4host() {
	mapfile -t s4hosts < <(univention-ldapsearch -LLL "(univentionService=Samba 4)" cn | VAL cn)
	for candidate in "${s4hosts[@]}"
	do
		[ "$candidate" = "$hostname" ] &&
			continue
		# ignore hosts without a DNS service principal account, they are RODC's
		# TODO Is there a better way to check for RODC's?
		id "dns-$candidate" >/dev/null ||
			continue
		ping -c 1 "$candidate.$domainname" >/dev/null ||
			continue
		echo "$candidate.$domainname"
		return 0
	done
	return 1
}

s4host_fqdn=$(determine_neighbour_s4host) ||
	fail_fast 134 "Skipping test: Could not find another Samba4 Service in Domain"

gponame=$(random_chars 8 "${_upperletters}${_lowerletters}${_ciphers}")	## samba RC6 seems to dislike UTF-8 in GPO names

## general sanity check: wait for the samba-share.py Listener to synchronize /etc/samba/shares.conf and /etc/samba/shares.conf.d (Bug #29399)
retry_delay=2 retry 15 samba-tool domain info 127.0.0.1 >/dev/null 2>&1 ||
	echo "samba-tool Failure (Bug #29399)" >&2

sysvol_path="/var/lib/samba/sysvol"
sysvol_domain_path="$sysvol_path/$domainname"
policies_path="$sysvol_domain_path/Policies"

# Bug #49686: use ip address instead of hostname for samba-tool gpo
s4host_ipaddr=$(dig +short "$s4host_fqdn")

echo "## create an fACL-free file in sysvol on remote DC $s4host_fqdn"
remote_temp_filename=$(univention-ssh "$tests_domainadmin_pwdfile" "$admin_account"@"$s4host_fqdn" mktemp --tmpdir="$sysvol_path")
univention-ssh "$tests_domainadmin_pwdfile" "$admin_account"@"$s4host_fqdn" "setfacl -b '$remote_temp_filename'; chmod 644 '$remote_temp_filename'"


undo univention-ssh "$tests_domainadmin_pwdfile" "$admin_account"@"$s4host_fqdn" rm "$remote_temp_filename"

## create the GPO
echo "## create the GPO '$gponame' on remote DC $s4host_fqdn"
gpo_cn=$(samba-tool gpo create "$gponame" -H ldap://"$s4host_ipaddr" -U"$admin_account%$tests_domainadmin_pwd" | sed -n "s/GPO '$gponame' created as //p")
[ -n "$gpo_cn" ] ||
	fail_fast 1 "WARNING: samba-tool gpo create did not return a GPO cn"

echo "## GPO was created on $s4host_fqdn with ID $gpo_cn"
undo samba-tool gpo del "$gpo_cn" -H ldap://"$s4host_ipaddr" -U"$admin_account%$tests_domainadmin_pwd"

gpo_path="$policies_path/$gpo_cn"

## Tests on remote DC
echo "## check whether the directory has been created on remote DC $s4host_fqdn"
retry 20 univention-ssh "$tests_domainadmin_pwdfile" "$admin_account"@"$s4host_fqdn" test -d "$gpo_path" >/dev/null ||
	fail_fast 1 "remote directory for GPO has not been created"

##check whether samba-tool lists the GPO the remote DC
echo "## check whether samba-tool lists the GPO on remote DC $s4host_fqdn"
check_gpo_remote () { output=$(samba-tool gpo show "$gpo_cn" -H ldap://"$s4host_ipaddr" -U"$admin_account%$tests_domainadmin_pwd" 2>&1) && grep -Eq "^GPO\s+:\s$gpo_cn" <<<"$output"; }
retry 10 check_gpo_remote ||
	fail_fast 1 "remote GPO is not listed in samba-tool: $output"

max_i=201
sleep_time=3
echo "## check whether the directory for the GPO has been replicated to the local system (waiting about $((max_i * sleep_time)) seconds)"
echo "## Note: to speed things up for interactive tests, you may run /usr/share/univention-samba4/scripts/sysvol-sync.sh manually now."
echo -n "Waiting for cron based sysvol-sync"
retry_delay="$sleep_time" retry "$max_i" [ -d "$gpo_path" ] ||
	fail_fast 1 "Directory for GPO has not been created after $((retry_i * sleep_time)) seconds"
echo "GPO sysvol replication took $((retry_i * sleep_time)) seconds."

[ -f "$remote_temp_filename" ] ||
	fail_fast 1 "fACL-free file $remote_temp_filename not replicated."

rm "$remote_temp_filename"

echo "## check GPO permissions"
mode=$(stat -c "%a" "$gpo_path")
[ "$mode" = 770 ] ||
	fail_fast 1 "GPO has wrong permission mode: $mode, expected 770"

echo "## check whether the GPO is listed in samba-tool"
check_gpo () { output=$(samba-tool gpo show "$gpo_cn" 2>&1) && grep -Eq "^GPO\s+:\s$gpo_cn" <<<"$output"; }
retry 10 check_gpo ||
	fail_fast 1 "GPO is not listed in samba-tool: ${output:-}"

exit "$RETVAL"
