From: Felix Schumacher Date: Wed, 6 Aug 2008 14:35:13 +0000 (+0200) Subject: jcifs-1.2.7 from tgz X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=6038efc3c0de506807c1ba0a80a2448b33137291;p=jcifs_without_docs.git jcifs-1.2.7 from tgz Fri Nov 18 17:08:56 EST 2005 jcifs-1.2.7 released / Transport Error, Filter Changes, Integer Overflow, User Contributed Patches, and More This release consists of the following changes: o Some debugging printlns left over from the last release have been removed. o Added setContentLength(0) to two other places for the NTLM HTTP Filter. This is required for HTTP 1.0 clients (e.g. Google appliance servers). o The name service code will now properly resolve DNS names that begin with digits. o Several instances of possible integer overflow have been fixed. o A patch for large read and write support has been added to the patches directory. A patch for reading security descriptors has been added to the patches directory. o If a transport was in error due to a connection timeout it could remain in the error state indefinitely. This issue has been fixed. --- diff --git a/README.txt b/README.txt index dbf3812..f53164a 100644 --- a/README.txt +++ b/README.txt @@ -1,3 +1,23 @@ +Fri Nov 18 17:08:56 EST 2005 +jcifs-1.2.7 released / Transport Error, Filter Changes, Integer Overflow, +User Contributed Patches, and More + +This release consists of the following changes: + + o Some debugging printlns left over from the last release have been + removed. + o Added setContentLength(0) to two other places for the NTLM HTTP + Filter. This is required for HTTP 1.0 clients (e.g. Google appliance + servers). + o The name service code will now properly resolve DNS names that begin + with digits. + o Several instances of possible integer overflow have been fixed. + o A patch for large read and write support has been added to the patches + directory. A patch for reading security descriptors has been added + to the patches directory. + o If a transport was in error due to a connection timeout it could + remain in the error state indefinitely. This issue has been fixed. + Fri Oct 7 19:47:53 EDT 2005 jcifs-1.2.6 released / Session Management and Filter Fix diff --git a/build.xml b/build.xml index 2af089c..e03e3f2 100644 --- a/build.xml +++ b/build.xml @@ -1,7 +1,7 @@ - - + + @@ -125,6 +125,7 @@ dependencies: Checks that all class dependencies are met. + @@ -139,6 +140,7 @@ dependencies: Checks that all class dependencies are met. + @@ -152,6 +154,7 @@ dependencies: Checks that all class dependencies are met. + @@ -167,6 +170,7 @@ dependencies: Checks that all class dependencies are met. + diff --git a/examples/AclCrawler.java b/examples/AclCrawler.java new file mode 100644 index 0000000..4c1a7fe --- /dev/null +++ b/examples/AclCrawler.java @@ -0,0 +1,61 @@ +import java.util.LinkedList; +import java.util.ListIterator; +import java.net.MalformedURLException; +import java.io.IOException; +import jcifs.smb.*; + +public class AclCrawler { + + int maxDepth; + + AclCrawler( int maxDepth ) { + this.maxDepth = maxDepth; + } + + void traverse( SmbFile f, int depth ) throws MalformedURLException, IOException { + + if( depth == 0 ) { + return; + } + + SmbFile[] l = f.listFiles(); + + for(int i = 0; l != null && i < l.length; i++ ) { + try { + System.out.println( l[i] ); + ACE[] acl = l[i].getSecurity(); + for (int j = 0; j < acl.length; j++) { + System.out.print( acl[j] ); + int a = acl[j].getAccessMask(); + if ((a & 0xFF000000) != 0) { + if ((a & ACE.GENERIC_ALL) != 0) { + System.out.print( " GENERIC_ALL" ); + } + if ((a & ACE.GENERIC_WRITE) != 0) { + System.out.print( " GENERIC_WRITE" ); + } + if ((a & ACE.GENERIC_READ) != 0) { + System.out.print( " GENERIC_READ" ); + } + } + System.out.println(); + } + if( l[i].isDirectory() ) { + traverse( l[i], depth - 1 ); + } + } catch( IOException ioe ) { + ioe.printStackTrace(); + } + } + } + + public static void main(String[] argv) throws Exception { + if (argv.length < 2) { + System.err.println( "usage: AclCrawler " ); + System.exit(1); + } + int depth = Integer.parseInt( argv[1] ); + AclCrawler sc = new AclCrawler( depth ); + sc.traverse( new SmbFile( argv[0] ), depth ); + } +} diff --git a/examples/ListACL.java b/examples/ListACL.java new file mode 100644 index 0000000..a29e1c5 --- /dev/null +++ b/examples/ListACL.java @@ -0,0 +1,12 @@ +import jcifs.smb.*; + +public class ListACL { + + public static void main( String[] args ) throws Exception { + SmbFile f = new SmbFile( args[0] ); + ACE[] acl = f.getSecurity(); + for (int i = 0; i < acl.length; i++) { + System.out.println( acl[i] ); + } + } +} diff --git a/patches/LargeReadWrite.patch b/patches/LargeReadWrite.patch new file mode 100644 index 0000000..ba96f7c --- /dev/null +++ b/patches/LargeReadWrite.patch @@ -0,0 +1,131 @@ +diff -Naur ../jcifs_1.2.6_org/src/jcifs/smb/SmbConstants.java src/jcifs/smb/SmbConstants.java +--- ../jcifs_1.2.6_org/src/jcifs/smb/SmbConstants.java Fri Oct 07 17:56:54 2005 ++++ src/jcifs/smb/SmbConstants.java Tue Oct 18 12:16:06 2005 +@@ -13,7 +13,7 @@ + static final int DEFAULT_RESPONSE_TIMEOUT = 10000; + static final int DEFAULT_SO_TIMEOUT = 15000; + static final int DEFAULT_RCV_BUF_SIZE = 60416; +- static final int DEFAULT_SND_BUF_SIZE = 16644; ++ static final int DEFAULT_SND_BUF_SIZE = 60416; + static final int DEFAULT_SSN_LIMIT = 250; + + static final InetAddress LADDR = Config.getLocalHost(); +@@ -61,6 +61,8 @@ + static final int CAP_LOCK_AND_READ = 0x0100; + static final int CAP_NT_FIND = 0x0200; + static final int CAP_DFS = 0x1000; ++ static final int CAP_LARGE_READX = 0x4000; ++ static final int CAP_LARGE_WRITEX = 0x8000; + + // file attribute encoding + static final int ATTR_READONLY = 0x01; +@@ -117,7 +119,10 @@ + ( USE_NTSMBS ? CAP_NT_SMBS : 0 ) | + ( USE_NTSTATUS ? CAP_STATUS32 : 0 ) | + ( USE_UNICODE ? CAP_UNICODE : 0 ) | +- CAP_DFS; ++ CAP_DFS | ++ CAP_LARGE_READX | ++ CAP_LARGE_WRITEX; ++ + static final int FLAGS2 = Config.getInt( "jcifs.smb.client.flags2", DEFAULT_FLAGS2 ); + static final int CAPABILITIES = Config.getInt( "jcifs.smb.client.capabilities", DEFAULT_CAPABILITIES ); + static final boolean TCP_NODELAY = Config.getBoolean( "jcifs.smb.client.tcpNoDelay", false ); +diff -Naur ../jcifs_1.2.6_org/src/jcifs/smb/SmbFileInputStream.java src/jcifs/smb/SmbFileInputStream.java +--- ../jcifs_1.2.6_org/src/jcifs/smb/SmbFileInputStream.java Fri Oct 07 17:56:54 2005 ++++ src/jcifs/smb/SmbFileInputStream.java Wed Oct 19 14:00:24 2005 +@@ -32,6 +32,7 @@ + + private long fp; + private int readSize, openFlags; ++ private int readSizeFile; + private byte[] tmp = new byte[1]; + + SmbFile file; +@@ -73,6 +74,12 @@ + } + readSize = Math.min( file.tree.session.transport.rcv_buf_size - 70, + file.tree.session.transport.server.maxBufferSize - 70 ); ++ ++ if(file.tree.session.transport.hasCapability(SmbConstants.CAP_LARGE_READX)) { ++ readSizeFile = Math.min(SmbConstants.RCV_BUF_SIZE - 70, 0xF000); ++ } else { ++ readSizeFile = readSize; ++ } + } + + /** +@@ -143,7 +150,9 @@ + + int r, n; + do { +- r = len > readSize ? readSize : len; ++ int blockSize = (file.getType() == SmbFile.TYPE_FILESYSTEM) ? readSizeFile : readSize; ++ ++ r = len > blockSize ? blockSize : len; + + if( file.log.level > 2 ) + file.log.println( "read: len=" + len + ",r=" + r + ",fp=" + fp ); +diff -Naur ../jcifs_1.2.6_org/src/jcifs/smb/SmbFileOutputStream.java src/jcifs/smb/SmbFileOutputStream.java +--- ../jcifs_1.2.6_org/src/jcifs/smb/SmbFileOutputStream.java Fri Oct 07 17:56:54 2005 ++++ src/jcifs/smb/SmbFileOutputStream.java Wed Oct 19 13:57:14 2005 +@@ -34,6 +34,7 @@ + private SmbFile file; + private boolean append, useNTSmbs; + private int openFlags, writeSize; ++ private int writeSizeFile; + private long fp; + private byte[] tmp = new byte[1]; + private SmbComWriteAndX reqx; +@@ -138,7 +139,14 @@ + } + file.open( openFlags, SmbFile.ATTR_NORMAL, 0 ); + this.openFlags &= ~(SmbFile.O_CREAT | SmbFile.O_TRUNC); /* in case close and reopen */ +- writeSize = file.tree.session.transport.snd_buf_size - 70; ++ writeSize = Math.min( file.tree.session.transport.snd_buf_size - 70, ++ file.tree.session.transport.server.maxBufferSize - 70 ); ++ ++ if(file.tree.session.transport.hasCapability(SmbConstants.CAP_LARGE_WRITEX)) { ++ writeSizeFile = Math.min(SmbConstants.SND_BUF_SIZE - 70, 0xF000); ++ } else { ++ writeSizeFile = writeSize; ++ } + + useNTSmbs = file.tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS ); + if( useNTSmbs ) { +@@ -217,7 +225,9 @@ + + int w; + do { +- w = len > writeSize ? writeSize : len; ++ int blockSize = (file.getType() == SmbFile.TYPE_FILESYSTEM) ? writeSizeFile : writeSize; ++ ++ w = len > blockSize ? blockSize : len; + if( useNTSmbs ) { + reqx.setParam( file.fid, fp, len - w, b, off, w ); + file.send( reqx, rspx ); +diff -Naur ../jcifs_1.2.6_org/src/jcifs/smb/SmbRandomAccessFile.java src/jcifs/smb/SmbRandomAccessFile.java +--- ../jcifs_1.2.6_org/src/jcifs/smb/SmbRandomAccessFile.java Fri Oct 07 17:56:54 2005 ++++ src/jcifs/smb/SmbRandomAccessFile.java Wed Oct 19 14:20:45 2005 +@@ -54,8 +54,20 @@ + throw new IllegalArgumentException( "Invalid mode" ); + } + file.open( openFlags, SmbFile.ATTR_NORMAL, options ); +- readSize = file.tree.session.transport.rcv_buf_size - 70; +- writeSize = file.tree.session.transport.snd_buf_size - 70; ++ ++ if(file.tree.session.transport.hasCapability(SmbConstants.CAP_LARGE_READX)) { ++ readSize = Math.min(SmbConstants.RCV_BUF_SIZE - 70, 0xF000); ++ } else { ++ readSize = file.tree.session.transport.rcv_buf_size - 70; ++ } ++ ++ if(file.tree.session.transport.hasCapability(SmbConstants.CAP_LARGE_WRITEX)) { ++ writeSize = Math.min(SmbConstants.SND_BUF_SIZE - 70, 0xF000); ++ } else { ++ writeSize = Math.min( file.tree.session.transport.snd_buf_size - 70, ++ file.tree.session.transport.server.maxBufferSize - 70 ); ++ } ++ + fp = 0L; + } diff --git a/patches/README.txt b/patches/README.txt new file mode 100644 index 0000000..031ee8d --- /dev/null +++ b/patches/README.txt @@ -0,0 +1,42 @@ +These patches are not supported. They are provided here only for your +conveinience. If you port a patch to a newer version of jCIFS please +resubmit it to the mailing list. + +SecurityDescriptors.patch: + +This patch add an SmbFile.getSecurity() method that returns an ACE[] +array for the target file. Note however that there is still no way to +resolve SIDs to names or visa versa. This patch is also rather intrusive +so it will take a bit of work to apply. There are file that go with this +patch that I placed into the smb directory rather than putting them in +the patch. They are ACE.java NtTransQuerySecurityDesc*.java SID.java +SmbComNtTransaction*.java but some have been renamed to .jav to disable +them from being compiled. So to apply the patch you will need to go +through each of the affected files adjusting as necessary to the 1.2.7 +codebase and then also rename the .jav files to .java and try to compile. + +Also see examples/ListACL.java and examples/AclCrawler.java. + +The ListACL.java example will list the ACEs of a specified path. Consider +the following commandline with resulting output of ListACL: + +$ java -Djcifs.properties=../miallen.prp ListACL smb://svr01/pub/a/b/c/d +direct allow 0x001F01FF S-1-5-21-839522115-1425521274-1417001333-61012 +inherited deny 0x000F01FF S-1-5-21-839522115-1425521274-1417001333-61011 +inherited allow 0x001F01FF S-1-5-21-839522115-1425521274-1417001333-61007 +inherited deny 0x000F01FF S-1-5-21-839522115-1425521274-1417001333-61012 +inherited allow 0x001F01FF S-1-5-32-544 +inherited allow 0x001F01FF S-1-5-18 +inherited allow 0x001200A9 S-1-5-32-545 + +LargeReadWrite.patch: + +This patch adds two SMBs that supposedly improves read and write +performance considerably. Unfortunately it's not crystal clear +that all implementation properly support the commands. Note that +in addition to this patch an '& 0xFFFF' needs to be added in +SmbTransport.java:doRecv:~437 to appear as: + + int size = Encdec.dec_uint16be( BUF, 2 ) & 0xFFFF; + +although this change has been made in 1.2.7. diff --git a/patches/SecurityDescriptors.patch b/patches/SecurityDescriptors.patch new file mode 100644 index 0000000..497f79a --- /dev/null +++ b/patches/SecurityDescriptors.patch @@ -0,0 +1,480 @@ +diff -Naur jcifs_1.1.11/src/jcifs/smb/ServerMessageBlock.java jcifs_1.1.11acl2/src/jcifs/smb/ServerMessageBlock.java +--- jcifs_1.1.11/src/jcifs/smb/ServerMessageBlock.java 2005-05-04 23:10:46.000000000 -0400 ++++ jcifs_1.1.11acl2/src/jcifs/smb/ServerMessageBlock.java 2005-05-10 22:09:32.000000000 -0400 +@@ -274,6 +274,8 @@ + static final byte SMB_COM_SESSION_SETUP_ANDX = (byte)0x73; + static final byte SMB_COM_LOGOFF_ANDX = (byte)0x74; + static final byte SMB_COM_TREE_CONNECT_ANDX = (byte)0x75; ++ static final byte SMB_COM_NT_TRANSACT = (byte)0xA0; ++ static final byte SMB_COM_NT_TRANSACT_SECONDARY = (byte)0xA1; + static final byte SMB_COM_NT_CREATE_ANDX = (byte)0xA2; + + /* +@@ -622,6 +624,12 @@ + case SMB_COM_CREATE_DIRECTORY: + c = "SMB_COM_CREATE_DIRECTORY"; + break; ++ case SMB_COM_NT_TRANSACT: ++ c = "SMB_COM_NT_TRANSACT"; ++ break; ++ case SMB_COM_NT_TRANSACT_SECONDARY: ++ c = "SMB_COM_NT_TRANSACT_SECONDARY"; ++ break; + default: + c = "UNKNOWN"; + } +diff -Naur jcifs_1.1.11/src/jcifs/smb/SmbComNTCreateAndX.java jcifs_1.1.11acl2/src/jcifs/smb/SmbComNTCreateAndX.java +--- jcifs_1.1.11/src/jcifs/smb/SmbComNTCreateAndX.java 2005-05-04 23:10:46.000000000 -0400 ++++ jcifs_1.1.11acl2/src/jcifs/smb/SmbComNTCreateAndX.java 2005-05-10 22:09:32.000000000 -0400 +@@ -107,6 +107,7 @@ + private int namelen_index; + + SmbComNTCreateAndX( String name, int flags, ++ int access, + int shareAccess, + int extFileAttributes, + int createOptions, +@@ -116,7 +117,7 @@ + command = SMB_COM_NT_CREATE_ANDX; + + // desiredAccess +- desiredAccess = ( flags >>> 16 ) & 0xFFFF; ++ desiredAccess = access; + desiredAccess |= FILE_READ_EA | FILE_READ_ATTRIBUTES; + + // extFileAttributes +diff -Naur jcifs_1.1.11/src/jcifs/smb/SmbComOpenAndX.java jcifs_1.1.11acl2/src/jcifs/smb/SmbComOpenAndX.java +--- jcifs_1.1.11/src/jcifs/smb/SmbComOpenAndX.java 2005-05-04 23:10:46.000000000 -0400 ++++ jcifs_1.1.11acl2/src/jcifs/smb/SmbComOpenAndX.java 2005-05-10 22:09:32.000000000 -0400 +@@ -58,13 +58,13 @@ + + // flags is NOT the same as flags member + +- SmbComOpenAndX( String fileName, int flags, ServerMessageBlock andx ) { ++ SmbComOpenAndX( String fileName, int flags, int access, ServerMessageBlock andx ) { + super( andx ); + this.path = fileName; + command = SMB_COM_OPEN_ANDX; + + // desiredAccess +- desiredAccess = ( flags >>> 16 ) & 0x3; ++ desiredAccess = access & 0x3; + if( desiredAccess == 0x3 ) { + desiredAccess = 0x2; /* Mmm, I thought 0x03 was RDWR */ + } +diff -Naur jcifs_1.1.11/src/jcifs/smb/SmbComTransaction.java jcifs_1.1.11acl2/src/jcifs/smb/SmbComTransaction.java +--- jcifs_1.1.11/src/jcifs/smb/SmbComTransaction.java 2005-05-04 23:10:46.000000000 -0400 ++++ jcifs_1.1.11acl2/src/jcifs/smb/SmbComTransaction.java 2005-05-10 22:09:32.000000000 -0400 +@@ -32,44 +32,47 @@ + private static final int PRIMARY_SETUP_OFFSET = 61; + private static final int SECONDARY_PARAMETER_OFFSET = 51; + +- private static final int DISCONNECT_TID = 0x01; ++ private static final int DISCONNECT_TID = 0x01; + private static final int ONE_WAY_TRANSACTION = 0x02; + + private static final int PADDING_SIZE = 2; + + private int flags = 0x00; +- private int parameterCount; +- private int parameterOffset; +- private int parameterDisplacement; +- private int dataCount; +- private int dataOffset; +- private int dataDisplacement; + private int fid; +- private int pad = 0; +- private int pad1 = 0; +- private boolean hasMore = true; +- private boolean isPrimary = true; +- private int bufParameterOffset; +- private int bufDataOffset; + + static final int TRANSACTION_BUF_SIZE = 0xFFFF; + + static final byte TRANS2_FIND_FIRST2 = (byte)0x01; +- static final byte TRANS2_FIND_NEXT2 = (byte)0x02; ++ static final byte TRANS2_FIND_NEXT2 = (byte)0x02; + static final byte TRANS2_QUERY_FS_INFORMATION = (byte)0x03; + static final byte TRANS2_QUERY_PATH_INFORMATION = (byte)0x05; +- static final byte TRANS2_GET_DFS_REFERRAL = (byte)0x10; ++ static final byte TRANS2_GET_DFS_REFERRAL = (byte)0x10; + static final byte TRANS2_SET_FILE_INFORMATION = (byte)0x08; + + static final int NET_SHARE_ENUM = 0x0000; + static final int NET_SERVER_ENUM2 = 0x0068; + static final int NET_SERVER_ENUM3 = 0x00D7; + +- static final byte TRANS_PEEK_NAMED_PIPE = (byte)0x23; +- static final byte TRANS_WAIT_NAMED_PIPE = (byte)0x53; +- static final byte TRANS_CALL_NAMED_PIPE = (byte)0x54; ++ static final byte TRANS_PEEK_NAMED_PIPE = (byte)0x23; ++ static final byte TRANS_WAIT_NAMED_PIPE = (byte)0x53; ++ static final byte TRANS_CALL_NAMED_PIPE = (byte)0x54; + static final byte TRANS_TRANSACT_NAMED_PIPE = (byte)0x26; + ++ protected int primarySetupOffset; ++ protected int secondaryParameterOffset; ++ protected int parameterCount; ++ protected int parameterOffset; ++ protected int parameterDisplacement; ++ protected int dataCount; ++ protected int dataOffset; ++ protected int dataDisplacement; ++ protected int pad = 0; ++ protected int pad1 = 0; ++ protected boolean hasMore = true; ++ protected boolean isPrimary = true; ++ protected int bufParameterOffset; ++ protected int bufDataOffset; ++ + int totalParameterCount; + int totalDataCount; + int maxParameterCount; +@@ -85,6 +88,8 @@ + + SmbComTransaction() { + maxParameterCount = 1024; ++ primarySetupOffset = PRIMARY_SETUP_OFFSET; ++ secondaryParameterOffset = SECONDARY_PARAMETER_OFFSET; + } + + void reset() { +@@ -100,9 +105,13 @@ + if( isPrimary ) { + isPrimary = false; + +- parameterOffset = PRIMARY_SETUP_OFFSET + ( setupCount * 2 ) + 2; +- if( command == SMB_COM_TRANSACTION && isResponse() == false ) { +- parameterOffset += stringWireLength( name, parameterOffset ); ++ parameterOffset = primarySetupOffset + ( setupCount * 2 ) + 2; ++ if (command != SMB_COM_NT_TRANSACT) { ++ if( command == SMB_COM_TRANSACTION && isResponse() == false ) { ++ parameterOffset += stringWireLength( name, parameterOffset ); ++ } ++ } else if (command == SMB_COM_NT_TRANSACT) { ++ parameterOffset += 2; + } + pad = parameterOffset % PADDING_SIZE; + pad = pad == 0 ? 0 : PADDING_SIZE - pad; +@@ -124,7 +133,11 @@ + + dataCount = Math.min( totalDataCount, available ); + } else { +- command = SMB_COM_TRANSACTION_SECONDARY; ++ if (command != SMB_COM_NT_TRANSACT) { ++ command = SMB_COM_TRANSACTION_SECONDARY; ++ } else { ++ command = SMB_COM_NT_TRANSACT_SECONDARY; ++ } + // totalParameterCount and totalDataCount are set ok from primary + + parameterOffset = SECONDARY_PARAMETER_OFFSET; +@@ -170,12 +183,12 @@ + writeInt2( maxDataCount, dst, dstIndex ); + dstIndex += 2; + dst[dstIndex++] = maxSetupCount; +- dst[dstIndex++] = (byte)0x00; // Reserved1 ++ dst[dstIndex++] = (byte)0x00; // Reserved1 + writeInt2( flags, dst, dstIndex ); + dstIndex += 2; + writeInt4( timeout, dst, dstIndex ); + dstIndex += 4; +- dst[dstIndex++] = (byte)0x00; // Reserved2 ++ dst[dstIndex++] = (byte)0x00; // Reserved2 + dst[dstIndex++] = (byte)0x00; + } + writeInt2( parameterCount, dst, dstIndex ); +@@ -195,7 +208,7 @@ + dstIndex += 2; + } else { + dst[dstIndex++] = (byte)setupCount; +- dst[dstIndex++] = (byte)0x00; // Reserved3 ++ dst[dstIndex++] = (byte)0x00; // Reserved3 + dstIndex += writeSetupWireFormat( dst, dstIndex ); + } + +@@ -211,7 +224,7 @@ + + if( parameterCount > 0 ) { + while( p-- > 0 ) { +- dst[dstIndex++] = (byte)0x00; // Pad ++ dst[dstIndex++] = (byte)0x00; // Pad + } + + System.arraycopy( txn_buf, bufParameterOffset, dst, dstIndex, parameterCount ); +@@ -221,7 +234,7 @@ + if( dataCount > 0 ) { + p = pad1; + while( p-- > 0 ) { +- dst[dstIndex++] = (byte)0x00; // Pad1 ++ dst[dstIndex++] = (byte)0x00; // Pad1 + } + System.arraycopy( txn_buf, bufDataOffset, dst, dstIndex, dataCount ); + bufDataOffset += dataCount; +diff -Naur jcifs_1.1.11/src/jcifs/smb/SmbComTransactionResponse.java jcifs_1.1.11acl2/src/jcifs/smb/SmbComTransactionResponse.java +--- jcifs_1.1.11/src/jcifs/smb/SmbComTransactionResponse.java 2005-05-04 23:10:46.000000000 -0400 ++++ jcifs_1.1.11acl2/src/jcifs/smb/SmbComTransactionResponse.java 2005-05-10 22:09:32.000000000 -0400 +@@ -22,26 +22,26 @@ + + abstract class SmbComTransactionResponse extends ServerMessageBlock implements Enumeration { + +- // relative to headerStart +- private static final int SETUP_OFFSET = 61; + + private static final int DISCONNECT_TID = 0x01; + private static final int ONE_WAY_TRANSACTION = 0x02; + +- private int totalParameterCount; +- private int totalDataCount; +- private int parameterCount; +- private int parameterOffset; +- private int parameterDisplacement; +- private int dataOffset; +- private int dataDisplacement; +- private int setupCount; +- private int pad; +- private int pad1; +- private boolean parametersDone, dataDone; ++ protected int totalParameterCount; ++ protected int totalDataCount; ++ protected int parameterCount; ++ protected int parameterOffset; ++ protected int parameterDisplacement; ++ protected int dataOffset; ++ protected int dataDisplacement; ++ protected int setupCount; ++ protected int pad; ++ protected int pad1; ++ protected boolean parametersDone, dataDone; + +- private int bufParameterStart; +- private int bufDataStart; ++ protected int bufParameterStart; ++ protected int bufDataStart; ++ ++ static final int SETUP_OFFSET = 61; + + int dataCount; + byte subCommand; +diff -Naur jcifs_1.1.11/src/jcifs/smb/SmbFileInputStream.java jcifs_1.1.11acl2/src/jcifs/smb/SmbFileInputStream.java +--- jcifs_1.1.11/src/jcifs/smb/SmbFileInputStream.java 2005-05-04 23:10:46.000000000 -0400 ++++ jcifs_1.1.11acl2/src/jcifs/smb/SmbFileInputStream.java 2005-05-10 22:09:32.000000000 -0400 +@@ -65,7 +65,7 @@ + SmbFileInputStream( SmbFile file, int openFlags ) throws SmbException, MalformedURLException, UnknownHostException { + this.file = file; + this.openFlags = openFlags; +- file.open( openFlags, SmbFile.ATTR_NORMAL, 0 ); ++ file.open( openFlags, 0, SmbFile.ATTR_NORMAL, 0 ); + readSize = Math.min( file.tree.session.transport.rcv_buf_size - 70, + file.tree.session.transport.server.maxBufferSize - 70 ); + } +@@ -121,7 +121,7 @@ + throw new IOException( "Bad file descriptor" ); + } + // ensure file is open +- file.open( openFlags, SmbFile.ATTR_NORMAL, 0 ); ++ file.open( openFlags, 0, SmbFile.ATTR_NORMAL, 0 ); + + /* + * Read AndX Request / Response +@@ -179,7 +179,7 @@ + } + + pipe = (SmbNamedPipe)file; +- file.open(( pipe.pipeType & 0xFF0000 ) | SmbFile.O_EXCL, SmbFile.ATTR_NORMAL, 0 ); ++ file.open( SmbFile.O_EXCL, pipe.pipeType, SmbFile.ATTR_NORMAL, 0 ); + + req = new TransPeekNamedPipe( file.unc, file.fid ); + resp = new TransPeekNamedPipeResponse( pipe ); +diff -Naur jcifs_1.1.11/src/jcifs/smb/SmbFile.java jcifs_1.1.11acl2/src/jcifs/smb/SmbFile.java +--- jcifs_1.1.11/src/jcifs/smb/SmbFile.java 2005-05-04 23:10:46.000000000 -0400 ++++ jcifs_1.1.11acl2/src/jcifs/smb/SmbFile.java 2005-05-10 22:09:32.000000000 -0400 +@@ -265,11 +265,10 @@ + + public class SmbFile extends URLConnection { + +- // these are shifted for use in flags +- static final int O_RDONLY = 0x010000; +- static final int O_WRONLY = 0x020000; +- static final int O_RDWR = 0x030000; +- static final int O_APPEND = 0x040000; ++ static final int O_RDONLY = 0x01; ++ static final int O_WRONLY = 0x02; ++ static final int O_RDWR = 0x04; ++ static final int O_APPEND = 0x08; + + // share access + /** +@@ -846,7 +845,7 @@ + boolean isConnected() { + return (connected = tree != null && tree.treeConnected); + } +- int open0( int flags, int attrs, int options ) throws SmbException { ++ int open0( int flags, int access, int attrs, int options ) throws SmbException { + int f; + + connect0(); +@@ -860,7 +859,7 @@ + + if( tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS )) { + SmbComNTCreateAndXResponse response = new SmbComNTCreateAndXResponse(); +- send( new SmbComNTCreateAndX( unc, flags, shareAccess, ++ send( new SmbComNTCreateAndX( unc, flags, access, shareAccess, + attrs, options, null ), response ); + f = response.fid; + attributes = response.extFileAttributes & ATTR_GET_MASK; +@@ -868,17 +867,17 @@ + isExists = true; + } else { + SmbComOpenAndXResponse response = new SmbComOpenAndXResponse(); +- send( new SmbComOpenAndX( unc, flags, null ), response ); ++ send( new SmbComOpenAndX( unc, flags, access, null ), response ); + f = response.fid; + } + + return f; + } +- void open( int flags, int attrs, int options ) throws SmbException { ++ void open( int flags, int access, int attrs, int options ) throws SmbException { + if( isOpen() ) { + return; + } +- fid = open0( flags, attrs, options ); ++ fid = open0( flags, access, attrs, options ); + opened = true; + } + boolean isOpen() { +@@ -1933,17 +1932,17 @@ + int off; + + try { +- open( SmbFile.O_RDONLY, ATTR_NORMAL, 0 ); ++ open( SmbFile.O_RDONLY, 0, ATTR_NORMAL, 0 ); + try { +- dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC | +- SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES << 16, attributes, 0 ); ++ dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC, ++ SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES, attributes, 0 ); + } catch( SmbAuthException sae ) { + if(( dest.attributes & ATTR_READONLY ) != 0 ) { + /* Remove READONLY and try again + */ + dest.setPathInformation( dest.attributes & ~ATTR_READONLY, 0L, 0L ); +- dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC | +- SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES << 16, attributes, 0 ); ++ dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC, ++ SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES, attributes, 0 ); + } else { + throw sae; + } +@@ -2262,7 +2261,7 @@ + if( getUncPath0().length() == 1 ) { + throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); + } +- close( open0( O_RDWR | O_CREAT | O_EXCL, ATTR_NORMAL, 0 ), 0L ); ++ close( open0( O_RDWR | O_CREAT | O_EXCL, 0, ATTR_NORMAL, 0 ), 0L ); + } + + void setPathInformation( int attrs, long ctime, long mtime ) throws SmbException { +@@ -2272,7 +2271,7 @@ + options = 1; + } + +- f = open0( O_RDONLY | SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES << 16, attrs, options ); ++ f = open0( O_RDONLY, SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES, attrs, options ); + sendTransaction( new Trans2SetFileInformation( f, attrs, ctime, mtime ), + new Trans2SetFileInformationResponse() ); + close( f, 0L ); +@@ -2502,4 +2501,19 @@ + public OutputStream getOutputStream() throws IOException { + return new SmbFileOutputStream( this ); + } ++ ++ public ACE[] getSecurity() throws IOException { ++ int f = open0( O_RDONLY, SmbComNTCreateAndX.READ_CONTROL, 0, isDirectory() ? 1 : 0 ); ++ ++ /* ++ * NtTrans Query Security Desc Request / Response ++ */ ++ ++ NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc( f, 0x04 ); ++ NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse(); ++ sendTransaction( request, response ); ++ ++ close( f, 0L ); ++ return response.aces; ++ } + } +diff -Naur jcifs_1.1.11/src/jcifs/smb/SmbFileOutputStream.java jcifs_1.1.11acl2/src/jcifs/smb/SmbFileOutputStream.java +--- jcifs_1.1.11/src/jcifs/smb/SmbFileOutputStream.java 2005-05-04 23:10:46.000000000 -0400 ++++ jcifs_1.1.11acl2/src/jcifs/smb/SmbFileOutputStream.java 2005-05-10 22:09:32.000000000 -0400 +@@ -136,7 +136,7 @@ + file.sendTransaction( new TransWaitNamedPipe( "\\pipe" + file.unc ), + new TransWaitNamedPipeResponse() ); + } +- file.open( openFlags, SmbFile.ATTR_NORMAL, 0 ); ++ file.open( openFlags, openFlags >>> 16, SmbFile.ATTR_NORMAL, 0 ); + this.openFlags &= ~(SmbFile.O_CREAT | SmbFile.O_TRUNC); /* in case close and reopen */ + writeSize = file.tree.session.transport.snd_buf_size - 70; + +@@ -206,7 +206,7 @@ + file.sendTransaction( new TransWaitNamedPipe( "\\pipe" + file.unc ), + new TransWaitNamedPipeResponse() ); + } +- file.open( openFlags, SmbFile.ATTR_NORMAL, 0 ); ++ file.open( openFlags, openFlags >>> 16, SmbFile.ATTR_NORMAL, 0 ); + if( append ) { + fp = file.length(); + } +diff -Naur jcifs_1.1.11/src/jcifs/smb/SmbRandomAccessFile.java jcifs_1.1.11acl2/src/jcifs/smb/SmbRandomAccessFile.java +--- jcifs_1.1.11/src/jcifs/smb/SmbRandomAccessFile.java 2005-05-04 23:10:46.000000000 -0400 ++++ jcifs_1.1.11acl2/src/jcifs/smb/SmbRandomAccessFile.java 2005-05-10 22:09:32.000000000 -0400 +@@ -53,7 +53,7 @@ + } else { + throw new IllegalArgumentException( "Invalid mode" ); + } +- file.open( openFlags, SmbFile.ATTR_NORMAL, options ); ++ file.open( openFlags, 0, SmbFile.ATTR_NORMAL, options ); + readSize = file.tree.session.transport.rcv_buf_size - 70; + writeSize = file.tree.session.transport.snd_buf_size - 70; + fp = 0L; +@@ -76,7 +76,7 @@ + + // ensure file is open + if( file.isOpen() == false ) { +- file.open( openFlags, SmbFile.ATTR_NORMAL, options ); ++ file.open( openFlags, 0, SmbFile.ATTR_NORMAL, options ); + } + + int r, n; +@@ -129,7 +129,7 @@ + + // ensure file is open + if( file.isOpen() == false ) { +- file.open( openFlags, SmbFile.ATTR_NORMAL, options ); ++ file.open( openFlags, 0, SmbFile.ATTR_NORMAL, options ); + } + + int w; +@@ -153,7 +153,7 @@ + public void setLength( long newLength ) throws SmbException { + // ensure file is open + if( file.isOpen() == false ) { +- file.open( openFlags, SmbFile.ATTR_NORMAL, options ); ++ file.open( openFlags, 0, SmbFile.ATTR_NORMAL, options ); + } + SmbComWriteResponse rsp = new SmbComWriteResponse(); + file.send( new SmbComWrite( file.fid, (int)(newLength & 0xFFFFFFFFL), 0, tmp, 0, 0 ), rsp ); +diff -Naur jcifs_1.1.11/src/jcifs/smb/TransactNamedPipeOutputStream.java jcifs_1.1.11acl2/src/jcifs/smb/TransactNamedPipeOutputStream.java +--- jcifs_1.1.11/src/jcifs/smb/TransactNamedPipeOutputStream.java 2005-05-04 23:10:46.000000000 -0400 ++++ jcifs_1.1.11acl2/src/jcifs/smb/TransactNamedPipeOutputStream.java 2005-05-10 22:09:32.000000000 -0400 +@@ -57,7 +57,7 @@ + new TransCallNamedPipeResponse( pipe )); + } else if(( pipe.pipeType & SmbNamedPipe.PIPE_TYPE_TRANSACT ) == + SmbNamedPipe.PIPE_TYPE_TRANSACT ) { +- pipe.open(( pipe.pipeType & 0xFFFF0000 ) | SmbFile.O_EXCL, SmbFile.ATTR_NORMAL, 0 ); ++ pipe.open( SmbFile.O_EXCL, pipe.pipeType, SmbFile.ATTR_NORMAL, 0 ); + TransTransactNamedPipe req = new TransTransactNamedPipe( pipe.fid, b, off, len ); + if (dcePipe) { + req.maxDataCount = 1024; diff --git a/src/jcifs/UniAddress.java b/src/jcifs/UniAddress.java index 458488f..1d341e4 100644 --- a/src/jcifs/UniAddress.java +++ b/src/jcifs/UniAddress.java @@ -224,9 +224,13 @@ public class UniAddress { return false; } - static boolean isValidDnsName( String hostname ) { - // Simple for now. Just handles "1" --> 1/0.0.0.1 kind of stuff - return Character.isDigit( hostname.charAt( 0 )) == false; + static boolean isAllDigits( String hostname ) { + for (int i = 0; i < hostname.length(); i++) { + if (Character.isDigit( hostname.charAt( i )) == false) { + return false; + } + } + return true; } /** @@ -281,7 +285,7 @@ public class UniAddress { } break; case RESOLVER_DNS: - if( isValidDnsName( hostname ) == false ) { + if( isAllDigits( hostname )) { throw new UnknownHostException( hostname ); } addr = InetAddress.getByName( hostname ); diff --git a/src/jcifs/http/NtlmHttpFilter.java b/src/jcifs/http/NtlmHttpFilter.java index fa3e453..fd67008 100644 --- a/src/jcifs/http/NtlmHttpFilter.java +++ b/src/jcifs/http/NtlmHttpFilter.java @@ -222,6 +222,7 @@ public class NtlmHttpFilter implements Filter { realm + "\""); } resp.setStatus( HttpServletResponse.SC_UNAUTHORIZED ); + resp.setContentLength(0); resp.flushBuffer(); return null; } diff --git a/src/jcifs/http/NtlmSsp.java b/src/jcifs/http/NtlmSsp.java index d3ba2be..3a1fbba 100644 --- a/src/jcifs/http/NtlmSsp.java +++ b/src/jcifs/http/NtlmSsp.java @@ -102,6 +102,7 @@ public class NtlmSsp implements NtlmFlags { resp.setHeader("WWW-Authenticate", "NTLM"); } resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + resp.setContentLength(0); resp.flushBuffer(); return null; } diff --git a/src/jcifs/smb/ACE.java b/src/jcifs/smb/ACE.java new file mode 100644 index 0000000..c9c3f72 --- /dev/null +++ b/src/jcifs/smb/ACE.java @@ -0,0 +1,63 @@ +package jcifs.smb; + +import jcifs.util.Hexdump; + +public class ACE { + + public static final int FILE_READ_DATA = 0x00000001; // 1 + public static final int FILE_WRITE_DATA = 0x00000002; // 2 + public static final int FILE_APPEND_DATA = 0x00000004; // 3 + public static final int FILE_READ_EA = 0x00000008; // 4 + public static final int FILE_WRITE_EA = 0x00000010; // 5 + public static final int FILE_EXECUTE = 0x00000020; // 6 + public static final int FILE_DELETE = 0x00000040; // 7 + public static final int FILE_READ_ATTRIBUTES = 0x00000080; // 8 + public static final int FILE_WRITE_ATTRIBUTES = 0x00000100; // 9 + public static final int DELETE = 0x00010000; // 16 + public static final int READ_CONTROL = 0x00020000; // 17 + public static final int WRITE_DAC = 0x00040000; // 18 + public static final int WRITE_OWNER = 0x00080000; // 19 + public static final int SYNCHRONIZE = 0x00100000; // 20 + public static final int GENERIC_ALL = 0x10000000; // 28 + public static final int GENERIC_EXECUTE = 0x20000000; // 29 + public static final int GENERIC_WRITE = 0x40000000; // 30 + public static final int GENERIC_READ = 0x80000000; // 31 + + boolean allow; + int flags; + int access; + SID sid; + + public boolean isAllow() { + return allow; + } + public boolean isInherited() { + return (flags & 0x10) != 0; + } + public int getAccessMask() { + return access; + } + public SID getSID() { + return sid; + } + + int decode( byte[] buf, int bi ) { + allow = buf[bi++] == (byte)0x00; + flags = buf[bi++] & 0xFF; + int size = ServerMessageBlock.readInt2(buf, bi); + bi += 2; + access = ServerMessageBlock.readInt4(buf, bi); + bi += 4; + sid = new SID(buf, bi); + return size; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append( isInherited() ? "inherited " : "direct " ); + sb.append( isAllow() ? "allow " : "deny " ); + sb.append( "0x" ).append( Hexdump.toHexString( access, 8 )); + sb.append( " " ).append( sid.toString() ); + return sb.toString(); + } +} diff --git a/src/jcifs/smb/NtTransQuerySecurityDesc.jav b/src/jcifs/smb/NtTransQuerySecurityDesc.jav new file mode 100644 index 0000000..7522e8b --- /dev/null +++ b/src/jcifs/smb/NtTransQuerySecurityDesc.jav @@ -0,0 +1,72 @@ +/* jcifs smb client library in Java + * Copyright (C) 2005 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.util.Hexdump; + +class NtTransQuerySecurityDesc extends SmbComNtTransaction { + + int fid; + int securityInformation; + + NtTransQuerySecurityDesc( int fid, int securityInformation ) { + this.fid = fid; + this.securityInformation = securityInformation; + command = SMB_COM_NT_TRANSACT; + function = NT_TRANSACT_QUERY_SECURITY_DESC; + setupCount = 0; + totalDataCount = 0; + maxParameterCount = 4; + maxDataCount = 4096; + maxSetupCount = (byte)0x00; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( fid, dst, dstIndex ); + dstIndex += 2; + dst[dstIndex++] = (byte)0x00; // Reserved + dst[dstIndex++] = (byte)0x00; // Reserved + writeInt4( securityInformation, dst, dstIndex ); + dstIndex += 4; + + return dstIndex - start; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "NtTransGetSecurityDesc[" + super.toString() + + ",fid=0x" + Hexdump.toHexString( fid, 4 ) + + ",securityInformation=0x" + Hexdump.toHexString( securityInformation, 8 ) + "]" ); + } +} diff --git a/src/jcifs/smb/NtTransQuerySecurityDescResponse.jav b/src/jcifs/smb/NtTransQuerySecurityDescResponse.jav new file mode 100644 index 0000000..cde45e6 --- /dev/null +++ b/src/jcifs/smb/NtTransQuerySecurityDescResponse.jav @@ -0,0 +1,85 @@ +/* jcifs smb client library in Java + * Copyright (C) 2005 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class NtTransQuerySecurityDescResponse extends SmbComNtTransactionResponse { + + int type; + ACE[] aces; + + NtTransQuerySecurityDescResponse() { + super(); + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + length = readInt4( buffer, bufferIndex ); + return 4; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + int start = bufferIndex; + + bufferIndex++; // revision + bufferIndex++; + type = readInt2(buffer, bufferIndex); + bufferIndex += 2; + readInt4(buffer, bufferIndex); // offset to owner sid + bufferIndex += 4; + readInt4(buffer, bufferIndex); // offset to group sid + bufferIndex += 4; + readInt4(buffer, bufferIndex); // offset to sacl + bufferIndex += 4; + int daclOffset = readInt4(buffer, bufferIndex); + + bufferIndex = start + daclOffset; + + bufferIndex++; // revision + bufferIndex++; + int size = readInt2(buffer, bufferIndex); + bufferIndex += 2; + int numAces = readInt4(buffer, bufferIndex); + bufferIndex += 4; + + if (numAces > 4096) + throw new RuntimeException( "Invalid SecurityDescriptor" ); + + aces = new ACE[numAces]; + for (int i = 0; i < numAces; i++) { + aces[i] = new ACE(); + bufferIndex += aces[i].decode(buffer, bufferIndex); + } + + return bufferIndex - start; + } + public String toString() { + return new String( "NtTransQuerySecurityResponse[" + + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/SID.java b/src/jcifs/smb/SID.java new file mode 100644 index 0000000..38b6380 --- /dev/null +++ b/src/jcifs/smb/SID.java @@ -0,0 +1,49 @@ +package jcifs.smb; + +import java.util.*; +import jcifs.util.Hexdump; + +public class SID { + + int revision; + int sub_authority_count; + byte[] identifier_authority = new byte[6]; + int[] sub_authority; + + public SID( byte[] src, int si ) { + revision = src[si++]; + sub_authority_count = src[si++]; + System.arraycopy(src, si, identifier_authority, 0, 6); + si += 6; + if (sub_authority_count > 100) + throw new RuntimeException( "Invalid SID" ); + sub_authority = new int[sub_authority_count]; + for (int i = 0; i < sub_authority_count; i++) { + sub_authority[i] = ServerMessageBlock.readInt4( src, si ); + si += 4; + } + } + + public String toString() { + String ret = "S-" + revision + "-"; + + if (identifier_authority[0] != (byte)0 || identifier_authority[1] != (byte)0) { + ret += "0x"; + ret += Hexdump.toHexString(identifier_authority, 0, 6); + } else { + long shift = 0; + long id = 0; + for (int i = 5; i > 1; i--) { + id += (identifier_authority[i] & 0xFFL) << shift; + shift += 8; + } + ret += id; + } + + for (int i = 0; i < sub_authority_count ; i++) + ret += "-" + (sub_authority[i] & 0xFFFFFFFFL); + + return ret; + } +} + diff --git a/src/jcifs/smb/SmbComNtTransaction.jav b/src/jcifs/smb/SmbComNtTransaction.jav new file mode 100644 index 0000000..69d2814 --- /dev/null +++ b/src/jcifs/smb/SmbComNtTransaction.jav @@ -0,0 +1,82 @@ +/* jcifs smb client library in Java + * Copyright (C) 2005 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +abstract class SmbComNtTransaction extends SmbComTransaction { + + // relative to headerStart + private static final int NTT_PRIMARY_SETUP_OFFSET = 69; + private static final int NTT_SECONDARY_PARAMETER_OFFSET = 51; + + static final int NT_TRANSACT_QUERY_SECURITY_DESC = 6; + + int function; + + SmbComNtTransaction() { + super(); + primarySetupOffset = NTT_PRIMARY_SETUP_OFFSET; + secondaryParameterOffset = NTT_SECONDARY_PARAMETER_OFFSET; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + if (command != SMB_COM_NT_TRANSACT_SECONDARY) { + dst[dstIndex++] = maxSetupCount; + } else { + dst[dstIndex++] = (byte)0x00; // Reserved + } + dst[dstIndex++] = (byte)0x00; // Reserved + dst[dstIndex++] = (byte)0x00; // Reserved + writeInt4( totalParameterCount, dst, dstIndex ); + dstIndex += 4; + writeInt4( totalDataCount, dst, dstIndex ); + dstIndex += 4; + if (command != SMB_COM_NT_TRANSACT_SECONDARY) { + writeInt4( maxParameterCount, dst, dstIndex ); + dstIndex += 4; + writeInt4( maxDataCount, dst, dstIndex ); + dstIndex += 4; + } + writeInt4( parameterCount, dst, dstIndex ); + dstIndex += 4; + writeInt4(( parameterCount == 0 ? 0 : parameterOffset ), dst, dstIndex ); + dstIndex += 4; + if (command == SMB_COM_NT_TRANSACT_SECONDARY) { + writeInt4( parameterDisplacement, dst, dstIndex ); + dstIndex += 4; + } + writeInt4( dataCount, dst, dstIndex ); + dstIndex += 4; + writeInt4(( dataCount == 0 ? 0 : dataOffset ), dst, dstIndex ); + dstIndex += 4; + if (command == SMB_COM_NT_TRANSACT_SECONDARY) { + writeInt4( dataDisplacement, dst, dstIndex ); + dstIndex += 4; + dst[dstIndex++] = (byte)0x00; // Reserved1 + } else { + dst[dstIndex++] = (byte)setupCount; + writeInt2( function, dst, dstIndex ); + dstIndex += 2; + dstIndex += writeSetupWireFormat( dst, dstIndex ); + } + + return dstIndex - start; + } +} diff --git a/src/jcifs/smb/SmbComNtTransactionResponse.jav b/src/jcifs/smb/SmbComNtTransactionResponse.jav new file mode 100644 index 0000000..2238456 --- /dev/null +++ b/src/jcifs/smb/SmbComNtTransactionResponse.jav @@ -0,0 +1,62 @@ +/* jcifs smb client library in Java + * Copyright (C) 2005 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +abstract class SmbComNtTransactionResponse extends SmbComTransactionResponse { + + SmbComNtTransactionResponse() { + super(); + } + + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + buffer[bufferIndex++] = (byte)0x00; // Reserved + buffer[bufferIndex++] = (byte)0x00; // Reserved + buffer[bufferIndex++] = (byte)0x00; // Reserved + + totalParameterCount = readInt4( buffer, bufferIndex ); + if( bufDataStart == 0 ) { + bufDataStart = totalParameterCount; + } + bufferIndex += 4; + totalDataCount = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + parameterCount = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + parameterOffset = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + parameterDisplacement = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + dataCount = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + dataOffset = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + dataDisplacement = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + setupCount = buffer[bufferIndex] & 0xFF; + bufferIndex += 2; + if( setupCount != 0 ) { + if( log.level > 2 ) + log.println( "setupCount is not zero: " + setupCount ); + } + + return bufferIndex - start; + } +} diff --git a/src/jcifs/smb/SmbRandomAccessFile.java b/src/jcifs/smb/SmbRandomAccessFile.java index 1829182..51d01c9 100644 --- a/src/jcifs/smb/SmbRandomAccessFile.java +++ b/src/jcifs/smb/SmbRandomAccessFile.java @@ -190,7 +190,7 @@ public class SmbRandomAccessFile implements DataOutput, DataInput { if((read( tmp, 0, 2 )) < 0 ) { throw new SmbException( "EOF" ); } - return Encdec.dec_uint16be( tmp, 0 ); + return Encdec.dec_uint16be( tmp, 0 ) & 0xFFFF; } public final char readChar() throws SmbException { if((read( tmp, 0, 2 )) < 0 ) { diff --git a/src/jcifs/smb/SmbTransport.java b/src/jcifs/smb/SmbTransport.java index 9a3fc6d..5248e3b 100644 --- a/src/jcifs/smb/SmbTransport.java +++ b/src/jcifs/smb/SmbTransport.java @@ -251,6 +251,14 @@ public class SmbTransport extends Transport implements SmbConstants { NEGOTIATE_REQUEST.mid = mid; int n = NEGOTIATE_REQUEST.encode( sbuf, 4 ); Encdec.enc_uint32be( n & 0xFFFF, sbuf, 0 ); /* 4 byte ssn msg header */ + + if (log.level > 3) { + log.println( NEGOTIATE_REQUEST ); + if (log.level > 5) { + Hexdump.hexdump( log, sbuf, 4, n ); + } + } + out.write( sbuf, 0, 4 + n ); out.flush(); /* Note the Transport thread isn't running yet so we can @@ -258,12 +266,19 @@ public class SmbTransport extends Transport implements SmbConstants { */ if (peekKey() == null) /* try to read header */ throw new IOException( "transport closed in negotiate" ); - int size = Encdec.dec_uint16be( sbuf, 2 ); + int size = Encdec.dec_uint16be( sbuf, 2 ) & 0xFFFF; if (size < 33 || (4 + size) > sbuf.length ) { throw new IOException( "Invalid payload size: " + size ); } readn( in, sbuf, 4 + 32, size - 32 ); resp.decode( sbuf, 4 ); + + if (log.level > 3) { + log.println( resp ); + if (log.level > 5) { + Hexdump.hexdump( log, sbuf, 4, n ); + } + } } } public void connect() throws SmbException { @@ -370,7 +385,7 @@ public class SmbTransport extends Transport implements SmbConstants { sbuf[35] = (byte)b; } - key.mid = Encdec.dec_uint16le( sbuf, 34 ); + key.mid = Encdec.dec_uint16le( sbuf, 34 ) & 0xFFFF; /* Unless key returned is null or invalid Transport.loop() always * calls doRecv() after and no one else but the transport thread @@ -419,7 +434,7 @@ public class SmbTransport extends Transport implements SmbConstants { synchronized (BUF) { System.arraycopy( sbuf, 0, BUF, 0, 4 + HEADER_LENGTH ); - int size = Encdec.dec_uint16be( BUF, 2 ); + int size = Encdec.dec_uint16be( BUF, 2 ) & 0xFFFF; if (size < (HEADER_LENGTH + 1) || (4 + size) > rcv_buf_size ) { throw new IOException( "Invalid payload size: " + size ); } @@ -451,7 +466,7 @@ public class SmbTransport extends Transport implements SmbConstants { } } protected void doSkip() throws IOException { - int size = Encdec.dec_uint16be( sbuf, 2 ); + int size = Encdec.dec_uint16be( sbuf, 2 ) & 0xFFFF; if (size < 33 || (4 + size) > rcv_buf_size ) { /* log message? */ in.skip( in.available() ); diff --git a/src/jcifs/util/transport/Transport.java b/src/jcifs/util/transport/Transport.java index d88628c..6438c8b 100644 --- a/src/jcifs/util/transport/Transport.java +++ b/src/jcifs/util/transport/Transport.java @@ -147,11 +147,11 @@ public abstract class Transport implements Runnable { public synchronized void connect( long timeout ) throws TransportException { switch (state) { case 0: -System.out.println( name + ": connect: state=" + state ); break; case 3: return; // already connected case 4: + state = 0; throw new TransportException( "Connection in error", te ); default: throw new TransportException( "Invalid state: " + state ); @@ -172,7 +172,9 @@ System.out.println( name + ": connect: state=" + state ); switch (state) { case 1: /* doConnect never returned */ - te = new TransportException( "Connection timeout" ); + state = 0; + thread = null; + throw new TransportException( "Connection timeout" ); case 2: if (te != null) { /* doConnect throw Exception */ state = 4; /* error */ @@ -180,7 +182,6 @@ System.out.println( name + ": connect: state=" + state ); throw te; } state = 3; /* Success! */ -System.out.println( name + ": connected: state=" + state ); return; default: te = new TransportException( "Invalid state: " + state ); @@ -192,12 +193,10 @@ System.out.println( name + ": connected: state=" + state ); case 0: /* not connected - just return */ return; case 3: /* connected - go ahead and disconnect */ -System.out.println( name + ": disconnecting: state=" + state + ",mapsize=" + response_map.size() + ",hard=" + hard); if (response_map.size() != 0 && !hard) { break; /* outstanding requests */ } doDisconnect( hard ); -System.out.println( name + ": disconnected: state=" + state ); case 4: /* in error - reset the transport */ thread = null; state = 0; @@ -235,7 +234,6 @@ System.out.println( name + ": disconnected: state=" + state ); } state = 2; // run connected run_thread.notify(); -System.out.println( name + ": run connected" ); } }