pwhist.exp   [plain text]


# password history tests

# one *non-interactive* kadmin.local request
proc onerq { rq pname str {flags ""} } {
    global REALMNAME
    global KADMIN_LOCAL

    spawn $KADMIN_LOCAL -r $REALMNAME -q "$rq $flags $pname"
    expect_after {
	timeout {
	    verbose "kadmin.local $rq $flags $pname timed out"
	    catch expect_after
	    kill [exp_pid]
	    close
	    expect eof
	    wait
	    return 0
	} eof {
	    verbose "kadmin.local $rq $flags $pname got EOF"
	    catch expect_after
	    wait
	    return 0
	}
    }
    expect $str
    expect_after
    expect eof
    wait
    return 1
}

proc addprinc { pname pw } {
    global REALMNAME

    return [onerq addprinc $pname \
		"Principal \"$pname@$REALMNAME\" created." "-pw $pw"]
}

proc delprinc { pname } {
    global REALMNAME
    return [onerq delprinc $pname \
		"Principal \"$pname@$REALMNAME\" deleted." "-force"]
}

proc cpw { pname pw } {
    global REALMNAME

    return [onerq cpw $pname \
		"Password for \"$pname@$REALMNAME\" changed." "-pw $pw"]
}

proc modprinc { pname flags } {
    global REALMNAME

    return [onerq modprinc $pname \
		"Principal \"$pname@$REALMNAME\" modified." $flags]
}

proc addpol { pname } {
    if ![onerq addpol $pname ""] {
	return 0
    }
    return [onerq getpol $pname "Policy: $pname"]
}

proc delpol { pname } {
    onerq delpol $pname "" -force
    return [onerq getpol $pname \
		"Policy does not exist while retrieving policy \"$pname\"."]
}

proc modpol { pname flags } {
    return [onerq modpol $pname "" $flags]
}

# Mandatory command must return true.
# Issues a break in its parent on failure.
proc mustrun { cmd } {
    if ![eval $cmd] {
	perror "mandatory command failed: $cmd"
	uplevel break
    }
}

# Fail test if command fails.
# Issues a break in its parent on failure.
proc chkpass { cmd } {
    upvar test test
    if ![eval $cmd] {
	verbose "unexpected failure: $cmd"
	fail $test
	uplevel break
    }
}

# Fail test if command succeeds.
# Issues a break in its parent on failure.
proc chkfail { cmd } {
    upvar test test
    if [eval $cmd] {
	verbose "unexpected success: $cmd"
	fail $test
	uplevel break
    }
}

# wrapper to run command (actually usually sequence of commands)
#
# If any part of CMD throws an exception, set failall, otherwise pass.
# If failall is already true, report unresolved.
proc wraptest { test cmd } {
    upvar failall failall
    if $failall {
	unresolved $test
	return
    }
    if [catch $cmd] {
	set failall 1
    } else {
	pass $test
    }
}

# Set up the kerberos database.
if {![get_hostname] \
    || ![setup_kerberos_files] \
    || ![setup_kerberos_env] \
    || ![setup_kerberos_db 0]} {
    return
}

set failall 0
wraptest "nkeys=1, nhist=3" {
    mustrun { addpol crashpol }
    mustrun { modpol crashpol "-history 3"}
    mustrun { addprinc crash 1111 }
    mustrun { modprinc crash "-policy crashpol" }
    chkpass { cpw crash 2222 }
    chkfail { cpw crash 2222 }
    chkfail { cpw crash 1111 }
}
verbose {old_keys [ 1111 ->[] ]}

# The following will result in reading/writing past array bounds if
# add_to_history() is not patched.
#
# NOTE: A pass from this test does not mean the bug isn't present;
# check with Purify, valgrind, etc.
wraptest "array bounds ok on nkeys=1, nhist 3->2" {
    mustrun { modpol crashpol "-history 2" }
    chkpass { cpw crash 3333 }
}
verbose {old_keys [ ->2222 ]}

wraptest "verify nhist=2" {
    mustrun { delprinc crash }
    mustrun { addprinc crash 1111 }
    mustrun { modprinc crash "-policy crashpol" }
    chkpass { cpw crash 2222 }
    chkfail { cpw crash 2222 }
    chkfail { cpw crash 1111 }
}
verbose {old_keys [ ->1111 ]}

# The following will fail if growing the history array causes an extra
# key to be lost due to failure to shift entries.
wraptest "grow nhist 2->3" {
    mustrun { modpol crashpol "-history 3" }
    chkpass { cpw crash 3333 }
    chkfail { cpw crash 3333 }
    chkfail { cpw crash 2222 }
    chkfail { cpw crash 1111 }
}
verbose {old_keys [ 2222 ->1111 ]}

wraptest "grow nhist 3->4" {
    mustrun { modpol crashpol "-history 4" }
    chkfail { cpw crash 3333 }
    chkfail { cpw crash 2222 }
    chkfail { cpw crash 1111 }
    chkpass { cpw crash 4444 }
    chkfail { cpw crash 3333 }
    chkfail { cpw crash 2222 }
    chkfail { cpw crash 1111 }
}
verbose {old_keys [ 2222 3333 ->1111 ]}
wraptest "shrink nhist 4->3" {
    mustrun { modpol crashpol "-history 3" }
    chkfail { cpw crash 4444 }
    chkfail { cpw crash 3333 }
    chkfail { cpw crash 2222 }
    chkfail { cpw crash 1111 }
    chkpass { cpw crash 5555 }
}
verbose {old_keys [ 4444 ->3333 ]}
wraptest "verify nhist=3" {
    chkfail { cpw crash 5555 }
    chkfail { cpw crash 4444 }
    chkfail { cpw crash 3333 }
    chkpass { cpw crash 2222 }
}
verbose {old_keys [ ->4444 5555 ]}
wraptest "shrink nhist 3->2" {
    mustrun { modpol crashpol "-history 2" }
    chkfail { cpw crash 2222 }
    chkfail { cpw crash 5555 }
    chkfail { cpw crash 4444 }
    chkpass { cpw crash 3333 }
}
verbose {old_keys [ ->2222 ]}

delprinc crash
delpol crashpol

stop_kerberos_daemons