jcifs-1.2.22 from tgz
authorFelix Schumacher <p0354740@isib001.(none)>
Wed, 6 Aug 2008 14:47:28 +0000 (16:47 +0200)
committerFelix Schumacher <p0354740@isib001.(none)>
Wed, 6 Aug 2008 14:47:28 +0000 (16:47 +0200)
Wed Jun 25 20:26:33 EDT 2008
jcifs-1.2.22

The SmbFileInputStream methods will now throw InterruptedIOExceptions
where apppropriate whereas previously they would throw SmbExceptions
with a root cause of TransportException with a root cause of
InterruptedException.

If SmbSession.send() throw an exception it could leave the session in a
bad state which could cause "Invalid parameter" exceptions on subsequent
requests.

An InterruptedException in jcifs.netbios.NameServiceClient was being
caught and ignored. It will now be re-thrown as an IOException so that all
threads used with/by JCIFS can be interrupted and caused to exit. Several
other similar (albeit less important) InterruptedExceptions were also
adjusted.

A jcifs.smb.client.dfs.disabled property has been added to disable domain
based DFS so that the client does not try and fail to resolve paths as
domain paths in non-domain environments (e.g. on the local machine).

The getSecurity and getShareSecurity methods will now return null if no
DACL is present on a file whereas previously it would retrun an empty
array. This allows the caller to distinguish between an empty DACL and
one that is simply empty.

15 files changed:
README.txt
build.xml
examples/InterruptTest.java
examples/runtests.sh
src/jcifs/dcerpc/DcerpcHandle.java
src/jcifs/dcerpc/msrpc/MsrpcShareGetInfo.java
src/jcifs/netbios/NameServiceClient.java
src/jcifs/smb/BufferCache.java
src/jcifs/smb/Dfs.java
src/jcifs/smb/NtTransQuerySecurityDescResponse.java
src/jcifs/smb/SecurityDescriptor.java
src/jcifs/smb/SmbFile.java
src/jcifs/smb/SmbFileInputStream.java
src/jcifs/smb/SmbSession.java
src/jcifs/smb/SmbTransport.java

index e939aae..c2b2b27 100644 (file)
@@ -1,4 +1,32 @@
+Wed Jun 25 20:26:33 EDT 2008
+jcifs-1.2.22
+
+The SmbFileInputStream methods will now throw InterruptedIOExceptions
+where apppropriate whereas previously they would throw SmbExceptions
+with a root cause of TransportException with a root cause of
+InterruptedException.
+
+If SmbSession.send() throw an exception it could leave the session in a
+bad state which could cause "Invalid parameter" exceptions on subsequent
+requests.
+
+An InterruptedException in jcifs.netbios.NameServiceClient was being
+caught and ignored. It will now be re-thrown as an IOException so that all
+threads used with/by JCIFS can be interrupted and caused to exit. Several
+other similar (albeit less important) InterruptedExceptions were also
+adjusted.
+
+A jcifs.smb.client.dfs.disabled property has been added to disable domain
+based DFS so that the client does not try and fail to resolve paths as
+domain paths in non-domain environments (e.g. on the local machine).
+
+The getSecurity and getShareSecurity methods will now return null if no
+DACL is present on a file whereas previously it would retrun an empty
+array. This allows the caller to distinguish between an empty DACL and
+one that is simply empty.
+
 Wed May 28 22:46:56 EDT 2008
+jcifs-1.2.21
 
 An NPE in jcifs.Config was accidentally introduced in 1.2.20. This has
 been fixed.
index 8a20066..5943d4d 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -1,7 +1,7 @@
 <project name="jcifs" default="usage" basedir=".">
 
-    <property name="version" value="1.2.21"/>
-    <property name="reldate" value="May 28, 2008"/>
+    <property name="version" value="1.2.22"/>
+    <property name="reldate" value="Jun 25, 2008"/>
 
     <target name="usage">
         <echo>
