#!/usr/share/ucs-test/runner bash
# shellcheck shell=bash
## desc: Test faillog via ssh, smb, krb
## roles: [domaincontroller_master]
## tags: [basic, univention, skip_admember]
## packages:
##  - univention-directory-manager-tools
##  - openssh-server
##  - smbclient
##  - heimdal-clients
##  - univention-samba | univention-samba4
## exposure: dangerous
## versions:
##  1.0-0: skip
##  2.4-0: fixed
##  3.2-0: skip

# shellcheck source=../../lib/ucr.sh
. "$TESTLIBPATH/ucr.sh" || exit 137
# shellcheck source=../../lib/user.sh
. "$TESTLIBPATH/user.sh" || exit 137
# shellcheck source=../../lib/base.sh
. "$TESTLIBPATH/base.sh" || exit 137

RETVAL=100
NAME=$(user_randomname)

ucr set \
	auth/faillog=yes \
	auth/faillog/lock_global=yes \
	auth/faillog/limit=6 \
	sshd/challengeresponse=yes \
	sshd/passwordauthentication=no

invoke-rc.d ssh restart

tdir=$(mktemp -d)
trap "rm -rf '$tdir' ; udm mail/domain remove --dn 'cn=$domainname,$ldap_base' ; user_remove '$NAME' ; ucr_restore ; invoke-rc.d ssh restart" EXIT
fake_passwd="$tdir/fake_passwd"
echo "foobar1234" >"$fake_passwd"

ssh_login () {
	univention-ssh -timeout 10 "$1" -o NumberOfPasswordPrompts=3 "$NAME@$hostname.$domainname" /usr/sbin/ucr get hostname
}

smb_login () {
	smbclient -g -L "$hostname" -U "${NAME}%$(<$1)"
}

krb_login () {
	kinit --password-file="${1}" "$NAME"
	local rc=$?
	kdestroy
	return $rc
}

udm mail/domain create --set name="$domainname"
user_create "$NAME" \
	--set password="$(<$tests_domainadmin_pwdfile)" \
	--set primaryGroup="$(get_domain_admins_dn)"

attempts=10
i=0
while ((i < attempts)) && ! /usr/lib/univention-pam/ldap-group-to-file.py; do
	((i+=1))
	sleep 1
done
if ((i==attempts)); then
	warning "ldap-group-to-file.py failed $i times"
fi

ssh_hostname="$(ssh_login "$tests_domainadmin_pwdfile")"
if [ "$ssh_hostname" != "$hostname" ]
then
	fail_test 110 "ssh login wasn't successful"
fi
if ! smb_login "$tests_domainadmin_pwdfile" | grep -q "^Disk|$NAME|"
then
	fail_test 110 "smb login wasn't successful"
fi
if ! krb_login "$tests_domainadmin_pwdfile"
then
	fail_test 110 "krb login wasn't successful"
fi

info "Lock all after tally"
ssh_login "$fake_passwd" # 3
ssh_login "$fake_passwd" # 6
ssh_hostname="$(ssh_login "$tests_domainadmin_pwdfile")"
if [ "$ssh_hostname" = "$hostname" ]
then
	fail_test 110 "ssh login was successful, but the user should be locked"
fi
if ! smb_login "$tests_domainadmin_pwdfile" | grep -q NT_STATUS_ACCOUNT_LOCKED_OUT
then
	fail_test 110 "smb login was successful, but the user should be locked"
fi
if krb_login "$tests_domainadmin_pwdfile"
then
	fail_test 110 "krb login was successful, but the user should be locked"
fi

info "Lock all"
python3 -m univention.lib.account lock --dn "$(user_dn "$NAME")" --lock-time "$(date --utc '+%Y%m%d%H%M%SZ')" || fail_test 110 "Could not manually lock user account!"
ssh_hostname="$(ssh_login "$tests_domainadmin_pwdfile")"
if [ "$ssh_hostname" = "$hostname" ]
then
	fail_test 110 "ssh login was successful, but the user should be locked"
fi
if ! smb_login "$tests_domainadmin_pwdfile" | grep -q NT_STATUS_ACCOUNT_LOCKED_OUT
then
	fail_test 110 "smb login was successful, but the user should be locked"
fi
if krb_login "$tests_domainadmin_pwdfile"
then
	fail_test 110 "krb login was successful, but the user should be locked"
fi

exit $RETVAL
# vim: set filetype=sh ts=4 :
