macOS API ccache, kinit for multiple principals gives internal credentials cache error

A. Karl Kornel karl at kornel.us
Tue Feb 18 16:39:43 EST 2025


On 2025-02-17 06:36 PM, Ken Hornstein wrote:

> <<<snip>>>
> 
> First, do you have a default_realm set in /etc/krb5.conf ?  Maybe that
> would fix it, and that would explain why it works for me.

I did not actually have a krb5.conf installed on my computer.  Stanford 
has the necessary SRV records in DNS for domain-to-realm lookup, KDC 
lookup, etc..  Plus, my normal workflow involves using bash aliases to 
do `kinit`, and those `kinit` commands include the realm name.  So, I've 
never been hurt (until now?) by not having a default realm set.

Plus, I didn't know that later macOS even supported putting something at 
path /etc/krb5.conf!  I thought that pretty much everything under / was 
locked down now.

Stanford's canonical krb5.conf is at 
https://web.stanford.edu/dept/its/support/kerberos/dist/krb5.conf -- I 
just downloaded it, and was able to install it to /etc/krb5.conf.

With the krb5.conf installed, I repeated my original test.  Here are the 
results:

* MacPorts MIT Kerberos `kdestroy -A`
* MacPorts MIT Kerberos `kinit -F akkornel at stanford.edu` -- works
* MacPorts MIT Kerberos `kinit -F akkornel/root at stanford.edu` -- works!
* MacPorts MIT Kerberos `klist -l` -- lists two credential caches!

To confirm your hypothesis, I edited the downloaded /etc/krb5.conf, 
removing the default_realm entry.  I then re-ran the tests with MIT 
Kerberos:

* MacPorts MIT Kerberos `kdestroy -A`
* MacPorts MIT Kerberos `kinit -F akkornel at stanford.edu` -- works
* MacPorts MIT Kerberos `kinit -F akkornel/root at stanford.edu` -- fails
* MacPorts MIT Kerberos `klist -l` -- lists a single credentials cache, 
for akkornel at stanford.edu

And I then did the same tests with the MIT Kerberos that I built:

* `~/bin/krb5/bin/kdestroy -A`
* `~/bin/krb5/bin/kinit -F akkornel at stanford.edu` -- works
* `~/bin/krb5/bin/kinit -F akkornel/root at stanford.edu` -- fails
* `~/bin/krb5/bin/klist -l` -- lists a single credentials cache, for 
akkornel at stanford.edu

So, I think your hypothesis is confirmed:

If you already have a credentials cache (created against one principal), 
and you use `kinit` with a different principal, and you do not have a 
default realm set, then `kinit` will fail with an "Internal credentials 
cache error while generating new ccache" error.

Still, I would like to get confirmation by looking at the syslog.  And 
it's been a heck of a time trying to figure out how to enable logging.

> It looks like this is in the MITKerberosShim package, specifically
> ccache.c.  And it looks like it calls the macro LOG_FAILURE(), which
> calls the function mshim_failure(), in misc.c.  It looks like THAT 
> might
> turn on logging if you create the preference file
> 
> /Library/Preferences/com.apple.MITKerberosShim

In init_log(), it looks like CopyKeyFromFile() is defined up in misc.c, 
starting at line 60.  It ends up looking for the file at path 
"/Library/Preferences/com.apple.MITKerberosShim.plist".  So, I used 
these two commands to create the plist and populate it:

sudo plutil -create xml1 
/Library/Preferences/com.apple.MITKerberosShim.plist
sudo plutil -insert EnableDebugging -bool True 
/Library/Preferences/com.apple.MITKerberosShim.plist

Even so, when I check in the Console app, I do not see anything being 
logged.  I do see that mshim_failure() calls init_log(), and it seems to 
have a mechanism to ensure that log init is only performed once.  Maybe 
I need to reboot?

I do have an OS update to do, so I'll leave the plist file created, and 
see if I start getting debug logs after a reboot.

> In api_macos_gen_new(), we call cc_context_create_new_ccache() with:
> 
>     err = cc_context_create_new_ccache(cc_context, cc_credentials_v5, 
> "",
>                                        &cc_ccache);
> 
> The third argument is supposed to be the principal name, and I thought
> "" was valid, but maybe technically it isn't, especially if you don't
> have a principal name defined?

I had a look through https://github.com/apple-oss-distributions/Heimdal, 
looking for calls to `create_new_ccache`.  I found create_new_ccache was 
called at three places:

* In acc_get_name(): The code calls _krb5_get_default_principal_local(), 
uses the resulting principal to call krb5_unparse_name(), and then uses 
the resulting name in create_new_ccache().

* In acc_initialize(): A principal is provided as a function parameter, 
which is passed to krb5_unparse_name(), and the resulting name is sent 
to create_new_ccache().

* In acc_move(): The call is only used if the destination cache does not 
exist.  get_principal() is called with the source cache, and the 
resulting name is sent to create_new_ccache().

So, at least in Heimdal, all of the call sites for create_new_ccache do 
provide a principal name.

I wonder, maybe there's an alternate path for creating a credentials 
cache?

~ Karl


More information about the Kerberos mailing list