cancel
Showing results for 
Search instead for 
Did you mean: 

[CIFS] Kerberos authentication doesn't start, but try NTLM

diegop
Champ in-the-making
Champ in-the-making
Hi,
i'm working on Alfresco 2.1 Community Edition.

My Alfresco installation has to authenticate every user through a Single-Sign-On mechanism in a Kerberos' Realm of a Windows Domain.

I have several problems to authenticate users of my domain when try to connect to CIFS server.

I followed this procedure meticulously:

http://wiki.alfresco.com/wiki/Configuring_the_CIFS_and_web_servers_for_Kerberos/AD_integration

installing Alfresco on my PC with Windows XP and it seemed to work.

The problems are born when I installed Alfresco on a test PC with Windows 2003 Server Edition.

Sometimes, when I try to connect to CIFS server, i have to wait several seconds before that appears a dialog where I have to put a user and a password to authenticate to CIFS through a NTLM authentication, but this dialog should not appear! The user logged should have to be automatically authenticated through Kerberos.

I debugged Alfresco and sniffed the smb packets by Wireshark and I noticed that when a kerberos authentication to have to start the object NegTokenInit  negToken, defined in the method doSpnegoSessionSetup of the class EnterpriseCifsAuthenticator has three OID (Object Identifiers) in this order: [OID.ID_KERBEROS5, OID.ID_MSKERBEROS5, OID.ID_NTLMSSP].

If (incorrectly) the CIFS server request a NTLM authentication i noticed that the negToken object described above has ONLY  one OID: [OID.ID_NTLMSSP].

So, what is the problem? Who set the wrong OID list read in the doSpnegoSessionSetup method? And why? How to resolve all this?

I put the code of the method doSpnegoSessionSetup of the class EnterpriseCifsAuthenticator:

    /**
     * Process an SPNEGO security blob
     *
     * @param sess SMBSrvSession
     * @param client ClientInfo
     * @param secbuf byte[]
     * @param secpos int
     * @param seclen int
     * @param unicode boolean
     * @exception SMBSrvException
     */
    private final byte[] doSpnegoSessionSetup( SMBSrvSession sess, ClientInfo client,
            byte[] secbuf, int secpos, int seclen, boolean unicode) throws SMBSrvException
    {
        //  Check the received token type, if it is a target token and there is a stored session setup object, this is the second
        //  stage of an NTLMSSP session setup that is wrapped with SPNEGO

        int tokType = -1;
       
        try
        {
            tokType = SPNEGO.checkTokenType( secbuf, secpos, seclen);
        }
        catch ( IOException ex)
        {
        }

        //  Check for the second stage of an NTLMSSP logon
       
        NegTokenTarg negTarg = null;
       
        if ( tokType == SPNEGO.NegTokenTarg && sess.hasSetupObject( client.getProcessId()) && sess.getSetupObject( client.getProcessId()) instanceof Type2NTLMMessage)
        {
            //  Get the NTLMSSP blob from the NegTokenTarg blob
           
            NegTokenTarg negToken = new NegTokenTarg();
           
            try
            {
                // Decode the security blob
               
                negToken.decode( secbuf, secpos, seclen);
            }
            catch ( IOException ex)
            {
                // Log the error
               
                logger.error(ex);
               
                // Return a logon failure status
               
                throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
            }

            //  Get the second stage NTLMSSP blob
           
            byte[] ntlmsspBlob = negToken.getResponseToken();

            //  Perform an NTLMSSP session setup
           
            byte[] ntlmsspRespBlob = doNtlmsspSessionSetup( sess, client, ntlmsspBlob, 0, ntlmsspBlob.length, unicode);
           
            //  NTLMSSP is a two stage process, set the SPNEGO status
           
            int spnegoSts = SPNEGO.AcceptCompleted;
           
            if ( sess.hasSetupObject( client.getProcessId()))
                spnegoSts = SPNEGO.AcceptIncomplete;
           
            //  Package the NTLMSSP response in an SPNEGO response

            negTarg = new NegTokenTarg( spnegoSts, null, ntlmsspRespBlob);
        }
        else if ( tokType == SPNEGO.NegTokenInit)
        {
            //  Parse the SPNEGO security blob to get the Kerberos ticket
           
            NegTokenInit negToken = new NegTokenInit();
           
            try
            {
                // Decode the security blob
               
                negToken.decode( secbuf, secpos, seclen);
            }
            catch ( IOException ex)
            {
                // Log the error
               
                logger.error(ex);
               
                // Return a logon failure status
               
                throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
            }
   
            //  Determine the authentication mechanism the client is using and logon
           
            String oidStr = null;
            if ( negToken.numberOfOids() > 0)
                oidStr = negToken.getOidAt( 0).toString();
           
            if ( oidStr != null && oidStr.equals( OID.ID_NTLMSSP))
            {
                //  NTLMSSP logon, get the NTLMSSP security blob that is inside the SPNEGO blob
               
                byte[] ntlmsspBlob = negToken.getMechtoken();
   
                //  Perform an NTLMSSP session setup
               
                byte[] ntlmsspRespBlob = doNtlmsspSessionSetup( sess, client, ntlmsspBlob, 0, ntlmsspBlob.length, unicode);
               
                //  NTLMSSP is a two stage process, set the SPNEGO status
               
                int spnegoSts = SPNEGO.AcceptCompleted;
               
                if ( sess.hasSetupObject( client.getProcessId()))
                    spnegoSts = SPNEGO.AcceptIncomplete;
               
                //  Package the NTLMSSP response in an SPNEGO response
   
                negTarg = new NegTokenTarg( spnegoSts, OID.NTLMSSP, ntlmsspRespBlob);
            }
            else if (  oidStr != null && (oidStr.equals( OID.ID_MSKERBEROS5) || oidStr.equals(OID.ID_KERBEROS5)))
            {
                //  Kerberos logon
               
                negTarg = doKerberosLogon( sess, negToken, client);
            }
            else
            {
                //  Debug
               
                if ( logger.isDebugEnabled())
                {
                    logger.debug("No matching authentication OID found");
                    logger.debug("  " + negToken.toString());
                }
                   
                //  No valid authentication mechanism
               
                throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
            }
        }
        else
        {
            //  Unknown SPNEGO token type
           
            logger.error( "Unknown SPNEGO token type");
           
            // Return a logon failure status
           
            throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
        }
       
        // Generate the NegTokenTarg blob

        byte[] respBlob = null;
       
        try
        {
            // Generate the response blob
           
           respBlob = negTarg.encode();
        }
        catch ( IOException ex)
        {
            //  Debug
           
            if ( logger.isDebugEnabled())
                logger.debug("Failed to encode NegTokenTarg", ex);

            //  Failed to build response blob
           
            throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
        }
       
        //  Return the SPNEGO response blob
       
        return respBlob;
    }

After read this page:

http://wiki.alfresco.com/wiki/Enterprise_Security_and_Authentication_Configuration

I know that Alfresco CIFS SSO is possible only with Enterprise Authenticator  with Kerberos. Isn't it?

P.S. Alfresco runs on a Windows 2003 Server (on a Tomcat), while every client has a Windows XP or Windows 2003 Server, could be an Active Directory settings problem?
1 REPLY 1

diegop
Champ in-the-making
Champ in-the-making
Hi,
nobody have some tips ?
What is the windows/lan configuration that should cause the missing OID for the authentication with Kerberos ?

If you need some information about configuration tell me.

Thank you in advance.