updated the 3.0 branch from the head branch - ready for alpha18
[kai/samba.git] / source3 / nmbd / nmbd_incomingrequests.c
index 3f2b92107455fb7f11cb17ceed396c350e1b00c7..834f237a2c24ae991be569a5866526ddca99008a 100644 (file)
@@ -449,175 +449,151 @@ For broadcast name queries:
 
 void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p)
 {
-  struct nmb_packet *nmb = &p->packet.nmb;
-  struct nmb_name *question = &nmb->question.question_name;
-  int name_type = question->name_type;
-  BOOL bcast = nmb->header.nm_flags.bcast;
-  int ttl=0;
-  int rcode = 0;
-  char *prdata = NULL;
-  char rdata[6];
-  BOOL success = False;
-  struct name_record *namerec = NULL;
-  int reply_data_len = 0;
-  int i;
-  DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n", 
-            inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question)));
+       struct nmb_packet *nmb = &p->packet.nmb;
+       struct nmb_name *question = &nmb->question.question_name;
+       int name_type = question->name_type;
+       BOOL bcast = nmb->header.nm_flags.bcast;
+       int ttl=0;
+       int rcode = 0;
+       char *prdata = NULL;
+       char rdata[6];
+       BOOL success = False;
+       struct name_record *namerec = NULL;
+       int reply_data_len = 0;
+       int i;
+       
+       DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n", 
+                inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question)));
   
