0
votes

I am using a keytab and setting it up using the kinit command on my windows commandline. I get the message "New ticket is stored in cache file".After that when I run my java application to access the keytab file for the key I get below error.

Authentication attempt failed javax.security.auth.login.LoginException: No key to store
javax.security.auth.login.LoginException: No key to store
    at com.sun.security.auth.module.Krb5LoginModule.commit(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at javax.security.auth.login.LoginContext.invoke(Unknown Source)
    at javax.security.auth.login.LoginContext.access$000(Unknown Source)
    at javax.security.auth.login.LoginContext$4.run(Unknown Source)
    at javax.security.auth.login.LoginContext$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)

I am trying to connect to the active directory using ldap. Below are the configuration settings:

-Djavax.security.auth.useSubjectCredsOnly=false
-Djava.security.auth.login.config=C:\Users\cXXXXXX\Git\gssapi_jaas.conf
-Dsun.security.krb5.debug=true

Debug is true storeKey true useTicketCache true useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is

C:\Users\cXXXXXX\Git\abcd.keytab refreshKrb5Config is false principal is xxxx_dev@xxxx.xxxxxx.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false Acquire TGT from Cache

KinitOptions cache name is C:\Users\cXXXXXX\krb5cc_cXXXXXX DEBUG client principal is xxxx_dev@xxxx.xxxxxx.COM DEBUG server principal is krbtgt/xxxx.xxxxxx.COM@Txxxx.xxxxxx.COM DEBUG key type: 23 DEBUG auth time: Mon Jul 01 14:20:21 EDT 2019 DEBUG start time: Mon Jul 01 14:20:21 EDT 2019 DEBUG end time: Tue Jul 02 00:20:21 EDT 2019 DEBUG renew_till time: null CCacheInputStream: readFlags() INITIAL; PRE_AUTH; Host address is /xx.xx.xxx.xx Host address is /xxx:0:0:0:xxxx:xxxx:xxxx:xxxx KrbCreds found the default ticket granting ticket in credential cache. Java config name: null Native config name: C:\windows\krb5.ini Obtained TGT from LSA: Credentials: client=sxxxx_dev@xxxx.xxxxxx.COM server=krbtgt/Txxxx.xxxxxx.COM@Txxxx.xxxxxx.COM authTime=20190701182021Z startTime=20190701182021Z endTime=20190702042021Z renewTill=null flags=INITIAL;PRE-AUTHENT EType (skey)=23 (tkt key)=18 Principal is sxxxx_dev@xxxx.xxxxxx.COM

Before adding the kinit cache fil, I was able to atleast validate the account, then I was having issues with GSSapi security. Trying to resolve that I added the cache and this new problem started to happen

public static void main(String[] args) {

    // 1. Log in (to Kerberos)
    LoginContext lc = null;
    try {
        /*lc = new LoginContext(Azrm017.class.getName(),
        new LuwCallBackHandler());
*/
        lc = new LoginContext("Azrm017");
        // Attempt authentication
        // You might want to do this in a "for" loop to give
        // user more than one chance to enter correct username/password
        lc.login();

    } catch (LoginException le) {
        System.err.println("Authentication attempt failed " + le);
        le.printStackTrace();
        System.err.println("Authentication attempt failed " + le.getSuppressed());

        System.exit(-1);
    }

    // 2. Perform JNDI work as logged in subject
    NamingEnumeration<SearchResult> ne =
            (NamingEnumeration<SearchResult>) Subject.doAs(lc.getSubject(),
                new SearchAction());
    while(ne.hasMoreElements()) {
        System.out.println(">>>> : " + ne.nextElement().getName());
    }

    //Subject.doAs(lc.getSubject(), new JndiAction(args));
    }
}


/**
 * The application must supply a PrivilegedAction that is to be run
 * inside a Subject.doAs() or Subject.doAsPrivileged().
 */
class SearchAction implements java.security.PrivilegedAction {

    public Object run() {

        // Set up the environment for creating the initial context
        Hashtable<String, String> env = new Hashtable<> (11);
        env.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.jndi.ldap.LdapCtxFactory");
        String cn = "dn:CN=xxxxxxx,OU=Service xxxxx,OU=Accounts,OU=xxxxx,DC=test,DC=xxxxxx,DC=com";
        env.put(Context.PROVIDER_URL, "ldap://test.xxxxxxx.com:389");
        env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
        env.put("javax.security.sasl.server.authentication", "true");
        env.put("javax.security.sasl.qop", "auth-conf");

        DirContext ctx = null;
        try {
           // Create initial context
           ctx = new InitialDirContext(env);

           SearchControls ctls = new SearchControls();
           ctls.setReturningAttributes(
                 new String[] {"displayName", "mail","description", "suSunetID"});

           NamingEnumeration<SearchResult> answer =
                ctx.search("cn=People, dc=test, dc=xxxxxxxx, dc=com",
                                 "(&(cn=p*)(sn=s*))", ctls);

            return answer;


        } catch (Exception e) {
               e.printStackTrace();
        }
         // Close the context when we're done
        finally {
            closeContext(ctx);
        }
        return null;
    }

Attached above

1
hi anyone has a answer for my question? - Bootham Deyyam

1 Answers

0
votes

This is a wrong combination of Krb5LoginModule options. If you want an initiator to store a key then that key must be used to acquire the ticket (i.e. useTicketCache should not be true).

Why do you want to store the key? Will the initiator also act as an acceptor? If yes, you should either use the keytab to authenticate (i.e. useTicketCache=false) or go with the ENC-TKT-IN-SKEY way (i.e. storeKey=false).