From: Felix Schumacher Date: Wed, 6 Aug 2008 14:23:39 +0000 (+0200) Subject: jcifs-1.1.1 from tgz X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=1299975a92ff9f463c9946d45cf996ec5b681146;p=jcifs_without_docs.git jcifs-1.1.1 from tgz Thu Oct 21 19:20:04 EDT 2004 jcifs-1.1.1 released A bug was discovered and fixed in the named pipe code. If a specific sequence of reads were performed the pipe could become corrupted. This fix is necessary for multi-pdu DCE requests to work. A small bug in the new NbtAddress.getAllByName method has been repaired. It will now broadcast for a name if a WINS address was not provided. --- diff --git a/README.txt b/README.txt index 8243d20..5eb970e 100644 --- a/README.txt +++ b/README.txt @@ -1,3 +1,10 @@ +Thu Oct 21 19:20:04 EDT 2004 +jcifs-1.1.1 released + +A bug was discovered and fixed in the named pipe code. If a specific sequence of reads were performed the pipe could become corrupted. This fix is necessary for multi-pdu DCE requests to work. + +A small bug in the new NbtAddress.getAllByName method has been repaired. It will now broadcast for a name if a WINS address was not provided. + jcifs-1.1.0 released The behavior of the firstCalledName/nextCalledName methods has been changed diff --git a/build.xml b/build.xml index 1a631f8..77cacc2 100644 --- a/build.xml +++ b/build.xml @@ -1,7 +1,7 @@ - - + + diff --git a/examples/ListDC.java b/examples/ListDC.java index b0ad0f2..191f384 100644 --- a/examples/ListDC.java +++ b/examples/ListDC.java @@ -4,10 +4,10 @@ public class ListDC { public static void main( String argv[] ) throws Exception { - NbtAddress[] addrs = NbtAddress.getAllByName( argv[0], 0x1C, null, null ); + NbtAddress[] addrs = NbtAddress.getAllByName( argv[0], 0x1C, null, null ); - for( int i = 0; i < addrs.length; i++ ) { - System.out.println( addrs[i] ); - } + for( int i = 0; i < addrs.length; i++ ) { + System.out.println( addrs[i] ); + } } } diff --git a/examples/Logon.java b/examples/Logon.java new file mode 100644 index 0000000..334521b --- /dev/null +++ b/examples/Logon.java @@ -0,0 +1,15 @@ +import jcifs.*; +import jcifs.smb.*; + +public class Logon { + + /* java Logon 192.168.1.15 "dom;user:pass" + */ + + public static void main( String argv[] ) throws Exception { + UniAddress dc = UniAddress.getByName( argv[0] ); + NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication( argv[1] ); + SmbSession.logon( dc, auth ); + } +} + diff --git a/examples/runtests.sh b/examples/runtests.sh old mode 100644 new mode 100755 diff --git a/jcifsacl.prp b/jcifsacl.prp new file mode 100644 index 0000000..d5a63e9 --- /dev/null +++ b/jcifsacl.prp @@ -0,0 +1 @@ +jcifs.smb.client.logonShare = JCIFSACL diff --git a/src/jcifs/http/NtlmHttpFilter.java b/src/jcifs/http/NtlmHttpFilter.java index 3ecad04..6881805 100644 --- a/src/jcifs/http/NtlmHttpFilter.java +++ b/src/jcifs/http/NtlmHttpFilter.java @@ -115,26 +115,26 @@ public class NtlmHttpFilter implements Filter { (offerBasic && msg.startsWith("Basic ")))) { if (msg.startsWith("NTLM ")) { HttpSession ssn = req.getSession(); - byte[] challenge; - - if( loadBalance ) { - NtlmChallenge chal = (NtlmChallenge)ssn.getAttribute( "NtlmHttpChal" ); - if( chal == null ) { - chal = SmbSession.getChallengeForDomain(); - ssn.setAttribute( "NtlmHttpChal", chal ); - } - dc = chal.dc; - challenge = chal.challenge; - } else { - dc = UniAddress.getByName( domainController, true ); - challenge = SmbSession.getChallenge( dc ); - } + byte[] challenge; + + if( loadBalance ) { + NtlmChallenge chal = (NtlmChallenge)ssn.getAttribute( "NtlmHttpChal" ); + if( chal == null ) { + chal = SmbSession.getChallengeForDomain(); + ssn.setAttribute( "NtlmHttpChal", chal ); + } + dc = chal.dc; + challenge = chal.challenge; + } else { + dc = UniAddress.getByName( domainController, true ); + challenge = SmbSession.getChallenge( dc ); + } if(( ntlm = NtlmSsp.authenticate( req, resp, challenge )) == null ) { return; } /* negotiation complete, remove the challenge object */ - ssn.removeAttribute( "NtlmHttpChal" ); + ssn.removeAttribute( "NtlmHttpChal" ); } else { String auth = new String(Base64.decode(msg.substring(6)), "US-ASCII"); @@ -148,7 +148,7 @@ public class NtlmHttpFilter implements Filter { defaultDomain; user = (index != -1) ? user.substring(index + 1) : user; ntlm = new NtlmPasswordAuthentication(domain, user, password); - dc = UniAddress.getByName( domainController, true ); + dc = UniAddress.getByName( domainController, true ); } try { diff --git a/src/jcifs/netbios/NameQueryResponse.java b/src/jcifs/netbios/NameQueryResponse.java index 693e0e9..d8d8f27 100644 --- a/src/jcifs/netbios/NameQueryResponse.java +++ b/src/jcifs/netbios/NameQueryResponse.java @@ -41,11 +41,11 @@ class NameQueryResponse extends NameServicePacket { int nodeType = ( src[srcIndex] & 0x60 ) >> 5; srcIndex += 2; int address = readInt4( src, srcIndex ); - if( address != 0 ) { - addrEntry[addrIndex] = new NbtAddress( recordName, address, groupName, nodeType ); - } else { - addrEntry[addrIndex] = null; - } + if( address != 0 ) { + addrEntry[addrIndex] = new NbtAddress( recordName, address, groupName, nodeType ); + } else { + addrEntry[addrIndex] = null; + } return 6; } diff --git a/src/jcifs/netbios/NameServiceClient.java b/src/jcifs/netbios/NameServiceClient.java index ac9f574..56bf06a 100644 --- a/src/jcifs/netbios/NameServiceClient.java +++ b/src/jcifs/netbios/NameServiceClient.java @@ -258,22 +258,37 @@ class NameServiceClient implements Runnable { NbtAddress[] getAllByName( Name name, InetAddress addr ) throws UnknownHostException { + int n; NameQueryRequest request = new NameQueryRequest( name ); NameQueryResponse response = new NameQueryResponse(); - request.addr = addr != null ? addr : NbtAddress.getWINSAddress(); - request.isBroadcast = false; + request.addr = addr != null ? addr : NbtAddress.getWINSAddress(); + request.isBroadcast = request.addr == null; - try { - send( request, response, RETRY_TIMEOUT ); - } catch( IOException ioe ) { - if( log.level > 1 ) - ioe.printStackTrace( log ); - throw new UnknownHostException( name.name ); - } + if( request.isBroadcast ) { + request.addr = baddr; + n = RETRY_COUNT; + } else { + request.isBroadcast = false; + n = 1; + } - return response.addrEntry; - } + do { + try { + send( request, response, RETRY_TIMEOUT ); + } catch( IOException ioe ) { + if( log.level > 1 ) + ioe.printStackTrace( log ); + throw new UnknownHostException( name.name ); + } + + if( response.received && response.resultCode == 0 ) { + return response.addrEntry; + } + } while( --n > 0 && request.isBroadcast ); + + throw new UnknownHostException( name.name ); + } NbtAddress getByName( Name name, InetAddress addr ) throws UnknownHostException { int n; diff --git a/src/jcifs/netbios/NameServicePacket.java b/src/jcifs/netbios/NameServicePacket.java index 38b7d47..32ce331 100644 --- a/src/jcifs/netbios/NameServicePacket.java +++ b/src/jcifs/netbios/NameServicePacket.java @@ -220,8 +220,8 @@ abstract class NameServicePacket { rDataLength = readInt2( src, srcIndex ); srcIndex += 2; - addrEntry = new NbtAddress[rDataLength / 6]; - end = srcIndex + rDataLength; + addrEntry = new NbtAddress[rDataLength / 6]; + end = srcIndex + rDataLength; for( addrIndex = 0; srcIndex < end; addrIndex++ ) { srcIndex += readRDataWireFormat( src, srcIndex ); } diff --git a/src/jcifs/netbios/NbtAddress.java b/src/jcifs/netbios/NbtAddress.java index cbff6e3..806a462 100644 --- a/src/jcifs/netbios/NbtAddress.java +++ b/src/jcifs/netbios/NbtAddress.java @@ -443,13 +443,13 @@ public final class NbtAddress { } } - public static NbtAddress[] getAllByName( String host, + public static NbtAddress[] getAllByName( String host, int type, String scope, InetAddress svr ) throws UnknownHostException { - return CLIENT.getAllByName( new Name( host, type, scope ), svr ); - } + return CLIENT.getAllByName( new Name( host, type, scope ), svr ); + } /** * Retrieve all addresses of a host by it's address. NetBIOS hosts can diff --git a/src/jcifs/smb/DosFileFilter.java b/src/jcifs/smb/DosFileFilter.java index a9514f3..4c1be77 100644 --- a/src/jcifs/smb/DosFileFilter.java +++ b/src/jcifs/smb/DosFileFilter.java @@ -40,6 +40,6 @@ public class DosFileFilter implements SmbFileFilter { * specified the server may still return objects that are not directories). */ public boolean accept( SmbFile file ) throws SmbException { - return (file.getAttributes() & attributes) != 0; + return (file.getAttributes() & attributes) != 0; } } diff --git a/src/jcifs/smb/Handler.java b/src/jcifs/smb/Handler.java index bf7167c..a02f753 100644 --- a/src/jcifs/smb/Handler.java +++ b/src/jcifs/smb/Handler.java @@ -101,7 +101,7 @@ public class Handler extends URLStreamHandler { if( port == -1 ) { port = getDefaultPort(); } - setURL( u, "smb://", u.getHost(), port, + setURL( u, "smb", u.getHost(), port, u.getAuthority(), userinfo, path, u.getQuery(), null ); } diff --git a/src/jcifs/smb/NtlmChallenge.java b/src/jcifs/smb/NtlmChallenge.java index c5c0874..e6f44f8 100644 --- a/src/jcifs/smb/NtlmChallenge.java +++ b/src/jcifs/smb/NtlmChallenge.java @@ -23,17 +23,17 @@ import jcifs.util.Hexdump; public final class NtlmChallenge { - public byte[] challenge; - public UniAddress dc; + public byte[] challenge; + public UniAddress dc; - NtlmChallenge( byte[] challenge, UniAddress dc ) { - this.challenge = challenge; - this.dc = dc; - } + NtlmChallenge( byte[] challenge, UniAddress dc ) { + this.challenge = challenge; + this.dc = dc; + } - public String toString() { - return "NtlmChallenge[challenge=0x" + - Hexdump.toHexString( challenge, 0, challenge.length * 2 ) + - ",dc=" + dc.toString() + "]"; - } + public String toString() { + return "NtlmChallenge[challenge=0x" + + Hexdump.toHexString( challenge, 0, challenge.length * 2 ) + + ",dc=" + dc.toString() + "]"; + } } diff --git a/src/jcifs/smb/SmbComNTCreateAndX.java b/src/jcifs/smb/SmbComNTCreateAndX.java index e908da3..d31b57d 100644 --- a/src/jcifs/smb/SmbComNTCreateAndX.java +++ b/src/jcifs/smb/SmbComNTCreateAndX.java @@ -116,6 +116,8 @@ class SmbComNTCreateAndX extends AndXServerMessageBlock { // desiredAccess desiredAccess = ( flags >>> 16 ) & 0xFFFF; +System.out.println( "desiredAccess: 0x" + jcifs.util.Hexdump.toHexString( desiredAccess, 8 )); +if (desiredAccess == 0) throw new RuntimeException(); desiredAccess |= FILE_READ_EA | FILE_READ_ATTRIBUTES; // extFileAttributes diff --git a/src/jcifs/smb/SmbException.java b/src/jcifs/smb/SmbException.java index bf9358e..ac1975a 100644 --- a/src/jcifs/smb/SmbException.java +++ b/src/jcifs/smb/SmbException.java @@ -75,7 +75,7 @@ public class SmbException extends IOException implements NtStatus, DosError, Win return "0x" + Hexdump.toHexString( errcode, 8 ); } static int getStatusByCode( int errcode ) { - if(( errcode & 0xC0000000 ) == 0xC0000000 ) { + if(( errcode & 0xC0000000 ) != 0 ) { return errcode; } else { int min = 0; diff --git a/src/jcifs/smb/SmbFileInputStream.java b/src/jcifs/smb/SmbFileInputStream.java index 2efc0bc..78cfcbc 100644 --- a/src/jcifs/smb/SmbFileInputStream.java +++ b/src/jcifs/smb/SmbFileInputStream.java @@ -30,11 +30,12 @@ import java.io.IOException; public class SmbFileInputStream extends InputStream { - private SmbFile file; private long fp; private int readSize, openFlags; private byte[] tmp = new byte[1]; + SmbFile file; + /** * Creates an {@link java.io.InputStream} for reading bytes from a file on * an SMB server addressed by the url parameter. See {@link diff --git a/src/jcifs/smb/SmbNamedPipe.java b/src/jcifs/smb/SmbNamedPipe.java index 7bbb605..5de24a6 100644 --- a/src/jcifs/smb/SmbNamedPipe.java +++ b/src/jcifs/smb/SmbNamedPipe.java @@ -116,6 +116,8 @@ public class SmbNamedPipe extends SmbFile { public static final int PIPE_TYPE_TRANSACT = 0x02; + public static final int PIPE_TYPE_DCE_TRANSACT = 0x02 | 0x04; + InputStream pipeIn; OutputStream pipeOut; int pipeType; diff --git a/src/jcifs/smb/SmbSession.java b/src/jcifs/smb/SmbSession.java index ad3c055..0b14cf7 100644 --- a/src/jcifs/smb/SmbSession.java +++ b/src/jcifs/smb/SmbSession.java @@ -52,75 +52,75 @@ changed without changing init parameters or reinitializing the webapp. public final class SmbSession { - private static final String LOGON_SHARE = Config.getProperty( "jcifs.smb.client.logonShare", "IPC$" ); + private static final String LOGON_SHARE = Config.getProperty( "jcifs.smb.client.logonShare", null ); private static final int LOOKUP_RESP_LIMIT = jcifs.Config.getInt( "jcifs.netbios.lookupRespLimit", 5 ); - private static final String DOMAIN = Config.getProperty("jcifs.smb.client.domain", null); - private static final String USERNAME = Config.getProperty("jcifs.smb.client.username", null); + private static final String DOMAIN = Config.getProperty("jcifs.smb.client.domain", null); + private static final String USERNAME = Config.getProperty("jcifs.smb.client.username", null); private static final int DEFAULT_CACHE_POLICY = 30; private static final int CACHE_POLICY = Config.getInt( "jcifs.netbios.cachePolicy", DEFAULT_CACHE_POLICY ); - static long dc_list_expiration; - static NbtAddress[] dc_list = null; - static int dc_list_index; /* always less than dc_list_range */ - static int dc_list_range = 1; /* always less than LOOKUP_RESP_LIMIT */ - - static void incr_dc_list_range() { - if( dc_list_range < LOOKUP_RESP_LIMIT && - dc_list_range < dc_list.length ) { - dc_list_range++; - } - } - public static NtlmChallenge getChallengeForDomain() - throws SmbException, UnknownHostException { - int starting_index; - - if( DOMAIN == null ) { - throw new SmbException( "A domain was not specified" ); - } + static long dc_list_expiration; + static NbtAddress[] dc_list = null; + static int dc_list_index; /* always less than dc_list_range */ + static int dc_list_range = 1; /* always less than LOOKUP_RESP_LIMIT */ + + static void incr_dc_list_range() { + if( dc_list_range < LOOKUP_RESP_LIMIT && + dc_list_range < dc_list.length ) { + dc_list_range++; + } + } + public static NtlmChallenge getChallengeForDomain() + throws SmbException, UnknownHostException { + int starting_index; + + if( DOMAIN == null ) { + throw new SmbException( "A domain was not specified" ); + } synchronized( DOMAIN ) { - if( dc_list_expiration < System.currentTimeMillis() ) { - dc_list = NbtAddress.getAllByName( DOMAIN, 0x1C, null, null ); - dc_list_expiration = System.currentTimeMillis() + CACHE_POLICY * 1000L; - if( dc_list_range > 1 ) { - dc_list_range /= 2; /* shrink dc_list_range */ - } - } - - starting_index = dc_list_index; - do { - if( dc_list_index == dc_list_range ) { - dc_list_index = 0; - } - NbtAddress addr = dc_list[dc_list_index]; - if( addr != null ) { - try { - UniAddress dc = new UniAddress( addr ); - SmbTransport trans = SmbTransport.getSmbTransport( dc, 0 ); - if( USERNAME == null ) { - if( SmbTransport.log.level > 1 ) - SmbTransport.log.println( "Default credentials (jcifs.smb.client.username/password) not specified. SMB signing may not work propertly. Skipping DC interrogation." ); - trans.negotiate(); - } else { - trans.getSmbSession( NtlmPasswordAuthentication.DEFAULT ).getSmbTree( LOGON_SHARE, null ).treeConnect( null, null ); - } - if( trans.sessions.size() > (trans.SSN_LIMIT / 10)) { - incr_dc_list_range(); - } - dc_list_index++; - return new NtlmChallenge( trans.server.encryptionKey, dc ); - } catch( SmbException se ) { - if( SmbTransport.log.level > 1 ) - SmbTransport.log.println( "Failed validate DC: " + addr + ": " + se.getMessage() ); - } - dc_list[dc_list_index] = null; /* dc no good */ - incr_dc_list_range(); - } - dc_list_index++; - } while( dc_list_index != starting_index ); + if( dc_list_expiration < System.currentTimeMillis() ) { + dc_list = NbtAddress.getAllByName( DOMAIN, 0x1C, null, null ); + dc_list_expiration = System.currentTimeMillis() + CACHE_POLICY * 1000L; + if( dc_list_range > 1 ) { + dc_list_range /= 2; /* shrink dc_list_range */ + } + } + + starting_index = dc_list_index; + do { + if( dc_list_index == dc_list_range ) { + dc_list_index = 0; + } + NbtAddress addr = dc_list[dc_list_index]; + if( addr != null ) { + try { + UniAddress dc = new UniAddress( addr ); + SmbTransport trans = SmbTransport.getSmbTransport( dc, 0 ); + if( USERNAME == null ) { + if( SmbTransport.log.level > 1 ) + SmbTransport.log.println( "Default credentials (jcifs.smb.client.username/password) not specified. SMB signing may not work propertly. Skipping DC interrogation." ); + trans.negotiate(); + } else { + trans.getSmbSession( NtlmPasswordAuthentication.DEFAULT ).getSmbTree( LOGON_SHARE, null ).treeConnect( null, null ); + } + if( trans.sessions.size() > (trans.SSN_LIMIT / 10)) { + incr_dc_list_range(); + } + dc_list_index++; + return new NtlmChallenge( trans.server.encryptionKey, dc ); + } catch( SmbException se ) { + if( SmbTransport.log.level > 1 ) + SmbTransport.log.println( "Failed validate DC: " + addr + ": " + se.getMessage() ); + } + dc_list[dc_list_index] = null; /* dc no good */ + incr_dc_list_range(); + } + dc_list_index++; + } while( dc_list_index != starting_index ); } - throw new UnknownHostException( "Failed to negotiate with a suitable domain controller for " + DOMAIN ); - } + throw new UnknownHostException( "Failed to negotiate with a suitable domain controller for " + DOMAIN ); + } public static byte[] getChallenge( UniAddress dc ) @@ -152,7 +152,14 @@ synchronized( DOMAIN ) { public static void logon( UniAddress dc, int port, NtlmPasswordAuthentication auth ) throws SmbException { - SmbTransport.getSmbTransport( dc, port ).getSmbSession( auth ).getSmbTree( LOGON_SHARE, null ).treeConnect( null, null ); + SmbTree tree = SmbTransport.getSmbTransport( dc, port ).getSmbSession( auth ).getSmbTree( LOGON_SHARE, null ); + if( LOGON_SHARE == null ) { + tree.treeConnect( null, null ); + } else { + Trans2FindFirst2 req = new Trans2FindFirst2( "\\", "*", SmbFile.ATTR_DIRECTORY ); + Trans2FindFirst2Response resp = new Trans2FindFirst2Response(); + tree.sendTransaction( req, resp ); + } } private int uid; @@ -165,7 +172,7 @@ synchronized( DOMAIN ) { SmbTransport transport = SmbTransport.NULL_TRANSPORT; NtlmPasswordAuthentication auth; - long expiration; + long expiration; SmbSession( UniAddress address, int port, InetAddress localAddr, int localPort, @@ -227,7 +234,7 @@ synchronized( DOMAIN ) { void sessionSetup( ServerMessageBlock andx, ServerMessageBlock andxResponse ) throws SmbException { - expiration = System.currentTimeMillis() + SmbTransport.SO_TIMEOUT; + expiration = System.currentTimeMillis() + SmbTransport.SO_TIMEOUT; synchronized( transport() ) { if( sessionSetup ) { diff --git a/src/jcifs/smb/SmbTransport.java b/src/jcifs/smb/SmbTransport.java index 605a3e6..0a45299 100644 --- a/src/jcifs/smb/SmbTransport.java +++ b/src/jcifs/smb/SmbTransport.java @@ -107,13 +107,13 @@ private static byte[] rcv_buf = new byte[0xFFFF]; private LinkedList referrals = new LinkedList(); private Mid[] mids = new Mid[MAX_MPX_COUNT]; private short mid_next; - private IOException socketException; - private long sessionExpiration = System.currentTimeMillis() + SO_TIMEOUT; + private IOException socketException; + private long sessionExpiration = System.currentTimeMillis() + SO_TIMEOUT; static final int SSN_LIMIT = - Config.getInt( "jcifs.smb.client.ssnLimit", DEFAULT_SSN_LIMIT ); + Config.getInt( "jcifs.smb.client.ssnLimit", DEFAULT_SSN_LIMIT ); static final int SO_TIMEOUT = - Config.getInt( "jcifs.smb.client.soTimeout", DEFAULT_SO_TIMEOUT ); + Config.getInt( "jcifs.smb.client.soTimeout", DEFAULT_SO_TIMEOUT ); static final String NATIVE_OS = Config.getProperty( "jcifs.smb.client.nativeOs", System.getProperty( "os.name" )); static final String NATIVE_LANMAN = @@ -223,22 +223,22 @@ private static byte[] rcv_buf = new byte[0xFFFF]; if( ssn.matches( auth )) { ssn.auth = auth; return ssn; - } - } - - /* close old sessions */ - long now = System.currentTimeMillis(); - if( sessionExpiration < now ) { - sessionExpiration = now + SO_TIMEOUT; - iter = sessions.listIterator(); - while( iter.hasNext() ) { - ssn = (SmbSession)iter.next(); - if( ssn.expiration < now ) { - ssn.logoff( false ); - sessions.remove( ssn ); - } - } - } + } + } + + /* close old sessions */ + long now = System.currentTimeMillis(); + if( sessionExpiration < now ) { + sessionExpiration = now + SO_TIMEOUT; + iter = sessions.listIterator(); + while( iter.hasNext() ) { + ssn = (SmbSession)iter.next(); + if( ssn.expiration < now ) { + ssn.logoff( false ); + sessions.remove( ssn ); + } + } + } ssn = new SmbSession( address, port, localAddr, localPort, auth ); ssn.transport = this; @@ -305,28 +305,28 @@ private static byte[] rcv_buf = new byte[0xFFFF]; state = ST_GROUND; } void start() throws SmbException { - try { - thread = new Thread( this, "JCIFS-SmbTransport" ); - thread.setDaemon( true ); - thread.start(); - - wait( RESPONSE_TIMEOUT ); /* wait for the thread to be started and socket opened */ - - if( socket == null ) { /* failed to open socket for some reason */ - tryClose( true ); - throw new SmbException( "Timeout trying to open socket (probably no ACK to SYN) for address", socketException ); - } - } catch( InterruptedException ie ) { - tryClose( true ); - throw new SmbException( "Interrupted opening socket", ie ); - } + try { + thread = new Thread( this, "JCIFS-SmbTransport" ); + thread.setDaemon( true ); + thread.start(); + + wait( RESPONSE_TIMEOUT ); /* wait for the thread to be started and socket opened */ + + if( socket == null ) { /* failed to open socket for some reason */ + tryClose( true ); + throw new SmbException( "Timeout trying to open socket (probably no ACK to SYN) for address", socketException ); + } + } catch( InterruptedException ie ) { + tryClose( true ); + throw new SmbException( "Interrupted opening socket", ie ); + } } public void run() { Mid mid = new Mid(); int i, m, nbtlen; ServerMessageBlock response; - try { + try { Object obj; NbtAddress naddr; String calledName; @@ -346,19 +346,19 @@ private static byte[] rcv_buf = new byte[0xFFFF]; do { try { socket = new NbtSocket( naddr, calledName, port, localAddr, localPort ); - if( TCP_NODELAY ) { - socket.setTcpNoDelay( true ); - } - socket.setSoTimeout( SO_TIMEOUT ); - in = new PushbackInputStream( socket.getInputStream(), PUSHBACK_BUF_SIZE ); - out = socket.getOutputStream(); + if( TCP_NODELAY ) { + socket.setTcpNoDelay( true ); + } + socket.setSoTimeout( SO_TIMEOUT ); + in = new PushbackInputStream( socket.getInputStream(), PUSHBACK_BUF_SIZE ); + out = socket.getOutputStream(); break; } catch( NbtException ne ) { if( ne.errorClass == NbtException.ERR_SSN_SRVC && ( ne.errorCode == NbtException.CALLED_NOT_PRESENT || ne.errorCode == NbtException.NOT_LISTENING_CALLED )) { - if( log.level > 2 ) - ne.printStackTrace( log ); + if( log.level > 2 ) + ne.printStackTrace( log ); } else { throw ne; } @@ -376,15 +376,15 @@ private static byte[] rcv_buf = new byte[0xFFFF]; } else { tconHostName = calledName; } - } catch( IOException ioe ) { - socketException = ioe; + } catch( IOException ioe ) { + socketException = ioe; if( log.level > 1 ) ioe.printStackTrace( log ); - return; - } finally { - synchronized( this ) { - notifyAll(); - } + return; + } finally { + synchronized( this ) { + notifyAll(); + } } while( thread == Thread.currentThread() ) { @@ -584,8 +584,8 @@ synchronized( rcv_buf ) { ServerMessageBlock response ) throws SmbException { Mid mid = null; - if( request.command != request.SMB_COM_NEGOTIATE ) - negotiate(); + if( request.command != request.SMB_COM_NEGOTIATE ) + negotiate(); request.flags2 |= flags2; request.useUnicode = useUnicode; @@ -708,7 +708,7 @@ synchronized( snd_buf ) { SmbComTransactionResponse response ) throws SmbException { Mid mid = null; - negotiate(); + negotiate(); request.flags2 |= flags2; request.useUnicode = useUnicode; @@ -863,27 +863,29 @@ synchronized( snd_buf ) { DfsReferral dr = getDfsReferral( request.auth, request.path ); referrals.add( dr ); throw dr; + case 0x80000005: + break; default: throw new SmbException( response.errorCode, null ); } } synchronized void negotiate() throws SmbException { - if( state == ST_GROUND ) { - state = ST_NEGOTIATING; - } else { - while( state != ST_NEGOTIATED ) { - try { - wait(); - } catch( InterruptedException ie ) { - tryClose( true ); - throw new SmbException( "Interrupted opening socket", ie ); - } - } - return; - } - - start(); /* start the transport thread (which opens the socket) */ + if( state == ST_GROUND ) { + state = ST_NEGOTIATING; + } else { + while( state != ST_NEGOTIATED ) { + try { + wait(); + } catch( InterruptedException ie ) { + tryClose( true ); + throw new SmbException( "Interrupted opening socket", ie ); + } + } + return; + } + + start(); /* start the transport thread (which opens the socket) */ if( this == NULL_TRANSPORT ) { throw new RuntimeException( "Null transport cannot be used" ); @@ -944,7 +946,7 @@ synchronized( snd_buf ) { } } - state = ST_NEGOTIATED; + state = ST_NEGOTIATED; } public String toString() { String ret = "SmbTransport[address=" + address; diff --git a/src/jcifs/smb/TransactNamedPipeInputStream.java b/src/jcifs/smb/TransactNamedPipeInputStream.java index 377d678..68f28b2 100644 --- a/src/jcifs/smb/TransactNamedPipeInputStream.java +++ b/src/jcifs/smb/TransactNamedPipeInputStream.java @@ -20,24 +20,24 @@ package jcifs.smb; import java.io.InputStream; import java.io.IOException; +import java.net.UnknownHostException; +import java.net.MalformedURLException; -class TransactNamedPipeInputStream extends InputStream { +class TransactNamedPipeInputStream extends SmbFileInputStream { private static final int INIT_PIPE_SIZE = 4096; - private SmbNamedPipe pipe; private byte[] pipe_buf = new byte[INIT_PIPE_SIZE]; private int beg_idx, nxt_idx, used; + private boolean dcePipe; Object lock; - TransactNamedPipeInputStream( SmbNamedPipe pipe ) { - this.pipe = pipe; + TransactNamedPipeInputStream( SmbNamedPipe pipe ) throws SmbException, MalformedURLException, UnknownHostException { + super( pipe, ( pipe.pipeType & 0xFFFF0000 ) | SmbFile.O_EXCL ); + this.dcePipe = ( pipe.pipeType & SmbNamedPipe.PIPE_TYPE_DCE_TRANSACT ) == SmbNamedPipe.PIPE_TYPE_DCE_TRANSACT; lock = new Object(); } - public void close() throws IOException { - pipe.close(); - } public int read() throws IOException { int result = -1; @@ -84,11 +84,12 @@ class TransactNamedPipeInputStream extends InputStream { used -= result; beg_idx = ( beg_idx + result ) % pipe_buf.length; } + return result; } public int available() throws IOException { - if( pipe.log.level > 2 ) - pipe.log.println( "Named Pipe available() does not apply to TRANSACT Named Pipes" ); + if( file.log.level > 2 ) + file.log.println( "Named Pipe available() does not apply to TRANSACT Named Pipes" ); return 0; } int receive( byte[] b, int off, int len ) { @@ -105,14 +106,14 @@ class TransactNamedPipeInputStream extends InputStream { tmp = pipe_buf; pipe_buf = new byte[new_size]; i = tmp.length - beg_idx; - if( used > i ) { + if( used > i ) { /* 2 chunks */ System.arraycopy( tmp, beg_idx, pipe_buf, 0, i ); System.arraycopy( tmp, 0, pipe_buf, i, used - i ); - nxt_idx = used; } else { System.arraycopy( tmp, beg_idx, pipe_buf, 0, used ); } beg_idx = 0; + nxt_idx = used; tmp = null; } @@ -128,4 +129,7 @@ class TransactNamedPipeInputStream extends InputStream { used += len; return len; } + public int dce_read( byte[] b, int off, int len ) throws IOException { + return super.read(b, off, len); + } } diff --git a/src/jcifs/smb/TransactNamedPipeOutputStream.java b/src/jcifs/smb/TransactNamedPipeOutputStream.java index adfa884..03890db 100644 --- a/src/jcifs/smb/TransactNamedPipeOutputStream.java +++ b/src/jcifs/smb/TransactNamedPipeOutputStream.java @@ -26,9 +26,11 @@ class TransactNamedPipeOutputStream extends OutputStream { private String path; private SmbNamedPipe pipe; private byte[] tmp = new byte[1]; + private boolean dcePipe; TransactNamedPipeOutputStream( SmbNamedPipe pipe ) throws IOException { this.pipe = pipe; + this.dcePipe = ( pipe.pipeType & SmbNamedPipe.PIPE_TYPE_DCE_TRANSACT ) == SmbNamedPipe.PIPE_TYPE_DCE_TRANSACT; path = pipe.unc; } @@ -55,9 +57,12 @@ class TransactNamedPipeOutputStream extends OutputStream { new TransCallNamedPipeResponse( pipe )); } else if(( pipe.pipeType & SmbNamedPipe.PIPE_TYPE_TRANSACT ) == SmbNamedPipe.PIPE_TYPE_TRANSACT ) { - pipe.open(( pipe.pipeType & 0xFF0000 ) | SmbFile.O_EXCL, SmbFile.ATTR_NORMAL, 0 ); - pipe.sendTransaction( new TransTransactNamedPipe( pipe.fid, b, off, len ), - new TransTransactNamedPipeResponse( pipe )); + pipe.open(( pipe.pipeType & 0xFFFF0000 ) | SmbFile.O_EXCL, SmbFile.ATTR_NORMAL, 0 ); + TransTransactNamedPipe req = new TransTransactNamedPipe( pipe.fid, b, off, len ); + if (dcePipe) { + req.maxDataCount = 1024; + } + pipe.sendTransaction( req, new TransTransactNamedPipeResponse( pipe )); } } } diff --git a/src/jcifs/util/Encdec.java b/src/jcifs/util/Encdec.java index 9361291..97f071d 100644 --- a/src/jcifs/util/Encdec.java +++ b/src/jcifs/util/Encdec.java @@ -261,7 +261,7 @@ public class Encdec { } public static String dec_utf8( byte[] src, int si, int slim ) throws IOException { char[] uni = new char[slim - si]; - int ui = 0, ch; + int ui, ch; for( ui = 0; si < slim && (ch = src[si++] & 0xFF) != 0; ui++ ) { if( ch < 0x80 ) { @@ -299,4 +299,16 @@ public class Encdec { return new String( uni, 0, ui ); } + public static String dec_ucs2le( byte[] src, int si, int slim, char[] buf ) throws IOException { + int bi; + + for( bi = 0; (si + 1) < slim; bi++, si += 2 ) { + buf[bi] = (char)dec_uint16le( src, si ); + if( buf[bi] == '\0' ) { + break; + } + } + + return new String( buf, 0, bi ); + } }