jcifs-1.3.16 from tgz
authorFelix <felix@h1611079.stratoserver.net>
Sun, 3 Jul 2011 10:41:40 +0000 (12:41 +0200)
committerFelix <felix@h1611079.stratoserver.net>
Sun, 3 Jul 2011 10:53:36 +0000 (12:53 +0200)
 * JCIFS now uses the InetSocketAddress class to explicitly bind and
   set the SO_TIMEOUT on client sockets before they are connected. This
   makes the SO_TIMEOUT effective when the target server socket is not
   listening and the client OS socket implementation takes a long time
   for the dropped SYN to timeout. This may significantly reduce
   resource consumption in applications that use multiple threads to
   constantly query servers that may not be listening.
 * When disconnecting a transport, new clauses have been added to better
   reset transport state whereas previously transports could get stuck
   in a disconnected state for unnecessarily long periods of time.
 * A new property jcifs.smb.client.ignoreCopyToException has been added.
   When set to "true" (the default), the SmbFile.copyTo() method will
   ignore (but log) exceptions trying to copy individual files or directories
   (such as because of a permissions error). To maintain backward
   compatibility, the default value of this property is "true" (exceptions
   are ignored). Setting this property to "false" will cause any exception
   that occurs trying to copy an individual file or directory to be thrown
   out of copyTo and abort the copy operation at the point of failure.
 * If an authentication exception occurs trying to connect to a server
   that has multiple IP addresses, JCIFS will not attempt to connect to
   more than one IP addresses because doing so could result in an account
   lockout.
 * The SID resolver code incorrectly resolved SIDs of an ACE in blocks
   of at most 10 where it should have used a limit of 64. This performance
   issue has been fixed.
 * JCIFS will not throw the artifical "Access is denied" error if the
   special NtlmPasswordCredential.ANONYMOUS credential is used explicitly
   (whereas normally JCIFS will deliberately throw an SmbAuthException
   if a login results in a guest login or if the anonymous identity is used).
 * The NetrServerEnum2 RAP call used incorrect parameter descriptiors which
   could result in "SmbException: 2320" errors trying to list domains and
   servers from the local NetBIOS browse service.
 * The NTLMSSP AUTHENTICATE_MESSAGE (aka "Type 2 Message") encoding routine
   incorrectly left out the TargetName field (although this had no effect
   on CIFS client behavior).

15 files changed:
build.xml
examples/ListFilesAnon.java [new file with mode: 0644]
examples/Makefile
examples/SidLookup.java
examples/TestGetParent.java [new file with mode: 0644]
examples/TestListLoop.java [new file with mode: 0644]
examples/runtests.sh
patches/GetOwnerSid.patch
src/jcifs/ntlmssp/Type2Message.java
src/jcifs/smb/NetServerEnum2.java
src/jcifs/smb/NtlmPasswordAuthentication.java
src/jcifs/smb/SmbFile.java
src/jcifs/smb/SmbSession.java
src/jcifs/smb/SmbTransport.java
src/jcifs/util/transport/Transport.java

index 36ab8fc..cb68a72 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -1,7 +1,7 @@
 <project name="jcifs" default="usage" basedir=".">
 
-    <property name="version" value="1.3.15"/>
-    <property name="reldate" value="Oct 7, 2010"/>
+    <property name="version" value="1.3.16"/>
+    <property name="reldate" value="Jun 23, 2011"/>
 
     <target name="usage">
         <echo>
@@ -47,7 +47,14 @@ dependencies: Checks that all class dependencies are met.
 
     <target name="compile" depends="dependencies">
         <mkdir dir="build"/>
-        <javac srcdir="src" destdir="build" debug="on">
+        <javac srcdir="src"
+            destdir="build"
+            source="1.5"
+            target="1.5"
+            fork="yes"
+            executable="/usr/local/java5/bin/javac"
+            compiler="javac1.5"
+            debug="on">
 <!--
             <compilerarg line="-Xlint:deprecation -Xlint:unchecked"/>
 -->
