[jcifs] Closed sockets result in an "unkown user name or bad password"-ex ception

Marro, Donato marro at e-Spirit.de
Wed Jun 8 12:35:16 GMT 2005


Hi,

i wrote a little servlet for testing authentication issues under
weak network conditions. The weak network conditions are simulated
through a delay in the NTLM-authentication part.


import javax.servlet.http.*;
import javax.servlet.ServletException;
import java.io.*;
import java.net.UnknownHostException;

import jcifs.smb.*;
import jcifs.UniAddress;
import jcifs.http.NtlmSsp;

import org.apache.log4j.Logger;

public class AuthServlet extends HttpServlet {

	// Value for jcifs.smb.client.soTimeout
	private static final String  soTimeout = "500";
	// Value for the delay between two NTLM-authentication steps
(simulating weak network conditions)
	private static final int authDelay = 500;
	// Server used for authetication
	private static final String server = "myServer";
	// Share for access-test
	private static final String share = "smb://myServer/myShare/";

	private static final NtlmSsp AUTH = new NtlmSsp();

	private static Logger log = Logger.getLogger(AuthServlet.class);


	public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {

		jcifs.Config.setProperty("jcifs.smb.client.soTimeout",
soTimeout);

		NtlmPasswordAuthentication ntlm = null;

		String msg = request.getHeader("Authorization");

		if (msg != null && msg.startsWith("NTLM ")) {
			log.debug("Performing NTLM-authentication against
server " + server + "...");
			UniAddress domainController = null;

			try {
				domainController =
UniAddress.getByName(server, true);

				Thread.sleep(authDelay);
				byte[] challenge =
SmbSession.getChallenge(domainController);
				ntlm = AUTH.doAuthentication(request,
response, challenge);
			}
			catch(Exception e) {
				log.error("Exception occured while
performing NTLM-Authentication to server "+domainController, e);
			}

			if (ntlm == null) {
				return;
			}

			log.debug("User '" + ntlm.getName() + "'
successfully authenticated via NTLM against Server "+domainController);
		} else {
			try {
				log.debug("Creating NTLM-Header for
response...");
				response.setHeader("WWW-Authenticate",
"NTLM");
				response.setHeader("Connection", "close");
	
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
				response.flushBuffer();
				return;
			}
			catch(Exception e) {
                		log.error("Could not send redirect to
"+request.getRequestURL().toString(), e);
			}
		}

		// Send the response
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("Passed NTLM-authentication
successfully!<br><br>");

		SmbFile testFile = new SmbFile(share, ntlm);
		try {
			testFile.exists();
			out.println("Access to file " + testFile.getPath() +
" successful!");
		}
		catch(Exception e) {
			out.println("Access to file " + testFile.getPath() +
" failed!<br>");
			out.println(e.getMessage());
			log.error("Access to file " + testFile.getPath() + "
failed!", e);
		}
        out.close();
    }
}


Now setting the value for jcifs.smb.client.soTimeout to a value near
or equal to the configured delay will cause the application to throw
"unknown user name or bad password"-exceptions while calling the exists()-
method. This increases the "failed-login" counter of this user in the
Active Directory (what leads to locked user-accounts).

Excerpt from the log-file:

[14:18:47 08 Jun 2005]   DEBUG (AuthServlet) - Creating NTLM-Header for
response...
[14:18:47 08 Jun 2005]   DEBUG (AuthServlet) - Performing
NTLM-authentication against server myServer...
[14:18:48 08 Jun 2005]   DEBUG (AuthServlet) - Performing
NTLM-authentication against server myServer...
[14:18:48 08 Jun 2005]   DEBUG (AuthServlet) - User 'E-SPIRIT\marro'
successfully authenticated via NTLM against Server myServer/192.168.100.10
[14:18:48 08 Jun 2005]   ERROR (AuthServlet) - Access to file
smb://myServer/myShare/ failed!
jcifs.smb.SmbAuthException: Logon failure: unknown user name or bad
password.
        at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:425)
        at jcifs.smb.SmbTransport.send(SmbTransport.java:528)
        at jcifs.smb.SmbSession.sessionSetup(SmbSession.java:263)
        at jcifs.smb.SmbSession.send(SmbSession.java:220)
        at jcifs.smb.SmbTree.treeConnect(SmbTree.java:134)
        at jcifs.smb.SmbFile.connect(SmbFile.java:790)
        at jcifs.smb.SmbFile.connect0(SmbFile.java:760)
        at jcifs.smb.SmbFile.exists(SmbFile.java:1245)
        at AuthServlet.doGet(AuthServlet.java:79)


I think this behavior is caused by a socket which is closed while
performing the NTLM-authentication. But why does the NTLM-authentication
not fail in this case and so prevents the user from accessing a file or
directory with invalid credentials?

Donato


More information about the jcifs mailing list