[krbdev.mit.edu #2685] profile iterator breaks when modifications made
Ken Raeburn via RT
rt-comment at krbdev.mit.edu
Fri Aug 27 17:14:51 EDT 2004
(This is a problem Miro ran into long ago, but we haven't bothered to
track down.)
If a program uses an iterator to walk over a set of entries in the
profile with a particular set of names, it's fine. If the same
program deletes entries from the profile when the iterator is
examining them, the iterator can get confused.
The simplest case is: Iterate over the list of KDCs for a realm. As
each entry is returned, delete it, and save out the result. There
should be no KDCs left; instead, the second one is always left.
After throwing together a Tcl wrapper (using SWIG) for the profile
library API, I've managed to reproduce the problem quite nicely:
set x [profile_init /tmp/krb5.conf]
puts [list Opened new profile object: $x]
set dr [profile_get_string $x libdefaults default_realm]
puts [list Default realm is $dr]
set kdcs [profile_get_values $x [list realms $dr kdc]]
puts [list KDC list: $kdcs]
set i [profile_iterator_create $x [list realms $dr kdc] 0]
puts [list New iterator over KDC list: $i]
set a hello
while {[string length [lindex $a 0]]} {
set a [profile_iterator $i]
puts [list Iterator returns value: $a]
}
puts done
set i [profile_iterator_create $x [list realms $dr kdc] 0]
puts [list New iterator over KDC list: $i]
set a hello
while {[string length [lindex $a 0]]} {
set a [profile_iterator $i]
puts [list Iterator returns value: $a]
set server [lindex $a 1]
if [string length $server] {
puts [list Deleting node: $server]
profile_update_relation $x [list realms $dr kdc] $server
set kdcs {}
catch {
set kdcs [profile_get_values $x [list realms $dr kdc]]
} z
puts [list New KDC list: $kdcs]
}
}
profile_release $x
shows the incorrect result:
Opened new profile object: _d0d40508_profile_t
Default realm is ATHENA.MIT.EDU
KDC list: {kerberos.mit.edu:88 kerberos-1.mit.edu:88 kerberos-2.mit.edu:88 kerberos-3.mit.edu:88}
New iterator over KDC list: _20020608_iter_t
Iterator returns value: {kdc kerberos.mit.edu:88}
Iterator returns value: {kdc kerberos-1.mit.edu:88}
Iterator returns value: {kdc kerberos-2.mit.edu:88}
Iterator returns value: {kdc kerberos-3.mit.edu:88}
Iterator returns value: {{} {}}
done
New iterator over KDC list: _d85c0608_iter_t
Iterator returns value: {kdc kerberos.mit.edu:88}
Deleting node: kerberos.mit.edu:88
New KDC list: {kerberos-1.mit.edu:88 kerberos-2.mit.edu:88 kerberos-3.mit.edu:88}
*** Note that at this point the iterator should return kerberos-1, but
*** never does; hence, the caller doesn't delete it.
Iterator returns value: {kdc kerberos-2.mit.edu:88}
Deleting node: kerberos-2.mit.edu:88
New KDC list: {kerberos-1.mit.edu:88 kerberos-3.mit.edu:88}
Iterator returns value: {kdc kerberos-3.mit.edu:88}
Deleting node: kerberos-3.mit.edu:88
New KDC list: kerberos-1.mit.edu:88
Iterator returns value: {{} {}}
Ken
More information about the krb5-bugs
mailing list