[jcifs] SamOEMChangePassword works
Michael B. Allen
miallen at eskimo.com
Sat Jun 15 07:01:13 EST 2002
On Fri, 14 Jun 2002 13:34:03 -0500
"Tony Thompson" <tony.thompson at stone-ware.com> wrote:
> I feel that I may be overstaying my welcome but, it seems like every time
> I make progress, I run into another wall. I now have two traces that I can
> compare and they are definately different.
You got it! Is this SamOEMChangePassword pcap of Windows to Windows?
Regardless your jCIFS RAP works. Good job. The rest is easy. I'll explain.
> According to the cifsrap2.doc file, the things that I should be writing
> into the transaction request parameters section are:
> - a 16 bit function number, in this case 214
> - the parameter descriptor string "zsT"
> - a null terminated ASCII string that represents the name of the user
> - a word with a value of 532 representing the size of the data buffer
> The problem is I think I also have to write in a data descriptor string
> "B516B16" even though it didn't say to in the document. So, I have almost
> the same information that is in the Win98 pcap except the word with the
> value of 532. The Win98 capture has a value of 814.
WARNING: Do not believe *anything* you read in the documentation, see in a
pcap, or hear through the grapevine. Even the hexdumps in the low pane of
Ethereal can be wrong.
In Ethereal that first "word" is being interpeted as a 4 byte integer. If
you consider only the first two bytes 04 02 that's 0x0204 in Little Endian
hex which is 516 decimal.
With CIFS you have to do a little reverse engineering from time to time.
But make no mistake, there's very little room for variablility here. Every
byte has to be just right. If you get so much as one bit wrong it may not
work. Or worse, it will only work on the one machine you tested against.
Welcome to the nightmare that is CIFS. Nothing makes sense. But this is
acctually the fun part. It's like those Scary Movie parodies where you
guess what's going to happen. Otherwise this would all be pretty mundane
One time I was trying to deciper strings that I was writing in Unicode, but
they appeared in the hexdump pane of Ethereal as a mangled 8 bit encoding.
So even the hexdumps are being interpreted (note the hexdumps in -Dlog=ALL
output of jCIFS are not interpreted, you can be confident that that's
really what's on the wire). The documentation can be particularly wrong.
This is why you need to look very closely at the behavior of an existing
client and server, preferrably NT to NT because that is inveriably
supported by any CIFS clients/servers. An you should be weary of what *I*
tell you. My banter about "zst" == "B516B16" was just plain wrong. Dispite
the fact that nothing is returned, it is indeed the return descriptor as
the pcap clealy shows and it is why it appears in the Samba source.
> There are other things that are not the same in the traces that I don't
> know how to rectify. In the Win98 pcap, it has a parameter count of 20. In
> the jCIFS capture, it has a parameter count of 22. There are several other
> things but some of them may dependent on each other (i.e. if I fix one
> thing the rest will correct themselves).
As you probably know by now, every SMB has a 'ParameterWords' section and a
'Bytes' section (also called Data section). See the section on
'Transactions' in the CIFS spec. So the ServerMessageBlock superclass has
four abstract methods:
abstract int writeParameterWordsWireFormat( byte dst, int dstIndex );
abstract int writeBytesWireFormat( byte dst, int dstIndex );
abstract int readParameterWordsWireFormat( byte buffer,
int bufferIndex )
abstract int readBytesWireFormat( byte buffer,
int bufferIndex )
To implement any SMB message you just have to fill in these methods and
give that object to send or sendTransaction. The top level writeWriteFormat
method will call writeParameterWordsWireFormat and write the return value
of that into the ParameterCount field. It will do the same for
writeBytesWireFormat writing the return value from that into the DataCount
field. Same principle for readParameterWordsWireFormat and
readBytesWireFormat. In other words, that 22 is being returned by your
writeParameterWordsWireFormat implementation. Have it return 20 instead. If
the accounting doesn't add up, that might be a further clue as to what
constitutes a valid message and help to reverse engineer the precise format.
More information about the jcifs