[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