KrbException "Message Stream Modified (41)" when connecting to SMB share using Kerberos

Dieter Hubau picture Dieter Hubau · Jan 8, 2014 · Viewed 19.3k times · Source

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?

Answer

Yahya picture Yahya · Sep 8, 2014

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/