KrbException "Message Stream Modified (41)" when connecting to SMB share using Kerberos
cifs, java, jcifs, kerberos, samba
Solution
Uppercase of the realm is very important to avoid "`Exception: krb_error 41 Message stream modified (41)`".
See http://sourceforge.net/p/spnego/discussion/1003769/thread/99b3ff67/
Problem
I'm having some issues with Kerberos authentication to perform file management with JCifs (Kerberos extension version 1.3.17) This is my current configuration of krb5.conf: ``` [libdefaults] default_realm = <REALM_NAME_UPPERCASE> udp_preference_limit = 1 [realms] <REALM_NAME_UPPERCASE> = { kdc = <DOMAIN_NAME_UPPERCASE>:88 admin_server = <DOMAIN_NAME_UPPERCASE> default_domain = <DOMAIN_NAME_UPPERCASE> } [domain_realm] .<domain_name> = <REALM_NAME_UPPERCASE> <domain_name> = <REALM_NAME_UPPERCASE> [appdefaults] kinit = { renewable = true forwardable = true } ``` And this is code authenticating the user and then trying to find a file on a fileserver in the network: ``` public static void main (String[] args) throws Exception { Subject subject = new Subject(); System.setProperty("java.security.krb5.conf", "C:/krb5.conf"); System.setProperty("sun.security.krb5.debug", "true"); Map<String, Object> state = new HashMap<String, Object>(); state.put("javax.security.auth.login.name", "USERNAME"); state.put("javax.security.auth.login.password", "PASSWORD".toCharArray()); Map<String, Object> options = new HashMap<String, Object>(); options.put("debug", "true"); options.put("useFirstPass", "true"); Krb5LoginModule login = new Krb5LoginModule(); login.initialize(subject, null, state, options); if (login.login()) { login.commit(); } String path = "file://HOST/242269/"; // existing file server folder Kerb5Authenticator kerberosAuthenticator = new Kerb5Authenticator(subject); SmbFile smbFile = new SmbFile(path, kerberosAuthenticator); SmbFile[] files = smbFile.listFiles(); for (SmbFile file : files) { System.out.println(file); } } ``` Now, when I run this code, it says it can authenticate the user with those credentials (when I change the credentials, authentication fails) and it creates a ticket for this user. When I later on try to retrieve the content of a file directory over CIFS, it gives me the following error: ``` 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) at jcifs.smb.SpnegoContext.initSecContext(SpnegoContext.java:80) at jcifs.smb.Kerb5Authenticator.setup(Kerb5Authenticator.java:196) at jcifs.smb.Kerb5Authenticator.access$000(Kerb5Authenticator.java:30) at jcifs.smb.Kerb5Authenticator$1.run(Kerb5Authenticator.java:168) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Unknown Source) at jcifs.smb.Kerb5Authenticator.sessionSetup(Kerb5Authenticator.java:166) at jcifs.smb.SmbSession.sessionSetup(SmbSession.java:320) at jcifs.smb.SmbSession.send(SmbSession.java:239) at jcifs.smb.SmbTree.treeConnect(SmbTree.java:176) at jcifs.smb.SmbFile.doConnect(SmbFile.java:925) at jcifs.smb.SmbFile.connect(SmbFile.java:974) at jcifs.smb.SmbFile.connect0(SmbFile.java:890) at jcifs.smb.SmbFile.resolveDfs(SmbFile.java:669) at jcifs.smb.SmbFile.send(SmbFile.java:783) at jcifs.smb.SmbFile.doFindFirstNext(SmbFile.java:2009) at jcifs.smb.SmbFile.doEnum(SmbFile.java:1758) at jcifs.smb.SmbFile.listFiles(SmbFile.java:1735) at jcifs.smb.SmbFile.listFiles(SmbFile.java:1668) ``` You can find the complete error log here (some details are obfuscated) Could someone please get me going in the right direction as to what I'm doing wrong here?