+Sun Jul 3 23:33:03 EDT 2005
+jcifs-1.2.1 released
+
+The SMB signing code was totally broken in the last release. It has been
+reparied. The setAttributes method did not work on directories. This has
+been fixed and the masks used to filter setAttributes/getAttributes have
+been optimized to allow getting and setting all possible attributes based
+on observed XP behavior. The getType() method would always return
+TYPE_SHARE if the SmbFiles were obtained through the listFiles() method on
+a workgroup or server URL. This issue has been fixed - getType() may now
+return TYPE_PRINTER and TYPE_NAMEDPIPE.
+
Sun May 22 18:22:32 EDT 2005
jcifs-1.2.0 released
<project name="jcifs" default="usage" basedir=".">
- <property name="version" value="1.2.0"/>
- <property name="reldate" value="May 22, 2005"/>
+ <property name="version" value="1.2.1"/>
+ <property name="reldate" value="Jul 4, 2005"/>
<target name="usage">
<echo>
byte[] msg;
int i = 0;
- while( i++ < 5 ) {
+ while( i++ < 3 ) {
msg = new String( "this is msg #" + i ).getBytes();
out.write( msg );
System.out.write( msg );
Thread.sleep( 17000 );
+out = new SmbFileOutputStream( f, true );
}
out.close();
SmbFile f1 = new SmbFile( argv[0] );
SmbFile f2 = new SmbFile( argv[1] );
+System.out.println( f1 );
+System.out.println( f2 );
System.err.println( f1.equals( f2 ));
}
}
static class ShortFilenameFilter implements SmbFilenameFilter {
public boolean accept( SmbFile dir, String name ) throws SmbException {
- return name.length() < 9;
+ return name.length() < 14;
}
}
static class BigFileFilter implements SmbFileFilter {
SmbFile file = new SmbFile( argv[0] );
BigFileFilter filter = new BigFileFilter();
- DosFileFilter everything = new DosFileFilter( "*",
- SmbFile.ATTR_DIRECTORY | SmbFile.ATTR_HIDDEN | SmbFile.ATTR_SYSTEM );
+ ShortFilenameFilter sfilter = new ShortFilenameFilter();
+ DosFileFilter everything = new DosFileFilter( "*", 0xFFFF );
long t1 = System.currentTimeMillis();
SmbFile[] files = file.listFiles( everything );
--- /dev/null
+#!/bin/sh
+
+JAVA_HOME=/usr/local/java
+CLASSPATH=../build:.
+PROPERTIES=../../miallen.prp
+RUN="${JAVA_HOME}/bin/java -cp ${CLASSPATH} -Djcifs.properties=${PROPERTIES}"
+
+SERVER=rnyxwbf8s5v31
+SHARE=pub
+WRITE_DIR=test/
+SRC_DIR=test/Junk
+FILE1=test/Junk/10883563.doc
+
+URL_SHARE=smb://${SERVER}/${SHARE}/
+URL_WRITE_DIR=${URL_SHARE}${WRITE_DIR}
+
+[ "$1" = "AllocInfo" ] && $RUN AllocInfo ${URL_SHARE}
+[ "$1" = "Append" ] && $RUN Append ${URL_WRITE_DIR}Append.txt
+[ "$1" = "AuthListFiles" ] && $RUN AuthListFiles smb://bogus\@${SERVER}/${SHARE}/
+[ "$1" = "CopyTo" ] && $RUN CopyTo ${URL_SHARE}${SRC_DIR}/ ${URL_SHARE}${WRITE_DIR}CopyTo/
+[ "$1" = "CreateFile" ] && $RUN CreateFile ${URL_WRITE_DIR}CreateFile.txt
+[ "$1" = "Delete" ] && $RUN Delete ${URL_WRITE_DIR}CreateFile.txt
+[ "$1" = "Equals" ] && $RUN Equals ${URL_WRITE_DIR}CreateFile.txt ${URL_SHARE}${WRITE_DIR}../${WRITE_DIR}CreateFile.txt
+[ "$1" = "Exists" ] && $RUN Exists ${URL_WRITE_DIR}
+[ "$1" = "FileInfo" ] && $RUN FileInfo ${URL_SHARE}${FILE1} 0
+[ "$1" = "FileOps" ] && $RUN FileOps ${URL_WRITE_DIR}
+[ "$1" = "FilterFiles" ] && $RUN FilterFiles ${URL_SHARE}${SRC_DIR}/
+[ "$1" = "GetDate" ] && $RUN GetDate ${URL_SHARE}${FILE1}
+[ "$1" = "Get" ] && $RUN Get ${URL_SHARE}test/Makefile.txt
+[ "$1" = "GetType" ] && $RUN GetType ${URL_SHARE}
+[ "$1" = "GrowWrite" ] && $RUN GrowWrite ${URL_WRITE_DIR}GrowWrite.txt
+[ "$1" = "GetURL" ] && $RUN GetURL ${URL_WRITE_DIR}Append.txt
+[ "$1" = "HttpURL" ] && $RUN HttpURL ${URL_WRITE_DIR} ../Append.txt
+[ "$1" = "Interleave" ] && $RUN Interleave ${URL_WRITE_DIR} 25
+[ "$1" = "IsDir" ] && $RUN IsDir ${URL_SHARE}${SRC_DIR}/
+[ "$1" = "Length" ] && $RUN Length ${URL_SHARE}${FILE1}
+[ "$1" = "ListFiles" ] && $RUN ListFiles ${URL_WRITE_DIR}
+[ "$1" = "List" ] && $RUN List ${URL_WRITE_DIR}
+[ "$1" = "ListTypes" ] && $RUN ListTypes ${URL_WRITE_DIR}
+[ "$1" = "Mkdir" ] && $RUN Mkdir ${URL_WRITE_DIR}Mkdir
+[ "$1" = "NodeStatus" ] && $RUN NodeStatus ${SERVER}
+[ "$1" = "Put" ] && $RUN Put ${URL_WRITE_DIR}Makefile
+[ "$1" = "Query" ] && $RUN Query ${SERVER}
+[ "$1" = "RenameTo" ] && $RUN RenameTo ${URL_WRITE_DIR}Makefile ${URL_WRITE_DIR}Makefile.txt
+[ "$1" = "SetAttrs" ] && $RUN SetAttrs ${URL_WRITE_DIR}Makefile.txt FFFF
+[ "$1" = "SetTime" ] && $RUN SetTime ${URL_WRITE_DIR}Makefile.txt
+[ "$1" = "SlowWrite" ] && $RUN SlowWrite ${URL_WRITE_DIR}SlowWrite.txt
+[ "$1" = "SlowRead" ] && $RUN SlowRead ${URL_WRITE_DIR}SlowWrite.txt
+[ "$1" = "SmbCrawler" ] && $RUN SmbCrawler ${URL_WRITE_DIR} 1000
+[ "$1" = "T2Crawler" ] && $RUN T2Crawler ${URL_WRITE_DIR} 3 1000
+[ "$1" = "TestRandomAccess1" ] && $RUN TestRandomAccess ${URL_WRITE_DIR}TestRandomAccess.bin 1
+[ "$1" = "TestRandomAccess2" ] && $RUN TestRandomAccess ${URL_WRITE_DIR}TestRandomAccess.bin 2 0
+[ "$1" = "TestRandomAccess3" ] && $RUN TestRandomAccess ${URL_WRITE_DIR}TestRandomAccess.bin 3 1234
+
+
SERVER=rnyxwbf8s5v31
SHARE=pub
-WRITE_DIR=test
+WRITE_DIR=test/
SRC_DIR=test/Junk
-FILE1=test/Junk/tracer/m31_gendler_big.jpg
+FILE1=test/Junk/10883563.doc
URL_SHARE=smb://${SERVER}/${SHARE}/
-URL_WRITE_DIR=${URL_SHARE}${WRITE_DIR}/
+URL_WRITE_DIR=${URL_SHARE}${WRITE_DIR}
set -x
$RUN AllocInfo ${URL_SHARE}
#$RUN Append ${URL_WRITE_DIR}Append.txt
$RUN AuthListFiles smb://bogus\@${SERVER}/${SHARE}/
-$RUN CopyTo ${URL_SHARE}${SRC_DIR}/ ${URL_SHARE}${WRITE_DIR}/CopyTo/
+$RUN CopyTo ${URL_SHARE}${SRC_DIR}/ ${URL_SHARE}${WRITE_DIR}CopyTo/
$RUN CreateFile ${URL_WRITE_DIR}CreateFile.txt
$RUN Delete ${URL_WRITE_DIR}CreateFile.txt
-$RUN Equals ${URL_WRITE_DIR}CreateFile.txt ${URL_SHARE}${WRITE_DIR}../${WRITE_DIR}/CreateFile.txt
+$RUN Equals ${URL_WRITE_DIR}CreateFile.txt ${URL_SHARE}${WRITE_DIR}../${WRITE_DIR}CreateFile.txt
$RUN Exists ${URL_WRITE_DIR}
$RUN FileInfo ${URL_SHARE}${FILE1} 0
$RUN FileOps ${URL_WRITE_DIR}
}
setFlags(flags);
setLMResponse(lmResponse);
- // NTLMv2 issues w/cross-domain authentication; leave NT empty if >= 3
- if (LM_COMPATIBILITY < 3) setNTResponse(ntResponse);
+ /* NTLMv2 issues w/cross-domain authentication; leave
+ * NT empty if NTLMv2 was sent by the client. NTLM response
+ * will always be 24 bytes; NTLMv2 response will always be
+ * longer. - Kevin Tapperson
+ */
+ if (ntResponse.length == 24) setNTResponse(ntResponse);
setDomain(new String(domain, charset));
setUser(new String(user, charset));
setWorkstation(new String(workstation, charset));
}
-
}
/* This filter can be considerably more efficient than other file filters
* as the specifed wildcard and attributes are passed to the server for
- * filtering there.
+ * filtering there (although attributes are largely ignored by servers
+ * they are filtered locally by the default accept method).
*/
public DosFileFilter( String wildcard, int attributes ) {
this.wildcard = wildcard;
public static final int NT_STATUS_INVALID_INFO_CLASS = 0xC0000003;
public static final int NT_STATUS_ACCESS_VIOLATION = 0xC0000005;
public static final int NT_STATUS_INVALID_HANDLE = 0xC0000008;
+ public static final int NT_STATUS_INVALID_PARAMETER = 0xC000000d;
public static final int NT_STATUS_NO_SUCH_DEVICE = 0xC000000e;
public static final int NT_STATUS_NO_SUCH_FILE = 0xC000000f;
public static final int NT_STATUS_ACCESS_DENIED = 0xC0000022;
public static final int NT_STATUS_PIPE_CLOSING = 0xC00000b1;
public static final int NT_STATUS_PIPE_LISTENING = 0xC00000b3;
public static final int NT_STATUS_FILE_IS_A_DIRECTORY = 0xC00000ba;
+ public static final int NT_STATUS_DUPLICATE_NAME = 0xC00000bd;
public static final int NT_STATUS_NETWORK_NAME_DELETED = 0xC00000c9;
public static final int NT_STATUS_BAD_NETWORK_NAME = 0xC00000cc;
public static final int NT_STATUS_NOT_A_DIRECTORY = 0xC0000103;
NT_STATUS_INVALID_INFO_CLASS,
NT_STATUS_ACCESS_VIOLATION,
NT_STATUS_INVALID_HANDLE,
+ NT_STATUS_INVALID_PARAMETER,
NT_STATUS_NO_SUCH_DEVICE,
NT_STATUS_NO_SUCH_FILE,
NT_STATUS_ACCESS_DENIED,
NT_STATUS_PIPE_CLOSING,
NT_STATUS_PIPE_LISTENING,
NT_STATUS_FILE_IS_A_DIRECTORY,
+ NT_STATUS_DUPLICATE_NAME,
NT_STATUS_NETWORK_NAME_DELETED,
NT_STATUS_BAD_NETWORK_NAME,
NT_STATUS_NOT_A_DIRECTORY,
"The parameter is incorrect.",
"Invalid access to memory location.",
"The handle is invalid.",
+ "The parameter is incorrect.",
"The system cannot find the file specified.",
"The system cannot find the file specified.",
"Access is denied.",
"The pipe is being closed.",
"Waiting for a process to open the other end of the pipe.",
"Access is denied.",
+ "A duplicate name exists on the network.",
"The specified network name is no longer available.",
"The network name cannot be found.",
"The directory name is invalid.",
}
}
- if(( createOptions & 0x01 ) == 0 ) {
+ if ((createOptions & 0x0001) == 0) {
this.createOptions = createOptions | 0x0040;
} else {
this.createOptions = createOptions;
this.b = b;
this.off = off;
count = len;
+ digest = null; /* otherwise recycled commands
+ * like writeandx will choke if session
+ * closes in between */
}
int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
int start = dstIndex;
this.b = b;
this.off = off;
dataLength = len;
+ digest = null; /* otherwise recycled commands
+ * like writeandx will choke if session
+ * closes in between */
}
int getBatchLimit( byte command ) {
if( command == SMB_COM_READ_ANDX ) {
static final int ATTR_NORMAL = 0x080;
static final int ATTR_TEMPORARY = 0x100;
- static final int ATTR_GET_MASK = 0x7FFF;
- static final int ATTR_SET_MASK = 0x27;
+ static final int ATTR_GET_MASK = 0x7FFF; /* orig 0x7fff */
+ static final int ATTR_SET_MASK = 0x30A7; /* orig 0x0027 */
static final int DEFAULT_ATTR_EXPIRATION_PERIOD = 5000;
int fid; // Initially 0; set by open()
int type;
boolean opened;
+ int tree_num;
/**
* Constructs an SmbFile representing a resource on an SMB network such as
}
fid = open0( flags, attrs, options );
opened = true;
+ tree_num = tree.tree_num;
}
boolean isOpen() {
- return opened && isConnected();
+ return opened && isConnected() && tree_num == tree.tree_num;
}
void close( int f, long lastWriteTime ) throws SmbException {
}
if( name.length() > 0 ) {
SmbFile f = new SmbFile( this, name,
- listType == 0 ? TYPE_WORKGROUP : (listType << 1),
+ e.getType(),
ATTR_READONLY | ATTR_DIRECTORY, 0L, 0L, 0L );
if( ff != null && ff.accept( f ) == false ) {
continue;
if( name.length() > 0 ) {
SmbFile f = new SmbFile( this, name, TYPE_FILESYSTEM,
e.getAttributes(), e.createTime(), e.lastModified(), e.length() );
+System.out.print(" " + name );
if( ff != null && ff.accept( f ) == false ) {
continue;
}
}
void setPathInformation( int attrs, long ctime, long mtime ) throws SmbException {
- int f, options = 0;
+ int f, dir;
- if(( attrs & ATTR_DIRECTORY ) != 0 ) {
- options = 1;
- }
+ exists();
+ dir = attributes & ATTR_DIRECTORY;
- f = open0( O_RDONLY | SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES << 16, attrs, options );
- send( new Trans2SetFileInformation( f, attrs, ctime, mtime ),
+ f = open0( O_RDONLY | SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES << 16,
+ dir, dir != 0 ? 0x0001 : 0x0040 );
+ send( new Trans2SetFileInformation( f, attrs | dir, ctime, mtime ),
new Trans2SetFileInformationResponse() );
close( f, 0L );
if( getUncPath0().length() == 1 ) {
throw new SmbException( "Invalid operation for workgroups, servers, or shares" );
}
-
setPathInformation( attrs & ATTR_SET_MASK, 0L, 0L );
}
this.openFlags = openFlags;
if (file.type != SmbFile.TYPE_NAMED_PIPE) {
file.open( openFlags, SmbFile.ATTR_NORMAL, 0 );
+ this.openFlags &= ~(SmbFile.O_CREAT | SmbFile.O_TRUNC);
} else {
file.connect0();
}
new TransWaitNamedPipeResponse() );
}
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;
useNTSmbs = file.tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS );
}
void sessionSetup( ServerMessageBlock andx,
ServerMessageBlock andxResponse ) throws SmbException {
-
synchronized( transport() ) {
if( sessionSetup ) {
return;
SmbComSessionSetupAndXResponse response = new SmbComSessionSetupAndXResponse( andxResponse );
/* Create SMB signature digest if necessary
- * Only the first SMB_COM_SESSION_SETUP_ANX with creds other than NULL initializes signing.
+ * Only the first SMB_COM_SESSION_SETUP_ANX with non-null or
+ * blank password initializes signing.
*/
- if( transport.isSignatureSetupRequired( auth )) {
+ if (transport.isSignatureSetupRequired( auth )) {
if( auth.hashesExternal && NtlmPasswordAuthentication.DEFAULT_PASSWORD != NtlmPasswordAuthentication.BLANK ) {
/* preauthentication
*/
}
synchronized SmbSession getSmbSession( NtlmPasswordAuthentication auth ) {
SmbSession ssn;
+ long now;
ListIterator iter = sessions.listIterator();
while( iter.hasNext() ) {
}
/* close old sessions */
- long now = System.currentTimeMillis();
- if( sessionExpiration < now ) {
+ if (SO_TIMEOUT > 0 && sessionExpiration < (now = System.currentTimeMillis())) {
sessionExpiration = now + SO_TIMEOUT;
iter = sessions.listIterator();
while( iter.hasNext() ) {
SmbComNegotiateResponse resp = new SmbComNegotiateResponse( server );
try {
- negotiate( 445, resp );
+ negotiate( port, resp );
} catch( ConnectException ce ) {
- negotiate( 139, resp );
+ port = port == 445 ? 139 : 445;
+ negotiate( port, resp );
}
if( resp.dialectIndex > 10 ) {
out.close();
in.close();
socket.close();
+ digest = null;
}
protected void makeKey( Request request ) throws IOException {
protected void doSend( Request request ) throws IOException {
synchronized (BUF) {
- int n = ((ServerMessageBlock)request).encode( BUF, 4 );
+ ServerMessageBlock smb = (ServerMessageBlock)request;
+ int n = smb.encode( BUF, 4 );
Encdec.enc_uint32be( n & 0xFFFF, BUF, 0 ); /* 4 byte session message header */
+ if (log.level > 3) {
+ do {
+ log.println( smb );
+ } while (smb instanceof AndXServerMessageBlock &&
+ (smb = ((AndXServerMessageBlock)smb).andx) != null);
+ if (log.level > 5) {
+ Hexdump.hexdump( log, BUF, 4, n );
+ }
+ }
out.write( BUF, 0, 4 + n );
}
}
protected void doRecv( Response response ) throws IOException {
ServerMessageBlock resp = (ServerMessageBlock)response;
resp.useUnicode = useUnicode;
+
synchronized (BUF) {
System.arraycopy( sbuf, 0, BUF, 0, 4 + HEADER_LENGTH );
int size = Encdec.dec_uint16be( BUF, 2 );
if (size < (HEADER_LENGTH + 1) || (4 + size) > rcv_buf_size ) {
throw new IOException( "Invalid payload size: " + size );
}
- if (resp instanceof SmbComReadAndXResponse) {
+ if (resp.command == ServerMessageBlock.SMB_COM_READ_ANDX) {
SmbComReadAndXResponse r = (SmbComReadAndXResponse)resp;
int off = HEADER_LENGTH;
/* WordCount thru dataOffset always 27 */
readn( in, BUF, 4 + off, r.dataOffset - off); /* pad */
readn( in, r.b, r.off, r.dataLength ); /* read direct */
}
- return;
+ } else {
+ readn( in, BUF, 4 + 32, size - 32 );
+ resp.decode( BUF, 4 );
+ if (resp instanceof SmbComTransactionResponse) {
+ ((SmbComTransactionResponse)resp).nextElement();
+ }
}
- readn( in, BUF, 4 + 32, size - 32 );
- resp.decode( BUF, 4 );
- if (resp instanceof SmbComTransactionResponse) {
- ((SmbComTransactionResponse)resp).nextElement();
+
+ if (digest != null) {
+ digest.verify( BUF, 4, resp );
}
}
}
default:
throw new SmbException( resp.errorCode, null );
}
+ if (resp.verifyFailed) {
+ throw new SmbException( "Signature verification failed." );
+ }
}
void send( ServerMessageBlock request, ServerMessageBlock response ) throws SmbException {
request.flags2 |= flags2;
request.useUnicode = useUnicode;
+ request.response = response; /* needed by sign */
+ if (request.digest == null)
+ request.digest = digest; /* for sign called in encode */
try {
if (response == null) {
doSend( request );
return;
} else if (request instanceof SmbComTransaction) {
+ response.command = request.command;
SmbComTransaction req = (SmbComTransaction)request;
SmbComTransactionResponse resp = (SmbComTransactionResponse)response;
}
} else {
+ response.command = request.command;
super.sendrecv( request, response, RESPONSE_TIMEOUT );
}
} catch( SmbException se ) {
class SmbTree {
+ private static int tree_conn_counter;
+
private int tid;
private String share;
String service = "?????";
SmbSession session;
boolean treeConnected, inDfs;
+ int tree_num;
SmbTree( SmbSession session, String share, String service ) {
this.session = session;
service = response.service;
inDfs = response.shareIsInDfs;
treeConnected = true;
+ tree_num = tree_conn_counter++;
}
}
void treeDisconnect( boolean inError ) {
this.path = filename + "\\";
}
this.wildcard = wildcard;
- this.searchAttributes = searchAttributes & SmbFile.ATTR_GET_MASK;
+ this.searchAttributes = searchAttributes & 0x37; /* generally ignored tho */
command = SMB_COM_TRANSACTION2;
subCommand = TRANS2_FIND_FIRST2;