public final class SmbSession {
- private static final String LOGON_SHARE = Config.getProperty( "jcifs.smb.client.logonShare", null );
- private static final int LOOKUP_RESP_LIMIT = jcifs.Config.getInt( "jcifs.netbios.lookupRespLimit", 5 );
- private static final String DOMAIN = Config.getProperty("jcifs.smb.client.domain", null);
- private static final String USERNAME = Config.getProperty("jcifs.smb.client.username", null);
- private static final int CACHE_POLICY = Config.getInt( "jcifs.netbios.cachePolicy", 1200 );
+ private static final String LOGON_SHARE =
+ Config.getProperty( "jcifs.smb.client.logonShare", null );
+ private static final int LOOKUP_RESP_LIMIT =
+ Config.getInt( "jcifs.netbios.lookupRespLimit", 3 );
+ private static final String DOMAIN =
+ Config.getProperty("jcifs.smb.client.domain", null);
+ private static final String USERNAME =
+ Config.getProperty("jcifs.smb.client.username", null);
+ private static final int CACHE_POLICY =
+ Config.getInt( "jcifs.netbios.cachePolicy", 60 * 10 ) * 60; /* 10 hours */
- static long dc_list_expiration;
static NbtAddress[] dc_list = null;
- static int dc_list_index; /* always less than dc_list_range */
- static int dc_list_range = 1; /* always less than LOOKUP_RESP_LIMIT */
-
- static void incr_dc_list_range() {
- if( dc_list_range < LOOKUP_RESP_LIMIT &&
- dc_list_range < dc_list.length ) {
- dc_list_range++;
+ static long dc_list_expiration;
+ static int dc_list_counter;
+
+ private static NtlmChallenge interrogate( NbtAddress addr ) throws SmbException {
+ UniAddress dc = new UniAddress( addr );
+ SmbTransport trans = SmbTransport.getSmbTransport( dc, 0 );
+ if (USERNAME == null) {
+ trans.negotiate();
+ if (SmbTransport.log.level > 2)
+ SmbTransport.log.println(
+ "Default credentials (jcifs.smb.client.username/password)" +
+ " not specified. SMB signing may not work propertly." +
+ " Skipping DC interrogation." );
+ } else {
+ SmbSession ssn = trans.getSmbSession( NtlmPasswordAuthentication.DEFAULT );
+ ssn.getSmbTree( LOGON_SHARE, null ).treeConnect( null, null );
}
+ return new NtlmChallenge( trans.server.encryptionKey, dc );
}
public static NtlmChallenge getChallengeForDomain()
throws SmbException, UnknownHostException {
- int starting_index;
-
if( DOMAIN == null ) {
throw new SmbException( "A domain was not specified" );
}
-synchronized( DOMAIN ) {
- if( dc_list_expiration < System.currentTimeMillis() ) {
- dc_list_expiration = System.currentTimeMillis() + CACHE_POLICY * 1000L;
-
- if( SmbTransport.log.level > 2 ) {
- SmbTransport.log.println( (new java.util.Date()) +
- ": LOGON_SHARE=" + LOGON_SHARE +
- ",LOOKUP_RESP_LIMIT=" + LOOKUP_RESP_LIMIT +
- ",DOMAIN=" + DOMAIN +
- ",USERNAME=" + USERNAME +
- ",CACHE_POLICY=" + CACHE_POLICY +
- ",dc_list.length=" + (dc_list == null ? 0 : dc_list.length) +
- ",dc_list_range=" + dc_list_range +
- ",dc_list_index=" + dc_list_index );
- }
-
- NbtAddress[] new_dc_list = NbtAddress.getAllByName( DOMAIN, 0x1C, null, null );
- if( new_dc_list == null) {
- dc_list_expiration = System.currentTimeMillis() + 10000; /* 10sec */
- throw new UnknownHostException( DOMAIN );
- } else if( new_dc_list.length >= dc_list_range ) {
- dc_list = new_dc_list;
- }
- if( dc_list_range > 1 ) {
- dc_list_range /= 2; /* shrink dc_list_range */
+ synchronized (DOMAIN) {
+ long now = System.currentTimeMillis();
+ if (dc_list_expiration < now) {
+ dc_list_expiration = now + CACHE_POLICY * 1000L;
+ NbtAddress[] list = NbtAddress.getAllByName( DOMAIN, 0x1C, null, null );
+ if (list != null && list.length > 0) {
+ dc_list = list;
+ } else { /* keep using the old list */
+ dc_list_expiration = now + 1000 * 60 * 15; /* 15 min */
+ if (SmbTransport.log.level > 1) {
+ SmbTransport.log.println( "Failed to retrieve DC list from WINS" );
+ }
+ }
}
- }
- starting_index = dc_list_index;
- do {
- if( dc_list_index == dc_list_range ) {
- dc_list_index = 0;
- }
- NbtAddress addr = dc_list[dc_list_index];
- if( addr != null ) {
- try {
- UniAddress dc = new UniAddress( addr );
- SmbTransport trans = SmbTransport.getSmbTransport( dc, 0 );
- if( USERNAME == null ) {
- if( SmbTransport.log.level > 2 )
- SmbTransport.log.println(
- "Default credentials (jcifs.smb.client.username/password)" +
- " not specified. SMB signing may not work propertly." +
- " Skipping DC interrogation." );
- trans.negotiate();
- } else {
- trans.getSmbSession( NtlmPasswordAuthentication.DEFAULT ).getSmbTree(
- LOGON_SHARE, null ).treeConnect( null, null );
+ int max = Math.min( dc_list.length, LOOKUP_RESP_LIMIT );
+ for (int j = 0; j < max; j++) {
+ int i = dc_list_counter++ % max;
+ if (dc_list[i] != null) {
+ try {
+ return interrogate( dc_list[i] );
+ } catch (SmbException se) {
+ if (SmbTransport.log.level > 1)
+ SmbTransport.log.println( "Failed validate DC: " + dc_list[i] +
+ ": " + se.getMessage() );
}
-synchronized( trans ) {
- if( trans.sessions.size() > (trans.SSN_LIMIT / 10)) {
- incr_dc_list_range();
- }
-}
- dc_list_index++;
- return new NtlmChallenge( trans.server.encryptionKey, dc );
- } catch( SmbException se ) {
- if( SmbTransport.log.level > 1 )
- SmbTransport.log.println( "Failed validate DC: " + addr +
- ": " + se.getMessage() );
+ dc_list[i] = null;
}
- dc_list[dc_list_index] = null; /* dc no good */
- incr_dc_list_range();
}
- dc_list_index++;
- } while( dc_list_index != starting_index );
-}
- dc_list_expiration = System.currentTimeMillis() + 10000; /* 10sec */
+ dc_list_expiration = now + 1000 * 60 * 15; /* 15 min */
+ }
+
throw new UnknownHostException(
"Failed to negotiate with a suitable domain controller for " + DOMAIN );
}
-
public static byte[] getChallenge( UniAddress dc )
throws SmbException, UnknownHostException {
return getChallenge(dc, 0);