[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 )
                                        throws IOException;
    abstract int readBytesWireFormat( byte[] buffer, 
                                        int bufferIndex )
                                        throws IOException;

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 mailing list