#!/usr/share/ucs-test/runner bash
# shellcheck shell=bash
## desc: "Change password vi s4 and verify shadowMax, shadowLastChange (posix pw expiry) and krb5PasswordEnd"
## exposure: dangerous
## packages:
##  - univention-samba4
##  - univention-s4-connector
## roles:
## - domaincontroller_master
## - domaincontroller_backup
## - domaincontroller_slave
## bugs:
##  - 36317

# shellcheck source=../../lib/base.sh
. "$TESTLIBPATH/base.sh" || exit 137
# shellcheck source=../../lib/udm.sh
. "$TESTLIBPATH/udm.sh" || exit 137
# shellcheck source=../../lib/random.sh
. "$TESTLIBPATH/random.sh" || exit 137
. "s4connector.sh" || exit 137

RETVAL=100

test -n "$connector_s4_ldap_host" || exit 137
connector_running_on_this_host || exit 137

function ad_change_password ()
{
	local uid="$1"
	local old="$2"
	local new="$3"

	samba-tool user password -U "$uid" --password "$old" --newpassword="$new"
	return $?
}

SYNCMODE="$(ad_get_sync_mode)"
HOST="$(ucr get connector/s4/ldap/host)"
EXPIRY_INTERVAL=99

ad_set_sync_mode "sync"

####################################################
# check shadowLastChange=now and shadowMax=x, krb5PasswordEnd=x
section "Test S4 password change with expiry policy"
####################################################

UDM_policies_pwhistory_name="$(random_chars)"
UDM_policies_pwhistory_expiryInterval=$EXPIRY_INTERVAL
udm_create "policies/pwhistory" || fail_test 110
policy_dn="cn=$UDM_policies_pwhistory_name,cn=pwhistory,cn=users,cn=policies,$ldap_base"
UDM_users_user_username="$(random_chars)"
UDM_users_user_lastname="$(random_chars)"
UDM_users_user_password="univention"
UDM_users_user_firstname="$(random_chars)"
udm_create "users/user" || fail_test 110
user_dn="uid=$UDM_users_user_username,cn=users,$ldap_base"
udm_modify "users/user" "" "" "" "" --policy-reference="$policy_dn" || fail_test 110
ad_wait_for_synchronization; fail_bool 0 110
ad_change_password "$UDM_users_user_username" "univention" "123-abc-ABC-?" || fail_test 110
ad_wait_for_synchronization; fail_bool 0 110
smbclient //"${HOST}"/sysvol -c ls -U "${UDM_users_user_username}%123-abc-ABC-?" ; fail_bool 0 100
expected_shadowMax="$((EXPIRY_INTERVAL - 1))"
expected_krb5PasswordEnd=$(date +"%Y%m%d000000Z" --date="@$(( $(date -u +"%s") + ($EXPIRY_INTERVAL * 24 * 3600)))")
expected_shadowLastChange="$(( $(date +"%s") / 3600 / 24 ))"
udm_verify_ldap_attribute "shadowLastChange" "$expected_shadowLastChange" "users/user" || fail_test 110
udm_verify_ldap_attribute "shadowMax" "$expected_shadowMax" "users/user" || fail_test 110
udm_verify_ldap_attribute "krb5PasswordEnd" "$expected_krb5PasswordEnd" "users/user" || fail_test 110
univention-ldapsearch uid="$UDM_users_user_username"

#######################################################
# check shadowLastChange=now and no shadowMax, krb5PasswordEnd
section "Test S4 password change without expiry policy"
#######################################################

udm_modify "users/user" "" "" "" "" --policy-dereference="$policy_dn" || fail_test 110
ad_wait_for_synchronization; fail_bool 0 110
ad_change_password "$UDM_users_user_username" "123-abc-ABC-?" "Univention.99" || fail_test 110
ad_wait_for_synchronization; fail_bool 0 110
smbclient //"${HOST}"/sysvol -c ls -U "${UDM_users_user_username}%Univention.99" ; fail_bool 0 100
eval "$(univention-policy-result -y /etc/machine.secret -D "$(ucr get ldap/hostdn)" -s "$user_dn")"
expected_shadowMax=""
expected_krb5PasswordEnd=""
expected_shadowLastChange="$(( $(date +"%s") / 3600 / 24 ))"
if [ -n "$univentionPWExpiryInterval" ]; then
	expected_shadowMax="$univentionPWExpiryInterval"
	expected_krb5PasswordEnd=$(date +"%Y%m%d000000Z" --date="@$(( $(date -u +"%s") + ($univentionPWExpiryInterval * 24 * 3600)))")
fi
udm_verify_ldap_attribute "shadowLastChange" "$expected_shadowLastChange" "users/user" || fail_test 110
udm_verify_ldap_attribute "shadowMax" "$expected_shadowMax" "users/user" || fail_test 110
udm_verify_ldap_attribute "krb5PasswordEnd" "$expected_krb5PasswordEnd" "users/user" || fail_test 110
univention-ldapsearch uid="$UDM_users_user_username"

##################
section "Clean up"
##################

udm_remove "users/user" || fail_test 110
udm_remove "policies/pwhistory" || fail_test 110
ad_wait_for_synchronization; fail_bool 0 110
udm_exists "users/user"; fail_bool 1 110
udm_exists "policies/pwhistory"; fail_bool 1 110
ad_set_sync_mode "$SYNCMODE"

exit "$RETVAL"
