added code that checks whether the DOMAIN<1b> name is claimed on the
authorSamba Release Account <samba-bugs@samba.org>
Wed, 12 Mar 1997 20:21:11 +0000 (20:21 +0000)
committerSamba Release Account <samba-bugs@samba.org>
Wed, 12 Mar 1997 20:21:11 +0000 (20:21 +0000)
local subnet _before_ going and registering it.  the reason for this
is that i don't want to cause chaos by registering the name twice.

it's ok to register DOMAIN<1b> with the WINS server, because the WINS
server's job is to check a) _if_ there's a current owner of the name
b) if the current owner exists c) if the current owner still wants the
name.  if they don't, the WINS server responds by saying, 'yes, you can
have it'.

lkcl

source/include/nameserv.h
source/nameresp.c
source/nameserv.c

index 75461ce5e60a363a3df8392473b296805a15ef70..027931f9e632aab9db8a77b6d834a51fbf58e40d 100644 (file)
@@ -123,7 +123,8 @@ enum state_type
        NAME_QUERY_DOM_SRV_CHK,
        NAME_QUERY_SRV_CHK,
        NAME_QUERY_FIND_MST,
-       NAME_QUERY_MST_CHK
+       NAME_QUERY_MST_CHK,
+       NAME_QUERY_DOMAIN,
 };
 
 /* a netbios name structure */
index 949bb366bb94287124ed059d4244f919ab8c13f0..77addc298529970ac253cc8dbca8603b65f75aad 100644 (file)
@@ -160,6 +160,34 @@ static void dead_netbios_entry(struct subnet_record *d,
          break;
        }
 
+       case NAME_QUERY_DOMAIN:
+       {
+         /* if no response received, there is no domain controller on
+         this local subnet.  it's ok for us to register
+       */
+
+         if (!n->bcast)
+         {
+                DEBUG(0,("NAME_QUERY_DOMAIN incorrectly used - contact samba-bugs!\n"));
+         /* XXXX whoops. someone's using this to unicast a packet.  this state
+            should only be used for broadcast checks
+          */
+         break;
+         }
+         if (n->num_msgs == 0)
+         {
+           if (ismyip(n->send_ip))
+           {
+          struct work_record *work = find_workgroupstruct(d,n->name.name,False);
+          if (work && d)
+          {
+                   become_domain_master(d,work);
+          }
+        }
+         }
+         break;
+       }
+
        default:
        {
          /* nothing to do but delete the dead expected-response structure */
index 7f1c0fadeeddbb2afedca5e0d56d7307d15b28f8..77c3906242205bc3ce96dfcadfbd7d3fe6bee761 100644 (file)
@@ -80,14 +80,18 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
      don't really own */  
   remove_netbios_name(d,name,type,SELF,n2->ip_flgs[0].ip);
 
-  if (ip_equal(d->bcast_ip, ipgrp)) {
-    if (!lp_wins_support()) {
+  if (ip_equal(d->bcast_ip, ipgrp))
+  {
+    if (!lp_wins_support())
+    {
       /* not a WINS server: we have to release them on the network */
       queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
                             name, type, 0, 0,0,NULL,NULL,
                             False, True, ipzero, ipzero);
     }
-  } else {
+  }
+  else
+  {
     /* local interface: release them on the network */
     queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
                         name, type, 0, 0,0,NULL,NULL,
@@ -181,19 +185,47 @@ void add_domain_names(time_t t)
       make_nmb_name(&n,lp_workgroup(),0x1c,scope);
       if (!find_name(d->namelist, &n, FIND_SELF))
       {
+        /* logon servers are group names - we don't expect this to fail. */
         DEBUG(0,("%s attempting to become logon server for %s %s\n",
              timestring(), lp_workgroup(), inet_ntoa(d->bcast_ip)));
         become_logon_server(d, work);
       }
     }
+
     if (lp_domain_master() && work && work->dom_state == DOMAIN_NONE)
     {
       make_nmb_name(&n,lp_workgroup(),0x1b,scope);
       if (!find_name(d->namelist, &n, FIND_SELF))
       {
-        DEBUG(1,("%s attempting to become logon server for %s %s\n",
-             timestring(), lp_workgroup(), inet_ntoa(d->bcast_ip)));
-        become_domain_master(d, work);
+        if (ip_equal(d->bcast_ip,ipgrp))
+        {
+          if (lp_wins_support())
+          {
+            /* use the wins server's capabilities (indirectly).  if
+               someone has already register the domain<1b> name with 
+               the WINS server, then the WINS server's job is to _check_
+               that the owner still wants it, before giving it away.
+             */
+               
+            DEBUG(1,("%s initiating becoming logon server for %s %s\n",
+                       timestring(), lp_workgroup(), inet_ntoa(d->bcast_ip)));
+            become_domain_master(d, work);
+          }
+        }
+        else
+        {
+          /* send out a query to establish whether there's a 
+             domain controller on the local subnet.  if not,
+             we can become a domain controller on that subnet.
+             it's only polite that we check, before claiming the
+             NetBIOS name 0x1b.
+           */
+
+          queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_DOMAIN,
+                               lp_workgroup(), 0x1b,
+                               0, 0,0,NULL,NULL,
+                               True, True, d->bcast_ip, d->bcast_ip);
+        }
       }
     }
   }