s3-vfs: Use ENOATTR in errno comparison for getxattr
[garming/samba-autobuild/.git] / source4 / nbt_server / packet.c
index f53d355daf54821598fdc4fa27e707338ecf2b6e..139549623753c6a01719bde9bffaea94e39f8cd2 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "includes.h"
 #include "nbt_server/nbt_server.h"
+#include "smbd/service_task.h"
 #include "lib/socket/socket.h"
 #include "librpc/gen_ndr/ndr_nbt.h"
 #include "param/param.h"
@@ -42,16 +43,16 @@ void nbtd_bad_packet(struct nbt_name_packet *packet,
   see if an incoming packet is a broadcast packet from one of our own
   interfaces
 */
-BOOL nbtd_self_packet_and_bcast(struct nbt_name_socket *nbtsock, 
+bool nbtd_self_packet_and_bcast(struct nbt_name_socket *nbtsock, 
                                struct nbt_name_packet *packet, 
                                const struct socket_address *src)
 {
-       struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private
+       struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
                                                       struct nbtd_interface);
 
        /* if its not a broadcast then its not considered a self packet */
        if (!(packet->operation & NBT_FLAG_BROADCAST)) {
-               return False;
+               return false;
        }
 
        /* 
@@ -63,88 +64,133 @@ BOOL nbtd_self_packet_and_bcast(struct nbt_name_socket *nbtsock,
         */
        if (iface->nbtsock == nbtsock &&
            iface != iface->nbtsrv->bcast_interface) {
-               return False;
+               return false;
        }
 
        return nbtd_self_packet(nbtsock, packet, src);
 }
 
-BOOL nbtd_self_packet(struct nbt_name_socket *nbtsock, 
+bool nbtd_self_packet(struct nbt_name_socket *nbtsock, 
                      struct nbt_name_packet *packet, 
                      const struct socket_address *src)
 {
-       struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private
+       struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
                                                       struct nbtd_interface);
        struct nbtd_server *nbtsrv = iface->nbtsrv;
        
        /* if its not from the nbt port, then it wasn't a broadcast from us */
-       if (src->port != lp_nbt_port()) {
-               return False;
+       if (src->port != lpcfg_nbt_port(iface->nbtsrv->task->lp_ctx)) {
+               return false;
        }
 
        /* we have to loop over our interface list, seeing if its from
           one of our own interfaces */
        for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
                if (strcmp(src->addr, iface->ip_address) == 0) {
-                       return True;
+                       return true;
                }
        }
 
-       return False;
+       return false;
 }
 
-
-/*
-  send a name query reply
-*/
-void nbtd_name_query_reply(struct nbt_name_socket *nbtsock, 
-                          struct nbt_name_packet *request_packet, 
-                          struct socket_address *src,
-                          struct nbt_name *name, uint32_t ttl,
-                          uint16_t nb_flags, const char **addresses)
+struct nbt_name_packet *nbtd_name_query_reply_packet(
+       TALLOC_CTX *mem_ctx,
+       uint16_t trn_id,
+       uint32_t ttl,
+       uint16_t nb_flags,
+       const struct nbt_name *name,
+       const char **addresses,
+       size_t num_addresses)
 {
        struct nbt_name_packet *packet;
-       size_t num_addresses = str_list_length(addresses);
-       struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, 
-                                                      struct nbtd_interface);
-       struct nbtd_server *nbtsrv = iface->nbtsrv;
-       int i;
+       size_t i;
+       struct nbt_res_rec *answer;
+       struct nbt_rdata_netbios *rdata;
+       NTSTATUS status;
 
        if (num_addresses == 0) {
-               DEBUG(3,("No addresses in name query reply - failing\n"));
-               return;
+               return NULL;
        }
 
-       packet = talloc_zero(nbtsock, struct nbt_name_packet);
-       if (packet == NULL) return;
+       packet = talloc_zero(mem_ctx, struct nbt_name_packet);
+       if (packet == NULL) {
+               return NULL;
+       }
 
-       packet->name_trn_id = request_packet->name_trn_id;
+       packet->name_trn_id = trn_id;
        packet->ancount = 1;
-       packet->operation = 
-               NBT_FLAG_REPLY | 
-               NBT_OPCODE_QUERY | 
-               NBT_FLAG_AUTHORITIVE |
+       packet->operation =
+               NBT_FLAG_REPLY |
+               NBT_OPCODE_QUERY |
+               NBT_FLAG_AUTHORITATIVE |
                NBT_FLAG_RECURSION_DESIRED |
                NBT_FLAG_RECURSION_AVAIL;
 
        packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
-       if (packet->answers == NULL) goto failed;
+       if (packet->answers == NULL) {
+               goto failed;
+       }
+       answer = packet->answers;
 
-       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];
+       status = nbt_name_dup(packet->answers, name, &answer->name);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto failed;
+       }
+       answer->rr_type  = NBT_QTYPE_NETBIOS;
+       answer->rr_class = NBT_QCLASS_IP;
+       answer->ttl      = ttl;
+
+       rdata = &answer->rdata.netbios;
+       rdata->length = num_addresses*6;
+       rdata->addresses = talloc_array(
+               packet->answers,
+               struct nbt_rdata_address,
+               num_addresses);
+       if (rdata->addresses == NULL) {
+               goto failed;
+       }
+
+       for (i=0; i<num_addresses; i++) {
+               struct nbt_rdata_address *addr = &rdata->addresses[i];
                addr->nb_flags = nb_flags;
                addr->ipaddr = talloc_strdup(packet->answers, addresses[i]);
-               if (addr->ipaddr == NULL) goto failed;
+               if (addr->ipaddr == NULL) {
+                       goto failed;
+               }
+       }
+
+       return packet;
+
+failed:
+       TALLOC_FREE(packet);
+       return NULL;
+}
+
+/*
+  send a name query reply
+*/
+void nbtd_name_query_reply(struct nbt_name_socket *nbtsock,
+                          struct nbt_name_packet *request_packet,
+                          struct socket_address *src,
+                          struct nbt_name *name, uint32_t ttl,
+                          uint16_t nb_flags, const char **addresses)
+{
+       struct nbt_name_packet *packet;
+       struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
+                                                      struct nbtd_interface);
+       struct nbtd_server *nbtsrv = iface->nbtsrv;
+
+       packet = nbtd_name_query_reply_packet(
+               nbtsock,
+               request_packet->name_trn_id,
+               ttl,
+               nb_flags,
+               name,
+               addresses,
+               str_list_length(addresses));
+       if (packet == NULL) {
+               return;
        }
 
        DEBUG(7,("Sending name query reply for %s at %s to %s:%d\n", 
@@ -153,7 +199,6 @@ void nbtd_name_query_reply(struct nbt_name_socket *nbtsock,
        nbtsrv->stats.total_sent++;
        nbt_name_reply_send(nbtsock, src, packet);
 
-failed:
        talloc_free(packet);
 }
 
@@ -167,7 +212,7 @@ void nbtd_negative_name_query_reply(struct nbt_name_socket *nbtsock,
 {
        struct nbt_name_packet *packet;
        struct nbt_name *name = &request_packet->questions[0].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);
        struct nbtd_server *nbtsrv = iface->nbtsrv;
 
@@ -176,10 +221,10 @@ void nbtd_negative_name_query_reply(struct nbt_name_socket *nbtsock,
 
        packet->name_trn_id = request_packet->name_trn_id;
        packet->ancount = 1;
-       packet->operation = 
-               NBT_FLAG_REPLY | 
-               NBT_OPCODE_QUERY | 
-               NBT_FLAG_AUTHORITIVE |
+       packet->operation =
+               NBT_FLAG_REPLY |
+               NBT_OPCODE_QUERY |
+               NBT_FLAG_AUTHORITATIVE |
                NBT_RCODE_NAM;
 
        packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
@@ -211,7 +256,7 @@ void nbtd_name_registration_reply(struct nbt_name_socket *nbtsock,
 {
        struct nbt_name_packet *packet;
        struct nbt_name *name = &request_packet->questions[0].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);
        struct nbtd_server *nbtsrv = iface->nbtsrv;
 
@@ -220,10 +265,10 @@ void nbtd_name_registration_reply(struct nbt_name_socket *nbtsock,
 
        packet->name_trn_id = request_packet->name_trn_id;
        packet->ancount = 1;
-       packet->operation = 
-               NBT_FLAG_REPLY | 
+       packet->operation =
+               NBT_FLAG_REPLY |
                NBT_OPCODE_REGISTER |
-               NBT_FLAG_AUTHORITIVE |
+               NBT_FLAG_AUTHORITATIVE |
                NBT_FLAG_RECURSION_DESIRED |
                NBT_FLAG_RECURSION_AVAIL |
                rcode;
@@ -259,7 +304,7 @@ void nbtd_name_release_reply(struct nbt_name_socket *nbtsock,
 {
        struct nbt_name_packet *packet;
        struct nbt_name *name = &request_packet->questions[0].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);
        struct nbtd_server *nbtsrv = iface->nbtsrv;
 
@@ -268,10 +313,10 @@ void nbtd_name_release_reply(struct nbt_name_socket *nbtsock,
 
        packet->name_trn_id = request_packet->name_trn_id;
        packet->ancount = 1;
-       packet->operation = 
-               NBT_FLAG_REPLY | 
+       packet->operation =
+               NBT_FLAG_REPLY |
                NBT_OPCODE_RELEASE |
-               NBT_FLAG_AUTHORITIVE |
+               NBT_FLAG_AUTHORITATIVE |
                rcode;
        
        packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
@@ -305,7 +350,7 @@ void nbtd_wack_reply(struct nbt_name_socket *nbtsock,
 {
        struct nbt_name_packet *packet;
        struct nbt_name *name = &request_packet->questions[0].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);
        struct nbtd_server *nbtsrv = iface->nbtsrv;
 
@@ -314,10 +359,10 @@ void nbtd_wack_reply(struct nbt_name_socket *nbtsock,
 
        packet->name_trn_id = request_packet->name_trn_id;
        packet->ancount = 1;
-       packet->operation = 
-               NBT_FLAG_REPLY | 
+       packet->operation =
+               NBT_FLAG_REPLY |
                NBT_OPCODE_WACK |
-               NBT_FLAG_AUTHORITIVE;
+               NBT_FLAG_AUTHORITATIVE;
        
        packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
        if (packet->answers == NULL) goto failed;
@@ -327,7 +372,7 @@ void nbtd_wack_reply(struct nbt_name_socket *nbtsock,
        packet->answers[0].rr_class          = NBT_QCLASS_IP;
        packet->answers[0].ttl               = ttl;
        packet->answers[0].rdata.data.length = 2;
-       packet->answers[0].rdata.data.data   = talloc_size(packet, 2);
+       packet->answers[0].rdata.data.data   = talloc_array(packet, uint8_t, 2);
        if (packet->answers[0].rdata.data.data == NULL) goto failed;
        RSSVAL(packet->answers[0].rdata.data.data, 0, request_packet->operation);