[jcifs] How long is a NtlmPasswordAuthentication object valid ?

eglass1 at comcast.net eglass1 at comcast.net
Fri Jul 18 20:25:46 EST 2003

> 	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.

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.

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).

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.


More information about the jcifs mailing list