RFC: win95 domain name passing & restrict anon parameter (2beta1)

thwartedefforts at wonky.org thwartedefforts at wonky.org
Mon Nov 16 22:08:57 GMT 1998


I'm working on the 'restrict anonymous' parameter as Luke suggested, but I'm
having a problem with browsing from win95 boxes, which I think is an issue
unrelated to the 'restrict anonymous' parameter -- yes, 'restrict anonymous'
does effect browsing as Jeremy pointed out, but in my attempt to account for
that, I'm seeing this problem.

Specificly, it appears that the domain name being sent by win95 is getting
interpretered as the NativeOS in reply_sesssetup_and_X because of a difference
in the password lengths, differences between what win95 provides and what
winNT/smbclient provides, that are used in a pointer calculation.

It may help to know that the domain name on my network is REACNET.  Most
clients are NTWKS SP3 or SP4, with a handful of Win95 (4.00.950 B from the 
System control panel).  There is also a NTSRV SP3 controlled domain with only 
it's PDC in it (soon to be turned off) also on the network.  Samba 
2.0.0beta1 is the PDC for REACNET.

All the variable names and code snippets are relative to 
smbd/reply.c:reply_sesssetup_and_X.  The line numbers in the debugging output
is going to be off because of my own debugging lines I've added.

Here's a dump of the start of inbuf generated by a win95 client for an
anonyous connection:

[1998/11/08 17:21:51, 2] lib/util.c:dump_data(4769)
  [000] 00 00 00 5F FF 53 4D 42  73 00 00 00 00 10 00 00  ..._.SMB s.......
[1998/11/08 17:21:51, 2] lib/util.c:dump_data(4777)
  [010] 00 00 00 00 00 00 00 00  00 00 00 00 01 00 77 1E  ........ ......w.
[1998/11/08 17:21:51, 2] lib/util.c:dump_data(4777)
  [020] 00 00 01 EB 0D FF 00 5F  00 68 0B 32 00 01 00 19  ......._ .h.2....
[1998/11/08 17:21:51, 2] lib/util.c:dump_data(4777)
  [030] 43 00 00 00 00 00 00 00  00 00 00 01 00 00 00 22  C....... ......."
[1998/11/08 17:21:51, 2] lib/util.c:dump_data(4777)
  [040] 00 00 00 52 45 41 43 4E  45 54 00 57 69 6E 64 6F  ...REACN ET.Windo
[1998/11/08 17:21:51, 2] lib/util.c:dump_data(4777)
  [050] 77 73 20 34 2E 30 00 57  69 6E 64 6F 77 73 20 34  ws 4.0.W indows 4
[1998/11/08 17:21:51, 2] lib/util.c:dump_data(4777)
  [060] 2E 30 00 00 00 00 00 00  00 00 00 00 00 00 00 00  .0...... ........
[1998/11/08 17:21:51, 2] lib/util.c:dump_data(4777)
  [070] 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
...
[1998/11/08 17:21:51, 3] smbd/reply.c:reply_sesssetup_and_X(577)
  Domain=[]  NativeOS=[REACNET] NativeLanMan=[Windows 4.0]
[1998/11/08 17:21:51, 3] smbd/reply.c:reply_sesssetup_and_X(581)
  sesssetupX:name=[]

Note that a username WAS NOT sent by win95, but a domain name was and the
domain variable is the empty string and NativeOS is the domain name.  From
looking at the dump, a domain name, NativeOS, and NativeLanMan are all
being sent.

Here's a dump of the start of inbuf generated by a winNT client for an
anonyous connection:

[1998/11/08 17:18:38, 2] lib/util.c:dump_data(4769)
  [000] 00 00 00 61 FF 53 4D 42  73 00 00 00 00 18 03 00  ...a.SMB s.......
[1998/11/08 17:18:38, 2] lib/util.c:dump_data(4777)
  [010] 00 00 3A 71 49 19 2F C3  EE 9E 00 00 00 00 FE CA  ..:qI./. ........
[1998/11/08 17:18:38, 2] lib/util.c:dump_data(4777)
  [020] 00 00 C0 07 0D FF 00 61  00 00 F0 32 00 01 00 39  .......a ...2...9
[1998/11/08 17:18:38, 2] lib/util.c:dump_data(4777)
  [030] 42 00 00 01 00 00 00 00  00 00 00 D4 00 00 00 24  B....... .......$
[1998/11/08 17:18:38, 2] lib/util.c:dump_data(4777)
  [040] 00 00 00 00 57 69 6E 64  6F 77 73 20 4E 54 20 31  ....Wind ows NT 1
[1998/11/08 17:18:38, 2] lib/util.c:dump_data(4777)
  [050] 33 38 31 00 00 57 69 6E  64 6F 77 73 20 4E 54 20  381..Win dows NT 
[1998/11/08 17:18:38, 2] lib/util.c:dump_data(4777)
  [060] 34 2E 30 00 00 00 00 00  00 00 00 00 00 00 00 00  4.0..... ........
