Kerberos and LDAP: Why does Java 6 truncate LDAP host names when using Kerberos? -
my task connect kerberized ldap server through java gss api. have small sample app use test connection, kerberos configuration, connection parameters, etc, sure can connect ldap server , retrieve data. code given below:
import java.io.fileinputstream; import java.io.ioexception; import java.security.privilegedactionexception; import java.security.privilegedexceptionaction; import java.util.hashmap; import java.util.hashtable; import java.util.map; import java.util.properties; import javax.naming.context; import javax.naming.namingenumeration; import javax.naming.namingexception; import javax.naming.directory.attributes; import javax.naming.directory.dircontext; import javax.naming.directory.searchcontrols; import javax.naming.directory.searchresult; import javax.naming.ldap.control; import javax.naming.ldap.initialldapcontext; import javax.security.auth.subject; import javax.security.auth.login.logincontext; import javax.security.auth.login.loginexception; import javax.security.auth.spi.loginmodule; public class testkerberizedldap implements runnable { public static void main(string[] args) { runnable rn = null; if (args.length == 1) { rn = new testkerberizedldap(args[0]); } else if (args.length == 0) { rn = new testkerberizedldap("c:/dev/projects/testkerberizedldap/src/testkerberizedldap.properties"); } else { printusage(); return; } rn.run(); } private static final string loginmoduleclassname = "com.sun.security.auth.module.krb5loginmodule"; private static final string koid = "1.2.840.113554.1.2.2"; private static final string soid = "1.3.6.1.5.5.2"; private subject subject; private dircontext ldapcontext; private string username; private string password; private string ldaphost; private testkerberizedldap(string propfilename) { properties prop = new properties(); try { fileinputstream istream = new fileinputstream(propfilename); prop.load(istream); istream.close(); } catch (ioexception e) { e.printstacktrace(); } system.out.println("properties found:"); (string propname : prop.stringpropertynames()) { system.out.println(propname + " = " + prop.getproperty(propname)); } system.out.println(); system.setproperty("java.security.krb5.conf", prop.getproperty("krbconf")); system.setproperty("java.security.krb5.debug", "true"); system.setproperty("sun.security.krb5.debug", "true"); ldaphost = prop.getproperty("ldaphost"); username = prop.getproperty("user"); password = prop.getproperty("password"); subject = null; ldapcontext = null; } public void run() { try { initsubject(); if (subject != null) { initcontextkerberized(); } } catch (exception ex) { ex.printstacktrace(); } } private void initcontextkerberized() throws exception { subject.doas(subject, new privilegedexceptionaction<object>() { public object run() throws exception { hashtable<string, string> env = new hashtable<string, string>(); env.put(context.initial_context_factory, "com.sun.jndi.ldap.ldapctxfactory"); env.put(context.provider_url, ldaphost); env.put(context.security_authentication, "gssapi"); ldapcontext = new initialldapcontext(env, new control[0]); // stuff ldapcontext here... searchldapdirectory(); return null; } }); } private void searchldapdirectory() throws namingexception { string base = "cn=users"; string filter = "(objectclass=user)"; searchcontrols sc = new searchcontrols(); sc.setsearchscope(searchcontrols.subtree_scope); namingenumeration<searchresult> ne = ldapcontext.search(base, filter, sc); int numelements = 0; system.out.println(); while (ne.hasmoreelements()) { searchresult sr = ne.nextelement(); attributes attr = sr.getattributes(); system.out.println(attr.get("name").get()); numelements++; } system.out.println("the number of elements returned " + numelements); } private void initsubject() throws instantiationexception, classnotfoundexception, illegalaccessexception { loginmodule module = null; try { module = (loginmodule) class.forname(loginmoduleclassname).newinstance(); subject = new subject(); map<string, string> options = new hashmap<string, string>(); map<string, object> sharedstate = new hashmap<string, object>(); if ((username != null) && (password != null)) { sharedstate.put("javax.security.auth.login.password", password.tochararray()); sharedstate.put("javax.security.auth.login.name", username); options.put("principal", username); options.put("storekey", "true"); options.put("usefirstpass", "true"); } else { options.put("principal", username); options.put("useticketcache", "true"); options.put("donotprompt", "true"); options.put("renewtgt", "true"); } options.put("debug", "true"); options.put("refreshkrb5config", "true"); module.initialize(subject, null, sharedstate, options); module.login(); module.commit(); } catch (loginexception ex) { ex.printstacktrace(); subject = null; if (module != null) { try { module.abort(); } catch (loginexception ex2) { ex2.printstacktrace(); } } } } private static void printusage() { system.out.println(); system.out.println("usage: testkerberizedldap <property file name>"); system.out.println(); } } within testkerberized.properties file, "ldaphost" property defined "ldap://dv2k8ad.2k8.hlp.net:389/dc=2k8,dc=hlp,dc=net".
now, when run app java 7, works charm. kerberos authentication succeeds, , data retrieved ldap server. however, cant run java 6. keeps giving me following exception:
found ticket user1@2k8.hlp.net go krbtgt/2k8.hlp.net@2k8.hlp.net expiring on thu jun 04 00:47:07 pdt 2015 entered krb5context.initseccontext state=state_new found ticket user1@2k8.hlp.net go krbtgt/2k8.hlp.net@2k8.hlp.net expiring on thu jun 04 00:47:07 pdt 2015 service ticket not found in subject >>> credentials acquireservicecreds: same realm default etypes default_tgs_enctypes: 23 16 3 1. >>> cksumtype: sun.security.krb5.internal.crypto.rsamd5cksumtype >>> etype: sun.security.krb5.internal.crypto.arcfourhmacetype >>> krbkdcreq send: kdc=172.23.5.151 udp:88, timeout=30000, number of retries =3, #bytes=1289 >>> kdccommunication: kdc=172.23.5.151 udp:88, timeout=30000,attempt =1, #bytes=1289 >>> krbkdcreq send: #bytes read=92 >>> krbkdcreq send: #bytes read=92 >>> kdcaccessibility: remove 172.23.5.151:88 >>> kdcrep: init() encoding tag 126 req type 13 >>>krberror: stime wed jun 03 14:47:07 pdt 2015 1433368027000 susec 109093 error code 7 error message server not found in kerberos database realm 2k8.hlp.net sname ldap/2k8.hlp.net msgtype 30 java.security.privilegedactionexception: javax.naming.authenticationexception: gssapi [root exception javax.security.sasl.saslexception: gss initiate failed [caused gssexception: no valid credentials provided (mechanism level: server not found in kerberos database (7))]] @ java.security.accesscontroller.doprivileged(native method) @ javax.security.auth.subject.doas(subject.java:396) @ testkerberizedldap.initcontextkerberized(testkerberizedldap.java:95) @ testkerberizedldap.run(testkerberizedldap.java:85) @ testkerberizedldap.main(testkerberizedldap.java:39) caused by: javax.naming.authenticationexception: gssapi [root exception javax.security.sasl.saslexception: gss initiate failed [caused gssexception: no valid credentials provided (mechanism level: server not found in kerberos database (7))]] @ com.sun.jndi.ldap.sasl.ldapsasl.saslbind(ldapsasl.java:150) @ com.sun.jndi.ldap.ldapclient.authenticate(ldapclient.java:214) @ com.sun.jndi.ldap.ldapctx.connect(ldapctx.java:2694) @ com.sun.jndi.ldap.ldapctx.<init>(ldapctx.java:293) @ com.sun.jndi.ldap.ldapctxfactory.getusingurl(ldapctxfactory.java:175) @ com.sun.jndi.ldap.ldapctxfactory.getusingurls(ldapctxfactory.java:193) @ com.sun.jndi.ldap.ldapctxfactory.getldapctxinstance(ldapctxfactory.java:136) @ com.sun.jndi.ldap.ldapctxfactory.getinitialcontext(ldapctxfactory.java:66) @ javax.naming.spi.namingmanager.getinitialcontext(namingmanager.java:667) @ javax.naming.initialcontext.getdefaultinitctx(initialcontext.java:288) @ javax.naming.initialcontext.init(initialcontext.java:223) @ javax.naming.ldap.initialldapcontext.<init>(initialldapcontext.java:134) @ testkerberizedldap$1.run(testkerberizedldap.java:101) ... 5 more caused by: javax.security.sasl.saslexception: gss initiate failed [caused gssexception: no valid credentials provided (mechanism level: server not found in kerberos database (7))] @ com.sun.security.sasl.gsskerb.gsskrb5client.evaluatechallenge(gsskrb5client.java:194) @ com.sun.jndi.ldap.sasl.ldapsasl.saslbind(ldapsasl.java:105) ... 17 more caused by: gssexception: no valid credentials provided (mechanism level: server not found in kerberos database (7)) @ sun.security.jgss.krb5.krb5context.initseccontext(krb5context.java:663) @ sun.security.jgss.gsscontextimpl.initseccontext(gsscontextimpl.java:230) @ sun.security.jgss.gsscontextimpl.initseccontext(gsscontextimpl.java:162) @ com.sun.security.sasl.gsskerb.gsskrb5client.evaluatechallenge(gsskrb5client.java:175) ... 18 more caused by: krbexception: server not found in kerberos database (7) @ sun.security.krb5.krbtgsrep.<init>(krbtgsrep.java:61) @ sun.security.krb5.krbtgsreq.getreply(krbtgsreq.java:185) @ sun.security.krb5.internal.credentialsutil.servicecreds(credentialsutil.java:294) @ sun.security.krb5.internal.credentialsutil.acquireservicecreds(credentialsutil.java:106) @ sun.security.krb5.credentials.acquireservicecreds(credentials.java:557) @ sun.security.jgss.krb5.krb5context.initseccontext(krb5context.java:594) ... 21 more caused by: krbexception: identifier doesn't match expected value (906) @ sun.security.krb5.internal.kdcrep.init(kdcrep.java:133) @ sun.security.krb5.internal.tgsrep.init(tgsrep.java:58) @ sun.security.krb5.internal.tgsrep.<init>(tgsrep.java:53) @ sun.security.krb5.krbtgsrep.<init>(krbtgsrep.java:46) ... 26 more it's worth noting module.commit() succeeded, , subject obtained, no issues there. noticed sname field in krberror message off. says ldap/2k8.hlp.net whereas should have been ldap/dv2k8ad.2k8.hlp.net.
following this, ran wireshark session capture kerberos packets being sent, , captured packets while running testkerberizedldap on both java 6 , java 7. tgt acquired successfully, because program got successful as-rep in both cases. however, tgs-req being sent kdc had different values. server name sent java 6 ldap/2k8.hlp.net , 1 sent java 7 ldap/dv2k8ad.2k8.hlp.net
i dont know why java 6 choosing trim ldap host name. if knows workaround, or fix (short of updating java), i'd grateful help.
yay, resolved!
this bug in java 1.6.0_22. switched using java 1.6.0_45, , worked charm :)
Comments
Post a Comment