Patch to allow DNS to override WINS

Peter Polkinghorne Peter.Polkinghorne at brunel.ac.uk
Thu Mar 9 11:26:33 GMT 2000


Version Info: Samba 2.0.6 on Solaris 2.5.1 & 7, built with Sun C 5.0.

Rationale: For us (and this is NOT true everywhere) every Samba server has
Netbios names that are equivalent to DNS names.  With DNS we have central
control of the name space.  It is orderly and with DHCP dynamic enough for
clients.  With WINS we have to defend our names, and alas with Samba have
no WINS replication.  We have 4 sites and the failure of WINS means major
loss of service for NT clients.

So I have devised a patch that gives the DNS namespace priority over the WINS
name space.  So any Netbios name with <0> or <20> type, is checked when
registered, re-registered or multihomed registered against DNS.

If not in DNS - allow, we do not care if people wish to give silly names to
their machines.

If in DNS and the registering IP address matches DNS - allow,
Else reject.

The multihomed check only ensures that there is 1 common address between
WINS and DNS, but I feel that is adequate.

The DNS check is done synchronously, which is a potential slow down, but
registration is relatively infrequent (certainly on the tests I have done).
Our main campus WINS server has 1,700 #00 registrations and works fine.

This effect is controlled by the configuration parameter: dns wins
a boolean which defaults to False to give the normal behaviour.


This has proved a big win for us, since it means we have multiple WINS servers
(one per campus) and use DNS replication to give resilience and consistency.

I hope it proves useful for someone else.

Here are the patches (to param/loadparm.c and ):

*** param/loadparm.c.orig       Thu Nov 11 02:36:05 1999
--- param/loadparm.c    Thu Mar  9 11:21:42 2000
***************
*** 208,213 ****
--- 208,214 ----
    BOOL sslCompatibility;
  #endif /* WITH_SSL */
    BOOL bDNSproxy;
+   BOOL bDNSwins;
    BOOL bWINSsupport;
    BOOL bWINSproxy;
    BOOL bLocalMaster;
***************
*** 758,763 ****
--- 759,765 ----
  
    {"WINS Options", P_SEP, P_SEPARATOR},
    {"dns proxy",        P_BOOL,    P_GLOBAL, &Globals.bDNSproxy,         
NULL,   NULL,  0},
+   {"dns wins",         P_BOOL,    P_GLOBAL, &Globals.bDNSwins,          
NULL,   NULL,  0},
    {"wins proxy",       P_BOOL,    P_GLOBAL, &Globals.bWINSproxy,        
NULL,   NULL,  0},
    {"wins server",      P_STRING,  P_GLOBAL, &Globals.szWINSserver,      
NULL,   NULL,  FLAG_BASIC},
    {"wins support",     P_BOOL,    P_GLOBAL, &Globals.bWINSsupport,      
NULL,   NULL,  FLAG_BASIC},
***************
*** 1002,1007 ****
--- 1004,1010 ----
    Globals.bWINSproxy = False;
  
    Globals.bDNSproxy = True;
+   Globals.bDNSwins = False;
  
    /*
     * smbd will check at runtime to see if this value
***************
*** 1234,1239 ****
--- 1237,1243 ----
  #endif        /* WITH_SSL */
  
  FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
+ FN_GLOBAL_BOOL(lp_dns_wins,&Globals.bDNSwins)
  FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
  FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
  FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