[1998/11/08 17:18:38, 2] lib/util.c:dump_data(4777)
  [070] 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
...
[1998/11/08 17:18:39, 3] smbd/reply.c:reply_sesssetup_and_X(577)
  Domain=[]  NativeOS=[Windows NT 1381] NativeLanMan=[]
[1998/11/08 17:18:39, 3] smbd/reply.c:reply_sesssetup_and_X(581)
  sesssetupX:name=[]

Note that NT also did not send a username (this is to be expected during
anonymous connections).  From this dump, NT is not sending a domain name,
but NativeOS is Windows NT 1381, and NativeLanMan is empty (if this should
be Windows NT 4.0 is up in the air -- if it is, then that would indicate
that this may be a client problem -- too many extra null bytes perhaps).

I've shown that smb_buf starts at 0x41 in all cases (for both win95 and
winNT), so at least the header information for this smb is correct (I 
assume -- I am not intimate with the SMB spec). 

The following code, which assigns to user and domain, appears:

  p += passlen1 + passlen2;
  fstrcpy(user,p); p = skip_string(p,1);
  domain = p;

I have observed that:
  For win95, passlen1 = 0 and passlen2 = 0
  For winNT, passlen1 = 1 and passlen2 = 0
  For smbclient, passlen1 = 0 and passlen2 = 0
when the client is browsing anonymously. I am still studying the code that
assigns to passlen1 and passlen2, so I don't know if this difference is 
related to the windows client or the server.  smbclient gives the winNT 
behaviour when browsing anonymously (smbclient -L machinename) -- that is,
it works, but the strings are one right after another.  Even the NT 
implementation seems to have an extra null byte between NativeOS and 
NativeLanMan.

When browsing with an explict username (smbclient -L machinename -U username, 
or a non-anon NT browse), passlen1 and passlen2 are both 24... as to be 
expected for encrypted passwords -- everything is fine in this case.

This means that for anonymous browsing:
  under win95, user is copied from byte 0x41 and domain is copied from 0x42.
  under winNT, user is copied from byte 0x42 and domain is copied from 0x43.
This causes a problem because the actual values (even though they are empty
strings) are being read from the wrong place when the client is win95.  When
the client is win95, smbd should be reading an empty string from byte 0x42
for the username, and the domain name from byte 0x43, just like it does when
the client is winNT or smbclient.  The values of passlen1 and passlen2 throw
off the reading of the subsequent values for win95 clients.

To complicate the issue, this comment appears about line 560 of reply.c:

    if passlen1==24 its a win95 system, and its setting the
    password length incorrectly. Luckily it still works with the
    default code because Win95 will null terminate the password
    anyway 

This gives a hint that the null terminator on the empty password is
getting interpreted wrong.  But I'm using encrypted passwords, and this
comment appears in a section that deals with non-encrypted passwords.

One fix I was thinking of could be to detect if the client is win95 and
modify passlen1 accordingly -- precedent would be the space for a null
password sent by wfw also handled in the same area.  This seems extremely
kludgy though, and I have a feeling that something better can be done or
there is something that someone missed in the setting of passlen1/passlen2 
(those conditions that examine passlen1 > 0 and such look pretty 
complicated :) ) and you samba guys know what it is. :)

That was my "fix" for this, which is requried for hetrogenous networks (NT 
and 95 and smbclient) with the "restrict anonymous" parameter I added, is
to massage the values of passlen1 and passlen2 before reading user and
domain out of the packet if they would yield empty strings.  This makes
browsing work for win95 machines even when my "restrict anonymous" is 
enabled, but obviously this is not an ideal fix.  

+ if (!passlen1 && !passlen2 && p[0] == 0 && p[1] == 0) {
+   DEBUG(3, ("passlen1 broken behaviour, could be win95, fixing\n"));
+   passlen1 = 1;
+ }
  p += passlen1 + passlen2;
  fstrcpy(user,p); p = skip_string(p,1);
  domain = p;

This is necessary for "restrict anonymous" because I'm interpreting 
"no username, no password, and no domain" to be an anonymous connection 
over an already validated connection. Because domain gets the wrong value, 
my code thinks the connection is anonymous and win95 clients can't browse.

Is it acceptable to massage the value of passlen1 if restrict anonymous
is true and leave it alone otherwise?  If so, this restrict anonymous
patch is ready for evaluation by the powers that be and possible inclusion,
and I can provide a diff.

The other side of the coin is that Microsoft fixed this is a patch to win95.
If so, does anyone know which patch that was?  I see samba mentioned a few
times on MS's patch list, but nothing concerning stuff like this.

See http://samba.anu.edu.au/listproc/samba-ntdom/2368.html for
Luke's description of of how restrict anonymous should work.

Andy.
thwartedefforts at wonky.org

PS.
How MS is able to get anything to work with this kind of inconsistant 
client operation.  This makes the work the samba team does that much more
impressive.  Woo woo!





More information about the samba-technical mailing list