@@ -58,6 +65,13 @@ dependencies: Checks that all class dependencies are met.
 
     <target name="jar" depends="compile">
         <jar jarfile="jcifs-${version}.jar">
+            <manifest>
+                <attribute name="Bundle-Version" value="${version}"/>
+                <attribute name="Bundle-Name" value="jcifs"/>
+                <attribute name="Bundle-ManifestVersion" value="2"/>
+                <attribute name="Bundle-SymbolicName" value="jcifs"/>
+                <attribute name="Export-Package" value="jcifs, jcifs.dcerpc, jcifs.dcerpc.msrpc, jcifs.http, jcifs.https, jcifs.netbios, jcifs.ntlmssp, jcifs.smb, jcifs.util, jcifs.util.transport"/>
+            </manifest>
             <fileset dir="build"/>
         </jar>
     </target>
diff --git a/examples/ListFilesAnon.java b/examples/ListFilesAnon.java
new file mode 100644 (file)
index 0000000..563b18c
--- /dev/null
@@ -0,0 +1,16 @@
+import jcifs.smb.SmbFile;
+import jcifs.smb.NtlmPasswordAuthentication;
+
+public class ListFilesAnon {
+
+    public static void main( String[] argv ) throws Exception {
+
+        for (int a = 0; a < argv.length; a++) {
+            SmbFile file = new SmbFile( argv[a], NtlmPasswordAuthentication.ANONYMOUS );
+            SmbFile[] files = file.listFiles();
+            for( int i = 0; i < files.length; i++ ) {
+                System.out.print( " " + files[i].getName() );
+            }
+        }
+    }
+}
index 8aca995..30420ff 100644 (file)
@@ -1,9 +1,9 @@
-JAVA_HOME=/usr/local/java4
+JAVA_HOME=/usr/local/java5
 CLASSPATH=../build:.
 
 .SUFFIXES: .java .class
 
-CLASSFILES=GetGroupMemberSidsFromURL.class ListACL.class LargeListFiles.class GetShareSecurity.class CountPerms.class AclCrawler.class SidCacheTest.class GetSecurity.class SidCrawler.class InterruptTest.class AllocInfo.class Append.class AuthListFiles.class CallNamedPipe.class CopyTo.class CreateFile.class Delete.class Equals.class Exists.class FileInfo.class FileOps.class FilterFiles.class GetDate.class GetDfsPath.class Get.class GetType.class GetURL.class GrowWrite.class HttpURL.class Interleave.class IsDir.class Length.class ListFiles.class List.class ListTypes.class Mkdir.class NodeStatus.class OpenExclusive.class PeekNamedPipe.class PipeTalk.class Put.class Query.class RenameTo.class SetAttrs.class SetTime.class SlowRead.class SlowWrite.class SmbCrawler.class SmbTableFile.class SmbTableFileRecord.class T2Crawler.class TestRandomAccess.class TestSmbURL.class TestUnicode.class ThreadedNbtQuery.class ThreadedSmbCrawler.class ThreadedUniQuery.class Torture1.class Torture2.class TortureTest5.class TransactNamedPipe.class URLTest.class VerifyGuest.class VerifyIO.class VerifyReads.class
+CLASSFILES=TestListLoop.class TestGetParent.class SidLookup.class GetGroupMemberSidsFromURL.class ListACL.class LargeListFiles.class GetShareSecurity.class CountPerms.class AclCrawler.class SidCacheTest.class GetSecurity.class SidCrawler.class InterruptTest.class AllocInfo.class Append.class AuthListFiles.class CallNamedPipe.class CopyTo.class CreateFile.class Delete.class Equals.class Exists.class FileInfo.class FileOps.class FilterFiles.class GetDate.class GetDfsPath.class Get.class GetType.class GetURL.class GrowWrite.class HttpURL.class Interleave.class IsDir.class Length.class ListFiles.class List.class ListTypes.class Mkdir.class NodeStatus.class OpenExclusive.class PeekNamedPipe.class PipeTalk.class Put.class Query.class RenameTo.class SetAttrs.class SetTime.class SlowRead.class SlowWrite.class SmbCrawler.class SmbTableFile.class SmbTableFileRecord.class T2Crawler.class TestRandomAccess.class TestSmbURL.class TestUnicode.class ThreadedNbtQuery.class ThreadedSmbCrawler.class ThreadedUniQuery.class Torture1.class Torture2.class TortureTest5.class TransactNamedPipe.class URLTest.class VerifyGuest.class VerifyIO.class VerifyReads.class
 
 all: ${CLASSFILES}
 
