Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8079627

Login with Krb5LoginModule fails if no default realm is set

XMLWordPrintable

      FULL PRODUCT VERSION :
      Java(TM) SE Runtime Environment (build 1.7.0_76-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 24.76-b04, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.3.9600]

      A DESCRIPTION OF THE PROBLEM :
      Up to JDK6, Krb5LoginModule has been working fine without any default realm configured, as long as the provided principal name includes a realm. In JDK7 (and supposedly in JDK8 also), it fails with saying "Cannot locate default realm."
      The error occurs at the point where it initializes a PrincipalName for krbtgt service principal before accessing the AS. It uses an overloaded constructor for PrincipalName which initializes its realm with the default realm. In JDK6, krb5.Config.getDefaultRealm() silently returned null if no default realm is set; in JDK7, it throws KrbException. The change occurred with the commit for implementing the following RFE.
      JDK-6785456 : Read Kerberos setting from Windows environment variables

      Since the realm name for this service principal is never used, it is no use setting it to the default realm or anything. So I suppose it should use another overloaded constructor for PrincipalName which leaves the realm part uninitialized.
      KrbAsReq(...)
              if (sname == null) {
                  sname = new PrincipalName("krbtgt" +
                                            PrincipalName.NAME_COMPONENT_SEPARATOR +
                                            cname.getRealmAsString(),
                                  PrincipalName.KRB_NT_SRV_INST);
              }
      ->
              if (sname == null) {
                  String[] snameParts = new String[] { "krbtgt", cname.getRealmAsString() };
                  sname = new PrincipalName(snameParts, PrincipalName.KRB_NT_SRV_INST);
              }


      REGRESSION. Last worked in version 6u45

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Please change the domain name / the user name / the password according to your test environment.
      * Create krb.conf as follows:
      [realms]
      MYDOMAIN.LOCAL = {
       kdc = mydc.mydomain.local:88
      }
      * Create login.conf as follows:
      Krb5Login {
       com.sun.security.auth.module.Krb5LoginModule required debug=true;
      };
      * Reset USERDNSDOMAIN environment variable if set (since you are logging in as a domain user)
      set USERDNSDOMAIN=
      Compile and run the test case as follows:
      java -Djava.security.krb5.conf=krb5.conf -Djava.security.auth.login.config=login.conf TestAuth

      Note that as long as you have ANYTHING set to default_realm in krb5.conf or USERDNSDOMAIN, it would pass.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      As you get with JDK6, the login attempt shoud succeed.

      Debug is true storeKey false useTicketCache false useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is false principal is null tryFirstPass is false useFirstPass is false storePass is false clearPass is false
                      [Krb5LoginModule] user entered username: DomUser01@MYDOMAIN.LOCAL

      Acquire TGT using AS Exchange
      principal is DomUser01@MYDOMAIN.LOCAL
      EncryptionKey: keyType=3 keyBytes (hex dump)=0000: 73 F4 3D 23 BF 75 83 A8
      EncryptionKey: keyType=1 keyBytes (hex dump)=0000: 73 F4 3D 23 BF 75 83 A8
      EncryptionKey: keyType=23 keyBytes (hex dump)=0000: D9 DE A9 F7 8F 03 ED A5 D0 EE D3 7B FD 2B 02 25 .............+.%

      EncryptionKey: keyType=16 keyBytes (hex dump)=0000: 9E 2F FD 0E D3 92 E9 FE E0 5E 29 AB E3 64 F1 F7 ./.......^)..d..
      0010: 15 4A 57 AE EF A4 F4 4A
      EncryptionKey: keyType=17 keyBytes (hex dump)=0000: FB 57 7A 00 40 76 D1 CB 06 D5 36 9D E8 F5 45 63 .Wz.@v....6...Ec

      Commit Succeeded

      サブジェクト:
              主体: DomUser01@MYDOMAIN.LOCAL
              非公開資格: Ticket (hex) = ...

      Client Principal = DomUser01@MYDOMAIN.LOCAL
      Server Principal = krbtgt/MYDOMAIN.LOCAL@MYDOMAIN.LOCAL
      Session Key = EncryptionKey: keyType=23 keyBytes (hex dump)=
      0000: 8E D9 A6 AD 0F 72 87 57 C1 BC F4 46 B1 BC 07 2E .....r.W...F....


      Forwardable Ticket false
      Forwarded Ticket false
      Proxiable Ticket false
      Proxy Ticket false
      Postdated Ticket false
      Renewable Ticket false
      Initial Ticket false
      Auth Time = Thu Mar 12 13:06:24 JST 2015
      Start Time = Thu Mar 12 13:06:24 JST 2015
      End Time = Thu Mar 12 23:06:24 JST 2015
      Renew Till = null
      Client Addresses Null

      ACTUAL -
      The login attempt fails.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Debug is true storeKey false useTicketCache false useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is false principal is null tryFirstPass is false useFirstPass is false storePass is false clearPass is false
                      [Krb5LoginModule] user entered username: DomUser01@MYDOMAIN.LOCAL
                      [Krb5LoginModule] authentication failed
      Cannot locate default realm
      Exception in thread "main" javax.security.auth.login.LoginException: Cannot locate default realm
              at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:763)
              at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:584)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.lang.reflect.Method.invoke(Method.java:606)
              at javax.security.auth.login.LoginContext.invoke(LoginContext.java:762)
              at javax.security.auth.login.LoginContext.access$000(LoginContext.java:203)
              at javax.security.auth.login.LoginContext$4.run(LoginContext.java:690)
              at javax.security.auth.login.LoginContext$4.run(LoginContext.java:688)
              at java.security.AccessController.doPrivileged(Native Method)
              at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:687)
              at javax.security.auth.login.LoginContext.login(LoginContext.java:595)
              at TestAuth.main(TestAuth.java:25)
      Caused by: KrbException: Cannot locate default realm
              at sun.security.krb5.PrincipalName.<init>(PrincipalName.java:367)
              at sun.security.krb5.KrbAsReq.<init>(KrbAsReq.java:118)
              at sun.security.krb5.KrbAsReqBuilder.build(KrbAsReqBuilder.java:268)
              at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:318)
              at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:364)
              at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:725)
              ... 13 more
      Caused by: KrbException: Cannot locate default realm
              at sun.security.krb5.Config.getDefaultRealm(Config.java:1181)
              at sun.security.krb5.PrincipalName.<init>(PrincipalName.java:365)
              ... 18 more
      Caused by: KrbException: Generic error (description in e-text) (60) - Unable to locate Kerberos realm
              at sun.security.krb5.Config.getRealmFromDNS(Config.java:1277)
              at sun.security.krb5.Config.getDefaultRealm(Config.java:1162)
              ... 19 more


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.security.auth.login.*;
      import javax.security.auth.callback.*;

      public class TestAuth {
       public static void main(String[] args) throws Exception {
        CallbackHandler ch = new CallbackHandler() {
         public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
          for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof TextOutputCallback) {
                TextOutputCallback toc = (TextOutputCallback)callbacks[i];
                System.out.println(toc.getMessage());
            } else if (callbacks[i] instanceof NameCallback) {
                NameCallback nc = (NameCallback)callbacks[i];
                nc.setName("DomUser01@MYDOMAIN.LOCAL");
            } else if (callbacks[i] instanceof PasswordCallback) {
                PasswordCallback pc = (PasswordCallback)callbacks[i];
                pc.setPassword("P@ssword0".toCharArray());
            }
          }
         }
        };
        LoginContext lc = new LoginContext("Krb5Login", ch);
        lc.login();
        System.out.println(lc.getSubject());
       }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Set ANYTHING as default_realm in krb5.conf

            psonal Pallavi Sonal (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: