JDK-8326538 : LDAP channel binding support not working with sun.security.jgss.native set to true
  • Type: Bug
  • Component: security-libs
  • Sub-Component: org.ietf.jgss
  • Affected Version: 17
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows
  • CPU: x86_64
  • Submitted: 2024-02-21
  • Updated: 2024-03-04
Related Reports
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
Java 17.0.10 running on Windows

A DESCRIPTION OF THE PROBLEM :
Setting sun.security.jgss.native to true is used to be able to skip setting up jaas and krb5 config files, enabling a passwordless access to a Windows active directory LDAP service. It seems however that when the Active Directory is configured with LdapEnforceChannelBinding set to a value 1 or 2 

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Same steps as mentioned in this issue: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8245527

The only change would be to use code in the field "Source code for an executable test case" instead.

To sum it up:

1. Have an AD domain controller with LdapEnforceChannelBinding set to 1 or 2
2. Execute the code provided. Important thing to highlight is the sun.security.jgss.native set to true

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I was able to query Windows AD LDAP service and retrieve information from it
ACTUAL -
I get the following error:

javax.naming.AuthenticationException: [LDAP: error code 49 - 80090346: LdapErr: DSID-0C090585, comment: AcceptSecurityContext error, data 80090346, v4563 ]

---------- BEGIN SOURCE ----------
package com.test.cbinding;

import com.sun.security.jgss.GSSUtil;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
import javax.security.auth.Subject;
import java.util.Hashtable;

public class LdapChannelBindingWithGSSAPI1 {

    public static String LDAPS_URL = "ldaps://yoururl.com";

    public static void main(String[] args) throws GSSException {
        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
        // Use native provider (REQUIRED FOR PASSWORLDLESS)
        System.setProperty("sun.security.jgss.native", "true");
        System.setProperty("sun.security.nativegss.debug", "true");

        GSSManager manager = GSSManager.getInstance();
        GSSCredential credential = manager.createCredential(GSSCredential.INITIATE_AND_ACCEPT);
        Subject subject = GSSUtil.createSubject(credential.getName(), credential);

        JndiAction jndiAction = new JndiAction();
        Subject.doAs(subject, jndiAction);
    }
}

class JndiAction implements java.security.PrivilegedAction {

    public Object run() {
        Hashtable env = new Hashtable();

        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, LdapChannelBindingWithGSSAPI1.LDAPS_URL);
        env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
        env.put("com.sun.jndi.ldap.tls.cbtype", "tls-server-end-point");
        env.put("com.sun.jndi.ldap.connect.timeout", "2000");

        try {
            //InitialDirContext initialDirContext = new InitialDirContext(env);
            InitialLdapContext initialDirContext = new InitialLdapContext(env, null);
            System.out.println(initialDirContext.getAttributes(""));
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return null;
    }
}


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

FREQUENCY : always