index aa410eb..807734a 100644 (file)
@@ -3,13 +3,13 @@ import jcifs.smb.*;
 public class SidLookup {
 
     public static void main(String[] argv) throws Exception {
-        if (argv.length < 1) {
-            System.err.println("usage: SidLookup S-1-5-21-1496946806-2192648263-3843101252");
+        if (argv.length < 2) {
+            System.err.println("usage: SidLookup dc1.busicorp.local S-1-5-21-1496946806-2192648263-3843101252-4321");
             return;
         }
 
-        SID sid = new SID(argv[0]);
-        sid.resolve("ts0", null);
+        SID sid = new SID(argv[1]);
+        sid.resolve(argv[0], null);
         System.out.println("      toString: " + sid.toString());
         System.out.println("   toSidString: " + sid.toDisplayString());
         System.out.println("       getType: " + sid.getType());
diff --git a/examples/TestGetParent.java b/examples/TestGetParent.java
new file mode 100644 (file)
index 0000000..74ebde4
--- /dev/null
@@ -0,0 +1,17 @@
+import jcifs.smb.SmbFile;
+
+public class TestGetParent
+{
+
+    public static void main( String argv[] ) throws Exception
+    {
+        if( argv.length < 1 ) {
+            throw new IllegalArgumentException( "smb:// URL is required" );
+        }
+
+        SmbFile f = new SmbFile(argv[0]);
+
+        System.out.println("  getPath: " + f.getPath());
+        System.out.println("getParent: " + f.getParent());
+    }
+}
diff --git a/examples/TestListLoop.java b/examples/TestListLoop.java
new file mode 100644 (file)
index 0000000..d06d835
--- /dev/null
@@ -0,0 +1,32 @@
+import jcifs.smb.SmbFile;
+import jcifs.smb.SmbException;
+
+public class TestListLoop
+{
+
+    public static void main( String argv[] ) throws Exception
+    {
+        if (argv.length < 2) {
+            System.err.println("usage: TestListLoop <smburl> <count>");
+            System.exit(0);
+        }
+
+        int count = Integer.parseInt(argv[1]);
+
+        for ( ;; ) {
+            try {
+                SmbFile f = new SmbFile(argv[0]);
+                SmbFile[] list = f.listFiles();
+                System.out.println("Successfully listed resource: " + list.length);
+            } catch (SmbException se) {
+                se.printStackTrace();
+            }
+
+            if (--count <= 0)
+                break;
+
+            Thread.sleep( 1000 );
+        }
+    }
+}
+
index 1041420..4b22758 100644 (file)
@@ -5,13 +5,13 @@ CLASSPATH=../build:.
 PROPERTIES=../../user2.prp
 RUN="${JAVA_HOME}/bin/java -cp ${CLASSPATH} -Djcifs.properties=${PROPERTIES}"
 
-#SERVER=192.168.2.110
+#SERVER=192.168.15.110
 SERVER=dc1.w.net
 SHARE=tmp
 DIR=test
 
 # Domain-based DFS
-#SERVER=192.168.2.110
+#SERVER=192.168.15.110
 #SERVER=w.net
 #SHARE=root2
 #DIR=test
@@ -21,7 +21,7 @@ DIR=test
 # smb://dc1.w.net/tmp/test/
 # smb://dc3.x.net/tmp/test/
 # Stand-alone DFS
-#SERVER=192.168.2.113
+#SERVER=192.168.15.113
 #SERVER=fs1.w.net
 #SHARE=DFSStandaloneRoot
 #DIR=DFSStandaloneLink/test
@@ -35,6 +35,12 @@ URL_WRITE_DIR=${URL_SHARE}${WRITE_DIR}
 
 set -x
 
+$RUN SidLookup dc1.w.net S-1-5-21-2779991279-2625083122-3494051191-1361
+$RUN TestGetParent 'smb://'
+$RUN TestGetParent ${URL_WRITE_DIR}
+$RUN TestListLoop 'smb://dc5.w.net/tmp/' 2
+$RUN TestCopy smb://fs1.w.net/tmp/xxx/ smb://dc5.w.net/tmp/deleteme/
+$RUN ListFiles smb://
 $RUN ListACL ${URL_WRITE_DIR}
 $RUN LargeListFiles ${URL_WRITE_DIR}
 $RUN CountPerms ${URL_WRITE_DIR} 100
index 3379710..711a0f6 100644 (file)
@@ -1,91 +1,86 @@
-diff -r temp/jcifs_1.2.13/src/jcifs/smb/SecurityDescriptor.java workspace/jcifs/src/jcifs/smb/SecurityDescriptor.java
+diff -r jcifs_1.3.15/src/jcifs/smb/SecurityDescriptor.java jcifs/src/jcifs/smb/SecurityDescriptor.java
 24a25
 >     SID owner_user, owner_group;
-38c39
+40c41
 <         ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to owner sid
 ---
 >         int ownerUOffset = ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to owner sid
-40c41
+42c43
 <         ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to group sid
 ---
 >         int ownerGOffset = ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to group sid
-42c43
+44c45
 <         ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to sacl
 ---
 >         int saclOffset = ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to sacl
-48,56c49,70
+48c49,53
+<         bufferIndex = start + daclOffset;
+---
+>         if (ownerUOffset > 0) {
+>             bufferIndex = start + ownerUOffset;
+>             owner_user = new SID(buffer, bufferIndex);
+>             bufferIndex += 28; // ???
+>         }
+50,55c55,59
 <         bufferIndex++; // revision
 <         bufferIndex++;
 <         int size = ServerMessageBlock.readInt2(buffer, bufferIndex);
 <         bufferIndex += 2;
 <         int numAces = ServerMessageBlock.readInt4(buffer, bufferIndex);
 <         bufferIndex += 4;
-< 
-<         if (numAces > 4096)
-<             throw new RuntimeException( "Invalid SecurityDescriptor" );
 ---
->         if ( ownerUOffset > 0 ) {
->           bufferIndex = start + ownerUOffset;
->           owner_user = new SID ( buffer, bufferIndex );
->           bufferIndex += 28; // ???
+>         if (ownerGOffset > 0) {
+>             bufferIndex = start + ownerGOffset;
+>             owner_group = new SID(buffer, bufferIndex);
+>             bufferIndex += 28; // ???
 >         }
-> 
->         if ( ownerGOffset > 0 ) {
->           bufferIndex = start + ownerGOffset;
->           owner_group = new SID ( buffer, bufferIndex );
->           bufferIndex += 28; // ???
->         }
-> 
->         if ( daclOffset > 0 ) {
->           bufferIndex++; // revision
->           bufferIndex++;
->           int size = ServerMessageBlock.readInt2(buffer, bufferIndex);
->           bufferIndex += 2;
->           int numAces = ServerMessageBlock.readInt4(buffer, bufferIndex);
->           bufferIndex += 4;
->  
->           if (numAces > 4096)
->               throw new RuntimeException( "Invalid SecurityDescriptor" );
-58,59c72,73
-<         aces = new ACE[numAces];
-<         for (int i = 0; i < numAces; i++) {
+57,58c61
+<         if (numAces > 4096)
+<             throw new IOException( "Invalid SecurityDescriptor" );
 ---
->           aces = new ACE[numAces];
->           for (int i = 0; i < numAces; i++) {
-61a76
->           }
-63d77
-< 
-Only in workspace/jcifs/src/jcifs/smb: SecurityDescriptor.java~
-diff -r temp/jcifs_1.2.13/src/jcifs/smb/SmbFile.java workspace/jcifs/src/jcifs/smb/SmbFile.java
-2722a2723,2752
+>         bufferIndex = start + daclOffset;
+60a64,73
+>             bufferIndex++; // revision
+>             bufferIndex++;
+>             int size = ServerMessageBlock.readInt2(buffer, bufferIndex);
+>             bufferIndex += 2;
+>             int numAces = ServerMessageBlock.readInt4(buffer, bufferIndex);
+>             bufferIndex += 4;
+> 
+>             if (numAces > 4096)
+>                 throw new IOException( "Invalid SecurityDescriptor" );
 > 
+diff -r jcifs_1.3.15/src/jcifs/smb/SmbFile.java jcifs/src/jcifs/smb/SmbFile.java
+2966a2967,2998
 >     public SID getOwnerUser() throws IOException {
->       int f = open0( O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0 );
 > 
->       /*
->        * NtTrans Query Security Desc Request / Response
->        */
+>         int f = open0(O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0);
+> 
+>         /*
+>          * NtTrans Query Security Desc Request / Response
+>          */
+> 
+>         NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc(f, 0x01);
+>         NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse();
+>         send(request, response);
+> 
+>         close(f, 0L);
+>         return response.securityDescriptor.owner_user;
+>     }
 > 
->       NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc( f, 0x01 );
->       NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse();
->       send( request, response );
+>     public SID getOwnerGroup() throws IOException {
 > 
->       close( f, 0L );
->       return response.securityDescriptor.owner_user;
->   }
+>         int f = open0(O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0);
 > 
->   public SID getOwnerGroup() throws IOException {
->       int f = open0( O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0 );
+>         /*
+>          * NtTrans Query Security Desc Request / Response
+>          */
 > 
->       /*
->        * NtTrans Query Security Desc Request / Response
->        */
+>         NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc(f, 0x02);
+>         NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse();
+>         send(request, response);
 > 
->       NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc( f, 0x02 );
->       NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse();
->       send( request, response );
+>         close(f, 0L);
+>         return response.securityDescriptor.owner_group;
+>     }
 > 
->       close( f, 0L );
->       return response.securityDescriptor.owner_group;
->   }
index 26fe976..5a902ea 100644 (file)
@@ -231,17 +231,13 @@ public class Type2Message extends NtlmMessage {
             byte[] targetInformation = getTargetInformation();
             int flags = getFlags();
             byte[] target = new byte[0];
-            if ((flags & (NTLMSSP_TARGET_TYPE_DOMAIN |
-                    NTLMSSP_TARGET_TYPE_SERVER |
-                            NTLMSSP_TARGET_TYPE_SHARE)) != 0) {
+            if ((flags & NTLMSSP_REQUEST_TARGET) != 0) {
                 if (targetName != null && targetName.length() != 0) {
                     target = (flags & NTLMSSP_NEGOTIATE_UNICODE) != 0 ?
                             targetName.getBytes(UNI_ENCODING) :
                             targetName.toUpperCase().getBytes(getOEMEncoding());
                 } else {
-                    flags &= (0xffffffff ^ (NTLMSSP_TARGET_TYPE_DOMAIN |
-                            NTLMSSP_TARGET_TYPE_SERVER |
-                                    NTLMSSP_TARGET_TYPE_SHARE));
+                    flags &= (0xffffffff ^ NTLMSSP_REQUEST_TARGET);
                 }
             }
             if (targetInformation != null) {
index f7cb728..dab09b4 100644 (file)
@@ -27,8 +27,8 @@ class NetServerEnum2 extends SmbComTransaction {
     static final int SV_TYPE_DOMAIN_ENUM = 0x80000000;
 
     static final String[] DESCR = {
+        "WrLehDO\u0000B16BBDz\u0000",
         "WrLehDz\u0000B16BBDz\u0000",
-        "WrLehDzz\u0000B16BBDz\u0000"
     };
 
     String domain, lastName = null;
@@ -42,8 +42,7 @@ class NetServerEnum2 extends SmbComTransaction {
         name = "\\PIPE\\LANMAN";
 
         maxParameterCount = 8;
-//        maxDataCount = 4096; why was this here?
-maxDataCount = 16384;
+        maxDataCount = 16384;
         maxSetupCount = (byte)0x00;
         setupCount = 0;
         timeout = 5000;
index d256d48..c453540 100644 (file)
@@ -192,6 +192,8 @@ public final class NtlmPasswordAuthentication implements Principal, Serializable
     }
     public static byte[] nTOWFv1(String password)
     {
+        if (password == null)
+            throw new RuntimeException("Password parameter is required");
         try {
             MD4 md4 = new MD4();
             md4.update(password.getBytes(SmbConstants.UNI_ENCODING));
index 9f63f4c..627df4b 100644 (file)
@@ -358,6 +358,7 @@ public class SmbFile extends URLConnection implements SmbConstants {
 
     static LogStream log = LogStream.getInstance();
     static long attrExpirationPeriod;
+    static boolean ignoreCopyToException;
 
     static {
 
@@ -367,6 +368,7 @@ public class SmbFile extends URLConnection implements SmbConstants {
             cnfe.printStackTrace();
         }
         attrExpirationPeriod = Config.getLong( "jcifs.smb.client.attrExpirationPeriod", DEFAULT_ATTR_EXPIRATION_PERIOD );
+        ignoreCopyToException = Config.getBoolean( "jcifs.smb.client.ignoreCopyToException", true );
         dfs = new Dfs();
     }
 
@@ -661,6 +663,9 @@ public class SmbFile extends URLConnection implements SmbConstants {
         return blank_resp;
     }
     void resolveDfs(ServerMessageBlock request) throws SmbException {
+        if (request instanceof SmbComClose)
+            return;
+
         connect0();
 
         DfsReferral dr = dfs.resolve(
@@ -948,6 +953,8 @@ int addressIndex;
             try {
                 doConnect();
                 return;
+            } catch(SmbAuthException sae) {
+                throw sae; // Prevents account lockout on servers with multiple IPs
             } catch(SmbException se) {
                 if (getNextAddress() == null) 
                     throw se;
@@ -2246,9 +2253,13 @@ if (this instanceof SmbNamedPipe) {
                         dest.fid, attributes, createTime, lastModified ),
                         new Trans2SetFileInformationResponse() );
                 dest.close( 0L );
-            } catch( Exception ex ) {
+            } catch( SmbException se ) {
+
+                if (ignoreCopyToException == false)
+                    throw new SmbException("Failed to copy file from [" + this.toString() + "] to [" + dest.toString() + "]", se);
+
                 if( log.level > 1 )
-                    ex.printStackTrace( log );
+                    se.printStackTrace( log );
             } finally {
                 close();
             }
@@ -2854,7 +2865,7 @@ if (this instanceof SmbNamedPipe) {
                 sids[ai] = aces[ai].sid;
             }
 
-            for (int off = 0; off < sids.length; off += 10) {
+            for (int off = 0; off < sids.length; off += 64) {
                 int len = sids.length - off;
                 if (len > 64)
                     len = 64;
index 0ebc807..86d627b 100644 (file)
@@ -28,10 +28,6 @@ import jcifs.UniAddress;
 import jcifs.netbios.NbtAddress;
 import jcifs.util.MD4;
 
-/**
- * Update June 2009: This logon method of this class does not and never will support NTLMv2. JCIFS does not implement the acceptor side of NTLM authentication. It can only initiate NTLM authentication as a client.
- */
-
 public final class SmbSession {
 
     private static final String LOGON_SHARE =
@@ -137,8 +133,6 @@ synchronized (DOMAIN) {
  * valid, the method will return without throwing an exception. See the
  * last <a href="../../../faq.html">FAQ</a> question.
  * <p>
- * Update June 2009: This method does not support NTLMv2. JCIFS does not implement the acceptor side of NTLM authentication. It can only initiate NTLM authentication as a client.
- * <p>
  * See also the <tt>jcifs.smb.client.logonShare</tt> property.
  */
     public static void logon( UniAddress dc,
@@ -328,7 +322,8 @@ synchronized (transport()) {
     
                         if( response.isLoggedInAsGuest &&
                                     "GUEST".equalsIgnoreCase( auth.username ) == false &&
-                                    transport.server.security != SmbConstants.SECURITY_SHARE) {
+                                    transport.server.security != SmbConstants.SECURITY_SHARE &&
+                                    auth != NtlmPasswordAuthentication.ANONYMOUS) {
                             throw new SmbAuthException( NtStatus.NT_STATUS_LOGON_FAILURE );
                         }
     
index 26b2be2..2e6c22b 100644 (file)
@@ -181,12 +181,20 @@ public class SmbTransport extends Transport implements SmbConstants {
     void ssn139() throws IOException {
         Name calledName = new Name( address.firstCalledName(), 0x20, null );
         do {
+/* These Socket constructors attempt to connect before SO_TIMEOUT can be applied
             if (localAddr == null) {
                 socket = new Socket( address.getHostAddress(), 139 );
             } else {
                 socket = new Socket( address.getHostAddress(), 139, localAddr, localPort );
             }
             socket.setSoTimeout( SO_TIMEOUT );
+*/
+
+            socket = new Socket();
+            if (localAddr != null)
+                socket.bind(new InetSocketAddress(localAddr, localPort));
+            socket.connect(new InetSocketAddress(address.getHostAddress(), 139), SO_TIMEOUT);
+
             out = socket.getOutputStream();
             in = socket.getInputStream();
 
@@ -241,12 +249,19 @@ public class SmbTransport extends Transport implements SmbConstants {
             } else {
                 if (port == 0)
                     port = DEFAULT_PORT; // 445
+/* These Socket constructors attempt to connect before SO_TIMEOUT can be applied
                 if (localAddr == null) {
                     socket = new Socket( address.getHostAddress(), port );
                 } else {
                     socket = new Socket( address.getHostAddress(), port, localAddr, localPort );
                 }
                 socket.setSoTimeout( SO_TIMEOUT );
+*/
+                socket = new Socket();
+                if (localAddr != null)
+                    socket.bind(new InetSocketAddress(localAddr, localPort));
+                socket.connect(new InetSocketAddress(address.getHostAddress(), port), SO_TIMEOUT);
+
                 out = socket.getOutputStream();
                 in = socket.getInputStream();
             }
@@ -344,15 +359,20 @@ public class SmbTransport extends Transport implements SmbConstants {
     }
     protected void doDisconnect( boolean hard ) throws IOException {
         ListIterator iter = sessions.listIterator();
-        while (iter.hasNext()) {
-            SmbSession ssn = (SmbSession)iter.next();
-            ssn.logoff( hard );
+        try {
+            while (iter.hasNext()) {
+                SmbSession ssn = (SmbSession)iter.next();
+                ssn.logoff( hard );
+            }
+            socket.shutdownOutput();
+            out.close();
+            in.close();
+            socket.close();
+        } finally {
+            digest = null;
+            socket = null;
+            tconHostName = null;
         }
-        socket.shutdownOutput();
-        out.close();
-        in.close();
-        socket.close();
-        digest = null;
     }
 
     protected void makeKey( Request request ) throws IOException {
index 8e3c40a..5f2790a 100644 (file)
@@ -198,6 +198,8 @@ public abstract class Transport implements Runnable {
         }
     }
     public synchronized void disconnect( boolean hard ) throws IOException {
+        IOException ioe = null;
+
         switch (state) {
             case 0: /* not connected - just return */
                 return;
@@ -207,7 +209,11 @@ public abstract class Transport implements Runnable {
                 if (response_map.size() != 0 && !hard) {
                     break; /* outstanding requests */
                 }
-                doDisconnect( hard );
+                try {
+                    doDisconnect( hard );
+                } catch (IOException ioe0) {
+                    ioe = ioe0;
+                }
             case 4: /* in error - reset the transport */
                 thread = null;
                 state = 0;
@@ -219,6 +225,9 @@ public abstract class Transport implements Runnable {
                 state = 0;
                 break;
         }
+
+        if (ioe != null)
+            throw ioe;
     }
     public void run() {
         Thread run_thread = Thread.currentThread();