Blame SOURCES/Move-some-dejagnu-kadmin-tests-to-Python-tests.patch

a53771
From d467303bd7c5dba858b0af30349ce796cebd193f Mon Sep 17 00:00:00 2001
a53771
From: Greg Hudson <ghudson@mit.edu>
a53771
Date: Thu, 22 Apr 2021 15:51:36 -0400
a53771
Subject: [PATCH] Move some dejagnu kadmin tests to Python tests
a53771
a53771
Remove the dejagnu scripts kadmin.exp, pwchange.exp, and pwhist.exp.
a53771
a53771
Add a new Python test script t_kadmin.py for the miscellaneous kadmin
a53771
tests from kadmin.exp.
a53771
a53771
In t_changepw.py, use modprinc +needchange for one of the kinit
a53771
password change tests to gain the same coverage as pwchange.exp had,
a53771
and add the "password changes are usable by kinit" tests from
a53771
kadmin.exp.
a53771
a53771
In t_policy.py, add the ticket 929 regression tests from kadmin.exp
a53771
and the ticket 2841 regression tests from pwhist.exp.
a53771
a53771
(cherry picked from commit 8027531caf6911bb07bf13de087da0e6bef5a348)
a53771
(cherry picked from commit 9b3d8b9c395bf1a889ea6d6439dc3543c680480d)
a53771
---
a53771
 src/tests/Makefile.in                         |    1 +
a53771
 src/tests/dejagnu/krb-standalone/kadmin.exp   | 1133 -----------------
a53771
 src/tests/dejagnu/krb-standalone/pwchange.exp |  145 ---
a53771
 src/tests/dejagnu/krb-standalone/pwhist.exp   |  217 ----
a53771
 src/tests/t_changepw.py                       |   34 +-
a53771
 src/tests/t_kadmin.py                         |   54 +
a53771
 src/tests/t_policy.py                         |   62 +
a53771
 7 files changed, 143 insertions(+), 1503 deletions(-)
a53771
 delete mode 100644 src/tests/dejagnu/krb-standalone/kadmin.exp
a53771
 delete mode 100644 src/tests/dejagnu/krb-standalone/pwchange.exp
a53771
 delete mode 100644 src/tests/dejagnu/krb-standalone/pwhist.exp
a53771
 create mode 100644 src/tests/t_kadmin.py
a53771
a53771
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
a53771
index 6b7749129..ab416cc5f 100644
a53771
--- a/src/tests/Makefile.in
a53771
+++ b/src/tests/Makefile.in
a53771
@@ -147,6 +147,7 @@ check-pytests: unlockiter s4u2self
a53771
 	$(RUNPYTEST) $(srcdir)/t_referral.py $(PYTESTFLAGS)
a53771
 	$(RUNPYTEST) $(srcdir)/t_skew.py $(PYTESTFLAGS)
a53771
 	$(RUNPYTEST) $(srcdir)/t_keytab.py $(PYTESTFLAGS)
a53771
+	$(RUNPYTEST) $(srcdir)/t_kadmin.py $(PYTESTFLAGS)
a53771
 	$(RUNPYTEST) $(srcdir)/t_kadmin_acl.py $(PYTESTFLAGS)
a53771
 	$(RUNPYTEST) $(srcdir)/t_kadmin_parsing.py $(PYTESTFLAGS)
a53771
 	$(RUNPYTEST) $(srcdir)/t_kdb.py $(PYTESTFLAGS)