-  /* Look up the name in the cache - if the request is a broadcast request that
-     came from a subnet we don't know about then search all the broadcast subnets
-     for a match (as we don't know what interface the request came in on). */
-
-  if(subrec == remote_broadcast_subnet)
-    namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
-  else
-    namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
-
-  /* Check if it is a name that expired */
-  if( namerec
-   && ( (namerec->data.death_time != PERMANENT_TTL)
-     && (namerec->data.death_time < p->timestamp) ) )
-  {
-    DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name)));
-    namerec = NULL;
-  }
-
-  if (namerec)
-  {
-
-    /* 
-     * Always respond to unicast queries.
-     * Don't respond to broadcast queries unless the query is for
-     * a name we own, a Primary Domain Controller name, or a WINS_PROXY 
-     * name with type 0 or 0x20. WINS_PROXY names are only ever added
-     * into the namelist if we were configured as a WINS proxy.
-     */
-
-    if( !bcast
-     || ( bcast
-       && ( (name_type == 0x1b)
-         || (namerec->data.source == SELF_NAME)
-         || (namerec->data.source == PERMANENT_NAME)
-         || ( (namerec->data.source == WINS_PROXY_NAME)
-           && ( (name_type == 0) || (name_type == 0x20) ) 
-            )
-          )
-        )
-      )
-    {
-      
-      /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY, 
-         or it's a Domain Master type. */
-
-      /*
-       * If this is a WINS_PROXY_NAME, then ceck that none of the IP 
-       * addresses we are returning is on the same broadcast subnet 
-       * as the requesting packet. If it is then don't reply as the 
-       * actual machine will be replying also and we don't want two 
-       * replies to a broadcast query.
-       */
-
-      if( namerec->data.source == WINS_PROXY_NAME )
-      {
-        for( i = 0; i < namerec->data.num_ips; i++)
-        {
-          if(same_net( namerec->data.ip[i], subrec->myip, subrec->mask_ip ))    
-          {
-            DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also \
-on the same subnet (%s) as the requestor. Not replying.\n", 
-                   nmb_namestr(&namerec->name), subrec->subnet_name ));
-            return;
-          }
-        }   
-      }     
-
-      ttl = (namerec->data.death_time != PERMANENT_TTL) ?
-                     namerec->data.death_time - p->timestamp : lp_max_ttl();
-
-      /* Copy all known ip addresses into the return data. */
-      /* Optimise for the common case of one IP address so 
-         we don't need a malloc. */
-
-      if( namerec->data.num_ips == 1 )
-        prdata = rdata;
-      else
-      {
-        if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
-        {
-          DEBUG(0,("process_name_query_request: malloc fail !\n"));
-          return;
-        }
-      }
-
-      for( i = 0; i < namerec->data.num_ips; i++ )
-      {
-        set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
-        putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
-      }
-
-      sort_query_replies(prdata, i, p->ip);
-      
-      reply_data_len = namerec->data.num_ips * 6;
-      success = True;
-    }
-  }
-
-  /*
-   * If a machine is broadcasting a name lookup request and we have lp_wins_proxy()
-   * set we should initiate a WINS query here. On success we add the resolved name 
-   * into our namelist with a type of WINS_PROXY_NAME and then reply to the query.
-   */
-
-  if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() && 
-     bcast && (subrec != remote_broadcast_subnet))
-  {
-    make_wins_proxy_name_query_request( subrec, p, question );
-    return;
-  }
-
-  if (!success && bcast)
-  {
-    if(prdata != rdata)
-      SAFE_FREE(prdata);
-    return; /* Never reply with a negative response to broadcasts. */
-  }
-
-  /* 
-   * Final check. From observation, if a unicast packet is sent
-   * to a non-WINS server with the recursion desired bit set
-   * then never send a negative response.
-   */
-
-  if(!success && !bcast && nmb->header.nm_flags.recursion_desired)
-  {
-    if(prdata != rdata)
-      SAFE_FREE(prdata);
-    return;
-  }
-
-  if (success)
-  {
-      rcode = 0;
-      DEBUG(3,("OK\n"));
-  }
-  else
-  {
-      rcode = NAM_ERR;
-      DEBUG(3,("UNKNOWN\n"));      
-  }
-
-  /* See rfc1002.txt 4.2.13. */
-
-  reply_netbios_packet(p,                              /* Packet to reply to. */
-                       rcode,                          /* Result code. */
-                       NMB_QUERY,                      /* nmbd type code. */
-                       NMB_NAME_QUERY_OPCODE,          /* opcode. */
-                       ttl,                            /* ttl. */
-                       prdata,                         /* data to send. */
-                       reply_data_len);                /* data length. */
-
-  if(prdata != rdata)
-    SAFE_FREE(prdata);
+       /* Look up the name in the cache - if the request is a broadcast request that
+          came from a subnet we don't know about then search all the broadcast subnets
+          for a match (as we don't know what interface the request came in on). */
+
+       if(subrec == remote_broadcast_subnet)
+               namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
+       else
+               namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+
+       /* Check if it is a name that expired */
+       if (namerec && 
+           ((namerec->data.death_time != PERMANENT_TTL) && 
+            (namerec->data.death_time < p->timestamp))) {
+               DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name)));
+               namerec = NULL;
+       }
+
+       if (namerec) {
+               /* 
+                * Always respond to unicast queries.
+                * Don't respond to broadcast queries unless the query is for
+                * a name we own, a Primary Domain Controller name, or a WINS_PROXY 
+                * name with type 0 or 0x20. WINS_PROXY names are only ever added
+                * into the namelist if we were configured as a WINS proxy.
+                */
+               
+               if (!bcast || 
+                   (bcast && ((name_type == 0x1b) ||
+                              (namerec->data.source == SELF_NAME) ||
+                              (namerec->data.source == PERMANENT_NAME) ||
+                              ((namerec->data.source == WINS_PROXY_NAME) &&
+                               ((name_type == 0) || (name_type == 0x20)))))) {
+                       /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY, 
+                          or it's a Domain Master type. */
+
+                       /*
+                        * If this is a WINS_PROXY_NAME, then ceck that none of the IP 
+                        * addresses we are returning is on the same broadcast subnet 
+                        * as the requesting packet. If it is then don't reply as the 
+                        * actual machine will be replying also and we don't want two 
+                        * replies to a broadcast query.
+                        */
+                       
+                       if (namerec->data.source == WINS_PROXY_NAME) {
+                               for( i = 0; i < namerec->data.num_ips; i++) {
+                                       if (same_net(namerec->data.ip[i], subrec->myip, subrec->mask_ip)) {
+                                               DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also on the same subnet (%s) as the requestor. Not replying.\n", 
+                                                        nmb_namestr(&namerec->name), subrec->subnet_name ));
+                                               return;
+                                       }
+                               }
+                       }
+
+                       ttl = (namerec->data.death_time != PERMANENT_TTL) ?
+                               namerec->data.death_time - p->timestamp : lp_max_ttl();
+
+                       /* Copy all known ip addresses into the return data. */
+                       /* Optimise for the common case of one IP address so 
+                          we don't need a malloc. */
+
+                       if (namerec->data.num_ips == 1) {
+                               prdata = rdata;
+                       } else {
+                               if ((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL) {
+                                       DEBUG(0,("process_name_query_request: malloc fail !\n"));
+                                       return;
+                               }
+                       }
+
+                       for (i = 0; i < namerec->data.num_ips; i++) {
+                               set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
+                               putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
+                       }
+
+                       sort_query_replies(prdata, i, p->ip);
+                       
+                       reply_data_len = namerec->data.num_ips * 6;
+                       success = True;
+               }
+       }
+
+       /*
+        * If a machine is broadcasting a name lookup request and we have lp_wins_proxy()
+        * set we should initiate a WINS query here. On success we add the resolved name 
+        * into our namelist with a type of WINS_PROXY_NAME and then reply to the query.
+        */
+       
+       if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() && 
+          bcast && (subrec != remote_broadcast_subnet)) {
+               make_wins_proxy_name_query_request( subrec, p, question );
+               return;
+       }
+
+       if (!success && bcast) {
+               if(prdata != rdata)
+                       SAFE_FREE(prdata);
+               return; /* Never reply with a negative response to broadcasts. */
+       }
+
+       /* 
+        * Final check. From observation, if a unicast packet is sent
+        * to a non-WINS server with the recursion desired bit set
+        * then never send a negative response.
+        */
+       
+       if(!success && !bcast && nmb->header.nm_flags.recursion_desired) {
+               if(prdata != rdata)
+                       SAFE_FREE(prdata);
+               return;
+       }
+
+       if (success) {
+               rcode = 0;
+               DEBUG(3,("OK\n"));
+       } else {
+               rcode = NAM_ERR;
+               DEBUG(3,("UNKNOWN\n"));      
+       }
+
+       /* See rfc1002.txt 4.2.13. */
+
+       reply_netbios_packet(p,                              /* Packet to reply to. */
+                            rcode,                          /* Result code. */
+                            NMB_QUERY,                      /* nmbd type code. */
+                            NMB_NAME_QUERY_OPCODE,          /* opcode. */
+                            ttl,                            /* ttl. */
+                            prdata,                         /* data to send. */
+                            reply_data_len);                /* data length. */
+       
+       if(prdata != rdata)
+               SAFE_FREE(prdata);
 }