[jcifs] How long is a NtlmPasswordAuthentication object valid ?

Allen, Michael B (RSCH) Michael_B_Allen at ml.com
Mon Jul 21 11:46:03 EST 2003

> -----Original Message-----
> From:	eglass1 at comcast.net [SMTP:eglass1 at comcast.net]
> Sent:	Friday, July 18, 2003 6:26 AM
> To:	Michael_B_Allen at ml.com
> Cc:	jcifs at lists.samba.org
> Subject:	Re: [jcifs] How long is a NtlmPasswordAuthentication object valid ?
> > 	Doesn't matter. The important question is, if you un-hardcode the
> > 	soTimeout in NtlmHttpFilter so that you can let the SmbTransport
> > close
> > 	after 15 seconds while your app is holding an SmbFile reference
> > created
> > 	with the NPA of the session does a new request that trys to access
> > the
> > 	file again now fail? If it does that's a problem.
> > 
> It's a kinda-sorta problem (I'm working off of notes/analysis rather than
> experimentation, so all of this might be incorrect).
> There are basically two use cases involved here:
> 1)  Authentication of the user accessing the site.
> 2)  Same as 1, but additionally accessing SMB resources as the user.
> The second instance (i.e., Davenport or NetworkExplorer) will (realistically)
> never experience the issue.  The reason is that since each request could
> potentially be accessing a resource from a different server, the NPAs cannot
> be cached in the session.  Since each request creates a new NPA specific to
> the server upon which the requested resource resides, the only time you would
> see an issue (I think) would be if the soTimeout is shorter than the time it
> takes to create the SmbFile and start using it.
	Well that's a problem scenario. If a Servlet does some long calculation for
	10 mintues and then trys to access a file the transport could have timed out
	already invalidating the NPA. But in hindsight I don't see how updating
	password hashes in-place would help this. Considering I can find no
	remnants of the said code I suspect it was something I wasted a lot of time
	on and never made it into a stable release.

> The first instance would see an issue if the NPA from the session was used to
> access an SMB resource after the transport closes (note that in any case the
> NPA is only valid for the server which generated the challenge).  This will
> (I believe) manifest itself as an SmbAuthException upon attempting to access
> the resource.  To the servlet developer, this would look the same as a user
> attempting to access a resource to which they do not have permission.
> Whether this is an issue would depend on what course of action the application
> developer takes:
> a) Don't catch the exception; this results in the error page mechanism being
> invoked by the container when it traps the SmbAuthException.  Subsequent
> accesses will result in the same.
> b) Catch it and present a "reasonable" message (i.e., a nice page stating the
> user can't access this resource).  Subsequent accesses will result in the same.
> c) Send an HTTP 403 (forbidden).  Subsequent accesses will result in the same.
> d) Send an HTTP 401 with "WWW-Authenticate: NTLM" to re-authenticate the user.
> Upon successful authentication, the NPA in the session will be replaced with
> the newly negotiated credentials; subsequent accesses will use this (until that
> one becomes invalid).
> In a), b), and c) the developer could also opt to remove the NPA from the
> session, which would result in re-authentication on subsequent access.
	e) If the Servlet is a long lived process increase the
	jcifs.smb.client.soTimeout period to 10x estimated TTL of the servlet.

> The only real way to preemptively detect transport closure would be to attempt
> connection to the server on each request; this would slow things down
> considerable, but would still be faster than not caching the credentials at
> all (since you would only need to do HTTP roundtrips if the NPA has indeed
> become invalid).
	Actually smbclient does this. It sends an SMB_COM_CHECK_DIRECTORY
	request every 3 seconds. We don't need to/want to do anything like that.

> Upon re-authentication, there are a few approaches we (jCIFS) could take to
> apply the new credentials:
> a) Replace the NPA in the session with the newly authenticated NPA.  This is
> what we currently do.
> b) Replace the password hashes in the existing NPA with the newly obtained
> byte arrays.
> c) Update the existing password hashes in the existing NPA with the contents
> of the newly obtained byte arrays (i.e. System.arraycopy).
> b) and c) have the advantage that SmbFiles in other concurrent requests which
> use the same NPA object would become revalidated once the hashes are updated.
> In a), each request would encounter the issue independently and update the
> NPA in the session.  If there are 5 outstanding requests, NTLM will take place
> 5 times before the system reaches a steady state.
> The disadvantage of b) and c) would be that synchronization would be required
> over all access to the hashes (since there is a possibility that a request
> being handled in a different thread would be changing them in-place).  This
> would slow down "normal" operations with the NPAs (maybe negligibly, though).
> What it boils down to is that if you're using the NPA from the HTTP session
> to access SMB resources, there is a possibility that the issue will occur.  It
> is important to note that the NPA from the session is only valid for the server
> which generated the challenge, so you can't use it for "general access" to
> arbitrary SMB resources anyway (semi-true; if HTTP Basic authentication is
> used rather than NTLM, not only will the issue not occur, but we have the
> password so we can generate responses for any resource on any server).
> If this is deemed an issue there are a few approaches we could take:
> 1) "Ping" the SMB server by attempting a connection on each request.  This
> would slow the filter down considerably, but would decrease the likelihood
> that the transport would close (since it would effectively be generating
> activity).  This would also detect that the transport has closed and provide
> an opportunity to re-establish authentication.
> 2) Wrap a try-catch block around doFilter, catching SmbAuthException:
>     try {
>         chain.doFilter(request, response);
>     } catch (SmbAuthException ex) {
>         // re-authenticate (and probably remove existing NPA from session)
>     }
> In the event that the application developer does not handle the exception,
> this would provide us with the opportunity to do so (preventing problems on
> subsequent accesses).
> Additionally, we could look at the possibility of doing in-place
> replacement/update of the hashes.  This could be combined with either of the
> above approaches to prevent concurrent requests from having to re-authenticate
> as well.  This may have a detrimental impact on performance in other areas of
> jCIFS, however; extensive testing would probably be appropriate.
> We could also opt not to address this; I'm not aware of anyone being affected,
> and it seems to be a bit of an edge case.
	Yeah. Let's just let this slide for now. It's not clear to me that there's really
	an issue here after all. At least it's been too long since I worked on the NTLM
	HTTP auth code to see the problem let alone fix anything.


More information about the jcifs mailing list