index 63cffab..0ba5c37 100644 (file)
@@ -1,3 +1,4 @@
+import java.io.InterruptedIOException;
 import jcifs.util.transport.TransportException;
 import jcifs.smb.*;
 
@@ -9,7 +10,7 @@ public class InterruptTest extends Thread {
         this.url = url;
     }
     public void run() {
-        for (int i = 0; i < 10; i++) {
+        for (int i = 0; i < 100; i++) {
             try {
                 SmbFileInputStream in = new SmbFileInputStream(url);
 
@@ -19,13 +20,16 @@ public class InterruptTest extends Thread {
                 }
 
                 in.close();
+            } catch(InterruptedIOException iioe) {
+                System.out.println("InterruptedIOException");
+                continue;
             } catch(SmbException se) {
                 Throwable t = se.getRootCause();
                 if (t instanceof TransportException) {
                     TransportException te = (TransportException)t;
                     t = te.getRootCause();
                     if (t instanceof InterruptedException) {
-                        System.out.println("interrupted ok");
+                        System.out.println("InterruptedException in constructor");
                         continue;
                     }
                 }
@@ -41,8 +45,7 @@ public class InterruptTest extends Thread {
     public static void main( String argv[] ) throws Exception {
         InterruptTest it = new InterruptTest(argv[0]);
         it.start();
-        Thread.sleep(300);
-        for (int i = 0; i < 10; i++) {
+        for (int i = 0; i < 20; i++) {
             Thread.sleep(200);
             it.interrupt();
         }
index 670504c..fd592b3 100644 (file)
@@ -6,7 +6,7 @@ PROPERTIES=../../user1.prp
 RUN="${JAVA_HOME}/bin/java -cp ${CLASSPATH} -Djcifs.properties=${PROPERTIES}"
 
 SERVER=dc1.w.net
-SHARE=target1
+SHARE=tmp
 WRITE_DIR=test/
 SRC_DIR=test/Junk
 FILE1=test/Junk/10883563.doc
@@ -27,7 +27,7 @@ $RUN GetSecurity ${URL_SHARE}
 $RUN GetShareSecurity ${URL_WRITE_DIR}
 $RUN SidCrawler ${URL_WRITE_DIR} 5
 $RUN GetGroupMemberSidsFromURL ${URL_WRITE_DIR}
-$RUN InterruptTest ${URL_WRITE_DIR}Append.txt
+$RUN InterruptTest ${URL_WRITE_DIR}${FILE1}
 $RUN AllocInfo ${URL_SHARE}
 $RUN Append ${URL_WRITE_DIR}Append.txt
 $RUN AuthListFiles smb://bogus\@${SERVER}/${SHARE}/
index 193fd30..7786a82 100644 (file)
@@ -131,7 +131,11 @@ public abstract class DcerpcHandle implements DcerpcConstants {
 
         isDirect = msg instanceof DcerpcBind;
 
-        stub = jcifs.smb.BufferCache.getBuffer();
+        try {
+            stub = jcifs.smb.BufferCache.getBuffer();
+        } catch (InterruptedException ie) {
+            throw new IOException(ie.getMessage());
+        }
         try {
             int off, tot, n;
 
index a795a12..d7c1081 100644 (file)
@@ -19,6 +19,8 @@
 
 package jcifs.dcerpc.msrpc;
 
+import java.io.IOException;
+
 import jcifs.smb.*;
 import jcifs.util.Hexdump;
 
@@ -30,13 +32,13 @@ public class MsrpcShareGetInfo extends srvsvc.ShareGetInfo {
         flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG;
     }
 
-    public ACE[] getSecurity() {
+    public ACE[] getSecurity() throws IOException {
         srvsvc.ShareInfo502 info502 = (srvsvc.ShareInfo502)info;
         if (info502.security_descriptor != null) {
             SecurityDescriptor sd;
             sd = new SecurityDescriptor(info502.security_descriptor, 0, info502.sd_size);
             return sd.aces;
         }
-        return new ACE[0];
+        return null;
     }
 }
index bc3bdf2..c250986 100644 (file)
@@ -20,7 +20,6 @@ package jcifs.netbios;
 
 import java.net.*;
 import java.io.IOException;
-import java.io.InterruptedIOException;
 import java.util.HashMap;
 import java.util.StringTokenizer;
 import jcifs.Config;
@@ -145,8 +144,6 @@ class NameServiceClient implements Runnable {
         // be ignored; see tryClose comment.
         if( socket == null ) {
             socket = new DatagramSocket( lport, laddr );
-jcifs.Config.socketCount++;
-log.println(jcifs.Config.socketCount + ": new Socket: " + socket);
             thread = new Thread( this, "JCIFS-NameServiceClient" );
             thread.setDaemon( true );
             thread.start();
@@ -164,10 +161,7 @@ log.println(jcifs.Config.socketCount + ": new Socket: " + socket);
              */
 
             if( socket != null ) {
-String s = socket.toString();
                 socket.close();
-jcifs.Config.socketCount--;
-log.println(jcifs.Config.socketCount + ": socket closed: " + s);
                 socket = null;
             }
             thread = null;
@@ -259,6 +253,7 @@ log.println(jcifs.Config.socketCount + ": socket closed: " + s);
                     }
 
                 } catch( InterruptedException ie ) {
+                    throw new IOException(ie.getMessage());
                 } finally {
                     responseTable.remove( nid );
                 }
index 17f97bf..14fa4fa 100644 (file)
@@ -48,26 +48,20 @@ public class BufferCache {
         return buf;
     }
 
-    static void getBuffers( SmbComTransaction req, SmbComTransactionResponse rsp ) {
+    static void getBuffers( SmbComTransaction req,
+                    SmbComTransactionResponse rsp ) throws InterruptedException {
         synchronized( cache ) {
-            try {
-                while ((freeBuffers + (MAX_BUFFERS - numBuffers)) < 2) {
-                    cache.wait();
-                }
-                req.txn_buf = getBuffer0();
-                rsp.txn_buf = getBuffer0();
-            } catch( InterruptedException ie ) {
-                ie.printStackTrace();
+            while ((freeBuffers + (MAX_BUFFERS - numBuffers)) < 2) {
+                cache.wait();
             }
+            req.txn_buf = getBuffer0();
+            rsp.txn_buf = getBuffer0();
         }
     }
-    static public byte[] getBuffer() {
+    static public byte[] getBuffer() throws InterruptedException {
         synchronized( cache ) {
             while ((freeBuffers + (MAX_BUFFERS - numBuffers)) < 1) {
-                try {
-                    cache.wait();
-                } catch(InterruptedException ie) {
-                }
+                cache.wait();
             }
             return getBuffer0();
         }
index 825dc94..5f7700a 100644 (file)
@@ -42,6 +42,7 @@ public class Dfs {
     static LogStream log = LogStream.getInstance();
     static final boolean strictView = Config.getBoolean("jcifs.smb.client.dfs.strictView", false);
     static final long TTL = Config.getLong("jcifs.smb.client.dfs.ttl", 300);
+    static final boolean DISABLED = Config.getBoolean("jcifs.smb.client.dfs.disabled", false);
 
     protected static CacheEntry FALSE_ENTRY = new Dfs.CacheEntry(0L);
 
@@ -49,6 +50,9 @@ public class Dfs {
     protected CacheEntry referrals = null;
 
     public HashMap getTrustedDomains(NtlmPasswordAuthentication auth) throws SmbAuthException {
+        if (DISABLED)
+            return null;
+
         if (_domains != null && System.currentTimeMillis() > _domains.expiration) {
             _domains = null;
         }
@@ -85,6 +89,9 @@ public class Dfs {
     }
     public SmbTransport getDc(String domain,
                     NtlmPasswordAuthentication auth) throws SmbAuthException {
+        if (DISABLED)
+            return null;
+
         try {
             UniAddress addr = UniAddress.getByName(domain, true);
             SmbTransport trans = SmbTransport.getSmbTransport(addr, 0);
@@ -107,6 +114,9 @@ public class Dfs {
                     String root,
                     String path,
                     NtlmPasswordAuthentication auth) throws SmbAuthException {
+        if (DISABLED)
+            return null;
+
         try {
             String p = "\\" + domain + "\\" + root;
             if (path != null)
@@ -130,7 +140,7 @@ public class Dfs {
         DfsReferral dr = null;
         long now = System.currentTimeMillis();
 
-        if (root.equals("IPC$")) {
+        if (DISABLED || root.equals("IPC$")) {
             return null;
         }
         HashMap domains = getTrustedDomains(auth);
@@ -217,6 +227,9 @@ public class Dfs {
         int s1, s2;
         String server, share, key;
 
+        if (DISABLED)
+            return;
+
         s1 = path.indexOf('\\', 1);
         s2 = path.indexOf('\\', s1 + 1);
         server = path.substring(1, s1);
index 3700805..31e2ec4 100644 (file)
@@ -18,6 +18,8 @@
 
 package jcifs.smb;
 
+import java.io.IOException;
+
 class NtTransQuerySecurityDescResponse extends SmbComNtTransactionResponse {
 
     SecurityDescriptor securityDescriptor;
@@ -48,8 +50,12 @@ class NtTransQuerySecurityDescResponse extends SmbComNtTransactionResponse {
         if (errorCode != 0)
             return 4;
 
-        securityDescriptor = new SecurityDescriptor();
-        bufferIndex += securityDescriptor.decode(buffer, bufferIndex, len);
+        try {
+            securityDescriptor = new SecurityDescriptor();
+            bufferIndex += securityDescriptor.decode(buffer, bufferIndex, len);
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe.getMessage());
+        }
 
         return bufferIndex - start;
     }
index f40b86e..90e1261 100644 (file)
@@ -27,10 +27,10 @@ public class SecurityDescriptor {
 
     public SecurityDescriptor() {
     }
-    public SecurityDescriptor(byte[] buffer, int bufferIndex, int len) {
+    public SecurityDescriptor(byte[] buffer, int bufferIndex, int len) throws IOException {
         this.decode(buffer, bufferIndex, len);
     }
-    public int decode(byte[] buffer, int bufferIndex, int len) {
+    public int decode(byte[] buffer, int bufferIndex, int len) throws IOException {
         int start = bufferIndex;
 
         bufferIndex++; // revision
@@ -55,20 +55,28 @@ public class SecurityDescriptor {
         bufferIndex += 4;
 
         if (numAces > 4096)
-            throw new RuntimeException( "Invalid SecurityDescriptor" );
+            throw new IOException( "Invalid SecurityDescriptor" );
 
-        aces = new ACE[numAces];
-        for (int i = 0; i < numAces; i++) {
-            aces[i] = new ACE();
-            bufferIndex += aces[i].decode(buffer, bufferIndex);
+        if (daclOffset != 0) {
+            aces = new ACE[numAces];
+            for (int i = 0; i < numAces; i++) {
+                aces[i] = new ACE();
+                bufferIndex += aces[i].decode(buffer, bufferIndex);
+            }
+        } else {
+            aces = null;
         }
 
         return bufferIndex - start;
     }
     public String toString() {
         String ret = "SecurityDescriptor:\n";
-        for (int ai = 0; ai < aces.length; ai++) {
-            ret += aces[ai].toString() + "\n";
+        if (aces != null) {
+            for (int ai = 0; ai < aces.length; ai++) {
+                ret += aces[ai].toString() + "\n";
+            }
+        } else {
+            ret += "NULL";
         }
         return ret;
     }
index 20ff7a9..3fe2650 100644 (file)
@@ -2807,6 +2807,7 @@ if (this instanceof SmbNamedPipe) {
 /**
  * Return an array of Access Control Entry (ACE) objects representing
  * the security descriptor associated with this file or directory.
+ * If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned.
  * @param resolveSids Attempt to resolve the SIDs within each ACE form
  * their numeric representation to their corresponding account names.
  */
@@ -2830,13 +2831,15 @@ if (this instanceof SmbNamedPipe) {
         }
 
         aces = response.securityDescriptor.aces;
-        processAces(aces, resolveSids);
+        if (aces != null)
+            processAces(aces, resolveSids);
 
         return aces;
     }
 /**
  * Return an array of Access Control Entry (ACE) objects representing
  * the share permissions on the share exporting this file or directory.
+ * If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned.
  * <p>
  * Note that this is different from calling <tt>getSecurity</tt> on a
  * share. There are actually two different ACLs for shares - the ACL on
@@ -2867,7 +2870,8 @@ if (this instanceof SmbNamedPipe) {
             if (rpc.retval != 0)
                 throw new SmbException(rpc.retval, true);
             aces = rpc.getSecurity();
-            processAces(aces, resolveSids);
+            if (aces != null)
+                processAces(aces, resolveSids);
         } finally {
             try {
                 handle.close();
index bd75f90..a5157a3 100644 (file)
@@ -23,6 +23,9 @@ import java.net.UnknownHostException;
 import java.net.MalformedURLException;
 import java.io.InputStream;
 import java.io.IOException;
+import java.io.InterruptedIOException;
+
+import jcifs.util.transport.TransportException;
 
 /**
  * This InputStream can read bytes from a file on an SMB file server. Offsets are 64 bits.
@@ -76,6 +79,20 @@ public class SmbFileInputStream extends InputStream {
                             file.tree.session.transport.server.maxBufferSize - 70 );
     }
 
+    protected IOException seToIoe(SmbException se) {
+        IOException ioe = se;
+        Throwable root = se.getRootCause();
+        if (root instanceof TransportException) {
+            ioe = (TransportException)root;
+            root = ((TransportException)ioe).getRootCause();
+        }
+        if (root instanceof InterruptedException) {
+            ioe = new InterruptedIOException(root.getMessage());
+            ioe.initCause(root);
+        }
+        return ioe;
+    }
+
 /**
  * Closes this input stream and releases any system resources associated with the stream.
  *
@@ -83,8 +100,12 @@ public class SmbFileInputStream extends InputStream {
  */
 
     public void close() throws IOException {
-        file.close();
-        tmp = null;
+        try {
+            file.close();
+            tmp = null;
+        } catch (SmbException se) {
+            throw seToIoe(se);
+        }
     }
 
 /**
@@ -163,7 +184,7 @@ if( file.type == SmbFile.TYPE_NAMED_PIPE ) {
                         se.getNtStatus() == NtStatus.NT_STATUS_PIPE_BROKEN ) {
                     return -1;
                 }
-                throw se;
+                throw seToIoe(se);
             }
             if(( n = response.dataLength ) <= 0 ) {
                 return (int)((fp - start) > 0L ? fp - start : -1);
@@ -191,19 +212,23 @@ if( file.type == SmbFile.TYPE_NAMED_PIPE ) {
             return 0;
         }
 
-        pipe = (SmbNamedPipe)file;
-        file.open(SmbFile.O_EXCL, pipe.pipeType & 0xFF0000, SmbFile.ATTR_NORMAL, 0 );
-
-        req = new TransPeekNamedPipe( file.unc, file.fid );
-        resp = new TransPeekNamedPipeResponse( pipe );
-
-        pipe.send( req, resp );
-        if( resp.status == TransPeekNamedPipeResponse.STATUS_DISCONNECTED ||
-                resp.status == TransPeekNamedPipeResponse.STATUS_SERVER_END_CLOSED ) {
-            file.opened = false;
-            return 0;
+        try {
+            pipe = (SmbNamedPipe)file;
+            file.open(SmbFile.O_EXCL, pipe.pipeType & 0xFF0000, SmbFile.ATTR_NORMAL, 0 );
+    
+            req = new TransPeekNamedPipe( file.unc, file.fid );
+            resp = new TransPeekNamedPipeResponse( pipe );
+    
+            pipe.send( req, resp );
+            if( resp.status == TransPeekNamedPipeResponse.STATUS_DISCONNECTED ||
+                    resp.status == TransPeekNamedPipeResponse.STATUS_SERVER_END_CLOSED ) {
+                file.opened = false;
+                return 0;
+            }
+            return resp.available;
+        } catch (SmbException se) {
+            throw seToIoe(se);
         }
-        return resp.available;
     }
 /**
  * Skip n bytes of data on this stream. This operation will not result
index 0be7059..67551d0 100644 (file)
@@ -236,7 +236,15 @@ do {
             }
             request.uid = uid;
             request.auth = auth;
-            transport.send( request, response );
+            try {
+                transport.send( request, response );
+            } catch (SmbException se) {
+                if (request instanceof SmbComTreeConnectAndX) {
+                    logoff(true);
+                }
+                request.digest = null;
+                throw se;
+            }
         }
     }
     void sessionSetup( ServerMessageBlock andx,
index 270ef07..e49853a 100644 (file)
@@ -182,8 +182,6 @@ public class SmbTransport extends Transport implements SmbConstants {
             } else {
                 socket = new Socket( address.getHostAddress(), 139, localAddr, localPort );
             }
-jcifs.Config.socketCount++;
-log.println(jcifs.Config.socketCount + ": new Socket: " + socket);
             socket.setSoTimeout( SO_TIMEOUT );
             out = socket.getOutputStream();
             in = socket.getInputStream();
@@ -193,13 +191,8 @@ log.println(jcifs.Config.socketCount + ": new Socket: " + socket);
             out.write( sbuf, 0, ssp.writeWireFormat( sbuf, 0 ));
             if (readn( in, sbuf, 0, 4 ) < 4) {
                 try {
-String s = socket.toString();
                     socket.close();
-jcifs.Config.socketCount--;
-log.println(jcifs.Config.socketCount + ": socket closed: " + s);
                 } catch(IOException ioe) {
-log.println(jcifs.Config.socketCount + ": socket close exception:");
-ioe.printStackTrace(log);
                 }
                 throw new SmbException( "EOF during NetBIOS session request" );
             }
@@ -213,10 +206,7 @@ ioe.printStackTrace(log);
                     switch (errorCode) {
                         case NbtException.CALLED_NOT_PRESENT:
                         case NbtException.NOT_LISTENING_CALLED:
-String s = socket.toString();
                             socket.close();
-jcifs.Config.socketCount--;
-log.println(jcifs.Config.socketCount + ": socket closed: " + s);
                             break;
                         default:
                             disconnect( true );
@@ -259,8 +249,6 @@ log.println(jcifs.Config.socketCount + ": socket closed: " + s);
                 } else {
                     socket = new Socket( address.getHostAddress(), port, localAddr, localPort );
                 }
-jcifs.Config.socketCount++;
-log.println(jcifs.Config.socketCount + ": new Socket: " + socket);
                 socket.setSoTimeout( SO_TIMEOUT );
                 out = socket.getOutputStream();
                 in = socket.getInputStream();
@@ -361,10 +349,7 @@ log.println(jcifs.Config.socketCount + ": new Socket: " + socket);
         socket.shutdownOutput();
         out.close();
         in.close();
-String s = socket.toString();
         socket.close();
-jcifs.Config.socketCount--;
-log.println(jcifs.Config.socketCount + ": socket closed: " + s);
         digest = null;
     }
 
@@ -635,6 +620,8 @@ log.println(jcifs.Config.socketCount + ": socket closed: " + s);
             }
         } catch( SmbException se ) {
             throw se;
+        } catch( InterruptedException ie ) {
+            throw new SmbException( ie.getMessage(), ie );
         } catch( IOException ioe ) {
             throw new SmbException( ioe.getMessage(), ioe );
         }