[jcifs] jcifs-1.2.9 with SSN_LIMIT=1

Waldheim, Frank F.Waldheim at ing-diba.de
Wed Oct 25 08:50:06 GMT 2006


hi there,

we encounter a problem with jcifs-1.2.9 (without kerberos)
accessing our windows 2003 server DCs (which require signing).

we sucessfully used jcifs with preauthentication but had a problem
with passwords that where (or have to be) changed. 

thats why we tried the other suggested solution with SSN_LIMIT=1.

In this case even the first access fails:
   NtlmHttpFilter: DOMCOMPANY\userid: 0xC0000005:
jcifs.smb.SmbAuthException: Invalid access to memory location.

we investigated three issues concerning the SSN_LIMIT=1 problem

1) SSN_LIMIT = 1 - getTransport

as already stated one year ago in:
http://thread.gmane.org/gmane.network.samba.java/4989/focus=4989
the mechanism of creating transports and finding them again seems to be
broken.
therefore a new transport is created for logon and the DC is not happy.

like stated in the patch above one can fix the logic in
SmbTransport.java to find the 
instance in CONNECTIONS even if SSN_LIMIT=1 by removing the first if
clause.


so the first part of our proposal is
  - remove the first if() - if( SSN_LIMIT != 1 )
  
  
2) SSN_LIMIT=1 and PreAuthentication - getTransport

If preauthentication is switched on (and the SSN_LIMIT ist still set to
1) 
there will never be a Transport  without a session. And therefore the
condition:
		conn.sessions.size() < SSN_LIMIT
can NOT evaluate to true and a new Transport is created.

therefore:
  - modify the test to: conn.sessions.size() <= SSN_LIMIT 
    (which is incorrect for a config without preauth)
  - (make SMBTransport aware of the current configuration - ugly)


3) SSN_LIMIT=1 - matches() 

when set SSN_LIMIT=1 (preauthentication turned OFF) we have
problems with parallel client-requests.
The basic problem seems to be: How to reuse the correct transport?
How is a request matched to the correct transport?


as shown in the sequence diagram (http://www.javachannel.de/ntlm.png)
the communication between the NTLMFilter
Servlet and the SMBSession is based on two actions:

 - getChallengeForDomain 
 - doLogon 

which both require the very same transport.
in our scope and from our understanding that means: 
1 Servlet thread uses 1 Transport (no reuse of transports!)

because of the fact that none of the fields used for matches() in
SmbTransport is updated after doConnect() and the fact that every
subsequent request for a transport by SMBSession only gives the DC
as a key (and it has no other chance according to the current interface)
the UniAddress is the ONLY way for the matches() method in SMBTransport 
to find the right transport for this request.

even if all this works well we cannot see how the mechanism in matches()
can find the RIGHT transport.
say that the algorithm in getChallengeForDomain decided to route
two requests to the same DC within a very short time ( one can 
assume a stress-test situation here which will cause the round-robin
to select the same DC within seconds even with 8 DCs configured) 
then there will be two transports with a session to the same DC in the
CONNECTIONS list 
and by design the first one will be returned which apparently can be the
wrong one.

this is a far more difficult issue as we cannot see a simple fix here.
we propose a new method in SMBSession designed for Authentication in a
'working-on-behalf' environment with respect to the handshake
of NTLM. 

that means we have to find a way to ensure some things:
 - clearly associate a calling thread with one DC/session/transport
triple
 - provide a well defined key for the caller to reselect such a triple
 - by design the ntlm authentification process has to hold a state 
   between getChallenge and logon which has to be reflected on both
sides;
   the weblayer AND the jcifs-lib.


for a start we implemented two alternative solutions to bring matches()
back in business:

1) use the encryption key which is sent back to the client during
getChallengeForDomain as
   a key to find the associated transport in matches().
   reset the values in doDisconnect() to 'free' the transport for reuse.

2) update the localport variable after doConnect() in negotiate() to
make matches() work.
   actively remove the Transport from the CONNECTIONS list.
	 

both solutions are awfully ugly. 
   as a result the SSN_LIMIT  is completely broken, because the
transport can never be used
   again  by another session because nobody knows the key (neither the
encryption key nor the localPort)
   so a SSN_LIMIT>1 will not show another behaviour than SSN_LIMIT=1


if you really read through this lengthly mail we ask you to help us to
find a way 
of how we can implement a fallback solution in a situation where
preauthentication is not possible.

hope to hear from you soon

-fw



Diese E-Mail enthaelt vertrauliche und/oder rechtlich geschuetzte
Informationen. Wenn Sie nicht der richtige Adressat sind oder diese
E-Mail irrtuemlich erhalten haben, informieren Sie bitte sofort den
Absender und vernichten Sie diese Mail. Das unerlaubte Kopieren sowie
die unbefugte Weitergabe dieser Mail ist nicht gestattet.
 
This e-mail may contain confidential and/or privileged information.
If you are not the intended recipient (or have received this e-mail
in error) please notify the sender immediately and destroy this e-mail.
Any unauthorized copying, disclosure or distribution of the material in
this e-mail is strictly forbidden.
-------------- next part --------------
HTML attachment scrubbed and removed


More information about the jcifs mailing list