JDK-8029994 : Support "include" and "includedir" in krb5.conf
  • Type: Enhancement
  • Component: security-libs
  • Sub-Component: org.ietf.jgss:krb5
  • Affected Version: 8
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • Submitted: 2013-12-11
  • Updated: 2019-08-16
  • Resolved: 2014-06-20
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8-poolResolved 9 b22Fixed
Related Reports
Relates :  
Relates :  
Sub Tasks
JDK-8177084 :  
Description
FULL PRODUCT VERSION :
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b119)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b61, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux XXX.deshaw.com 2.6.32-358.18.1.el6.4.deshaw.x86_64 #1 SMP Fri Oct 11 16:57:25 BST 2013 x86_64 x86_64 x86_64 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
The changes in http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/33e29fbc3e5b cause the sun.security.krb5.Config class to fail to parse an /etc/krb5.conf file containing an "includedir" directive, because that directive will appear at the start of the file, before the first "section".  This will result in an exception being thrown and the Kerberos operation failing.

REGRESSION.  Last worked in version 7u40

ADDITIONAL REGRESSION INFORMATION:
java version "1.7.0_40"
Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode)


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Take an auth config file that looks like this, which we'll call jaas.config:

-----------------
KrbLogin {
    com.sun.security.auth.module.Krb5LoginModule sufficient
        useTicketCache="true";
};

com.sun.security.jgss.krb5.initiate
{
        com.sun.security.auth.module.Krb5LoginModule required
        doNotPrompt=true
        useTicketCache=true
        debug=false;
};
-----------------

Then use an /etc/krb5.conf file that contains an "includedir" directive at the top, as specified by http://web.mit.edu/~kerberos/krb5-devel/doc/admin/conf_files/krb5_conf.html.  Run the KerberosBug class provided elsewhere in this request with those two files, using a command like the following:

java -Djava.security.auth.login.config=jaas.config -Djava.security.krb5.conf=krb5.conf KerberosBug


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect the program to run without printing anything.  If you run with jdk7, this is what you'll see.
ACTUAL -
In jdk8, you see the following:

     [java] Exception in thread "main" javax.security.auth.login.LoginException: KrbException: Config file must starts with a section
     [java] at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:804)
     [java] at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
     [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     [java] at java.lang.reflect.Method.invoke(Method.java:483)
     [java] at javax.security.auth.login.LoginContext.invoke(LoginContext.java:777)
     [java] at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
     [java] at javax.security.auth.login.LoginContext$4.run(LoginContext.java:690)
     [java] at javax.security.auth.login.LoginContext$4.run(LoginContext.java:688)
     [java] at java.security.AccessController.doPrivileged(Native Method)
     [java] at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:688)
     [java] at javax.security.auth.login.LoginContext.login(LoginContext.java:586)
     [java] at KerberosBug.main(KerberosBug.java:26)
     [java] Caused by: KrbException: KrbException: Config file must starts with a section
     [java] at sun.security.krb5.Realm.getDefault(Realm.java:62)
     [java] at sun.security.krb5.PrincipalName.<init>(PrincipalName.java:451)
     [java] at sun.security.krb5.PrincipalName.<init>(PrincipalName.java:460)
     [java] at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:706)
     [java] ... 13 more
     [java] Caused by: KrbException: Config file must starts with a section
     [java] at sun.security.krb5.Config.loadConfigFile(Config.java:553)
     [java] at sun.security.krb5.Config.<init>(Config.java:176)
     [java] at sun.security.krb5.Config.getInstance(Config.java:98)
     [java] at sun.security.krb5.Realm.getDefault(Realm.java:58)
     [java] ... 16 more
     [java] Java Result: 1

As a result of this error, the Kerberos operation fails.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
You see the following exception:

     [java] Exception in thread "main" javax.security.auth.login.LoginException: KrbException: Config file must starts with a section
     [java] at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:804)
     [java] at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
     [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     [java] at java.lang.reflect.Method.invoke(Method.java:483)
     [java] at javax.security.auth.login.LoginContext.invoke(LoginContext.java:777)
     [java] at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
     [java] at javax.security.auth.login.LoginContext$4.run(LoginContext.java:690)
     [java] at javax.security.auth.login.LoginContext$4.run(LoginContext.java:688)
     [java] at java.security.AccessController.doPrivileged(Native Method)
     [java] at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:688)
     [java] at javax.security.auth.login.LoginContext.login(LoginContext.java:586)
     [java] at KerberosBug.main(KerberosBug.java:26)
     [java] Caused by: KrbException: KrbException: Config file must starts with a section
     [java] at sun.security.krb5.Realm.getDefault(Realm.java:62)
     [java] at sun.security.krb5.PrincipalName.<init>(PrincipalName.java:451)
     [java] at sun.security.krb5.PrincipalName.<init>(PrincipalName.java:460)
     [java] at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:706)
     [java] ... 13 more
     [java] Caused by: KrbException: Config file must starts with a section
     [java] at sun.security.krb5.Config.loadConfigFile(Config.java:553)
     [java] at sun.security.krb5.Config.<init>(Config.java:176)
     [java] at sun.security.krb5.Config.getInstance(Config.java:98)
     [java] at sun.security.krb5.Realm.getDefault(Realm.java:58)
     [java] ... 16 more
     [java] Java Result: 1


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginContext;

public class KerberosBug
{
    private static class CBHandler implements CallbackHandler
    {
        @Override
        public void handle(Callback[] callbacks)
        {
            // No need to do anything
        }
    }

    /**
     * Test method which will throw an exception
     * if there's a problem.
     */
    public static void main(String[] args) throws Exception
    {
        LoginContext loginContext = new LoginContext(
            "KrbLogin",
            new CBHandler()
        );
        loginContext.login();
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
The only workaround is to manually remove the includedir directive from the krb5.conf file before starting the JVM.
Comments
release note: Before this enhancement, when the same setting for a single-valued option (say, default_realm) is defined more than once in krb5.conf, Oracle JDK chooses the last value, now it chooses the first, to be consistent with other krb5 vendors. However we don't suggest users doing this way.
26-02-2014

8-defer-request justification: This is an RFE instead of a bug. We will consider support it in a future release (8u20 and 9). Currently, user can remove the includedir directive and copy the content that needs to be included inside the krb5.conf file. Or, they can create an independent krb5.conf for Java and use it through the java.security.krb5.conf system property.
12-12-2013