I am using jTDS to connect to SQLServer. Inside jTDS uses GSS to get the kerberos service ticket and create a secure context. Since my application has been living for a long time, and my connections are maintained for the whole time when I need the kerberos service ticket to be renewable in order to allow the SQL server to update them myself (in accordance with kdc policies, all tickets expire after 12 hours).
What jTDS does to get the kerberos token (more or less):
GSSManager manager = GSSManager.getInstance(); // Oids for Kerberos5 Oid mech = new Oid("1.2.840.113554.1.2.2"); Oid nameType = new Oid("1.2.840.113554.1.2.2.1"); // Canonicalize hostname to create SPN like MIT Kerberos does GSSName serverName = manager.createName("MSSQLSvc/" + host + ":" + port, nameType); GSSContext gssContext = manager.createContext(serverName, mech, null, GSSContext.DEFAULT_LIFETIME); gssContext.requestMutualAuth(false); gssContext.requestCredDeleg(true); byte[] ticket = gssContext.initSecContext(new byte[0], 0, 0);
I suspect that the ticket I receive is not renewable. I check this by doing the following:
ExtendedGSSContext extendedContext = (ExtendedGSSContext) gssContext; boolean[] flags = (boolean[]) extendedContext.inquireSecContext(InquireType.KRB5_GET_TKT_FLAGS); System.out.println("Renewable = " + flags[8]);
In our specific configuration, GSS gets the kerberos TGT from the JAAS login module. We have the following set of variables: false -Djavax.security.auth.useSubjectCredsOnly=false , and the following login module is installed in the login.cfg file:
com.sun.security.jgss.krb5.initiate { com.sun.security.auth.module.Krb5LoginModule required useKeytTab=true keyTab="/home/batman/.batman.ktab" principal=" batman@GOTHAMCITY.INT " storeKey=true doNotPrompt=true debug=false };
Another thing I notice is that the getLifetime() GSSContext does not work. It always returns 2147483647 (max int) no matter what the real life time of the ticket is.
I feel comfortable with the jTDS branching driver, so I can change the way it sets the GSS context if necessary.
What I tried:
Use your own implementation of GSS api:
This is great for me in terms of getting renewable tickets, but it poses another set of problems (in terms of ensuring the correct set of ticket cache and proper ticket updates). If I can get around this option, it would be nice. As I observe here, the getLifetime() method actually returns the real life time in seconds of the ticket.
Repeated execution of KerberosLoginModule:
Based on the answer to this question Jaas - Request for renewable Kerberos tickets I re-executed LoginModule to install RENEW KDCOption in KrbAsReqBuilder before requesting TGT. This works great in the sense that I get a renewable TGT, but the ticket received from that TGT GSS is still not renewable. If I set a breakpoint in the constructor of the KDCOption object and set the RENEW flag manually for every request (even KrbTgsReq made by GSS), it works, but for this change to take place, it requires a serious rewrite to GSS, which I donβt feel comfortable with.