ntvfs: Remove unused and untested SMB1 -> SMB2 proxy module
[bbaumbach/samba-autobuild/.git] / source4 / nbt_server / query.c
index 28406081eaf8ec4c5ca93c28f1d3e810fc699298..8cf387c2dcd040b13193aacbcecbc4f5d504d663 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
-#include "dlinklist.h"
+#include "../lib/util/dlinklist.h"
 #include "system/network.h"
 #include "nbt_server/nbt_server.h"
-
-/*
-  send a name query reply
-*/
-static void nbtd_name_query_reply(struct nbt_name_socket *nbtsock, 
-                                 struct nbt_name_packet *request_packet, 
-                                 const char *src_address, int src_port,
-                                 struct nbt_name *name, uint32_t ttl,
-                                 uint16_t nb_flags, const char **addresses)
-{
-       struct nbt_name_packet *packet;
-       size_t num_addresses = str_list_length(addresses);
-       int i;
-
-       if (num_addresses == 0) {
-               DEBUG(3,("No addresses in name query reply - failing\n"));
-               return;
-       }
-
-       packet = talloc_zero(nbtsock, struct nbt_name_packet);
-       if (packet == NULL) return;
-
-       packet->name_trn_id = request_packet->name_trn_id;
-       packet->ancount = 1;
-       packet->operation = 
-               NBT_FLAG_REPLY | 
-               NBT_OPCODE_QUERY | 
-               NBT_FLAG_AUTHORITIVE |
-               NBT_FLAG_RECURSION_DESIRED |
-               NBT_FLAG_RECURSION_AVAIL;
-
-       packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
-       if (packet->answers == NULL) goto failed;
-
-       packet->answers[0].name     = *name;
-       packet->answers[0].rr_type  = NBT_QTYPE_NETBIOS;
-       packet->answers[0].rr_class = NBT_QCLASS_IP;
-       packet->answers[0].ttl      = ttl;
-       packet->answers[0].rdata.netbios.length = num_addresses*6;
-       packet->answers[0].rdata.netbios.addresses = 
-               talloc_array(packet->answers, struct nbt_rdata_address, num_addresses);
-       if (packet->answers[0].rdata.netbios.addresses == NULL) goto failed;
-
-       for (i=0;i<num_addresses;i++) {
-               struct nbt_rdata_address *addr = 
-                       &packet->answers[0].rdata.netbios.addresses[i];
-               addr->nb_flags = nb_flags;
-               addr->ipaddr = talloc_strdup(packet->answers, addresses[i]);
-               if (addr->ipaddr == NULL) goto failed;
-       }
-
-       DEBUG(7,("Sending name query reply for %s<%02x> at %s to %s:%d\n", 
-                name->name, name->type, src_address, addresses[0], src_port));
-       
-       nbt_name_reply_send(nbtsock, src_address, src_port, packet);
-
-failed:
-       talloc_free(packet);
-}
-
+#include "nbt_server/wins/winsserver.h"
+#include "smbd/service_task.h"
+#include "librpc/gen_ndr/ndr_nbt.h"
+#include "lib/socket/socket.h"
+#include "param/param.h"
 
 /*
   answer a name query
 */
 void nbtd_request_query(struct nbt_name_socket *nbtsock, 
                        struct nbt_name_packet *packet, 
-                       const char *src_address, int src_port)
+                       struct socket_address *src)
 {
        struct nbtd_iface_name *iname;
        struct nbt_name *name;
-       struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private
+       struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
                                                       struct nbtd_interface);
 
        /* see if its a node status query */
        if (packet->qdcount == 1 &&
            packet->questions[0].question_type == NBT_QTYPE_STATUS) {
-               nbtd_query_status(nbtsock, packet, src_address, src_port);
+               nbtd_query_status(nbtsock, packet, src);
                return;
        }
 
-       NBT_ASSERT_PACKET(packet, src_address, packet->qdcount == 1);
-       NBT_ASSERT_PACKET(packet, src_address, packet->questions[0].question_type == NBT_QTYPE_NETBIOS);
-       NBT_ASSERT_PACKET(packet, src_address, packet->questions[0].question_class == NBT_QCLASS_IP);
+       NBTD_ASSERT_PACKET(packet, src, packet->qdcount == 1);
+       NBTD_ASSERT_PACKET(packet, src, 
+                          packet->questions[0].question_type == NBT_QTYPE_NETBIOS);
+       NBTD_ASSERT_PACKET(packet, src, 
+                          packet->questions[0].question_class == NBT_QCLASS_IP);
 
        /* see if we have the requested name on this interface */
        name = &packet->questions[0].name;
 
        iname = nbtd_find_iname(iface, name, 0);
        if (iname == NULL) {
-               DEBUG(7,("Query for %s<%02x> from %s - not found on %s\n",
-                        name->name, name->type, src_address, iface->ip_address));
+               /* don't send negative replies to broadcast queries */
+               if (packet->operation & NBT_FLAG_BROADCAST) {
+                       return;
+               }
+
+               if (packet->operation & NBT_FLAG_RECURSION_DESIRED) {
+                       nbtd_winsserver_request(nbtsock, packet, src);
+                       return;
+               }
+
+               /* otherwise send a negative reply */
+               nbtd_negative_name_query_reply(nbtsock, packet, src);
+               return;
+       }
+
+       /*
+        * normally we should forward all queries with the
+        * recursion desired flag to the wins server, but this
+        * breaks are winsclient code, when doing mhomed registrations
+        */
+       if (!(packet->operation & NBT_FLAG_BROADCAST) &&
+          (packet->operation & NBT_FLAG_RECURSION_DESIRED) &&
+          (iname->nb_flags & NBT_NM_GROUP) &&
+          lpcfg_we_are_a_wins_server(iface->nbtsrv->task->lp_ctx)) {
+               nbtd_winsserver_request(nbtsock, packet, src);
                return;
        }
 
@@ -122,12 +91,12 @@ void nbtd_request_query(struct nbt_name_socket *nbtsock,
           ignore it for now */
        if (!(iname->nb_flags & NBT_NM_ACTIVE) && 
            (packet->operation & NBT_FLAG_BROADCAST)) {
-               DEBUG(7,("Query for %s<%02x> from %s - name not active yet on %s\n",
-                        name->name, name->type, src_address, iface->ip_address));
+               DEBUG(7,("Query for %s from %s - name not active yet on %s\n",
+                        nbt_name_string(packet, name), src->addr, iface->ip_address));
                return;
        }
 
-       nbtd_name_query_reply(nbtsock, packet, src_address, src_port,
+       nbtd_name_query_reply(nbtsock, packet, src,
                              &iname->name, iname->ttl, iname->nb_flags, 
                              nbtd_address_list(iface, packet));
 }