lsa_string/lsa_stringlarge null terminator and buffer size
Michael B Allen
ioplex at gmail.com
Thu Jul 9 12:49:03 MDT 2009
On Thu, Jul 9, 2009 at 12:57 PM, Matthieu
Patou<mat+Informatique.Samba at matws.net> wrote:
> Dear all,
> I find some strange things while creating patch for netlogon dissector for
> wireshark I think it can (or lead already) to problems.
> Samba is using type lsa_string and lsa_stringlarge for mapping the type
> RPC_UNICODE_STRING as it used in MS-NRPC (but certainly not only here).
> I guess that large is used when we want to have size > len (in order to
> include null terminators), windows only use the same type but sometimes
> len=size sometimes not, cf. Wkst Os entry of packet 13 (value Windows XP
> Pro). Usually for the latter case it's indicated in the spec that the string
> is null terminated, for instance with this entry which is OsName described
> page 38 it is the case.
Null terminatiors and the size / len of a string are two completely
Also, the strings you're asking about are not really LSA_STRING. Samba
just calls them that because that IDL was developed over a period of
many years through network analysis and no one really knew what things
were called at the time. As it turns out the real type is
UNICODE_STRING which has the IDL:
typedef struct _UNICODE_STRING
[size_is(MaximumLength / 2),length_is(Length / 2)] USHORT *Buffer;
So Length is the length of the number of bytes of the string that
represent text (which might include a null term). The MaximumLength
(which is what you call size) is the size in bytes of the buffer that
the string is in. Buffer is a pointer to a conformant array which also
has it's own size and length which has the same meaning as
MaxiumumLength and Length. Of course this is all rather redundant and
confusing because the UNICODE_STRING data structure is also a C
language level type used by the OS but the IDL has to describe how to
transform the that data structure into NDR so it ends up encoding
conformance information twice.
Anyway, none of the above has anything to do with null termination.
After you decode the NDR and ultimately get a string, it will either
have a trailing 0 byte or not. Whether or not the string is null
terminated is defined in the documentation on a
structure-by-structure, field-by-field basis like OsName in
NETLOGON_WORKSTATION_INFO you mentioned.
I actually know very little about PIDL and the WireShark dissectors so
I don't know where they handle UNICODE_STRING null terminators. In my
code, I always deal with it outside of the NDR / DCERPC layer. For
example, in Java we have a UnicodeString class that takes the
UNICODE_STRING structure and a "boolean zterm" parameter that
indicates that the string is or is not be null terminated. This way
users just get a standard Java String.
> After a few chat on IRC and reading the idl for netlogon I have the
> impression samba on reads the number of byte indicated by len (because it's
> a lsa_string). In this case reading or not those bytes is harmless because
> the next string is an empty dummy string but what would happen if it wasn't
> the case ? the read is shifted by 2 bytes.
> In the particular example of this call to GetDomainInfo is tomorrow the
> dummy 3 entry starts to be used the Max Count and Actual Count will be
> multiplied by 2^16 if I'm not wrong ...
Again, I'm not really sure how WireShark dissectors handle
UNICODE_STRING but if the documentation says that a string is zero
terminated (or better still, you look at the "wire" and see the Length
includes two extra 0 bytes) then you will need to subtract 2 bytes
from Length when converting the string from UTF-16LE to UTF-8. If this
is all something handled by PIDL using an IDL extension (which sounds
like something PIDL would do), then you'll need to adjust the IDL.
I use WireShark all the time and the NETLOGON protocol is important to
one of my products. It's a great tool. Keep up the good work!
Michael B Allen
Java Active Directory Integration
More information about the samba-technical