a53771
diff --git a/src/tests/dejagnu/krb-standalone/kadmin.exp b/src/tests/dejagnu/krb-standalone/kadmin.exp
a53771
deleted file mode 100644
a53771
index fa50a61fb..000000000
a53771
--- a/src/tests/dejagnu/krb-standalone/kadmin.exp
a53771
+++ /dev/null
a53771
@@ -1,1133 +0,0 @@
a53771
-# Kerberos kadmin test.
a53771
-# This is a DejaGnu test script.
a53771
-# This script tests Kerberos kadmin5 using kadmin.local as verification.
a53771
-
a53771
-#++
a53771
-# kadmin_add	- Test add new v5 principal function of kadmin.
a53771
-#
a53771
-# Adds principal $pname with password $password.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_add { pname password } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KADMIN_LOCAL
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-    global tmppwd
a53771
-
a53771
-    set good 0
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "ank $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin add $pname lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin add $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin add $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*:" {
a53771
-	send "adminpass$KEY\r"
a53771
-    }
a53771
-    expect "Enter password for principal \"$pname@$REALMNAME\":" { send "$password\r" }
a53771
-    expect "Re-enter password for principal \"$pname@$REALMNAME\":" { send "$password\r" }
a53771
-    expect "Principal \"$pname@$REALMNAME\" created." { set good 1 }
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin add)"
a53771
-    catch "close -i $spawn_id"
a53771
-    if { $good == 1 } {
a53771
-	#
a53771
-	# use kadmin.local to verify that a principal was created and that its
a53771
-	# salt types are 0 (normal).
a53771
-	#
a53771
-	envstack_push
a53771
-	setup_kerberos_env kdc
a53771
-	spawn $KADMIN_LOCAL -r $REALMNAME
a53771
-	envstack_pop
a53771
-	expect_after {
a53771
-	    -i $spawn_id
a53771
-	    timeout {
a53771
-		fail "kadmin add $pname"
a53771
-		catch "expect_after"
a53771
-		return 0
a53771
-	    }
a53771
-	    eof {
a53771
-		fail "kadmin add $pname"
a53771
-		catch "expect_after"
a53771
-		return 0
a53771
-	    }
a53771
-	}
a53771
-	set good 0
a53771
-	expect "kadmin.local: " { send "getprinc $pname\r" }
a53771
-	expect "Principal: $pname@$REALMNAME" { set good 1 }
a53771
-	expect "Expiration date:" { verbose "got expiration date" }
a53771
-	expect "Last password change:" { verbose "got last pwchange" }
a53771
-	expect "Password expiration date:" { verbose "got pwexpire date" }
a53771
-	expect "Maximum ticket life:" { verbose "got max life" }
a53771
-	expect "Maximum renewable life:" { verbose "got max rlife" }
a53771
-	expect "Last modified:" { verbose "got last modified" }
a53771
-	expect "Last successful authentication:" { verbose "last succ auth" }
a53771
-	expect "Last failed authentication:" { verbose "last pw failed" }
a53771
-	expect "Failed password attempts:" { verbose "num failed attempts" }
a53771
-	expect "Number of keys:" { verbose "num keys"} 
a53771
-	expect {
a53771
-		"Key: " { verbose "Key listed" 
a53771
-			exp_continue
a53771
-		}
a53771
-		"Attributes:" { verbose "attributes" }
a53771
-	}
a53771
-	expect "kadmin.local: " { send "q\r" }
a53771
-
a53771
-	expect_after
a53771
-	expect eof
a53771
-	set k_stat [wait -i $spawn_id]
a53771
-	verbose "wait -i $spawn_id returned $k_stat (kadmin.local show)"
a53771
-	catch "close -i $spawn_id"
a53771
-	if { $good == 1 } {
a53771
-	    pass "kadmin add $pname"
a53771
-	    return 1
a53771
-	}
a53771
-	else {
a53771
-	    fail "kadmin add $pname"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    else {
a53771
-	fail "kadmin add $pname"
a53771
-	return 0
a53771
-    }
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_add_rnd	- Test add new v5 principal with random key function.
a53771
-#
a53771
-# Adds principal $pname with random key.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_add_rnd { pname { flags "" } } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KADMIN_LOCAL
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-    global tmppwd
a53771
-
a53771
-    set good 0
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "ank -randkey $flags $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin add rnd $pname lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin add_rnd $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin add_rnd $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *" {
a53771
-	send "adminpass$KEY\r"
a53771
-    }
a53771
-    expect "Principal \"$pname@$REALMNAME\" created." { set good 1 }
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin add_rnd)"
a53771
-    catch "close -i $spawn_id"
a53771
-    if { $good == 1 } {
a53771
-	#
a53771
-	# use kadmin.local to verify that a principal was created and that its
a53771
-	# salt types are 0 (normal).
a53771
-	#
a53771
-	envstack_push
a53771
-	setup_kerberos_env kdc
a53771
-	spawn $KADMIN_LOCAL -r $REALMNAME
a53771
-	envstack_pop
a53771
-	expect_after {
a53771
-	     -i $spawn_id
a53771
-	    timeout {
a53771
-		fail "kadmin add_rnd $pname"
a53771
-		catch "expect_after"
a53771
-		return 0
a53771
-	    }
a53771
-	    eof {
a53771
-		fail "kadmin add_rnd $pname"
a53771
-		catch "expect_after"
a53771
-		return 0
a53771
-	    }
a53771
-	}
a53771
-	set good 0
a53771
-	expect "kadmin.local:" { send "getprinc $pname\r" }
a53771
-	expect "Principal: $pname@$REALMNAME" { set good 1 }
a53771
-	expect "kadmin.local:" { send "q\r" }
a53771
-	expect_after
a53771
-	expect eof
a53771
-	set k_stat [wait -i $spawn_id]
a53771
-	verbose "wait -i $spawn_id returned $k_stat (kadmin.local show)"
a53771
-	catch "close -i $spawn_id"
a53771
-	if { $good == 1 } {
a53771
-	    pass "kadmin add_rnd $pname"
a53771
-	    return 1
a53771
-	}
a53771
-	else {
a53771
-	    fail "kadmin add_rnd $pname"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    else {
a53771
-	fail "kadmin add_rnd $pname"
a53771
-	return 0
a53771
-    }
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_show	- Test show principal function of kadmin.
a53771
-# 
a53771
-# Retrieves entry for $pname.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_show { pname } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "get_principal $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin show $pname lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin show $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin show $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *"
a53771
-    send "adminpass$KEY\r"
a53771
-    expect -re "\r.*Principal: $pname@$REALMNAME.*Key: .*Attributes:.*Policy: .*\r"
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin show)"
a53771
-    catch "close -i $spawn_id"
a53771
-    pass "kadmin show $pname"
a53771
-    return 1
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_cpw	- Test change password function of kadmin
a53771
-#
a53771
-# Change password of $pname to $password.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_cpw { pname password } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "cpw $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin cpw $pname lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin cpw $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin cpw $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *" {
a53771
-	send "adminpass$KEY\r"
a53771
-    }
a53771
-
a53771
-    expect "Enter password for principal \"$pname@$REALMNAME\":" { send "$password\r" }
a53771
-    expect "Re-enter password for principal \"$pname@$REALMNAME\":" { send "$password\r" }
a53771
-    # When in doubt, jam one of these in there.
a53771
-    expect "\r"
a53771
-    expect "Password for \"$pname@$REALMNAME\" changed."
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin cpw)"
a53771
-    catch "close -i $spawn_id"
a53771
-    pass "kadmin cpw $pname"
a53771
-    return 1
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_cpw_rnd	- Test change random key function of kadmin.
a53771
-#
a53771
-# Changes principal $pname's key to a new random key.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_cpw_rnd { pname } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "cpw -randkey $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin cpw_rnd $pname lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin cpw_rnd $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin cpw_rnd $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *" {
a53771
-	send "adminpass$KEY\r"
a53771
-    }
a53771
-    # When in doubt, jam one of these in there.
a53771
-    expect "\r"
a53771
-    expect "Key for \"$pname@$REALMNAME\" randomized."
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin cpw_rnd)"
a53771
-    catch "close -i $spawn_id"
a53771
-    pass "kadmin cpw_rnd $pname"
a53771
-    return 1
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_modify	- Test modify principal function of kadmin.
a53771
-#
a53771
-# Modifies principal $pname with flags $flags.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_modify { pname flags } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "modprinc $flags $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin modify $pname ($flags) lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin modify $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin modify $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *"
a53771
-    send "adminpass$KEY\r"
a53771
-    # When in doubt, jam one of these in there.
a53771
-    expect "\r"
a53771
-    expect "Principal \"$pname@$REALMNAME\" modified."
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin modify)"
a53771
-    catch "close -i $spawn_id"
a53771
-    pass "kadmin modify $pname"
a53771
-    return 1
a53771
-}
a53771
-
a53771
-
a53771
-#++
a53771
-# kadmin_list	- Test list database function of kadmin.
a53771
-#
a53771
-# Lists the database and verifies that output matches regular expression
a53771
-# "(.*@$REALMNAME)*".  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_list {  } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-
a53771
-    # "*" would match everything
a53771
-    # "*n" should match a few like kadmin/admin but see ticket 5667
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "get_principals *n"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin ldb lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	"Communication failure" {
a53771
-	    fail "kadmin ldb got RPC error"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin ldb"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin ldb"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *" {
a53771
-	send "adminpass$KEY\r"
a53771
-    }
a53771
-    expect -re "\(.*@$REALMNAME\r\n\)+"
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin list)"
a53771
-    catch "close -i $spawn_id"
a53771
-    pass "kadmin ldb"
a53771
-    return 1
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_extract	- Test extract service key function of kadmin.
a53771
-#
a53771
-# Extracts service key for service name $name instance $instance.  Returns
a53771
-# 1 on success.
a53771
-#--
a53771
-proc kadmin_extract { instance name } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-    global tmppwd
a53771
-
a53771
-    catch "exec rm -f $tmppwd/keytab"
a53771
-
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "xst -k $tmppwd/keytab $name/$instance"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin xst $instance $name lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin xst $instance $name"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin xst $instance $name"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *" {
a53771
-	send "adminpass$KEY\r"
a53771
-    }
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin xst)"
a53771
-    catch "close -i $spawn_id"
a53771
-    catch "exec rm -f $instance-new-keytab"
a53771
-    pass "kadmin xst $instance $name"
a53771
-    return 1
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_delete	- Test delete principal function of kadmin.
a53771
-#
a53771
-# Deletes principal $pname.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_delete { pname } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KADMIN_LOCAL
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-    global tmppwd
a53771
-
a53771
-    set good 0
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "delprinc -force $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin_delete $pname lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin delprinc $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin delprinc $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *" {
a53771
-	send "adminpass$KEY\r"
a53771
-    }
a53771
-    expect "Principal \"$pname@$REALMNAME\" deleted." { set good 1 }
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin delprinc)"
a53771
-    catch "close -i $spawn_id"
a53771
-    if { $good == 1 } {
a53771
-	#
a53771
-	# use kadmin.local to verify that the old principal is not present.
a53771
-	#
a53771
-	envstack_push
a53771
-	setup_kerberos_env kdc
a53771
-	spawn $KADMIN_LOCAL -r $REALMNAME
a53771
-	envstack_pop
a53771
-	expect_after {
a53771
-	    -i $spawn_id
a53771
-	    timeout {
a53771
-		fail "kadmin delprinc $pname"
a53771
-		catch "expect_after"
a53771
-		return 0
a53771
-	    }
a53771
-	    eof {
a53771
-		fail "kadmin delprinc $pname"
a53771
-		catch "expect_after"
a53771
-		return 0
a53771
-	    }
a53771
-	}
a53771
-	set good 0
a53771
-	expect "kadmin.local: " { send "getprinc $pname\r" }
a53771
-	expect "Principal does not exist while retrieving \"$pname@$REALMNAME\"." { set good 1 }
a53771
-	expect "kadmin.local: " { send "quit\r" }
a53771
-	expect_after
a53771
-	expect eof
a53771
-	set k_stat [wait -i $spawn_id]
a53771
-	verbose "wait -i $spawn_id returned $k_stat (kadmin.local show)"
a53771
-	catch "close -i $spawn_id"
a53771
-	if { $good == 1 } {
a53771
-	    pass "kadmin delprinc $pname"
a53771
-	    return 1
a53771
-	}
a53771
-	else {
a53771
-	    fail "kadmin delprinc $pname"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    else {
a53771
-	fail "kadmin delprinc $pname"
a53771
-	return 0
a53771
-    }
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_delete	- Test delete principal function of kadmin.
a53771
-#
a53771
-# Deletes principal $pname.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_delete_locked_down { pname } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KADMIN_LOCAL
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-    global tmppwd
a53771
-
a53771
-    #
a53771
-    # First test that we fail, then unlock and retry
a53771
-    #
a53771
-
a53771
-    set good 0
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "delprinc -force $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin_delete $pname lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin delprinc $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin delprinc $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *" {
a53771
-	send "adminpass$KEY\r"
a53771
-    }
a53771
-    expect "delete_principal: Operation requires ``delete'' privilege while deleting principal \"$pname@$REALMNAME\"" { set good 1 }
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin delprinc)"
a53771
-    catch "close -i $spawn_id"
a53771
-    if { $good == 1 } {
a53771
-	#
a53771
-	# use kadmin.local to remove lockdown.
a53771
-	#
a53771
-	envstack_push
a53771
-	setup_kerberos_env kdc
a53771
-	spawn $KADMIN_LOCAL -r $REALMNAME
a53771
-	envstack_pop
a53771
-	expect_after {
a53771
-	    -i $spawn_id
a53771
-	    timeout {
a53771
-		fail "kadmin delprinc $pname"
a53771
-		catch "expect_after"
a53771
-		return 0
a53771
-	    }
a53771
-	    eof {
a53771
-		fail "kadmin delprinc $pname"
a53771
-		catch "expect_after"
a53771
-		return 0
a53771
-	    }
a53771
-	}
a53771
-	set good 0
a53771
-	expect "kadmin.local: " { send "modprinc -lockdown_keys $pname\r" }
a53771
-	expect "Principal \"$pname@$REALMNAME\" modified." { set good 1 }
a53771
-	expect "kadmin.local: " { send "quit\r" }
a53771
-	expect_after
a53771
-	expect eof
a53771
-	set k_stat [wait -i $spawn_id]
a53771
-	verbose "wait -i $spawn_id returned $k_stat (kadmin.local show)"
a53771
-	catch "close -i $spawn_id"
a53771
-	if { $good == 1 } {
a53771
-            set good 0
a53771
-            if {[kadmin_delete $pname]} { set good 1 }
a53771
-        }
a53771
-	if { $good == 1 } {
a53771
-	    pass "kadmin delprinc $pname"
a53771
-	    return 1
a53771
-	}
a53771
-	else {
a53771
-	    fail "kadmin delprinc $pname"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    else {
a53771
-	fail "kadmin delprinc $pname"
a53771
-	return 0
a53771
-    }
a53771
-}
a53771
-
a53771
-#++
a53771
-# kpasswd_cpw	- Test password changing using kpasswd.
a53771
-#
a53771
-# Change $princ's password from $opw to $npw.  Returns 1 on success.
a53771
-#--
a53771
-proc kpasswd_cpw { princ opw npw } {
a53771
-    global KPASSWD
a53771
-    global REALMNAME
a53771
-
a53771
-    spawn $KPASSWD $princ
a53771
-    expect_after {
a53771
-	timeout {
a53771
-	    fail "kpasswd $princ $npw"
a53771
-#	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kpasswd $princ $npw"
a53771
-#	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-
a53771
-#    expect "Changing password for $princ."
a53771
-#    expect "Old password:" { send "$opw\r" }
a53771
-#    expect "New password:" { send "$npw\r" }
a53771
-#    expect "New password (again):" { send "$npw\r" }
a53771
-    expect "Password for $princ@$REALMNAME:" { send "$opw\r" }
a53771
-    expect "Enter new password:"  { send "$npw\r" }
a53771
-    expect "Enter it again:"      { send "$npw\r" }
a53771
-#    expect "Kerberos password changed."
a53771
-    expect "Password changed."
a53771
-    expect_after
a53771
-    expect eof
a53771
-
a53771
-    if ![check_exit_status "kpasswd"] {
a53771
-	fail "kpasswd $princ $npw"
a53771
-	return 0
a53771
-    }
a53771
-    pass "kpasswd $princ $npw"
a53771
-    return 1
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_addpol	- Test add new policy function of kadmin.
a53771
-#
a53771
-# Adds policy $pname.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_addpol { pname } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KADMIN_LOCAL
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-    global tmppwd
a53771
-
a53771
-    set good 0
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "addpol $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin addpol $pname lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin addpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin addpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *" {
a53771
-	send "adminpass$KEY\r"
a53771
-    }
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin addpol)"
a53771
-    catch "close -i $spawn_id"
a53771
-    #
a53771
-    # use kadmin.local to verify that a policy was created
a53771
-    #
a53771
-    envstack_push
a53771
-    setup_kerberos_env kdc
a53771
-    spawn $KADMIN_LOCAL -r $REALMNAME
a53771
-    envstack_pop
a53771
-    expect_after {
a53771
-        -i $spawn_id
a53771
-        timeout {
a53771
-	    fail "kadmin addpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-        }
a53771
-        eof {
a53771
-	    fail "kadmin addpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-        }
a53771
-    }
a53771
-    set good 0
a53771
-    expect "kadmin.local: " { send "getpol $pname\r" }
a53771
-    expect "Policy: $pname" { set good 1 }
a53771
-    expect "Maximum password life:" { verbose "got max pw life" }
a53771
-    expect "Minimum password life:" { verbose "got min pw life" }
a53771
-    expect "Minimum password length:" { verbose "got min pw length" }
a53771
-    expect "Minimum number of password character classes:" {
a53771
-        verbose "got min pw character classes" }
a53771
-    expect "Number of old keys kept:" { verbose "got num old keys kept" }
a53771
-    expect "kadmin.local: " { send "q\r" }
a53771
-
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin.local showpol)"
a53771
-    catch "close -i $spawn_id"
a53771
-    if { $good == 1 } {
a53771
-        pass "kadmin addpol $pname"
a53771
-        return 1
a53771
-    }
a53771
-    else {
a53771
-        fail "kadmin addpol $pname"
a53771
-        return 0
a53771
-    }
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_delpol	- Test delete policy function of kadmin.
a53771
-#
a53771
-# Deletes policy $pname.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_delpol { pname } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KADMIN_LOCAL
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-    global tmppwd
a53771
-
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "delpol -force $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin_delpol $pname lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin delpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin delpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *" {
a53771
-	send "adminpass$KEY\r"
a53771
-    }
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin delpol)"
a53771
-    catch "close -i $spawn_id"
a53771
-    #
a53771
-    # use kadmin.local to verify that the old policy is not present.
a53771
-    #
a53771
-    envstack_push
a53771
-    setup_kerberos_env kdc
a53771
-    spawn $KADMIN_LOCAL -r $REALMNAME
a53771
-    envstack_pop
a53771
-    expect_after {
a53771
-        -i $spawn_id
a53771
-        timeout {
a53771
-	    fail "kadmin delpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-        }
a53771
-        eof {
a53771
-	    fail "kadmin delpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-        }
a53771
-    }
a53771
-    set good 0
a53771
-    expect "kadmin.local: " { send "getpol $pname\r" }
a53771
-    expect "Policy does not exist while retrieving policy \"$pname\"." {
a53771
-	set good 1
a53771
-    }
a53771
-    expect "kadmin.local: " { send "quit\r" }
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin.local showpol)"
a53771
-    catch "close -i $spawn_id"
a53771
-    if { $good == 1 } {
a53771
-        pass "kadmin delpol $pname"
a53771
-        return 1
a53771
-    }
a53771
-    else {
a53771
-        fail "kadmin delpol $pname"
a53771
-        return 0
a53771
-    }
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_listpols	- Test list policy database function of kadmin.
a53771
-#
a53771
-# Lists the policies.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_listpols {  } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "get_policies *"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin lpols lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin lpols"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin lpols"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *" {
a53771
-	send "adminpass$KEY\r"
a53771
-    }
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin listpols)"
a53771
-    catch "close -i $spawn_id"
a53771
-    pass "kadmin lpols"
a53771
-    return 1
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_modpol	- Test modify policy function of kadmin.
a53771
-#
a53771
-# Modifies policy $pname with flags $flags.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_modpol { pname flags } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "modpol $flags $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin modpol $pname ($flags) lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin modpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin modpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *"
a53771
-    send "adminpass$KEY\r"
a53771
-    # When in doubt, jam one of these in there.
a53771
-    expect "\r"
a53771
-    # Sadly, kadmin doesn't print a confirmation message for policy operations.
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin modpol)"
a53771
-    catch "close -i $spawn_id"
a53771
-    pass "kadmin modpol $pname"
a53771
-    return 1
a53771
-}
a53771
-
a53771
-#++
a53771
-# kadmin_showpol	- Test show policy function of kadmin.
a53771
-# 
a53771
-# Retrieves entry for $pname.  Returns 1 on success.
a53771
-#--
a53771
-proc kadmin_showpol { pname } {
a53771
-    global REALMNAME
a53771
-    global KADMIN
a53771
-    global KEY
a53771
-    global spawn_id
a53771
-
a53771
-    spawn $KADMIN -p krbtest/admin@$REALMNAME -q "get_policy $pname"
a53771
-    expect_after {
a53771
-	"Cannot contact any KDC" {
a53771
-	    fail "kadmin showpol $pname lost KDC"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kadmin showpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kadmin showpol $pname"
a53771
-	    catch "expect_after"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect -re "assword\[^\r\n\]*: *"
a53771
-    send "adminpass$KEY\r"
a53771
-    expect -re "\r.*Policy: $pname.*Number of old keys kept: .*\r"
a53771
-    expect_after
a53771
-    expect eof
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin showpol)"
a53771
-    catch "close -i $spawn_id"
a53771
-    pass "kadmin showpol $pname"
a53771
-    return 1
a53771
-}
a53771
-
a53771
-#++
a53771
-# kdestroy
a53771
-#--
a53771
-proc kdestroy { } {
a53771
-    global KDESTROY
a53771
-
a53771
-    spawn $KDESTROY -5
a53771
-    if ![check_exit_status "kdestroy"] {
a53771
-	return 0
a53771
-    }
a53771
-    return 1
a53771
-}
a53771
-
a53771
-# Wrap the tests in a procedure, so that we can kill the daemons if
a53771
-# we get some sort of error.
a53771
-
a53771
-proc kadmin_test { } {
a53771
-    global hostname
a53771
-
a53771
-    # Start up the kerberos and kadmind daemons
a53771
-    if {![start_kerberos_daemons 0] } {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    # Test basic kadmin functions.
a53771
-    if {![kadmin_add v5principal/instance1 v5principal] \
a53771
-	|| ![kadmin_addpol standardpol] \
a53771
-	|| ![kadmin_showpol standardpol] \
a53771
-	|| ![kadmin_listpols] \
a53771
-	|| ![kadmin_modpol standardpol "-minlength 5"] \
a53771
-	|| ![kadmin_add v4principal/instance2 v4principal] \
a53771
-	|| ![kadmin_add_rnd v5random] \
a53771
-	|| ![kadmin_show v5principal/instance1] \
a53771
-	|| ![kadmin_show v4principal/instance2] \
a53771
-	|| ![kadmin_show v5random] \
a53771
-	|| ![kadmin_cpw v5principal/instance1 faroutman] \
a53771
-	|| ![kadmin_cpw v4principal/instance2 honkydory] \
a53771
-	|| ![kadmin_cpw_rnd v5random] \
a53771
-	|| ![kadmin_modify v5random -allow_tix] \
a53771
-	|| ![kadmin_modify v5random +allow_tix] \
a53771
-	|| ![kadmin_modify v5random "-policy standardpol"] \
a53771
-	|| ![kadmin_list] \
a53771
-	|| ![kadmin_extract instance1 v5principal] \
a53771
-	|| ![kadmin_delete v5random] \
a53771
-	|| ![kadmin_delete v4principal/instance2] \
a53771
-	|| ![kadmin_delete v5principal/instance1] \
a53771
-	|| ![kadmin_delpol standardpol]} {
a53771
-	return
a53771
-    }
a53771
-
a53771
-# You cannot extract a v4 key...
a53771
-#	|| ![kadmin_extractv4 instance2 v4principal] \
a53771
-
a53771
-    # now test kpasswd
a53771
-    if {![kadmin_add testprinc/instance thisisatest] \
a53771
-	    || ![kpasswd_cpw testprinc/instance thisisatest anothertest] \
a53771
-	    || ![kpasswd_cpw testprinc/instance anothertest goredsox] \
a53771
-	    || ![kadmin_delete testprinc/instance]} {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    # now test that we can kinit with principals/passwords.
a53771
-    # We defer kdestroying until after kpasswd at least once to test FAST automatic use in kpasswd
a53771
-    if {![kadmin_add testprinc1/instance thisisatest] \
a53771
-	    || ![kinit testprinc1/instance thisisatest 0] \
a53771
-	    || ![kpasswd_cpw testprinc1/instance thisisatest anothertest] \
a53771
-	    || ![kdestroy] \
a53771
-	    || ![kinit testprinc1/instance anothertest 0] \
a53771
-	    || ![kdestroy] \
a53771
-	    || ![kpasswd_cpw testprinc1/instance anothertest goredsox] \
a53771
-	    || ![kinit testprinc1/instance goredsox 0] \
a53771
-	    || ![kdestroy] \
a53771
-	    || ![kadmin_cpw testprinc1/instance betterwork] \
a53771
-	    || ![kinit testprinc1/instance betterwork 0] \
a53771
-	    || ![kdestroy] \
a53771
-	    || ![kadmin_delete testprinc1/instance]} {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    # now test modify changes.
a53771
-    if {![kadmin_add testuser longtestpw] \
a53771
-	    || ![kinit testuser longtestpw 0] \
a53771
-	    || ![kdestroy] \
a53771
-	    || ![kadmin_modify testuser "-maxlife \"2500 seconds\""] \
a53771
-	    || ![kinit testuser longtestpw 0] \
a53771
-	    || ![kdestroy] \
a53771
-	    || ![kadmin_delete testuser]} {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    # now test that reducing the history number doesn't make kadmind vulnerable.
a53771
-    if {![kadmin_addpol crashpol] \
a53771
-	    || ![kadmin_modpol crashpol "-history 5"] \
a53771
-	    || ![kadmin_add crash first] \
a53771
-	    || ![kadmin_modify crash "-policy crashpol"] \
a53771
-	    || ![kadmin_cpw crash second] \
a53771
-	    || ![kadmin_cpw crash third] \
a53771
-	    || ![kadmin_cpw crash fourth] \
a53771
-	    || ![kadmin_modpol crashpol "-history 3"] \
a53771
-	    || ![kadmin_cpw crash fifth] \
a53771
-	    || ![kadmin_delete crash] \
a53771
-	    || ![kadmin_delpol crashpol]} {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    # test retrieval of large number of principals
a53771
-    # bug [2877]
a53771
-    for { set i 0 } { $i < 200 } { incr i } {
a53771
-	if { ![kadmin_add "foo$i" foopass] } {
a53771
-	    return
a53771
-	}
a53771
-    }
a53771
-
a53771
-    if { ![kadmin_list] } {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    # test fallback to kadmin/hostname
a53771
-    if {![kadmin_add_rnd kadmin/$hostname] \
a53771
-	    || ![kadmin_delete_locked_down kadmin/admin] \
a53771
-	    || ![kadmin_list] \
a53771
-	    || ![kadmin_add_rnd kadmin/admin -allow_tgs_req] \
a53771
-	    || ![kadmin_list]} {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    verbose "kadmin_test succeeded"
a53771
-}
a53771
-
a53771
-run_once kadmin {
a53771
-    # Set up the kerberos database.
a53771
-    if {![get_hostname] \
a53771
-	    || ![setup_kerberos_files] \
a53771
-	    || ![setup_kerberos_env] \
a53771
-	    || ![setup_kerberos_db 0]} {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    # Run the test.
a53771
-    set status [catch kadmin_test msg]
a53771
-
a53771
-    # Shut down the kerberos daemons and the rsh daemon.
a53771
-    stop_kerberos_daemons
a53771
-
a53771
-    if { $status != 0 } {
a53771
-	send_error "ERROR: error in kadmin.exp\n"
a53771
-	send_error "$msg\n"
a53771
-	exit 1
a53771
-    }
a53771
-}
a53771
diff --git a/src/tests/dejagnu/krb-standalone/pwchange.exp b/src/tests/dejagnu/krb-standalone/pwchange.exp
a53771
deleted file mode 100644
a53771
index 010e8344a..000000000
a53771
--- a/src/tests/dejagnu/krb-standalone/pwchange.exp
a53771
+++ /dev/null
a53771
@@ -1,145 +0,0 @@
a53771
-# Password-changing Kerberos test.
a53771
-# This is a DejaGnu test script.
a53771
-
a53771
-# We are about to start up a couple of daemon processes.  We do all
a53771
-# the rest of the tests inside a proc, so that we can easily kill the
a53771
-# processes when the procedure ends.
a53771
-
a53771
-proc kinit_expecting_pwchange { name pass newpass } {
a53771
-    global REALMNAME
a53771
-    global KINIT
a53771
-    global spawn_id
a53771
-
a53771
-    # Use kinit to get a ticket.
a53771
-	#
a53771
-	# For now always get forwardable tickets. Later when we need to make
a53771
-	# tests that distinguish between forwardable tickets and otherwise
a53771
-	# we should but another option to this proc. --proven
a53771
-	#
a53771
-    spawn $KINIT -5 -f $name@$REALMNAME
a53771
-    expect {
a53771
-	"Password for $name@$REALMNAME:" {
a53771
-	    verbose "kinit started"
a53771
-	}
a53771
-	timeout {
a53771
-	    fail "kinit"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kinit"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    send "$pass\r"
a53771
-    expect {
a53771
-	"Enter new password: " { }
a53771
-	timeout {
a53771
-	    fail "kinit (new password prompt)"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kinit (new password prompt)"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    send "$newpass\r"
a53771
-    expect {
a53771
-	" again: " { }
a53771
-	timeout {
a53771
-	    fail "kinit (new password prompt2)"
a53771
-	    return 0
a53771
-	}
a53771
-	eof {
a53771
-	    fail "kinit (new password prompt2)"
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    send "$newpass\r"
a53771
-    expect eof
a53771
-    if ![check_exit_status kinit] {
a53771
-	return 0
a53771
-    }
a53771
-
a53771
-    return 1
a53771
-}
a53771
-
a53771
-proc doit { } {
a53771
-    global REALMNAME
a53771
-    global KLIST
a53771
-    global KDESTROY
a53771
-    global KEY
a53771
-    global KADMIN_LOCAL
a53771
-    global KTUTIL
a53771
-    global hostname
a53771
-    global tmppwd
a53771
-    global spawn_id
a53771
-    global supported_enctypes
a53771
-    global KRBIV
a53771
-    global portbase
a53771
-    global mode
a53771
-
a53771
-    # Start up the kerberos and kadmind daemons.
a53771
-    if ![start_kerberos_daemons 0] {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    # Use kadmin to add a key.
a53771
-    if ![add_kerberos_key pwchanger 0] {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    setup_kerberos_env kdc
a53771
-    spawn $KADMIN_LOCAL -q "modprinc +needchange pwchanger"
a53771
-    catch expect_after
a53771
-    expect {
a53771
-	timeout {
a53771
-	    fail "kadmin.local modprinc +needchange"
a53771
-	}
a53771
-	eof {
a53771
-	    pass "kadmin.local modprinc +needchange"
a53771
-	}
a53771
-    }
a53771
-    set k_stat [wait -i $spawn_id]
a53771
-    verbose "wait -i $spawn_id returned $k_stat (kadmin modprinc +needchange)"
a53771
-    catch "close -i $spawn_id"
a53771
-
a53771
-    setup_kerberos_env client
a53771
-    if ![kinit_expecting_pwchange pwchanger pwchanger$KEY floople] {
a53771
-	return
a53771
-    }
a53771
-    pass "kinit (password change)"
a53771
-    if ![kinit pwchanger floople 0] {
a53771
-	return
a53771
-    }
a53771
-    pass "kinit (new password)"
a53771
-
a53771
-    # Destroy the ticket.
a53771
-    spawn $KDESTROY -5
a53771
-    if ![check_exit_status "kdestroy"] {
a53771
-	return
a53771
-    }
a53771
-    pass "kdestroy"
a53771
-}
a53771
-
a53771
-run_once pwchange {
a53771
-    # Set up the Kerberos files and environment.
a53771
-    if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    # Initialize the Kerberos database.  The argument tells
a53771
-    # setup_kerberos_db that it is being called from here.
a53771
-    if ![setup_kerberos_db 0] {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    set status [catch doit msg]
a53771
-
a53771
-    stop_kerberos_daemons
a53771
-
a53771
-    if { $status != 0 } {
a53771
-	send_error "ERROR: error in pwchange.exp\n"
a53771
-	send_error "$msg\n"
a53771
-	exit 1
a53771
-    }
a53771
-}
a53771
diff --git a/src/tests/dejagnu/krb-standalone/pwhist.exp b/src/tests/dejagnu/krb-standalone/pwhist.exp
a53771
deleted file mode 100644
a53771
index ed7a3771a..000000000
a53771
--- a/src/tests/dejagnu/krb-standalone/pwhist.exp
a53771
+++ /dev/null
a53771
@@ -1,217 +0,0 @@
a53771
-# password history tests
a53771
-
a53771
-# one *non-interactive* kadmin.local request
a53771
-proc onerq { rq pname str {flags ""} } {
a53771
-    global REALMNAME
a53771
-    global KADMIN_LOCAL
a53771
-
a53771
-    spawn $KADMIN_LOCAL -r $REALMNAME -q "$rq $flags $pname"
a53771
-    expect_after {
a53771
-	timeout {
a53771
-	    verbose "kadmin.local $rq $flags $pname timed out"
a53771
-	    catch expect_after
a53771
-	    kill [exp_pid]
a53771
-	    close
a53771
-	    expect eof
a53771
-	    wait
a53771
-	    return 0
a53771
-	} eof {
a53771
-	    verbose "kadmin.local $rq $flags $pname got EOF"
a53771
-	    catch expect_after
a53771
-	    wait
a53771
-	    return 0
a53771
-	}
a53771
-    }
a53771
-    expect $str
a53771
-    expect_after
a53771
-    expect eof
a53771
-    wait
a53771
-    return 1
a53771
-}
a53771
-
a53771
-proc addprinc { pname pw } {
a53771
-    global REALMNAME
a53771
-
a53771
-    return [onerq addprinc $pname \
a53771
-		"Principal \"$pname@$REALMNAME\" created." "-pw $pw"]
a53771
-}
a53771
-
a53771
-proc delprinc { pname } {
a53771
-    global REALMNAME
a53771
-    return [onerq delprinc $pname \
a53771
-		"Principal \"$pname@$REALMNAME\" deleted." "-force"]
a53771
-}
a53771
-
a53771
-proc cpw { pname pw } {
a53771
-    global REALMNAME
a53771
-
a53771
-    return [onerq cpw $pname \
a53771
-		"Password for \"$pname@$REALMNAME\" changed." "-pw $pw"]
a53771
-}
a53771
-
a53771
-proc modprinc { pname flags } {
a53771
-    global REALMNAME
a53771
-
a53771
-    return [onerq modprinc $pname \
a53771
-		"Principal \"$pname@$REALMNAME\" modified." $flags]
a53771
-}
a53771
-
a53771
-proc addpol { pname } {
a53771
-    if ![onerq addpol $pname ""] {
a53771
-	return 0
a53771
-    }
a53771
-    return [onerq getpol $pname "Policy: $pname"]
a53771
-}
a53771
-
a53771
-proc delpol { pname } {
a53771
-    onerq delpol $pname "" -force
a53771
-    return [onerq getpol $pname \
a53771
-		"Policy does not exist while retrieving policy \"$pname\"."]
a53771
-}
a53771
-
a53771
-proc modpol { pname flags } {
a53771
-    return [onerq modpol $pname "" $flags]
a53771
-}
a53771
-
a53771
-# Mandatory command must return true.
a53771
-# Issues a break in its parent on failure.
a53771
-proc mustrun { cmd } {
a53771
-    if ![eval $cmd] {
a53771
-	perror "mandatory command failed: $cmd"
a53771
-	uplevel break
a53771
-    }
a53771
-}
a53771
-
a53771
-# Fail test if command fails.
a53771
-# Issues a break in its parent on failure.
a53771
-proc chkpass { cmd } {
a53771
-    upvar test test
a53771
-    if ![eval $cmd] {
a53771
-	verbose "unexpected failure: $cmd"
a53771
-	fail $test
a53771
-	uplevel break
a53771
-    }
a53771
-}
a53771
-
a53771
-# Fail test if command succeeds.
a53771
-# Issues a break in its parent on failure.
a53771
-proc chkfail { cmd } {
a53771
-    upvar test test
a53771
-    if [eval $cmd] {
a53771
-	verbose "unexpected success: $cmd"
a53771
-	fail $test
a53771
-	uplevel break
a53771
-    }
a53771
-}
a53771
-
a53771
-# wrapper to run command (actually usually sequence of commands)
a53771
-#
a53771
-# If any part of CMD throws an exception, set failall, otherwise pass.
a53771
-# If failall is already true, report unresolved.
a53771
-proc wraptest { test cmd } {
a53771
-    upvar failall failall
a53771
-    if $failall {
a53771
-	unresolved $test
a53771
-	return
a53771
-    }
a53771
-    if [catch $cmd] {
a53771
-	set failall 1
a53771
-    } else {
a53771
-	pass $test
a53771
-    }
a53771
-}
a53771
-
a53771
-run_once pwhist {
a53771
-    # Set up the kerberos database.
a53771
-    if {![get_hostname] \
a53771
-	    || ![setup_kerberos_files] \
a53771
-	    || ![setup_kerberos_env kdc] \
a53771
-	    || ![setup_kerberos_db 0]} {
a53771
-	return
a53771
-    }
a53771
-
a53771
-    set failall 0
a53771
-    wraptest "nkeys=1, nhist=3" {
a53771
-	mustrun { addpol crashpol }
a53771
-	mustrun { modpol crashpol "-history 3"}
a53771
-	mustrun { addprinc crash 1111 }
a53771
-	mustrun { modprinc crash "-policy crashpol" }
a53771
-	chkpass { cpw crash 2222 }
a53771
-	chkfail { cpw crash 2222 }
a53771
-	chkfail { cpw crash 1111 }
a53771
-    }
a53771
-    verbose {old_keys [ 1111 ->[] ]}
a53771
-
a53771
-    # The following will result in reading/writing past array bounds if
a53771
-    # add_to_history() is not patched.
a53771
-    #
a53771
-    # NOTE: A pass from this test does not mean the bug isn't present;
a53771
-    # check with Purify, valgrind, etc.
a53771
-    wraptest "array bounds ok on nkeys=1, nhist 3->2" {
a53771
-	mustrun { modpol crashpol "-history 2" }
a53771
-	chkpass { cpw crash 3333 }
a53771
-    }
a53771
-    verbose {old_keys [ ->2222 ]}
a53771
-
a53771
-    wraptest "verify nhist=2" {
a53771
-	mustrun { delprinc crash }
a53771
-	mustrun { addprinc crash 1111 }
a53771
-	mustrun { modprinc crash "-policy crashpol" }
a53771
-	chkpass { cpw crash 2222 }
a53771
-	chkfail { cpw crash 2222 }
a53771
-	chkfail { cpw crash 1111 }
a53771
-    }
a53771
-    verbose {old_keys [ ->1111 ]}
a53771
-
a53771
-    # The following will fail if growing the history array causes an extra
a53771
-    # key to be lost due to failure to shift entries.
a53771
-    wraptest "grow nhist 2->3" {
a53771
-	mustrun { modpol crashpol "-history 3" }
a53771
-	chkpass { cpw crash 3333 }
a53771
-	chkfail { cpw crash 3333 }
a53771
-	chkfail { cpw crash 2222 }
a53771
-	chkfail { cpw crash 1111 }
a53771
-    }
a53771
-    verbose {old_keys [ 2222 ->1111 ]}
a53771
-
a53771
-    wraptest "grow nhist 3->4" {
a53771
-	mustrun { modpol crashpol "-history 4" }
a53771
-	chkfail { cpw crash 3333 }
a53771
-	chkfail { cpw crash 2222 }
a53771
-	chkfail { cpw crash 1111 }
a53771
-	chkpass { cpw crash 4444 }
a53771
-	chkfail { cpw crash 3333 }
a53771
-	chkfail { cpw crash 2222 }
a53771
-	chkfail { cpw crash 1111 }
a53771
-    }
a53771
-    verbose {old_keys [ 2222 3333 ->1111 ]}
a53771
-    wraptest "shrink nhist 4->3" {
a53771
-	mustrun { modpol crashpol "-history 3" }
a53771
-	chkfail { cpw crash 4444 }
a53771
-	chkfail { cpw crash 3333 }
a53771
-	chkfail { cpw crash 2222 }
a53771
-	chkfail { cpw crash 1111 }
a53771
-	chkpass { cpw crash 5555 }
a53771
-    }
a53771
-    verbose {old_keys [ 4444 ->3333 ]}
a53771
-    wraptest "verify nhist=3" {
a53771
-	chkfail { cpw crash 5555 }
a53771
-	chkfail { cpw crash 4444 }
a53771
-	chkfail { cpw crash 3333 }
a53771
-	chkpass { cpw crash 2222 }
a53771
-    }
a53771
-    verbose {old_keys [ ->4444 5555 ]}
a53771
-    wraptest "shrink nhist 3->2" {
a53771
-	mustrun { modpol crashpol "-history 2" }
a53771
-	chkfail { cpw crash 2222 }
a53771
-	chkfail { cpw crash 5555 }
a53771
-	chkfail { cpw crash 4444 }
a53771
-	chkpass { cpw crash 3333 }
a53771
-    }
a53771
-    verbose {old_keys [ ->2222 ]}
a53771
-
a53771
-    delprinc crash
a53771
-    delpol crashpol
a53771
-
a53771
-    stop_kerberos_daemons
a53771
-}
a53771
diff --git a/src/tests/t_changepw.py b/src/tests/t_changepw.py
a53771
index 573bdbd49..bf8e3a9eb 100755
a53771
--- a/src/tests/t_changepw.py
a53771
+++ b/src/tests/t_changepw.py
a53771
@@ -1,23 +1,24 @@
a53771
 from k5test import *
a53771
 
a53771
-# This file is intended to cover any password-changing mechanism.  For
a53771
-# now it only contains a regression test for #7868.
a53771
-
a53771
 realm = K5Realm(create_host=False, get_creds=False, start_kadmind=True)
a53771
+realm.prep_kadmin()
a53771
 
a53771
 # Mark a principal as expired and change its password through kinit.
a53771
+mark('password change via kinit')
a53771
 realm.run([kadminl, 'modprinc', '-pwexpire', '1 day ago', 'user'])
a53771
 pwinput = password('user') + '\nabcd\nabcd\n'
a53771
 realm.run([kinit, realm.user_princ], input=pwinput)
a53771
 
a53771
-# Do the same thing with FAST, with tracing turned on.
a53771
-realm.run([kadminl, 'modprinc', '-pwexpire', '1 day ago', 'user'])
a53771
+# Regression test for #7868 (preauth options ignored when
a53771
+# krb5_get_init_creds_password() initiates a password change).  This
a53771
+# time use the REQUIRES_PWCHANGE bit instead of the password
a53771
+# expiration time.
a53771
+mark('password change via kinit with FAST')
a53771
+realm.run([kadminl, 'modprinc', '+needchange', 'user'])
a53771
 pwinput = 'abcd\nefgh\nefgh\n'
a53771
 out, trace = realm.run([kinit, '-T', realm.ccache, realm.user_princ],
a53771
                        input=pwinput, return_trace=True)
a53771
-
a53771
-# Read the trace and check that FAST was used when getting the
a53771
-# kadmin/changepw ticket.
a53771
+# Check that FAST was used when getting the kadmin/changepw ticket.
a53771
 getting_changepw = fast_used_for_changepw = False
a53771
 for line in trace.splitlines():
a53771
     if 'Getting initial credentials for user@' in line:
a53771
@@ -29,4 +30,21 @@ for line in trace.splitlines():
a53771
 if not fast_used_for_changepw:
a53771
     fail('FAST was not used to get kadmin/changepw ticket')
a53771
 
a53771
+# Test that passwords specified via kadmin and kpasswd are usable with
a53771
+# kinit.
a53771
+mark('password change usability by kinit')
a53771
+realm.run([kadminl, 'addprinc', '-pw', 'pw1', 'testprinc'])
a53771
+# Run kpasswd with an active cache to exercise automatic FAST use.
a53771
+realm.kinit('testprinc', 'pw1')
a53771
+realm.run([kpasswd, 'testprinc'], input='pw1\npw2\npw2\n')
a53771
+realm.kinit('testprinc', 'pw2')
a53771
+realm.run([kdestroy])
a53771
+realm.run([kpasswd, 'testprinc'], input='pw2\npw3\npw3\n')
a53771
+realm.kinit('testprinc', 'pw3')
a53771
+realm.run([kdestroy])
a53771
+realm.run_kadmin(['cpw', '-pw', 'pw4', 'testprinc'])
a53771
+realm.kinit('testprinc', 'pw4')
a53771
+realm.run([kdestroy])
a53771
+realm.run([kadminl, 'delprinc', 'testprinc'])
a53771
+
a53771
 success('Password change tests')
a53771
diff --git a/src/tests/t_kadmin.py b/src/tests/t_kadmin.py
a53771
new file mode 100644
a53771
index 000000000..fe6a3cc2e
a53771
--- /dev/null
a53771
+++ b/src/tests/t_kadmin.py
a53771
@@ -0,0 +1,54 @@
a53771
+from k5test import *
a53771
+
a53771
+realm = K5Realm(start_kadmind=True)
a53771
+
a53771
+# Create a principal.  Test -q option and keyboard entry of the admin
a53771
+# password and principal password.  Verify creation with kadmin.local.
a53771
+realm.run([kadmin, '-q', 'addprinc princ/pw'],
a53771
+          input=password('admin') + '\npw1\npw1\n')
a53771
+realm.run([kadminl, 'getprinc', 'princ/pw'],
a53771
+          expected_msg='Principal: princ/pw@KRBTEST.COM')
a53771
+
a53771
+# Run the remaining tests with a cache for efficiency.
a53771
+realm.prep_kadmin()
a53771
+
a53771
+realm.run_kadmin(['addpol', 'standardpol'])
a53771
+realm.run_kadmin(['listpols'], expected_msg='standardpol')
a53771
+realm.run_kadmin(['modpol', '-minlength', '5', 'standardpol'])
a53771
+realm.run_kadmin(['getpol', 'standardpol'],
a53771
+                 expected_msg='Minimum password length: 5')
a53771
+
a53771
+realm.run_kadmin(['addprinc', '-randkey', 'princ/random'])
a53771
+realm.run([kadminl, 'getprinc', 'princ/random'],
a53771
+          expected_msg='Principal: princ/random@KRBTEST.COM')
a53771
+
a53771
+realm.run_kadmin(['cpw', 'princ/pw'], input='newpw\nnewpw\n')
a53771
+realm.run_kadmin(['cpw', '-randkey', 'princ/random'])
a53771
+
a53771
+realm.run_kadmin(['modprinc', '-allow_tix', 'princ/random'])
a53771
+realm.run_kadmin(['modprinc', '+allow_tix', 'princ/random'])
a53771
+realm.run_kadmin(['modprinc', '-policy', 'standardpol', 'princ/random'])
a53771
+
a53771
+realm.run_kadmin(['listprincs'], expected_msg='princ/random@KRBTEST.COM')
a53771
+
a53771
+realm.run_kadmin(['ktadd', 'princ/pw'])
a53771
+
a53771
+realm.run_kadmin(['delprinc', 'princ/random'])
a53771
+realm.run([kadminl, 'getprinc', 'princ/random'], expected_code=1,
a53771
+          expected_msg='Principal does not exist')
a53771
+realm.run_kadmin(['delprinc', 'princ/pw'])
a53771
+realm.run([kadminl, 'getprinc', 'princ/pw'], expected_code=1,
a53771
+          expected_msg='Principal does not exist')
a53771
+
a53771
+realm.run_kadmin(['delpol', 'standardpol'])
a53771
+realm.run([kadminl, 'getpol', 'standardpol'], expected_code=1,
a53771
+          expected_msg='Policy does not exist')
a53771
+
a53771
+# Regression test for #2877 (fixed-sized GSSRPC buffers can't
a53771
+# accomodate large listprinc results).
a53771
+mark('large listprincs result')
a53771
+for i in range(200):
a53771
+    realm.run_kadmin(['addprinc', '-randkey', 'foo%d' % i])
a53771
+realm.run_kadmin(['listprincs'], expected_msg='foo199')
a53771
+
a53771
+success('kadmin and kpasswd tests')
a53771
diff --git a/src/tests/t_policy.py b/src/tests/t_policy.py
a53771
index 5a0c06b86..2bb4f5f18 100755
a53771
--- a/src/tests/t_policy.py
a53771
+++ b/src/tests/t_policy.py
a53771
@@ -25,6 +25,68 @@ realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser'], expected_code=1,
a53771
 realm.run([kadminl, 'cpw', '-pw', '3rdpassword', 'pwuser'])
a53771
 realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser'])
a53771
 
a53771
+# Regression test for #929 (kadmind crash with more historical
a53771
+# passwords in a principal entry than current policy history setting).
a53771
+mark('password history (policy value reduced below current array size)')
a53771
+realm.run([kadminl, 'addpol', '-history', '5', 'histpol'])
a53771
+realm.addprinc('histprinc', 'first')
a53771
+realm.run([kadminl, 'modprinc', '-policy', 'histpol', 'histprinc'])
a53771
+realm.run([kadminl, 'cpw', '-pw', 'second', 'histprinc'])
a53771
+realm.run([kadminl, 'cpw', '-pw', 'third', 'histprinc'])
a53771
+realm.run([kadminl, 'cpw', '-pw', 'fourth', 'histprinc'])
a53771
+realm.run([kadminl, 'modpol', '-history', '3', 'histpol'])
a53771
+realm.run([kadminl, 'cpw', '-pw', 'fifth', 'histprinc'])
a53771
+realm.run([kadminl, 'delprinc', 'histprinc'])
a53771
+
a53771
+# Regression test for #2841 (heap buffer overflow when policy history
a53771
+# value is reduced to match the number of historical passwords for a
a53771
+# principal).
a53771
+mark('password history (policy value reduced to current array size)')
a53771
+def histfail(*pwlist):
a53771
+    for pw in pwlist:
a53771
+        realm.run([kadminl, 'cpw', '-pw', pw, 'histprinc'], expected_code=1,
a53771
+                  expected_msg='Cannot reuse password')
a53771
+realm.run([kadminl, 'modpol', '-history', '3', 'histpol'])
a53771
+realm.addprinc('histprinc', '1111')
a53771
+realm.run([kadminl, 'modprinc', '-policy', 'histpol', 'histprinc'])
a53771
+realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc'])
a53771
+histfail('2222', '1111')
a53771
+realm.run([kadminl, 'modpol', '-history', '2', 'histpol'])
a53771
+realm.run([kadminl, 'cpw', '-pw', '3333', 'histprinc'])
a53771
+
a53771
+# Test that the history array is properly resized if the policy
a53771
+# history value is increased after the array is filled.
a53771
+mark('password history (policy value increase)')
a53771
+realm.run([kadminl, 'delprinc', 'histprinc'])
a53771
+realm.addprinc('histprinc', '1111')
a53771
+realm.run([kadminl, 'modprinc', '-policy', 'histpol', 'histprinc'])
a53771
+realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc'])
a53771
+histfail('2222', '1111')
a53771
+realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc'], expected_code=1,
a53771
+          expected_msg='Cannot reuse password')
a53771
+realm.run([kadminl, 'cpw', '-pw', '1111', 'histprinc'], expected_code=1,
a53771
+          expected_msg='Cannot reuse password')
a53771
+realm.run([kadminl, 'modpol', '-history', '3', 'histpol'])
a53771
+realm.run([kadminl, 'cpw', '-pw', '3333', 'histprinc'])
a53771
+histfail('3333', '2222', '1111')
a53771
+realm.run([kadminl, 'modpol', '-history', '4', 'histpol'])
a53771
+histfail('3333', '2222', '1111')
a53771
+realm.run([kadminl, 'cpw', '-pw', '4444', 'histprinc'])
a53771
+histfail('4444', '3333', '2222', '1111')
a53771
+
a53771
+# Test that when the policy history value is reduced, all currently
a53771
+# known old passwords still fail until the next password change, after
a53771
+# which the new number of old passwords fails (but no more).
a53771
+mark('password history (policy value reduction)')
a53771
+realm.run([kadminl, 'modpol', '-history', '3', 'histpol'])
a53771
+histfail('4444', '3333', '2222', '1111')
a53771
+realm.run([kadminl, 'cpw', '-pw', '5555', 'histprinc'])
a53771
+histfail('5555', '3333', '3333')
a53771
+realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc'])
a53771
+realm.run([kadminl, 'modpol', '-history', '2', 'histpol'])
a53771
+histfail('2222', '5555', '4444')
a53771
+realm.run([kadminl, 'cpw', '-pw', '3333', 'histprinc'])
a53771
+
a53771
 # Test references to nonexistent policies.
a53771
 mark('nonexistent policy references')
a53771
 realm.run([kadminl, 'addprinc', '-randkey', '-policy', 'newpol', 'newuser'])