Fixed bug that John found in WINS server code. When nmbd as a WINS
authorJeremy Allison <jra@samba.org>
Mon, 20 Apr 1998 20:32:50 +0000 (20:32 +0000)
committerJeremy Allison <jra@samba.org>
Mon, 20 Apr 1998 20:32:50 +0000 (20:32 +0000)
server is sending out a name_query after a WACK, it needs to send
a packet with recursion_desired = 0 (yes Luke, you were right all
along :-). If it doesn't then if it's talking to itself then the
query packet ends up back in the WINS server instead of in the client
side code.
Makefile: Changed proto generation to stop including NMBDOBJ twice.
nmbd_namequery.c nmbd_packets.c nmbd_winsserver.c: Added extra
query_name_from_wins_server() code.

Jeremy.

source/include/proto.h
source/nmbd/nmbd_namequery.c
source/nmbd/nmbd_packets.c
source/nmbd/nmbd_winsserver.c

index 3afc150649420ad6d12e5604b32e8f5a3ce3d79d..539ddc2ae581fc7dd6a2b54004dc850d10a48e58 100644 (file)
@@ -1276,6 +1276,11 @@ BOOL query_name(struct subnet_record *subrec, char *name, int type,
                    query_name_success_function success_fn,
                    query_name_fail_function fail_fn, 
                    struct userdata_struct *userdata);
+BOOL query_name_from_wins_server(struct in_addr ip_to, 
+                   char *name, int type,
+                   query_name_success_function success_fn,
+                   query_name_fail_function fail_fn, 
+                   struct userdata_struct *userdata);
 
 /*The following definitions come from  nmbd_nameregister.c  */
 
@@ -1347,6 +1352,13 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
                           query_name_fail_function fail_fn,
                           struct userdata_struct *userdata,
                           struct nmb_name *nmbname);
+struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
+                          response_function resp_fn,
+                          timeout_response_function timeout_fn,
+                          query_name_success_function success_fn,
+                          query_name_fail_function fail_fn,
+                          struct userdata_struct *userdata,
+                          struct nmb_name *nmbname);
 struct response_record *queue_node_status( struct subnet_record *subrec,
                           response_function resp_fn,
                           timeout_response_function timeout_fn,
index 51f18edd0535df34d1596b63d58a16dbf1952261..1794efe890b5855b07383394095b309fd77cbc24 100644 (file)
@@ -232,3 +232,32 @@ BOOL query_name(struct subnet_record *subrec, char *name, int type,
   }
   return False;
 }
+
+/****************************************************************************
+ Try and query for a name from nmbd acting as a WINS server.
+****************************************************************************/
+
+BOOL query_name_from_wins_server(struct in_addr ip_to, 
+                   char *name, int type,
+                   query_name_success_function success_fn,
+                   query_name_fail_function fail_fn, 
+                   struct userdata_struct *userdata)
+{
+  struct nmb_name nmbname;
+
+  make_nmb_name(&nmbname, name, type, scope);
+
+  if(queue_query_name_from_wins_server( ip_to,
+        query_name_response,
+        query_name_timeout_response,
+        success_fn,
+        fail_fn,
+        userdata,
+        &nmbname) == NULL)
+  {
+    DEBUG(0,("query_name_from_wins_server: Failed to send packet trying to query name %s\n",
+          namestr(&nmbname)));
+    return True;
+  }
+  return False;
+}
index 19c61a877a11c6dc553172d3438370bc4268bb79..54f4f3a2cbced075352e052aaf8ad0c01d1f095a 100644 (file)
@@ -281,6 +281,28 @@ static BOOL initiate_name_query_packet( struct packet_struct *packet)
   return send_netbios_packet( packet );
 }
 
+/***************************************************************************
+ Sends out a name query - from a WINS server. 
+**************************************************************************/
+
+static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
+{   
+  struct nmb_packet *nmb = NULL;
+  
+  nmb = &packet->packet.nmb;
+
+  nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
+  nmb->header.arcount = 0;
+    
+  nmb->header.nm_flags.recursion_desired = False;
+  
+  DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
+           namestr(&nmb->question.question_name),
+           BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+    
+  return send_netbios_packet( packet );
+} 
+
 /***************************************************************************
  Sends out a name register.
 **************************************************************************/
@@ -679,6 +701,48 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
   return rrec;
 }
 
+/****************************************************************************
+ Queue a query name packet to a given address from the WINS subnet.
+****************************************************************************/
+struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
+                          response_function resp_fn,
+                          timeout_response_function timeout_fn,
+                          query_name_success_function success_fn,
+                          query_name_fail_function fail_fn,
+                          struct userdata_struct *userdata,
+                          struct nmb_name *nmbname)
+{
+  struct packet_struct *p;
+  struct response_record *rrec;
+  BOOL bcast = False;
+
+  if(( p = create_and_init_netbios_packet(nmbname, bcast, to_ip)) == NULL)
+    return NULL;
+
+  if(initiate_name_query_packet_from_wins_server( p ) == False)
+  {
+    p->locked = False;
+    free_packet(p);
+    return NULL;
+  }
+
+  if((rrec = make_response_record(wins_server_subnet,           /* subnet record. */
+               p,                     /* packet we sent. */
+               resp_fn,               /* function to call on response. */
+               timeout_fn,            /* function to call on timeout. */
+               (success_function)success_fn,            /* function to call on operation success. */
+               (fail_function)fail_fn,               /* function to call on operation fail. */
+               userdata)) == NULL)
+  {
+    p->locked = False;
+    free_packet(p);
+    return NULL;
+  }
+
+  return rrec;
+}
+
 /****************************************************************************
  Queue a node status packet to a given name and address.
 ****************************************************************************/
index afc8741366f761ae83a4acff4c98d2620b52cbfc..d089686917a0b9a25e706aa1514a3f3ca471ed13 100644 (file)
@@ -808,20 +808,17 @@ is one of our (WINS server) names. Denying registration.\n", namestr(question) )
     memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
 
     /*
-     * As query_name uses the subnet broadcast address as the destination
-     * of the packet we temporarily change the subnet broadcast address to
-     * be the first IP address of the name owner and send the packet. This
-     * is a *horrible* hack but the alternative is to add the destination
-     * address parameter to all query_name() calls. I hate this code :-).
+     * Use the new call to send a query directly to an IP address.
+     * This sends the query directly to the IP address, and ensures
+     * the recursion desired flag is not set (you were right Luke :-).
+     * This function should *only* be called from the WINS server
+     * code. JRA.
      */
 
-    subrec->bcast_ip = *namerec->ip;
-
-    query_name( subrec, question->name, question->name_type, 
+    query_name_from_wins_server( *namerec->ip, question->name, question->name_type, 
                 wins_register_query_success,
                 wins_register_query_fail,
                 userdata);
-    subrec->bcast_ip = ipzero;
     return;
   }