title: GSSException: Message stream modified (41)
body: <p>I'm working with an LDAP in forest architecture (all servers and my server are windows). I'm binding to the AD using NTLM authentication.</p>
  
  <p>I have a JAVA code that perform the operations against the LDAP server.</p>
  
  <p>The code is wrapped as a tomcat servlet.</p>
  
  <p>When running the JAVA code directly (just executing the LDAP authentication code as an application), the bind works both against the local domain (local domain = I logged in to windows, and ran this process with a user of this domain) and foreign domains.</p>
  
  <p>When running the JAVA code as a servlet, the bind works and authenticates users from one domain but does not work if I'm trying to authenticate users from other domain, it won't work (it will work only if I'll restart tomcat).</p>
  
  <p>I'm getting an exception:</p>
  
  <pre><code>GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Message stream modified (41))]]
  </code></pre>
  
  <p>I'll mention that it is the same code, with the same configurations and the same krb5 file.</p>
  
  <p><strong>Edit:</strong>
  More information:</p>
  
  <p>This is my code:</p>
  
  <pre><code>public void func(String realm, String kdc) {
      try {
        URL configURL = getClass().getResource("jaas_ntlm_configuration.txt");
          System.setProperty("java.security.auth.login.config", configURL.toString());
  
              System.setProperty("java.security.krb5.realm", realm);
              System.setProperty("java.security.krb5.kdc",kdc);
  
          // If the application is run on NT rather than Unix, use this name
          String loginAppName = "MyConfig";
  
          // Create login context
          LoginContext lc = new LoginContext(loginAppName, new SampleCallbackHandler());
  
          // Retrieve the information on the logged-in user
          lc.login();
  
          // Get the authenticated subject
          Subject subject = lc.getSubject();
  
          System.out.println(subject.toString());
  
          Subject.doAs(subject, new JndiAction(new String[] { "" }));
      }
      catch (LoginException e) {
        e.printStackTrace();
      }
  }
  
  class JndiAction implements java.security.PrivilegedAction {
      private String[] args;
  
      public JndiAction(String[] origArgs) {
          this.args = (String[])origArgs.clone();
      }
  
      public Object run() {
          performJndiOperation(args);
          return null;
      }
  
      private static void performJndiOperation(String[] args) {
  
          // Set up environment for creating initial context
          Hashtable env = new Hashtable(11);
  
          env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
  
          // Must use fully qualified hostname
          env.put(Context.PROVIDER_URL, "ldap://server:389");
  
          // Request the use of the "GSSAPI" SASL mechanism
          // Authenticate by using already established Kerberos credentials
          env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
  
          try {
              // Create the initial context
              DirContext ctx = new InitialLdapContext(env, null);
  
  
              // Close the context when we're done
              ctx.close();
          } catch (NamingException e) {
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>And my jaas_ntlm_configuration.txt file contains:</p>
  
  <pre><code>MyConfig { com.sun.security.auth.module.Krb5LoginModule required
  useTicketCache=true
  doNotPrompt=false;
  };
  </code></pre>
  
  <p>My krb5.conf file is:</p>
  
  <pre><code># 
  # All rights reserved.
  #
  #pragma ident   @(#)krb5.conf   1.1 00/12/08
  
  [libdefaults]
      default_tkt_enctypes = des3-cbc-sha1 des-cbc-md5 des-cbc-crc
      default_tgs_enctypes = des3-cbc-sha1 des-cbc-md5 des-cbc-crc
      forwardable  = true
      renewable  = true
      noaddresses = true
      clockskew  = 300
  
  [realms]
          SUB1.DOMAIN.COM = {
                  kdc = DDC.SUB1.DOMAIN.COM
          default_domain=DOMAIN.COM
          }
      SUB2.DOMAIN.COM = {
                  kdc = DDC.SUB.DOMAIN.COM
          default_domain=DOMAIN.COM
          }
      SUB3.DOMAIN.COM = {
                  kdc = DDC.SUB3.DOMAIN.COM
          default_domain=DOMAIN.COM
          }
  
  [domain_realm]
      .DOMAIN.COM = SUB1.DOMAIN.COM
      .DOMAIN.COM = SUB2.DOMAIN.COM
      .DOMAIN.COM = SUB3.DOMAIN.COM
  
  [logging]
          default = FILE:/var/krb5/kdc.log
          kdc = FILE:/var/krb5/kdc.log
      kdc_rotate = {
  
  # How often to rotate kdc.log. Logs will get rotated no more
  # often than the period, and less often if the KDC is not used
  # frequently.
  
          period = 1d
  
  # how many versions of kdc.log to keep around (kdc.log.0, kdc.log.1, ...)
  
          versions = 10
      }
  
  [appdefaults]   
      kinit = {
          renewable = true
          forwardable= true
      }
      rlogin = {
          forwardable= true
      }
      rsh = {
          forwardable= true
      }
      telnet = {
              autologin = true 
          forwardable= true
      }
  </code></pre>
  
  <p>I added the following as java parameters:</p>
  
  <pre><code>-Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.krb5.conf="krb5.conf" -Dsun.security.krb5.debug=true
  </code></pre>
  
  <p>If I call func("SUB*.DOMAIN.COM", "DDC.SUB*.DOMAIN.COM") always with the same subdomain - it will work, but if I'll call with one subdomain and then with another, the second will fail.</p>
  
  <p><strong>More information:</strong></p>
  
  <p>Here is the output with krb5.debug=true:</p>
  
  <pre><code>java -Xmx100m -cp gssapi_test.jar -Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.krb5.conf="krb5.conf" -Dsun.security.krb5.debug=true  gssapitest.myTest my_config.txt
  2 users provided. Performing authentication #1
  Reading configuration file my_config.txt
  kdc: DDC.SUB1.DOMAIN.COM, realm: SUB1.DOMAIN.COM
  &gt;&gt;&gt;KinitOptions cache name is C:\Users\user1\krb5cc_user1
  &gt;&gt; Acquire default native Credentials
  &gt;&gt;&gt; Obtained TGT from LSA: Credentials:
  client=user1@SUB1.DOMAIN.COM
  server=krbtgt/SUB1.DOMAIN.COM@SUB1.DOMAIN.COM
  authTime=20130422075139Z
  startTime=20130422075139Z
  endTime=20130422175139Z
  renewTill=20130429075139Z
  flags: FORWARDABLE;RENEWABLE;INITIAL;PRE-AUTHENT
  EType (int): 23
  Subject:
      Principal: user1@SUB1.DOMAIN.COM
      Private Credential: Ticket (hex) = 
  .....
  
  Client Principal = user1@SUB1.DOMAIN.COM
  Server Principal = krbtgt/SUB1.DOMAIN.COM@SUB1.DOMAIN.COM
  Session Key = EncryptionKey: keyType=23 keyBytes (hex dump)=
  0000: 2B 8C 97 3C 8E 83 66 F1   6D 58 6C 37 20 0E 1F 53  +..&lt;..f.mXl7 ..S
  
  
  Forwardable Ticket true
  Forwarded Ticket false
  Proxiable Ticket false
  Proxy Ticket false
  Postdated Ticket false
  Renewable Ticket true
  Initial Ticket true
  Auth Time = Mon Apr 22 15:51:39 2013
  Start Time = Mon Apr 22 15:51:39 2013
  End Time = Tue Apr 23 01:51:39 2013
  Renew Till = Mon Apr 29 15:51:39 2013
  Client Addresses  Null 
  
  Connecting to LDAP
  Config name: krb5.conf
  Found ticket for user1@SUB1.DOMAIN.COM to go to krbtgt/SUB1.DOMAIN.COM@SUB1.DOMAIN.COM expiring on Tue Apr 23 01:51:39 2013
  Entered Krb5Context.initSecContext with state=STATE_NEW
  Service ticket not found in the subject
  &gt;&gt;&gt; Credentials acquireServiceCreds: same realm
  default etypes for default_tgs_enctypes: 16 3 1.
  &gt;&gt;&gt; CksumType: sun.security.krb5.internal.crypto.RsaMd5CksumType
  &gt;&gt;&gt; EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
  &gt;&gt;&gt; KdcAccessibility: reset
  &gt;&gt;&gt; KrbKdcReq send: kdc=DDC.SUB1.DOMAIN.COM UDP:88, timeout=30000, number of retries =3, #bytes=1554
  &gt;&gt;&gt; KDCCommunication: kdc=DDC.SUB1.DOMAIN.COM UDP:88, timeout=30000,Attempt =1, #bytes=1554
  &gt;&gt;&gt; KrbKdcReq send: #bytes read=107
  &gt;&gt;&gt; KrbKdcReq send: kdc=DDC.SUB1.DOMAIN.COM TCP:88, timeout=30000, number of retries =3, #bytes=1554
  &gt;&gt;&gt; KDCCommunication: kdc=DDC.SUB1.DOMAIN.COM TCP:88, timeout=30000,Attempt =1, #bytes=1554
  &gt;&gt;&gt;DEBUG: TCPClient reading 1497 bytes
  &gt;&gt;&gt; KrbKdcReq send: #bytes read=1497
  &gt;&gt;&gt; KdcAccessibility: remove DDC.SUB1.DOMAIN.COM
  &gt;&gt;&gt; EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
  &gt;&gt;&gt; KrbApReq: APOptions are 00000000 00000000 00000000 00000000
  &gt;&gt;&gt; EType: sun.security.krb5.internal.crypto.DesCbcMd5EType
  Krb5Context setting mySeqNumber to: 1005735013
  Krb5Context setting peerSeqNumber to: 0
  Created InitSecContextToken:
  .....
  
  Krb5Context.unwrap: token=[60 33 06 09 2a 86 48 86 f7 12 01 02 02 02 01 00 00 ff ff ff ff 94 52 14 5b f6 02 28 1c a4 3c c5 8f 03 9c a2 d6 e5 f6 f1 18 ed 6f 16 ab 07 a0 00 00 04 04 04 04 ]
  Krb5Context.unwrap: data=[07 a0 00 00 ]
  Krb5Context.wrap: data=[01 01 00 00 ]
  Krb5Context.wrap: token=[60 33 06 09 2a 86 48 86 f7 12 01 02 02 02 01 00 00 ff ff ff ff 2d b6 92 0d d9 51 da aa ef 41 67 33 5c de b3 e6 ce 9a 46 31 a0 a8 0e 27 01 01 00 00 04 04 04 04 ]
  Connected
  Disconnected
  #1: Done
  Performing authentication #2
  Reading configuration file my_config.txt
  kdc: DDC.SUB2.DOMAIN.COM, realm: SUB2.DOMAIN.COM
  &gt;&gt;&gt;KinitOptions cache name is C:\Users\user1\krb5cc_user1
  &gt;&gt; Acquire default native Credentials
  &gt;&gt;&gt; Obtained TGT from LSA: Credentials:
  client=user1@SUB1.DOMAIN.COM
  server=krbtgt/SUB1.DOMAIN.COM@SUB1.DOMAIN.COM
  authTime=20130422075139Z
  startTime=20130422075139Z
  endTime=20130422175139Z
  renewTill=20130429075139Z
  flags: FORWARDABLE;RENEWABLE;INITIAL;PRE-AUTHENT
  EType (int): 23
  Subject:
      Principal: user1@SUB1.DOMAIN.COM
      Private Credential: Ticket (hex) = 
  .....
  
  Client Principal = user1@SUB1.DOMAIN.COM
  Server Principal = krbtgt/SUB1.DOMAIN.COM@SUB1.DOMAIN.COM
  Session Key = EncryptionKey: keyType=23 keyBytes (hex dump)=
  0000: 2B 8C 97 3C 8E 83 66 F1   6D 58 6C 37 20 0E 1F 53  +..&lt;..f.mXl7 ..S
  
  
  Forwardable Ticket true
  Forwarded Ticket false
  Proxiable Ticket false
  Proxy Ticket false
  Postdated Ticket false
  Renewable Ticket true
  Initial Ticket true
  Auth Time = Mon Apr 22 15:51:39 2013
  Start Time = Mon Apr 22 15:51:39 2013
  End Time = Tue Apr 23 01:51:39 2013
  Renew Till = Mon Apr 29 15:51:39 2013
  Client Addresses  Null 
  
  Connecting to LDAP
  Found ticket for user1@SUB1.DOMAIN.COM to go to krbtgt/SUB1.DOMAIN.COM@SUB1.DOMAIN.COM expiring on Tue Apr 23 01:51:39 2013
  Entered Krb5Context.initSecContext with state=STATE_NEW
  Service ticket not found in the subject
  &gt;&gt;&gt; Credentials acquireServiceCreds: same realm
  default etypes for default_tgs_enctypes: 16 3 1.
  &gt;&gt;&gt; CksumType: sun.security.krb5.internal.crypto.RsaMd5CksumType
  &gt;&gt;&gt; EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
  &gt;&gt;&gt; KrbKdcReq send: kdc=DDC.SUB1.DOMAIN.COM UDP:88, timeout=30000, number of retries =3, #bytes=1554
  &gt;&gt;&gt; KDCCommunication: kdc=DDC.SUB1.DOMAIN.COM UDP:88, timeout=30000,Attempt =1, #bytes=1554
  &gt;&gt;&gt; KrbKdcReq send: #bytes read=107
  &gt;&gt;&gt; KrbKdcReq send: kdc=DDC.SUB1.DOMAIN.COM TCP:88, timeout=30000, number of retries =3, #bytes=1554
  &gt;&gt;&gt; KDCCommunication: kdc=DDC.SUB1.DOMAIN.COM TCP:88, timeout=30000,Attempt =1, #bytes=1554
  &gt;&gt;&gt;DEBUG: TCPClient reading 1482 bytes
  &gt;&gt;&gt; KrbKdcReq send: #bytes read=1482
  &gt;&gt;&gt; KdcAccessibility: remove DDC.SUB1.DOMAIN.COM
  &gt;&gt;&gt; EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
  KrbException: Message stream modified (41)
      at sun.security.krb5.KrbKdcRep.check(Unknown Source)
      at sun.security.krb5.KrbTgsRep.&lt;init&gt;(Unknown Source)
      at sun.security.krb5.KrbTgsReq.getReply(Unknown Source)
      at sun.security.krb5.KrbTgsReq.sendAndGetCreds(Unknown Source)
      at sun.security.krb5.internal.CredentialsUtil.serviceCreds(Unknown Source)
      at sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(Unknown Source)
      at sun.security.krb5.Credentials.acquireServiceCreds(Unknown Source)
      at sun.security.jgss.krb5.Krb5Context.initSecContext(Unknown Source)
      at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
      at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
      at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(Unknown Source)
      at com.sun.jndi.ldap.sasl.LdapSasl.saslBind(Unknown Source)
      at com.sun.jndi.ldap.LdapClient.authenticate(Unknown Source)
      at com.sun.jndi.ldap.LdapCtx.connect(Unknown Source)
      at com.sun.jndi.ldap.LdapCtx.&lt;init&gt;(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source)
      at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
      at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
      at javax.naming.InitialContext.init(Unknown Source)
      at javax.naming.ldap.InitialLdapContext.&lt;init&gt;(Unknown Source)
      at gssapitest.JndiAction.performJndiOperation(myTest.java:603)
      at gssapitest.JndiAction.run(myTest.java:577)
      at java.security.AccessController.doPrivileged(Native Method)
      at javax.security.auth.Subject.doAs(Unknown Source)
      at gssapitest.myTest.Do(myTest.java:59)
      at gssapitest.myTest.main(myTest.java:513)
  javax.naming.AuthenticationException: GSSAPI [Root exception is javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Message stream modified (41))]]
      at com.sun.jndi.ldap.sasl.LdapSasl.saslBind(Unknown Source)
      at com.sun.jndi.ldap.LdapClient.authenticate(Unknown Source)
      at com.sun.jndi.ldap.LdapCtx.connect(Unknown Source)
      at com.sun.jndi.ldap.LdapCtx.&lt;init&gt;(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source)
      at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
      at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
      at javax.naming.InitialContext.init(Unknown Source)
      at javax.naming.ldap.InitialLdapContext.&lt;init&gt;(Unknown Source)
      at gssapitest.JndiAction.performJndiOperation(myTest.java:603)
      at gssapitest.JndiAction.run(myTest.java:577)
      at java.security.AccessController.doPrivileged(Native Method)
      at javax.security.auth.Subject.doAs(Unknown Source)
      at gssapitest.myTest.Do(myTest.java:59)
      at gssapitest.myTest.main(myTest.java:513)
  Caused by: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Message stream modified (41))]
      at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(Unknown Source)
      ... 18 more
  Caused by: GSSException: No valid credentials provided (Mechanism level: Message stream modified (41))
      at sun.security.jgss.krb5.Krb5Context.initSecContext(Unknown Source)
      at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
      at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
      ... 19 more
  Caused by: KrbException: Message stream modified (41)
      at sun.security.krb5.KrbKdcRep.check(Unknown Source)
      at sun.security.krb5.KrbTgsRep.&lt;init&gt;(Unknown Source)
      at sun.security.krb5.KrbTgsReq.getReply(Unknown Source)
      at sun.security.krb5.KrbTgsReq.sendAndGetCreds(Unknown Source)
      at sun.security.krb5.internal.CredentialsUtil.serviceCreds(Unknown Source)
      at sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(Unknown Source)
      at sun.security.krb5.Credentials.acquireServiceCreds(Unknown Source)
      ... 22 more
  FAILED
  </code></pre>
  
  <p>What can I do? Am I doings something wrongs?</p>
  
  <p>Thanks.</p>