From: Pavel Filipenský Date: Fri, 3 Sep 2021 17:10:01 +0000 (+0200) Subject: selftest: Add tests for keytab update X-Git-Tag: tdb-1.4.11~25 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=90ec8adf1f2ef8ec25ea67c066fec7f731bbb4dc;p=thirdparty%2Fsamba.git selftest: Add tests for keytab update BUG: https://bugzilla.samba.org/show_bug.cgi?id=6750 Signed-off-by: Pavel Filipenský Reviewed-by: Stefan Metzmacher --- diff --git a/source3/script/tests/test_update_keytab.sh b/source3/script/tests/test_update_keytab.sh new file mode 100755 index 00000000000..2c38b53ccca --- /dev/null +++ b/source3/script/tests/test_update_keytab.sh @@ -0,0 +1,450 @@ +#!/bin/sh + +if [ $# -lt 1 ]; then +cat <{REALM} +keytab3="\ + -1 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM + -2 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM + -3 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM +"; + +# spns=wurst/brot\@$dcvars->{REALM},wurst1/brot\@$dcvars->{REALM},wurst2/brot\@$dcvars->{REALM}:sync_kvno=yes +keytab3k="\ + 5 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM + 5 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM + 5 aes256-cts-hmac-sha1-96 wurst2/brot@ADDOM.SAMBA.EXAMPLE.COM + 3 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM + 3 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM + 3 aes256-cts-hmac-sha1-96 wurst2/brot@ADDOM.SAMBA.EXAMPLE.COM + 4 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM + 4 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM + 4 aes256-cts-hmac-sha1-96 wurst2/brot@ADDOM.SAMBA.EXAMPLE.COM +"; + +# find the biggest vno and store it into global variable vno +get_biggest_vno() +{ + keytab="$1" + cmd="$samba_net ads keytab list $keytab" + eval echo "$cmd" + out=$(eval "$cmd") + ret=$? + + echo "$out" + + if [ $ret != 0 ] ; then + echo "command failed" + return 1 + fi + + #global variable vno + vno=$(echo "$out" | sort -n | tail -1 | awk '{printf $1}') + + if [ -z "$vno" ] ; then + echo "There is no key with vno in the keytab list above." + return 1 + fi + + return 0 +} + +# Heimdal format +# 3 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM +# 3 aes128-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM +# 3 arcfour-hmac-md5 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM + +# MIT format +# 3 AES-256 CTS mode with 96-bit SHA-1 HMAC HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM +# 3 AES-128 CTS mode with 96-bit SHA-1 HMAC HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM +# 3 ArcFour with HMAC/md5 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM + +# The sed command using the pattern $SED1 normalizes both: + +# Heimdal format +# 3 AES-256 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM +# 3 AES-128 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM +# 3 ArcFour HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM + +# MIT format +# 3 AES-256 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM +# 3 AES-128 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM +# 3 ArcFour HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM + + +# Normalize enc types and remove repeating spaces +SED1="\ +s/aes256-cts-hmac-sha1-96/AES-256/;\ +s/aes128-cts-hmac-sha1-96/AES-128/;\ +s/arcfour-hmac-md5/ArcFour/;\ +s/AES-256 CTS mode with 96-bit SHA-1 HMAC/AES-256/;\ +s/AES-128 CTS mode with 96-bit SHA-1 HMAC/AES-128/;\ +s/ArcFour with HMAC\/md5/ArcFour/;\ +s/ \\+/ /g" + +# Remove the first column with Vno +SED2="s/^ \+-\?[0-9]\+ \+//" + +compare_keytabs_sync_kvno() +{ + sed "$SED1" < "$1" | sort -k1rn -k3 | sed "$SED2" > "${1}.sync_kvno" + sed "$SED1" < "$2" | sort -k1rn -k3 | sed "$SED2" > "${2}.sync_kvno" + diff --ignore-case "${1}.sync_kvno" "${2}.sync_kvno" + return $? +} + +compare_keytabs_nosync_kvno() +{ + sed "$SED1" < "$1" | sort -k1rn -k3 > "${1}.nosync_kvno" + sed "$SED1" < "$2" | sort -k1rn -k3 > "${2}.nosync_kvno" + diff --ignore-case "${1}.nosync_kvno" "${2}.nosync_kvno" + return $? +} + +test_pwd_change() +{ + testname="$1" + shift + + # get biggest vno before password change from keytab1k + get_biggest_vno "$PREFIX_ABS/ad_member_idmap_nss/keytab1k" + old_vno=$vno + + if [ ! "$old_vno" -gt 0 ] ; then + echo "There is no key with vno in the keytab list above." + return 1 + fi + + # change password + cmd="$*"; + eval echo "$cmd" + out=$(eval "$cmd") + ret=$? + + if [ $ret != 0 ] ; then + echo "$out" + echo "command failed" + return 1 + fi + + # test ads join + cmd="$samba_net ads testjoin" + eval echo "$cmd" + out=$(eval "$cmd") + ret=$? + + if [ $ret != 0 ] ; then + echo "$out" + echo "command failed" + return 1 + fi + + # if keytab was updated the bigest vno should be incremented by one + get_biggest_vno "$PREFIX_ABS/ad_member_idmap_nss/keytab1k" + + if [ ! "$vno" -eq $((old_vno + 1)) ] ; then + echo "Old vno=$old_vno, new vno=$vno. Increment by one failed." + return 1 + fi + + # Store keytabs in the tmp dir + for keytab in $keytabs_all + do + $samba_net ads keytab list "$PREFIX_ABS/ad_member_idmap_nss/$keytab" | grep -v "^Vno\|^Warning\|^$" > "$TMPDIR/${keytab}_${testname}" + done + + # Compare keytabs that do not sync kvno + for keytab in $keytabs_nosync_kvno + do + if ! compare_keytabs_nosync_kvno "$TMPDIR/${keytab}_template" "$TMPDIR/${keytab}_${testname}" + then + echo "Comparison of $keytab failed" + return 1 + fi + done + + # Compare keytabs that sync kvno + for keytab in $keytabs_sync_kvno + do + if ! compare_keytabs_sync_kvno "$TMPDIR/${keytab}_template" "$TMPDIR/${keytab}_${testname}" + then + echo "Comparison of $keytab failed" + return 1 + fi + done + + return 0 +} + + +# Create tmp dir +TMPDIR=$(mktemp -d "$PREFIX_ABS/ad_member_idmap_nss/keytab_dir_XXXXXX") + +# Create template files using the variables defined above +printf '%s' "$keytab0" > "$TMPDIR/keytab0_template" +printf '%s' "$keytab0k" > "$TMPDIR/keytab0k_template" +printf '%s' "$keytab1" > "$TMPDIR/keytab1_template" +printf '%s' "$keytab1k" > "$TMPDIR/keytab1k_template" +printf '%s' "$keytab2" > "$TMPDIR/keytab2_template" +printf '%s' "$keytab2k" > "$TMPDIR/keytab2k_template" +printf '%s' "$keytab3" > "$TMPDIR/keytab3_template" +printf '%s' "$keytab3k" > "$TMPDIR/keytab3k_template" + +# Other approach could e.g. compare first six entries from the template. +# The 6 entries correspond to password and old_password, each has 3 enc. types. +# for k in "$TMPDIR"/keytab*_template +# do +# head -6 "$k" > "${k}_head6" +# done + +# Remove all keytabs +for keytab in $keytabs_all +do + rm -f "$PREFIX_ABS/ad_member_idmap_nss/$keytab" +done + +DC_DNSNAME="${DC_SERVER}.${REALM}" +SMBCLIENT_UNC="//${DC_DNSNAME}/tmp" + +# To have both old and older password we do one unnecessary password change: +testit "wbinfo_change_secret_initial" \ + "$samba_wbinfo" --change-secret --domain="${DOMAIN}" \ + || failed=$((failed + 1)) + +testit "wbinfo_check_secret_initial" \ + "$samba_wbinfo" --check-secret --domain="${DOMAIN}" \ + || failed=$((failed + 1)) + +# Create/sync all keytabs +testit "net_ads_keytab_sync" "$samba_net" ads keytab create || failed=$((failed + 1)) + +testit "wbinfo_change_secret" \ + test_pwd_change "wbinfo_changesecret" \ + "$samba_wbinfo --change-secret --domain=${DOMAIN}" \ + || failed=$((failed + 1)) + +testit "wbinfo_check_secret" \ + "$samba_wbinfo" --check-secret --domain="${DOMAIN}" \ + || failed=$((failed + 1)) + +test_smbclient "Test machine login with the changed secret" \ + "ls" "${SMBCLIENT_UNC}" \ + --machine-pass || + failed=$((failed + 1)) + + +testit "rpcclient_changetrustpw" test_pwd_change "rpcclient_changetrustpw" "$samba_rpcclient --machine-pass ncacn_np:${DC_DNSNAME}[schannel] -c change_trust_pw" || failed=$((failed + 1)) +testit "net_rpc_changetrustpw" test_pwd_change "net_rpc_changetrustpw" "$samba_net rpc changetrustpw -I ${DC_DNSNAME}" || failed=$((failed + 1)) +testit "net_ads_changetrustpw" test_pwd_change "net_ads_changetrustpw" "$samba_net ads changetrustpw -I ${DC_DNSNAME}" || failed=$((failed + 1)) + +test_smbclient "Test machine login with the changed secret end" \ + "ls" "${SMBCLIENT_UNC}" \ + --machine-pass || + failed=$((failed + 1)) + +# Delete tmp dir +rm -rf "$TMPDIR" + +testok "$0" "$failed" diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 772dfa8672f..2474b36325f 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -670,6 +670,15 @@ for env in ["nt4_member", "ad_member"]: plantestsuite("samba3.blackbox.net_cred_change", "%s:local" % env, [os.path.join(samba3srcdir, "script/tests/test_net_cred_change.sh"), configuration]) plantestsuite("samba3.blackbox.net_cred_change_at", "ad_member_s3_join:local", [os.path.join(samba3srcdir, "script/tests/test_net_cred_change_at.sh"), configuration, '$DC_SERVER']) +plantestsuite( + "samba3.blackbox.update_keytab", + "ad_member_idmap_nss:local", + [ + os.path.join(samba3srcdir, "script/tests/test_update_keytab.sh"), + "$DOMAIN", + configuration, + ], +) env = "ad_member" t = "--krb5auth=$DOMAIN/$DC_USERNAME%$DC_PASSWORD"