Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : 4 : answer name queries 5 : 6 : Copyright (C) Andrew Tridgell 2005 7 : 8 : This program is free software; you can redistribute it and/or modify 9 : it under the terms of the GNU General Public License as published by 10 : the Free Software Foundation; either version 3 of the License, or 11 : (at your option) any later version. 12 : 13 : This program is distributed in the hope that it will be useful, 14 : but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : GNU General Public License for more details. 17 : 18 : You should have received a copy of the GNU General Public License 19 : along with this program. If not, see <http://www.gnu.org/licenses/>. 20 : */ 21 : 22 : #include "includes.h" 23 : #include "../lib/util/dlinklist.h" 24 : #include "system/network.h" 25 : #include "nbt_server/nbt_server.h" 26 : #include "nbt_server/wins/winsserver.h" 27 : #include "samba/service_task.h" 28 : #include "librpc/gen_ndr/ndr_nbt.h" 29 : #include "lib/socket/socket.h" 30 : #include "param/param.h" 31 : 32 : /* 33 : answer a name query 34 : */ 35 6645 : void nbtd_request_query(struct nbt_name_socket *nbtsock, 36 : struct nbt_name_packet *packet, 37 : struct socket_address *src) 38 : { 39 40 : struct nbtd_iface_name *iname; 40 40 : struct nbt_name *name; 41 6645 : struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data, 42 : struct nbtd_interface); 43 : 44 : /* see if its a node status query */ 45 6645 : if (packet->qdcount == 1 && 46 6645 : packet->questions[0].question_type == NBT_QTYPE_STATUS) { 47 19 : nbtd_query_status(nbtsock, packet, src); 48 19 : return; 49 : } 50 : 51 6626 : NBTD_ASSERT_PACKET(packet, src, packet->qdcount == 1); 52 6626 : NBTD_ASSERT_PACKET(packet, src, 53 : packet->questions[0].question_type == NBT_QTYPE_NETBIOS); 54 6626 : NBTD_ASSERT_PACKET(packet, src, 55 : packet->questions[0].question_class == NBT_QCLASS_IP); 56 : 57 : /* see if we have the requested name on this interface */ 58 6626 : name = &packet->questions[0].name; 59 : 60 6626 : iname = nbtd_find_iname(iface, name, 0); 61 6626 : if (iname == NULL) { 62 : /* don't send negative replies to broadcast queries */ 63 5373 : if (packet->operation & NBT_FLAG_BROADCAST) { 64 5305 : return; 65 : } 66 : 67 58 : if (packet->operation & NBT_FLAG_RECURSION_DESIRED) { 68 56 : nbtd_winsserver_request(nbtsock, packet, src); 69 56 : return; 70 : } 71 : 72 : /* otherwise send a negative reply */ 73 2 : nbtd_negative_name_query_reply(nbtsock, packet, src); 74 2 : return; 75 : } 76 : 77 : /* 78 : * normally we should forward all queries with the 79 : * recursion desired flag to the wins server, but this 80 : * breaks are winsclient code, when doing mhomed registrations 81 : */ 82 1253 : if (!(packet->operation & NBT_FLAG_BROADCAST) && 83 439 : (packet->operation & NBT_FLAG_RECURSION_DESIRED) && 84 0 : (iname->nb_flags & NBT_NM_GROUP) && 85 0 : lpcfg_we_are_a_wins_server(iface->nbtsrv->task->lp_ctx)) { 86 0 : nbtd_winsserver_request(nbtsock, packet, src); 87 0 : return; 88 : } 89 : 90 : /* if the name is not yet active and its a broadcast query then 91 : ignore it for now */ 92 1253 : if (!(iname->nb_flags & NBT_NM_ACTIVE) && 93 195 : (packet->operation & NBT_FLAG_BROADCAST)) { 94 195 : DEBUG(7,("Query for %s from %s - name not active yet on %s\n", 95 : nbt_name_string(packet, name), src->addr, iface->ip_address)); 96 195 : return; 97 : } 98 : 99 1058 : nbtd_name_query_reply(nbtsock, packet, src, 100 1058 : &iname->name, iname->ttl, iname->nb_flags, 101 : nbtd_address_list(iface, packet)); 102 : }