*** nmbd/nmbd_winsserver.c.orig Thu Nov 11 02:36:04 1999
--- nmbd/nmbd_winsserver.c      Tue Feb 22 14:47:29 2000
***************
*** 167,172 ****
--- 167,210 ----
  }
  
  /****************************************************************************
+ Utility function to see if name and IP address consistent with DNS
+  - Peter Polkinghorne, Brunel University Feb 2000 - dns wins support
+ *****************************************************************************
/
+ 
+ static BOOL check_name_ip_DNS(const char *name, struct in_addr ip)
+ {
+   struct hostent * hp;
+   struct in_addr tp;
+   char **p;
+ 
+   DEBUG(3,("check_name_ip_DNS: name %s IP %s - ", name, inet_ntoa(ip)));
+ 
+ /* do look up - potential slow down - as know DNS go to sys_gethostbyname
+   to avoid treble lookup with multicase */
+   hp = sys_gethostbyname( name );
+ 
+ /* now see if address there, ip is in set returned - otherwise return true */
+ /* NOTE assume hostent returns list of addresses null terminated */
+   if ( hp ) {
+     for ( p=hp->h_addr_list; *p != 0; p++ ) {
+ 
+       putip((char *)&tp, *p);
+       if ( ip_equal( ip, tp ) ) {
+         DEBUG(3,("found match\n"));
+       return True;
+       }
+     }
+ /* no match */
+     DEBUG(3,("miss match\n"));
+     return False;
+ 
+   } else {
+     DEBUG(3,("no DNS record\n"));
+     return True;
+   }
+ }
+ 
+ /****************************************************************************
  Load or create the WINS database.
  *****************************************************************************
/
  
***************
*** 479,484 ****
--- 517,535 ----
     * and return success.
     */
  
+ /* But first see if Unique, right question type and DNS matches IFF dns wins
+    Peter Polkinghorne, Brunel University */
+ 
+   if( lp_dns_wins() && !group &&
+       (question->name_type == 0x0 || question->name_type == 0x20 ) &&
+       ! check_name_ip_DNS(question->name,from_ip) )
+   {
+     DEBUG(3,("wins_process_name_refresh_request: Name %s IP %s \
+ does not match DNS.\n", nmb_namestr(question), inet_ntoa(from_ip) ));
+     send_wins_name_registration_response(RFS_ERR, 0, p);
+     return;
+   }
+ 
    if((!group || (group && (question->name_type == 0x1c))) && 
find_ip_in_name_record(namerec, from_ip ))
    {
      /*
***************
*** 688,693 ****
--- 739,758 ----
    DEBUG(3,("wins_process_name_registration_request: %s name registration for 
name %s \
  IP %s\n", registering_group_name ? "Group" : "Unique", 
nmb_namestr(question), inet_ntoa(from_ip) ));
  
+ /* But first see if Unique, right question type and DNS matches IFF dns wins
+    Note may not be optimal time - could we exploit DNS recs in WINS already?
+    Peter Polkinghorne, Brunel University */
+ 
+   if( lp_dns_wins() && !registering_group_name &&
+       (question->name_type == 0x0 || question->name_type == 0x20 ) &&
+       ! check_name_ip_DNS(question->name,from_ip) )
+   {
+     DEBUG(3,("wins_process_name_request: Name %s IP %s \
+ does not match DNS.\n", nmb_namestr(question), inet_ntoa(from_ip) ));
+     send_wins_name_registration_response(RFS_ERR, 0, p);
+     return;
+   }
+ 
    /*
     * See if the name already exists.
     */
***************
*** 1044,1049 ****
--- 1109,1132 ----
      send_wins_name_registration_response(0, ttl, p);  
      return;
    }
+ 
+ /* But first see if right question type and DNS matches IFF dns wins
+    Note may not be optimal time - could we exploit DNS recs in WINS already?
+    For multihomed request we just require originating IP match DNS
+    name -> IP mapping - do not check if all registered addresses match.
+    This is probably OK as may not wish to register ALL interfaces - could
+    in v. odd circumstances cause problems?
+    Peter Polkinghorne, Brunel University */
+ 
+   if( lp_dns_wins() && 
+       (question->name_type == 0x0 || question->name_type == 0x20 ) &&
+       ! check_name_ip_DNS(question->name,from_ip) )
+   {
+     DEBUG(3,("wins_process_multihomed_name_registration_request: Name %s IP 
%s \
+ does not match DNS.\n", nmb_namestr(question), inet_ntoa(from_ip) ));
+     send_wins_name_registration_response(RFS_ERR, 0, p);
+     return;
+   }
  
    /*
     * See if the name already exists.

-- 
-----------------------------------------------------------------------------
| Peter Polkinghorne, Computer Centre, Brunel University, Uxbridge, UB8 3PH,|
| Peter.Polkinghorne at brunel.ac.uk   +44 1895 274000 x2561       UK          |
-----------------------------------------------------------------------------




More information about the samba-technical mailing list