nmbd incompatibility with NT 4.0 WINS w/ 1C records

Bert Driehuis driehuis at playbeing.org
Wed Feb 11 17:47:56 GMT 2004


In $orkplace, we're using Samba 2.2.8 on FreeBSD to service WINS on a
bunch of sites. We've noticed some corner cases where nmbd isn't quite
compatible with NT 4.0, when dealing with 1C group records.

When Googling for answers, I did not spot any previous occurances, but
feel free to tell me to redo my homework if you feel I should.

Executive summary: in the face of network unreliability, nmbd may refuse
to add a BDC to the 0x1c record for the domain, where NT WINS works as
expected. I propose a patch to rectify this situation.

The situation that exposes the problem is a bit weird. At one of our
sites, we have an older 100 mbit switch that insists on doing a Spanning
Tree Discovery every time an NT server boots up. As a result, the BDC
fails to register it's 0x1c record for the domain it services and Bad
Things result from that. What we see on a network sniff when the BDC is
hooked up to a dumb hub and it reboots:

Shutdown selected from menu
	bdc->winssvr	Unicast WINS DeRegister FOO-BAR 1C
<reboot occurs>
	bdc->winssvr	Unicast WINS Register FOO-BAR 1CD

and everything is hunky-dory. When we hook the BDC to the switch, it
looks like this:

Shutdown selected from menu
	bdc->winssvr	Unicast WINS DeRegister FOO-BAR 1C
<reboot occurs>
	bdc->winssvr	<WINS Register gets eaten by switch>
<time passes>
	bdc->netcast	Netcast WINS Register FOO-BAR 1C
<more time passes>
	bdc->winssvr	Unicast WINS Refresh FOO-BAR 1C

The final refresh is acknowledged by nmbd, but nmbd takes no actual
action, and the IP address is not added to the 0x1c record. It is
arguably wrong to do a Refresh when the Register didn't succeeed, but
that is the way the NT BDC handles it. When we replace winssvr with an
actual Windows NT WINS server, the same sequence of events results in a
successful registration.

Looking at wins_process_name_refresh_request in nmbd_winsserver.c, I
notice that a Refresh for a non-existent record gets treated as a
Register. I'm wondering why a Refresh for an existing 0x1c record, that
the requestor is not yet a member of, isn't treated like a Register as
well.

The attached diff fixes the symptoms I'm seeing. It is relative to
2.2.8a, but 3.0.2 does not seem to be functionally different. The
attached diff is written to make minimal changes to the code and best
illustrate the solution I think is correct (or at least, bug-compatible
with NT).

It could more readably be rewritten like this:

		/* warning: untested fix */
  if(!group || (group && (question->name_type == 0x1c)))
  {
    /*
     * Add from_ip to the record if required
     */
    if (group && !find_ip_in_name_record(namerec, from_ip ))
      add_ip_to_name_record(namerec, from_ip);
    /*
     * Update the ttl.
     */
    update_name_ttl(namerec, ttl);
    send_wins_name_registration_response(0, ttl, p);
    wins_hook("refresh", namerec, ttl);
    return;
  }

but I'm not sufficiently versed in this code to be able to promise that
this covers all the corner cases.

Cheers,

				-- Bert

-- 
Bert Driehuis -- driehuis at playbeing.org -- +31-20-3116119
If the only tool you've got is an axe, every problem looks like fun!
-------------- next part --------------
*** nmbd_winsserver.c	Fri Mar 14 22:34:48 2003
--- /var/tmp/nmbd_winsserver.c	Thu Feb  5 19:14:20 2004
***************
*** 479,482 ****
--- 479,489 ----
      send_wins_name_registration_response(0, ttl, p);
      wins_hook("refresh", namerec, ttl);
+     return;
+   }
+   else if((group && (question->name_type == 0x1c)))
+   {
+     DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \
+ the IP is not yet associated with the name. Treating as registration.\n", nmb_namestr(question) ));
+     wins_process_name_registration_request(subrec,p);
      return;
    }


More information about the samba-technical mailing list