I'm not sure that this bug is in the Kerberos library side, but I'll
start here and we can reassign if the problem is somewhere else.
If you run the following Perl script (with libnet-ldap-perl,
libauthen-sasl-cyrus-perl, and libauthen-krb5-perl installed along
with the MIT Kerberos Cyrus SASL GSSAPI module package installed):
#!/usr/bin/perl
use Net::LDAP;
use Authen::SASL qw(Cyrus);
use Authen::Krb5;
sub dir_bind {
my ($serverName) = @_;
print "Creating LDAP object for $serverName\n";
my $ld = Net::LDAP->new($serverName);
my $mech = 'GSSAPI';
my $sasl = Authen::SASL->new(mechanism => $mech);
print "binding using $mech\n";
$ld->bind("", sasl=>$sasl);
$ld->unbind if $ld;
}
dir_bind('ldap1.stanford.edu');
dir_bind('ldap2.stanford.edu');
exit;
you get:
Creating LDAP object for ldap1.stanford.edu
binding using GSSAPI
Creating LDAP object for ldap2.stanford.edu
binding using GSSAPI
perl: ../../../src/util/support/threads.c:351: krb5int_key_register: Assertion `destructors_set[keynum] == 0' failed.
Abort
All of the following must be true to trigger this:
1. Creating and using two separate Authen::SASL objects. Just creating
one will not trigger this bug.
2. Loading Authen::Krb5 (note that it's not used). If it's not loaded,
this won't be a problem.
3. Not loading any other module that loads libgssapi_krb5 into Perl's
context. If you add "use Net::Remctl;" to the script, the assertion
goes away; similarly for Authen::Krb5::Admin, or anything else that
loads the GSSAPI library.
My theory of what's happening here:
1. Authen::Krb5 loads libkrb5support but not libgssapi_krb5.
2. Cyrus loads the GSSAPI module when the SASL object is created and
used, which loads libgssapi_krb5 and initializes it.
3. Cyrus unloads the GSSAPI module when the Authen::SASL object goes
out of scope, which then unloads libgssapi_krb5, but something
doesn't work properly about cleaning up the library initialization.
libkrb5support is not unloaded and hangs on to that library
initialization data. (If Authen::Krb5 weren't loaded, it wouldn't
stay loaded, and this problem then doesn't occur.)
4. When Cyrus loads the GSSAPI module again, it reloads libgssapi_krb5,
which tries to initialize itself again. Since libkrb5support thinks
it's already initialized, it asserts.
Assuming this theory is correct, the question is why, when libgssai_krb5
is unloaded, it isn't cleaning up its initialization properly.