RFR: 8349546: Linux support for Kerberos "nativeccache" functionality [v13]
Nick Hall
duke at openjdk.org
Tue Nov 18 18:59:07 UTC 2025
On Tue, 18 Nov 2025 12:21:09 GMT, Nick Hall <duke at openjdk.org> wrote:
>> _Purpose_
>>
>> This PR allows Linux based applications using JAAS to acquire Kerberos TGTs natively using the local system's Kerberos libraries/configuration, building on existing support on Windows/MacOSX.
>>
>> _Rationale_
>>
>> Currently the (pure java) JAAS codebase only supports file-based credential caches (ccaches). There are many other useful types of ccache accessible via the local system libraries; this change allows credentials to be acquired natively using those libraries, and thus adds support for all other ccache types supported by the local system (e.g. KCM, in-memory and kernel types), This support already exists on MacOSX and Windows.
>>
>> The code change here largely uses the MacOSX code, edited for Linux with associated build system changes. It also adds an appropriate jtreg test which uses some native test helper code to manufacture an in-memory cache, and then uses the new code to acquire these credentials natively. This has been tested on Linux/Mac and the jtreg test passes on each (I couldn't see any existing tests on MacOSX for this feature).
>>
>> Additionally this PR fixes a bug that's existed for a while (see L585-588 in `nativeccache.c`) - without this code, this is a 100% reproducible segfault on Linux (it's unclear why this hasn't affected the Mac JVMs up to now, probably just no calling code that provides an empty list of addresses). It also fixes a (non problem) typo in the variable name in a function prototype.
>>
>> _Implementation Detail_
>>
>> Note that there were multiple possible ways of doing this:
>>
>> 1) Duplicate the MacOSX `nativeccache.c`, edit lightly for Linux and build a new library on Linux only (`liblinuxkrb5`), leaving MacOSX largely unchanged, but at the expense of this code duplication.
>>
>> 2) Create a new shared library used on both platforms with conditional compilation to manage the differences. This necessitates a library name change on MacOSX and potentially knock-on packaging changes on that platform, which seemed a potentially expensive side-effect.
>>
>> 3) Create a shared `nativeccache.c` (using `EXTRA_SRC` in the build) and build separate MacOSX/Linux libraries. This allows the MacOSX library name to remain unchanged, and only adds a new library in Linux.
>>
>> I tried all three options; 3 seemed to be the best compromise all around, although is one of the options that effectively introduces a "no-op" change on MacOSX as a result. Hopefully the additional jtreg test is sufficient to compensat...
>
> Nick Hall has updated the pull request incrementally with one additional commit since the last revision:
>
> Clean up jtreg run/compile directives, attend to other review comments
For what it's worth, here's how this looks using KCM on a host...
...with libkrb5
krb5loginmodule[0x3|main|Krb5LoginModule.java:647|2025-11-18 13:30:45.208]: Acquire TGT from Cache
krb5loginmodule[0x3|main|Krb5LoginModule.java:678|2025-11-18 13:30:45.252]: Principal is user-redacted at REALM.REDACTED
krb5loginmodule[0x3|main|Krb5LoginModule.java:1140|2025-11-18 13:30:45.272]: Commit Succeeded
krb5loginmodule[0x3|main|Krb5LoginModule.java:1190|2025-11-18 13:30:45.273]: [Krb5LoginModule]: Entering logout
krb5loginmodule[0x3|main|Krb5LoginModule.java:1218|2025-11-18 13:30:45.273]: [Krb5LoginModule]: logged out Subject
...without libkrb5:
krb5loginmodule[0x3|main|Krb5LoginModule.java:647|2025-11-18 13:34:13.604]: Acquire TGT from Cache
Exception in thread "main" java.lang.UnsatisfiedLinkError: /path/redacted/jdk/build/linux-x86_64-server-release/jdk/lib/liblinuxkrb5.so: libkrb5.so.3: cannot open shared object file: No such file or directory
at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:326)
at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:187)
at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:129)
at java.base/jdk.internal.loader.NativeLibraries.findFromPaths(NativeLibraries.java:254)
at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:239)
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2315)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.base/java.lang.System.loadLibrary(System.java:1685)
at java.security.jgss/sun.security.krb5.Credentials.ensureLoaded(Credentials.java:535)
at java.security.jgss/sun.security.krb5.Credentials.acquireDefaultCreds(Credentials.java:449)
at java.security.jgss/sun.security.krb5.Credentials.acquireTGTFromCache(Credentials.java:335)
at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:649)
at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:601)
at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:603)
at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:460)
at RunWhoAmI.main(RunWhoAmI.java:22)
...without libkrb5, but with a small patch to also catch `UnsatisfiedLinkError`:
krb5loginmodule[0x3|main|Krb5LoginModule.java:647|2025-11-18 13:52:09.045]: Acquire TGT from Cache
krb5loginmodule[0x3|main|Krb5LoginModule.java:678|2025-11-18 13:52:09.053]: Principal is null
krb5loginmodule[0x3|main|Krb5LoginModule.java:681|2025-11-18 13:52:09.053]: null credentials from Ticket Cache
krb5loginmodule[0x3|main|Krb5LoginModule.java:608|2025-11-18 13:52:09.054]: [Krb5LoginModule] authentication failed
Unable to obtain Principal Name for authentication
Login failed
javax.security.auth.login.LoginException: Unable to obtain Principal Name for authentication
at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.promptForName(Krb5LoginModule.java:816)
at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:693)
at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:601)
at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:603)
at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:460)
at RunWhoAmI.main(RunWhoAmI.java:22)
-------------
PR Comment: https://git.openjdk.org/jdk/pull/28075#issuecomment-3549110005
More information about the security-dev
mailing list