s3-vfs: Use ENOATTR in errno comparison for getxattr
[garming/samba-autobuild/.git] / source4 / nbt_server / defense.c
index 2e34aca1ee3d2f521a8164e06fcee849a7e7c770..fbe22aa781bb7568efbc5506bb4553ef726b20a5 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 defense reply
-*/
-static void nbtd_name_defense_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 *address)
-{
-       struct nbt_name_packet *packet;
-
-       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 | 
-               (request_packet->operation & NBT_OPCODE) |
-               NBT_FLAG_AUTHORITIVE |
-               NBT_FLAG_RECURSION_DESIRED |
-               NBT_FLAG_RECURSION_AVAIL |
-               NBT_RCODE_ACT;
-       
-       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 = 6;
-       packet->answers[0].rdata.netbios.addresses = 
-               talloc_array(packet->answers,
-                            struct nbt_rdata_address, 1);
-       if (packet->answers[0].rdata.netbios.addresses == NULL) goto failed;
-       packet->answers[0].rdata.netbios.addresses[0].nb_flags = nb_flags;
-       packet->answers[0].rdata.netbios.addresses[0].ipaddr = 
-               talloc_strdup(packet->answers, address);
-       if (packet->answers[0].rdata.netbios.addresses[0].ipaddr == NULL) goto failed;
-
-       DEBUG(7,("Sending name defense reply for %s<%02x> at %s to %s:%d\n", 
-                name->name, name->type, src_address, address, src_port));
-       
-       nbt_name_reply_send(nbtsock, src_address, src_port, packet);
-
-failed:
-       talloc_free(packet);
-}
+#include "nbt_server/wins/winsserver.h"
+#include "librpc/gen_ndr/ndr_nbt.h"
+#include "lib/socket/socket.h"
 
 
 /*
@@ -82,29 +34,46 @@ failed:
 */
 void nbtd_request_defense(struct nbt_name_socket *nbtsock, 
                          struct nbt_name_packet *packet, 
-                         const char *src_address, int src_port)
+                         struct socket_address *src)
 {
-       struct nbt_iface_name *iname;
+       struct nbtd_iface_name *iname;
        struct nbt_name *name;
-       struct nbt_interface *iface = talloc_get_type(nbtsock->incoming.private, 
-                                                     struct nbt_interface);
+       struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
+                                                      struct nbtd_interface);
+
+       /*
+        * if the packet comes from one of our interfaces
+        * it must be our winsclient trying to reach the winsserver
+        */
+       if (nbtd_self_packet(nbtsock, packet, src)) {
+               nbtd_winsserver_request(nbtsock, packet, src);
+               return;
+       }
 
-       NBT_ASSERT_PACKET(packet, src_address, packet->qdcount == 1);
-       NBT_ASSERT_PACKET(packet, src_address, packet->arcount == 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->arcount == 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);
+       NBTD_ASSERT_PACKET(packet, src, 
+                         packet->additional[0].rr_type == NBT_QTYPE_NETBIOS);
+       NBTD_ASSERT_PACKET(packet, src, 
+                         packet->additional[0].rr_class == NBT_QCLASS_IP);
+       NBTD_ASSERT_PACKET(packet, src, 
+                         packet->additional[0].rdata.netbios.length == 6);
 
        /* see if we have the requested name on this interface */
        name = &packet->questions[0].name;
 
        iname = nbtd_find_iname(iface, name, NBT_NM_ACTIVE);
-       if (iname != NULL) {
-               DEBUG(2,("Defending name %s<%02x> on %s against %s\n",
-                        name->name, name->type, iface->bcast_address, src_address));
-               nbtd_name_defense_reply(nbtsock, packet, src_address, src_port,
-                                       &iname->name, iname->ttl, iname->nb_flags, 
-                                       iface->ip_address);
+       if (iname != NULL && 
+           !(name->type == NBT_NAME_LOGON || iname->nb_flags & NBT_NM_GROUP)) {
+               DEBUG(2,("Defending name %s on %s against %s\n",
+                        nbt_name_string(packet, name), 
+                        iface->bcast_address, src->addr));
+               nbtd_name_registration_reply(nbtsock, packet, src, NBT_RCODE_ACT);
+       } else {
+               nbtd_winsserver_request(nbtsock, packet, src);
        }
 }