LCOV - code coverage report
Current view: top level - source3/libsmb - namequery.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 1138 1698 67.0 %
Date: 2024-04-21 15:09:00 Functions: 60 65 92.3 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    name query routines
       4             :    Copyright (C) Andrew Tridgell 1994-1998
       5             :    Copyright (C) Jeremy Allison 2007.
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "libsmb/namequery.h"
      23             : #include "../lib/util/tevent_ntstatus.h"
      24             : #include "libads/sitename_cache.h"
      25             : #include "../lib/addns/dnsquery.h"
      26             : #include "../lib/addns/dnsquery_srv.h"
      27             : #include "../libcli/netlogon/netlogon.h"
      28             : #include "lib/async_req/async_sock.h"
      29             : #include "lib/tsocket/tsocket.h"
      30             : #include "libsmb/nmblib.h"
      31             : #include "libsmb/unexpected.h"
      32             : #include "../libcli/nbt/libnbt.h"
      33             : #include "libads/kerberos_proto.h"
      34             : #include "lib/gencache.h"
      35             : #include "librpc/gen_ndr/dns.h"
      36             : #include "lib/util/util_net.h"
      37             : #include "lib/util/tsort.h"
      38             : #include "lib/util/string_wrappers.h"
      39             : 
      40             : /* nmbd.c sets this to True. */
      41             : bool global_in_nmbd = False;
      42             : 
      43             : /*
      44             :  * Utility function to convert from a sockaddr_storage
      45             :  * array to a struct samba_sockaddr array.
      46             :  */
      47             : 
      48         831 : static NTSTATUS sockaddr_array_to_samba_sockaddr_array(
      49             :                                 TALLOC_CTX *ctx,
      50             :                                 struct samba_sockaddr **sa_out,
      51             :                                 size_t *count_out,
      52             :                                 const struct sockaddr_storage *ss_in,
      53             :                                 size_t count_in)
      54             : {
      55         831 :         struct samba_sockaddr *sa = NULL;
      56           0 :         size_t i;
      57         831 :         size_t count = 0;
      58             : 
      59         831 :         if (count_in == 0) {
      60             :                 /*
      61             :                  * Zero length arrays are returned as NULL.
      62             :                  * in the name resolution code.
      63             :                  */
      64           0 :                 *count_out = 0;
      65           0 :                 *sa_out = NULL;
      66           0 :                 return NT_STATUS_OK;
      67             :         }
      68         831 :         sa = talloc_zero_array(ctx,
      69             :                                 struct samba_sockaddr,
      70             :                                 count_in);
      71         831 :         if (sa == NULL) {
      72           0 :                 return NT_STATUS_NO_MEMORY;
      73             :         }
      74         831 :         count = 0;
      75        2431 :         for (i = 0; i < count_in; i++) {
      76           0 :                 bool ok;
      77             : 
      78             :                 /* Filter out zero addresses. */
      79        1600 :                 if (is_zero_addr(&ss_in[i])) {
      80           0 :                         continue;
      81             :                 }
      82        1600 :                 ok = sockaddr_storage_to_samba_sockaddr(&sa[count],
      83        1600 :                                                         &ss_in[i]);
      84        1600 :                 if (!ok) {
      85           0 :                         continue;
      86             :                 }
      87        1600 :                 count++;
      88             :         }
      89         831 :         if (count == 0) {
      90             :                 /*
      91             :                  * Zero length arrays are returned as NULL.
      92             :                  * in the name resolution code.
      93             :                  */
      94           0 :                 TALLOC_FREE(sa);
      95             :         }
      96         831 :         *count_out = count;
      97         831 :         *sa_out = sa;
      98         831 :         return NT_STATUS_OK;
      99             : }
     100             : 
     101             : /****************************
     102             :  * SERVER AFFINITY ROUTINES *
     103             :  ****************************/
     104             : 
     105             :  /* Server affinity is the concept of preferring the last domain
     106             :     controller with whom you had a successful conversation */
     107             : 
     108             : /****************************************************************************
     109             : ****************************************************************************/
     110             : #define SAFKEY_FMT      "SAF/DOMAIN/%s"
     111             : #define SAF_TTL         900
     112             : #define SAFJOINKEY_FMT  "SAFJOIN/DOMAIN/%s"
     113             : #define SAFJOIN_TTL     3600
     114             : 
     115         842 : static char *saf_key(TALLOC_CTX *mem_ctx, const char *domain)
     116             : {
     117         842 :         return talloc_asprintf_strupper_m(mem_ctx, SAFKEY_FMT, domain);
     118             : }
     119             : 
     120         919 : static char *saf_join_key(TALLOC_CTX *mem_ctx, const char *domain)
     121             : {
     122         919 :         return talloc_asprintf_strupper_m(mem_ctx, SAFJOINKEY_FMT, domain);
     123             : }
     124             : 
     125             : /****************************************************************************
     126             : ****************************************************************************/
     127             : 
     128         668 : bool saf_store( const char *domain, const char *servername )
     129             : {
     130           0 :         char *key;
     131           0 :         time_t expire;
     132         668 :         bool ret = False;
     133             : 
     134         668 :         if ( !domain || !servername ) {
     135          14 :                 DEBUG(2,("saf_store: "
     136             :                         "Refusing to store empty domain or servername!\n"));
     137          14 :                 return False;
     138             :         }
     139             : 
     140         654 :         if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
     141           4 :                 DEBUG(0,("saf_store: "
     142             :                         "refusing to store 0 length domain or servername!\n"));
     143           4 :                 return False;
     144             :         }
     145             : 
     146         650 :         key = saf_key(talloc_tos(), domain);
     147         650 :         if (key == NULL) {
     148           0 :                 DEBUG(1, ("saf_key() failed\n"));
     149           0 :                 return false;
     150             :         }
     151         650 :         expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
     152             : 
     153         650 :         DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
     154             :                 domain, servername, (unsigned int)expire ));
     155             : 
     156         650 :         ret = gencache_set( key, servername, expire );
     157             : 
     158         650 :         TALLOC_FREE( key );
     159             : 
     160         650 :         return ret;
     161             : }
     162             : 
     163         141 : bool saf_join_store( const char *domain, const char *servername )
     164             : {
     165           0 :         char *key;
     166           0 :         time_t expire;
     167         141 :         bool ret = False;
     168             : 
     169         141 :         if ( !domain || !servername ) {
     170           0 :                 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
     171           0 :                 return False;
     172             :         }
     173             : 
     174         141 :         if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
     175           0 :                 DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
     176           0 :                 return False;
     177             :         }
     178             : 
     179         141 :         key = saf_join_key(talloc_tos(), domain);
     180         141 :         if (key == NULL) {
     181           0 :                 DEBUG(1, ("saf_join_key() failed\n"));
     182           0 :                 return false;
     183             :         }
     184         141 :         expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
     185             : 
     186         141 :         DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
     187             :                 domain, servername, (unsigned int)expire ));
     188             : 
     189         141 :         ret = gencache_set( key, servername, expire );
     190             : 
     191         141 :         TALLOC_FREE( key );
     192             : 
     193         141 :         return ret;
     194             : }
     195             : 
     196          68 : bool saf_delete( const char *domain )
     197             : {
     198           0 :         char *key;
     199          68 :         bool ret = False;
     200             : 
     201          68 :         if ( !domain ) {
     202          34 :                 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
     203          34 :                 return False;
     204             :         }
     205             : 
     206          34 :         key = saf_join_key(talloc_tos(), domain);
     207          34 :         if (key == NULL) {
     208           0 :                 DEBUG(1, ("saf_join_key() failed\n"));
     209           0 :                 return false;
     210             :         }
     211          34 :         ret = gencache_del(key);
     212          34 :         TALLOC_FREE(key);
     213             : 
     214          34 :         if (ret) {
     215          34 :                 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain ));
     216             :         }
     217             : 
     218          34 :         key = saf_key(talloc_tos(), domain);
     219          34 :         if (key == NULL) {
     220           0 :                 DEBUG(1, ("saf_key() failed\n"));
     221           0 :                 return false;
     222             :         }
     223          34 :         ret = gencache_del(key);
     224          34 :         TALLOC_FREE(key);
     225             : 
     226          34 :         if (ret) {
     227          34 :                 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
     228             :         }
     229             : 
     230          34 :         return ret;
     231             : }
     232             : 
     233             : /****************************************************************************
     234             : ****************************************************************************/
     235             : 
     236         744 : char *saf_fetch(TALLOC_CTX *mem_ctx, const char *domain )
     237             : {
     238         744 :         char *server = NULL;
     239           0 :         time_t timeout;
     240         744 :         bool ret = False;
     241         744 :         char *key = NULL;
     242             : 
     243         744 :         if ( !domain || strlen(domain) == 0) {
     244           0 :                 DEBUG(2,("saf_fetch: Empty domain name!\n"));
     245           0 :                 return NULL;
     246             :         }
     247             : 
     248         744 :         key = saf_join_key(talloc_tos(), domain);
     249         744 :         if (key == NULL) {
     250           0 :                 DEBUG(1, ("saf_join_key() failed\n"));
     251           0 :                 return NULL;
     252             :         }
     253             : 
     254         744 :         ret = gencache_get( key, mem_ctx, &server, &timeout );
     255             : 
     256         744 :         TALLOC_FREE( key );
     257             : 
     258         744 :         if ( ret ) {
     259         586 :                 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
     260             :                         server, domain ));
     261         586 :                 return server;
     262             :         }
     263             : 
     264         158 :         key = saf_key(talloc_tos(), domain);
     265         158 :         if (key == NULL) {
     266           0 :                 DEBUG(1, ("saf_key() failed\n"));
     267           0 :                 return NULL;
     268             :         }
     269             : 
     270         158 :         ret = gencache_get( key, mem_ctx, &server, &timeout );
     271             : 
     272         158 :         TALLOC_FREE( key );
     273             : 
     274         158 :         if ( !ret ) {
     275         151 :                 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
     276             :                                         domain ));
     277             :         } else {
     278           7 :                 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
     279             :                         server, domain ));
     280             :         }
     281             : 
     282         158 :         return server;
     283             : }
     284             : 
     285         849 : static void set_socket_addr_v4(struct samba_sockaddr *addr)
     286             : {
     287         849 :         if (!interpret_string_addr(&addr->u.ss, lp_nbt_client_socket_address(),
     288             :                                    AI_NUMERICHOST|AI_PASSIVE)) {
     289           0 :                 zero_sockaddr(&addr->u.ss);
     290             :                 /* zero_sockaddr sets family to AF_INET. */
     291           0 :                 addr->sa_socklen = sizeof(struct sockaddr_in);
     292             :         }
     293         849 :         if (addr->u.ss.ss_family != AF_INET) {
     294           0 :                 zero_sockaddr(&addr->u.ss);
     295             :                 /* zero_sockaddr sets family to AF_INET. */
     296           0 :                 addr->sa_socklen = sizeof(struct sockaddr_in);
     297             :         }
     298         849 : }
     299             : 
     300           0 : static struct in_addr my_socket_addr_v4(void)
     301             : {
     302           0 :         struct samba_sockaddr my_addr = {0};
     303             : 
     304           0 :         set_socket_addr_v4(&my_addr);
     305           0 :         return my_addr.u.in.sin_addr;
     306             : }
     307             : 
     308             : /****************************************************************************
     309             :  Generate a random trn_id.
     310             : ****************************************************************************/
     311             : 
     312         849 : static int generate_trn_id(void)
     313             : {
     314           0 :         uint16_t id;
     315             : 
     316         849 :         generate_random_buffer((uint8_t *)&id, sizeof(id));
     317             : 
     318         849 :         return id % (unsigned)0x7FFF;
     319             : }
     320             : 
     321             : /****************************************************************************
     322             :  Parse a node status response into an array of structures.
     323             : ****************************************************************************/
     324             : 
     325          60 : static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p,
     326             :                                 size_t *num_names,
     327             :                                 struct node_status_extra *extra)
     328             : {
     329           0 :         struct node_status *ret;
     330           0 :         size_t i;
     331          60 :         size_t result_count = 0;
     332             : 
     333          60 :         result_count = CVAL(p,0);
     334             : 
     335          60 :         if (result_count == 0)
     336           0 :                 return NULL;
     337             : 
     338          60 :         ret = talloc_array(mem_ctx, struct node_status,result_count);
     339          60 :         if (!ret)
     340           0 :                 return NULL;
     341             : 
     342          60 :         p++;
     343         569 :         for (i=0;i< result_count;i++) {
     344         509 :                 strlcpy(ret[i].name,p,16);
     345         509 :                 trim_char(ret[i].name,'\0',' ');
     346         509 :                 ret[i].type = CVAL(p,15);
     347         509 :                 ret[i].flags = p[16];
     348         509 :                 p += 18;
     349         509 :                 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
     350             :                            ret[i].type, ret[i].flags));
     351             :         }
     352             :         /*
     353             :          * Also, pick up the MAC address ...
     354             :          */
     355          60 :         if (extra) {
     356           0 :                 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
     357             :         }
     358          60 :         *num_names = result_count;
     359          60 :         return ret;
     360             : }
     361             : 
     362             : struct sock_packet_read_state {
     363             :         struct tevent_context *ev;
     364             :         enum packet_type type;
     365             :         int trn_id;
     366             : 
     367             :         struct nb_packet_reader *reader;
     368             :         struct tevent_req *reader_req;
     369             : 
     370             :         struct tdgram_context *sock;
     371             :         struct tevent_req *socket_req;
     372             :         uint8_t *buf;
     373             :         struct tsocket_address *addr;
     374             : 
     375             :         bool (*validator)(struct packet_struct *p,
     376             :                           void *private_data);
     377             :         void *private_data;
     378             : 
     379             :         struct packet_struct *packet;
     380             : };
     381             : 
     382             : static void sock_packet_read_got_packet(struct tevent_req *subreq);
     383             : static void sock_packet_read_got_socket(struct tevent_req *subreq);
     384             : 
     385         849 : static struct tevent_req *sock_packet_read_send(
     386             :         TALLOC_CTX *mem_ctx,
     387             :         struct tevent_context *ev,
     388             :         struct tdgram_context *sock,
     389             :         struct nb_packet_reader *reader,
     390             :         enum packet_type type,
     391             :         int trn_id,
     392             :         bool (*validator)(struct packet_struct *p, void *private_data),
     393             :         void *private_data)
     394             : {
     395           0 :         struct tevent_req *req;
     396           0 :         struct sock_packet_read_state *state;
     397             : 
     398         849 :         req = tevent_req_create(mem_ctx, &state,
     399             :                                 struct sock_packet_read_state);
     400         849 :         if (req == NULL) {
     401           0 :                 return NULL;
     402             :         }
     403         849 :         state->ev = ev;
     404         849 :         state->reader = reader;
     405         849 :         state->sock = sock;
     406         849 :         state->type = type;
     407         849 :         state->trn_id = trn_id;
     408         849 :         state->validator = validator;
     409         849 :         state->private_data = private_data;
     410             : 
     411         849 :         if (reader != NULL) {
     412         380 :                 state->reader_req = nb_packet_read_send(state, ev, reader);
     413         380 :                 if (tevent_req_nomem(state->reader_req, req)) {
     414           0 :                         return tevent_req_post(req, ev);
     415             :                 }
     416         380 :                 tevent_req_set_callback(
     417             :                         state->reader_req, sock_packet_read_got_packet, req);
     418             :         }
     419             : 
     420         849 :         state->socket_req = tdgram_recvfrom_send(state, ev, state->sock);
     421         849 :         if (tevent_req_nomem(state->socket_req, req)) {
     422           0 :                 return tevent_req_post(req, ev);
     423             :         }
     424         849 :         tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
     425             :                                 req);
     426             : 
     427         849 :         return req;
     428             : }
     429             : 
     430           0 : static void sock_packet_read_got_packet(struct tevent_req *subreq)
     431             : {
     432           0 :         struct tevent_req *req = tevent_req_callback_data(
     433             :                 subreq, struct tevent_req);
     434           0 :         struct sock_packet_read_state *state = tevent_req_data(
     435             :                 req, struct sock_packet_read_state);
     436           0 :         NTSTATUS status;
     437             : 
     438           0 :         status = nb_packet_read_recv(subreq, state, &state->packet);
     439             : 
     440           0 :         TALLOC_FREE(state->reader_req);
     441             : 
     442           0 :         if (!NT_STATUS_IS_OK(status)) {
     443           0 :                 if (state->socket_req != NULL) {
     444             :                         /*
     445             :                          * Still waiting for socket
     446             :                          */
     447           0 :                         return;
     448             :                 }
     449             :                 /*
     450             :                  * Both socket and packet reader failed
     451             :                  */
     452           0 :                 tevent_req_nterror(req, status);
     453           0 :                 return;
     454             :         }
     455             : 
     456           0 :         if ((state->validator != NULL) &&
     457           0 :             !state->validator(state->packet, state->private_data)) {
     458           0 :                 DEBUG(10, ("validator failed\n"));
     459             : 
     460           0 :                 TALLOC_FREE(state->packet);
     461             : 
     462           0 :                 state->reader_req = nb_packet_read_send(state, state->ev,
     463             :                                                         state->reader);
     464           0 :                 if (tevent_req_nomem(state->reader_req, req)) {
     465           0 :                         return;
     466             :                 }
     467           0 :                 tevent_req_set_callback(
     468             :                         state->reader_req, sock_packet_read_got_packet, req);
     469           0 :                 return;
     470             :         }
     471             : 
     472           0 :         TALLOC_FREE(state->socket_req);
     473           0 :         tevent_req_done(req);
     474             : }
     475             : 
     476         444 : static void sock_packet_read_got_socket(struct tevent_req *subreq)
     477             : {
     478         444 :         struct tevent_req *req = tevent_req_callback_data(
     479             :                 subreq, struct tevent_req);
     480         444 :         struct sock_packet_read_state *state = tevent_req_data(
     481             :                 req, struct sock_packet_read_state);
     482         444 :         struct samba_sockaddr addr = {0};
     483           0 :         ssize_t ret;
     484           0 :         ssize_t received;
     485           0 :         int err;
     486           0 :         bool ok;
     487             : 
     488         444 :         received = tdgram_recvfrom_recv(subreq, &err, state,
     489             :                                         &state->buf, &state->addr);
     490             : 
     491         444 :         TALLOC_FREE(state->socket_req);
     492             : 
     493         444 :         if (received == -1) {
     494           0 :                 if (state->reader_req != NULL) {
     495             :                         /*
     496             :                          * Still waiting for reader
     497             :                          */
     498         336 :                         return;
     499             :                 }
     500             :                 /*
     501             :                  * Both socket and reader failed
     502             :                  */
     503           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(err));
     504           0 :                 return;
     505             :         }
     506         444 :         ok = tsocket_address_is_inet(state->addr, "ipv4");
     507         444 :         if (!ok) {
     508           0 :                 goto retry;
     509             :         }
     510         444 :         ret = tsocket_address_bsd_sockaddr(state->addr,
     511             :                                         &addr.u.sa,
     512             :                                         sizeof(addr.u.in));
     513         444 :         if (ret == -1) {
     514           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(errno));
     515           0 :                 return;
     516             :         }
     517             : 
     518         888 :         state->packet = parse_packet_talloc(
     519         444 :                 state, (char *)state->buf, received, state->type,
     520         444 :                 addr.u.in.sin_addr, addr.u.in.sin_port);
     521         444 :         if (state->packet == NULL) {
     522           0 :                 DEBUG(10, ("parse_packet failed\n"));
     523           0 :                 goto retry;
     524             :         }
     525         888 :         if ((state->trn_id != -1) &&
     526         444 :             (state->trn_id != packet_trn_id(state->packet))) {
     527           0 :                 DEBUG(10, ("Expected transaction id %d, got %d\n",
     528             :                            state->trn_id, packet_trn_id(state->packet)));
     529           0 :                 goto retry;
     530             :         }
     531             : 
     532         444 :         if ((state->validator != NULL) &&
     533         444 :             !state->validator(state->packet, state->private_data)) {
     534         108 :                 DEBUG(10, ("validator failed\n"));
     535         108 :                 goto retry;
     536             :         }
     537             : 
     538         336 :         tevent_req_done(req);
     539         336 :         return;
     540             : 
     541         108 : retry:
     542         108 :         TALLOC_FREE(state->packet);
     543         108 :         TALLOC_FREE(state->buf);
     544         108 :         TALLOC_FREE(state->addr);
     545             : 
     546         108 :         state->socket_req = tdgram_recvfrom_send(state, state->ev, state->sock);
     547         108 :         if (tevent_req_nomem(state->socket_req, req)) {
     548           0 :                 return;
     549             :         }
     550         108 :         tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
     551             :                                 req);
     552             : }
     553             : 
     554         336 : static NTSTATUS sock_packet_read_recv(struct tevent_req *req,
     555             :                                       TALLOC_CTX *mem_ctx,
     556             :                                       struct packet_struct **ppacket)
     557             : {
     558         336 :         struct sock_packet_read_state *state = tevent_req_data(
     559             :                 req, struct sock_packet_read_state);
     560           0 :         NTSTATUS status;
     561             : 
     562         336 :         if (tevent_req_is_nterror(req, &status)) {
     563           0 :                 return status;
     564             :         }
     565         336 :         *ppacket = talloc_move(mem_ctx, &state->packet);
     566         336 :         return NT_STATUS_OK;
     567             : }
     568             : 
     569             : struct nb_trans_state {
     570             :         struct tevent_context *ev;
     571             :         struct tdgram_context *sock;
     572             :         struct nb_packet_reader *reader;
     573             : 
     574             :         struct tsocket_address *src_addr;
     575             :         struct tsocket_address *dst_addr;
     576             :         uint8_t *buf;
     577             :         size_t buflen;
     578             :         enum packet_type type;
     579             :         int trn_id;
     580             : 
     581             :         bool (*validator)(struct packet_struct *p,
     582             :                           void *private_data);
     583             :         void *private_data;
     584             : 
     585             :         struct packet_struct *packet;
     586             : };
     587             : 
     588             : static void nb_trans_got_reader(struct tevent_req *subreq);
     589             : static void nb_trans_done(struct tevent_req *subreq);
     590             : static void nb_trans_sent(struct tevent_req *subreq);
     591             : static void nb_trans_send_next(struct tevent_req *subreq);
     592             : 
     593         849 : static struct tevent_req *nb_trans_send(
     594             :         TALLOC_CTX *mem_ctx,
     595             :         struct tevent_context *ev,
     596             :         const struct samba_sockaddr *_my_addr,
     597             :         const struct samba_sockaddr *_dst_addr,
     598             :         bool bcast,
     599             :         uint8_t *buf, size_t buflen,
     600             :         enum packet_type type, int trn_id,
     601             :         bool (*validator)(struct packet_struct *p,
     602             :                           void *private_data),
     603             :         void *private_data)
     604             : {
     605         849 :         const struct sockaddr *my_addr = &_my_addr->u.sa;
     606         849 :         size_t my_addr_len = sizeof(_my_addr->u.in); /*We know it's AF_INET.*/
     607         849 :         const struct sockaddr *dst_addr = &_dst_addr->u.sa;
     608         849 :         size_t dst_addr_len = sizeof(_dst_addr->u.in); /*We know it's AF_INET.*/
     609           0 :         struct tevent_req *req, *subreq;
     610           0 :         struct nb_trans_state *state;
     611           0 :         int ret;
     612             : 
     613         849 :         req = tevent_req_create(mem_ctx, &state, struct nb_trans_state);
     614         849 :         if (req == NULL) {
     615           0 :                 return NULL;
     616             :         }
     617         849 :         state->ev = ev;
     618         849 :         state->buf = buf;
     619         849 :         state->buflen = buflen;
     620         849 :         state->type = type;
     621         849 :         state->trn_id = trn_id;
     622         849 :         state->validator = validator;
     623         849 :         state->private_data = private_data;
     624             : 
     625         849 :         ret = tsocket_address_bsd_from_sockaddr(state,
     626             :                                                 my_addr, my_addr_len,
     627             :                                                 &state->src_addr);
     628         849 :         if (ret == -1) {
     629           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(errno));
     630           0 :                 return tevent_req_post(req, ev);
     631             :         }
     632             : 
     633         849 :         ret = tsocket_address_bsd_from_sockaddr(state,
     634             :                                                 dst_addr, dst_addr_len,
     635             :                                                 &state->dst_addr);
     636         849 :         if (ret == -1) {
     637           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(errno));
     638           0 :                 return tevent_req_post(req, ev);
     639             :         }
     640             : 
     641         849 :         ret = tdgram_inet_udp_broadcast_socket(state->src_addr, state,
     642             :                                                &state->sock);
     643         849 :         if (ret == -1) {
     644           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(errno));
     645           0 :                 return tevent_req_post(req, ev);
     646             :         }
     647             : 
     648         849 :         subreq = nb_packet_reader_send(state,
     649             :                                        ev,
     650             :                                        global_nmbd_socket_dir(),
     651             :                                        type,
     652         849 :                                        state->trn_id,
     653             :                                        NULL);
     654         849 :         if (tevent_req_nomem(subreq, req)) {
     655           0 :                 return tevent_req_post(req, ev);
     656             :         }
     657         849 :         tevent_req_set_callback(subreq, nb_trans_got_reader, req);
     658         849 :         return req;
     659             : }
     660             : 
     661         849 : static void nb_trans_got_reader(struct tevent_req *subreq)
     662             : {
     663         849 :         struct tevent_req *req = tevent_req_callback_data(
     664             :                 subreq, struct tevent_req);
     665         849 :         struct nb_trans_state *state = tevent_req_data(
     666             :                 req, struct nb_trans_state);
     667           0 :         NTSTATUS status;
     668             : 
     669         849 :         status = nb_packet_reader_recv(subreq, state, &state->reader);
     670         849 :         TALLOC_FREE(subreq);
     671             : 
     672         849 :         if (!NT_STATUS_IS_OK(status)) {
     673         469 :                 DEBUG(10, ("nmbd not around\n"));
     674         469 :                 state->reader = NULL;
     675             :         }
     676             : 
     677         849 :         subreq = sock_packet_read_send(
     678             :                 state, state->ev, state->sock,
     679             :                 state->reader, state->type, state->trn_id,
     680             :                 state->validator, state->private_data);
     681         849 :         if (tevent_req_nomem(subreq, req)) {
     682           0 :                 return;
     683             :         }
     684         849 :         tevent_req_set_callback(subreq, nb_trans_done, req);
     685             : 
     686         849 :         subreq = tdgram_sendto_send(state, state->ev,
     687             :                                     state->sock,
     688         849 :                                     state->buf, state->buflen,
     689         849 :                                     state->dst_addr);
     690         849 :         if (tevent_req_nomem(subreq, req)) {
     691           0 :                 return;
     692             :         }
     693         849 :         tevent_req_set_callback(subreq, nb_trans_sent, req);
     694             : }
     695             : 
     696         849 : static void nb_trans_sent(struct tevent_req *subreq)
     697             : {
     698         849 :         struct tevent_req *req = tevent_req_callback_data(
     699             :                 subreq, struct tevent_req);
     700         849 :         struct nb_trans_state *state = tevent_req_data(
     701             :                 req, struct nb_trans_state);
     702           0 :         ssize_t sent;
     703           0 :         int err;
     704             : 
     705         849 :         sent = tdgram_sendto_recv(subreq, &err);
     706         849 :         TALLOC_FREE(subreq);
     707         849 :         if (sent == -1) {
     708          37 :                 DEBUG(10, ("sendto failed: %s\n", strerror(err)));
     709          37 :                 tevent_req_nterror(req, map_nt_error_from_unix(err));
     710          37 :                 return;
     711             :         }
     712         812 :         subreq = tevent_wakeup_send(state, state->ev,
     713             :                                     timeval_current_ofs(1, 0));
     714         812 :         if (tevent_req_nomem(subreq, req)) {
     715           0 :                 return;
     716             :         }
     717         812 :         tevent_req_set_callback(subreq, nb_trans_send_next, req);
     718             : }
     719             : 
     720           0 : static void nb_trans_send_next(struct tevent_req *subreq)
     721             : {
     722           0 :         struct tevent_req *req = tevent_req_callback_data(
     723             :                 subreq, struct tevent_req);
     724           0 :         struct nb_trans_state *state = tevent_req_data(
     725             :                 req, struct nb_trans_state);
     726           0 :         bool ret;
     727             : 
     728           0 :         ret = tevent_wakeup_recv(subreq);
     729           0 :         TALLOC_FREE(subreq);
     730           0 :         if (!ret) {
     731           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
     732           0 :                 return;
     733             :         }
     734           0 :         subreq = tdgram_sendto_send(state, state->ev,
     735             :                                     state->sock,
     736           0 :                                     state->buf, state->buflen,
     737           0 :                                     state->dst_addr);
     738           0 :         if (tevent_req_nomem(subreq, req)) {
     739           0 :                 return;
     740             :         }
     741           0 :         tevent_req_set_callback(subreq, nb_trans_sent, req);
     742             : }
     743             : 
     744         336 : static void nb_trans_done(struct tevent_req *subreq)
     745             : {
     746         336 :         struct tevent_req *req = tevent_req_callback_data(
     747             :                 subreq, struct tevent_req);
     748         336 :         struct nb_trans_state *state = tevent_req_data(
     749             :                 req, struct nb_trans_state);
     750           0 :         NTSTATUS status;
     751             : 
     752         336 :         status = sock_packet_read_recv(subreq, state, &state->packet);
     753         336 :         TALLOC_FREE(subreq);
     754         336 :         if (tevent_req_nterror(req, status)) {
     755           0 :                 return;
     756             :         }
     757         336 :         tevent_req_done(req);
     758             : }
     759             : 
     760         373 : static NTSTATUS nb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     761             :                               struct packet_struct **ppacket)
     762             : {
     763         373 :         struct nb_trans_state *state = tevent_req_data(
     764             :                 req, struct nb_trans_state);
     765           0 :         NTSTATUS status;
     766             : 
     767         373 :         if (tevent_req_is_nterror(req, &status)) {
     768          37 :                 return status;
     769             :         }
     770         336 :         *ppacket = talloc_move(mem_ctx, &state->packet);
     771         336 :         return NT_STATUS_OK;
     772             : }
     773             : 
     774             : /****************************************************************************
     775             :  Do a NBT node status query on an open socket and return an array of
     776             :  structures holding the returned names or NULL if the query failed.
     777             : **************************************************************************/
     778             : 
     779             : struct node_status_query_state {
     780             :         struct samba_sockaddr my_addr;
     781             :         struct samba_sockaddr addr;
     782             :         uint8_t buf[1024];
     783             :         ssize_t buflen;
     784             :         struct packet_struct *packet;
     785             : };
     786             : 
     787             : static bool node_status_query_validator(struct packet_struct *p,
     788             :                                         void *private_data);
     789             : static void node_status_query_done(struct tevent_req *subreq);
     790             : 
     791          60 : struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx,
     792             :                                           struct tevent_context *ev,
     793             :                                           struct nmb_name *name,
     794             :                                           const struct sockaddr_storage *addr)
     795             : {
     796           0 :         struct tevent_req *req, *subreq;
     797           0 :         struct node_status_query_state *state;
     798           0 :         struct packet_struct p;
     799          60 :         struct nmb_packet *nmb = &p.packet.nmb;
     800           0 :         bool ok;
     801             : 
     802          60 :         req = tevent_req_create(mem_ctx, &state,
     803             :                                 struct node_status_query_state);
     804          60 :         if (req == NULL) {
     805           0 :                 return NULL;
     806             :         }
     807             : 
     808          60 :         if (addr->ss_family != AF_INET) {
     809             :                 /* Can't do node status to IPv6 */
     810           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
     811           0 :                 return tevent_req_post(req, ev);
     812             :         }
     813             : 
     814          60 :         ok = sockaddr_storage_to_samba_sockaddr(&state->addr, addr);
     815          60 :         if (!ok) {
     816             :                 /* node status must be IPv4 */
     817           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
     818           0 :                 return tevent_req_post(req, ev);
     819             :         }
     820          60 :         state->addr.u.in.sin_port = htons(NMB_PORT);
     821             : 
     822          60 :         set_socket_addr_v4(&state->my_addr);
     823             : 
     824          60 :         ZERO_STRUCT(p);
     825          60 :         nmb->header.name_trn_id = generate_trn_id();
     826          60 :         nmb->header.opcode = 0;
     827          60 :         nmb->header.response = false;
     828          60 :         nmb->header.nm_flags.bcast = false;
     829          60 :         nmb->header.nm_flags.recursion_available = false;
     830          60 :         nmb->header.nm_flags.recursion_desired = false;
     831          60 :         nmb->header.nm_flags.trunc = false;
     832          60 :         nmb->header.nm_flags.authoritative = false;
     833          60 :         nmb->header.rcode = 0;
     834          60 :         nmb->header.qdcount = 1;
     835          60 :         nmb->header.ancount = 0;
     836          60 :         nmb->header.nscount = 0;
     837          60 :         nmb->header.arcount = 0;
     838          60 :         nmb->question.question_name = *name;
     839          60 :         nmb->question.question_type = 0x21;
     840          60 :         nmb->question.question_class = 0x1;
     841             : 
     842          60 :         state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
     843             :                                      &p);
     844          60 :         if (state->buflen == 0) {
     845           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
     846           0 :                 DEBUG(10, ("build_packet failed\n"));
     847           0 :                 return tevent_req_post(req, ev);
     848             :         }
     849             : 
     850          60 :         subreq = nb_trans_send(state,
     851             :                                 ev,
     852          60 :                                 &state->my_addr,
     853          60 :                                 &state->addr,
     854             :                                 false,
     855          60 :                                 state->buf,
     856          60 :                                 state->buflen,
     857             :                                 NMB_PACKET,
     858             :                                 nmb->header.name_trn_id,
     859             :                                 node_status_query_validator,
     860             :                                 NULL);
     861          60 :         if (tevent_req_nomem(subreq, req)) {
     862           0 :                 DEBUG(10, ("nb_trans_send failed\n"));
     863           0 :                 return tevent_req_post(req, ev);
     864             :         }
     865          60 :         if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(10, 0))) {
     866           0 :                 return tevent_req_post(req, ev);
     867             :         }
     868          60 :         tevent_req_set_callback(subreq, node_status_query_done, req);
     869          60 :         return req;
     870             : }
     871             : 
     872          60 : static bool node_status_query_validator(struct packet_struct *p,
     873             :                                         void *private_data)
     874             : {
     875          60 :         struct nmb_packet *nmb = &p->packet.nmb;
     876          60 :         debug_nmb_packet(p);
     877             : 
     878          60 :         if (nmb->header.opcode != 0 ||
     879          60 :             nmb->header.nm_flags.bcast ||
     880          60 :             nmb->header.rcode ||
     881          60 :             !nmb->header.ancount ||
     882          60 :             nmb->answers->rr_type != 0x21) {
     883             :                 /*
     884             :                  * XXXX what do we do with this? could be a redirect,
     885             :                  * but we'll discard it for the moment
     886             :                  */
     887           0 :                 return false;
     888             :         }
     889          60 :         return true;
     890             : }
     891             : 
     892          60 : static void node_status_query_done(struct tevent_req *subreq)
     893             : {
     894          60 :         struct tevent_req *req = tevent_req_callback_data(
     895             :                 subreq, struct tevent_req);
     896          60 :         struct node_status_query_state *state = tevent_req_data(
     897             :                 req, struct node_status_query_state);
     898           0 :         NTSTATUS status;
     899             : 
     900          60 :         status = nb_trans_recv(subreq, state, &state->packet);
     901          60 :         TALLOC_FREE(subreq);
     902          60 :         if (tevent_req_nterror(req, status)) {
     903           0 :                 return;
     904             :         }
     905          60 :         tevent_req_done(req);
     906             : }
     907             : 
     908          60 : NTSTATUS node_status_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     909             :                                 struct node_status **pnode_status,
     910             :                                 size_t *pnum_names,
     911             :                                 struct node_status_extra *extra)
     912             : {
     913          60 :         struct node_status_query_state *state = tevent_req_data(
     914             :                 req, struct node_status_query_state);
     915           0 :         struct node_status *node_status;
     916          60 :         size_t num_names = 0;
     917           0 :         NTSTATUS status;
     918             : 
     919          60 :         if (tevent_req_is_nterror(req, &status)) {
     920           0 :                 return status;
     921             :         }
     922          60 :         node_status = parse_node_status(
     923          60 :                 mem_ctx, &state->packet->packet.nmb.answers->rdata[0],
     924             :                 &num_names, extra);
     925          60 :         if (node_status == NULL) {
     926           0 :                 return NT_STATUS_NO_MEMORY;
     927             :         }
     928          60 :         *pnode_status = node_status;
     929          60 :         *pnum_names = num_names;
     930          60 :         return NT_STATUS_OK;
     931             : }
     932             : 
     933          56 : NTSTATUS node_status_query(TALLOC_CTX *mem_ctx, struct nmb_name *name,
     934             :                            const struct sockaddr_storage *addr,
     935             :                            struct node_status **pnode_status,
     936             :                            size_t *pnum_names,
     937             :                            struct node_status_extra *extra)
     938             : {
     939          56 :         TALLOC_CTX *frame = talloc_stackframe();
     940           0 :         struct tevent_context *ev;
     941           0 :         struct tevent_req *req;
     942          56 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
     943             : 
     944          56 :         ev = samba_tevent_context_init(frame);
     945          56 :         if (ev == NULL) {
     946           0 :                 goto fail;
     947             :         }
     948          56 :         req = node_status_query_send(ev, ev, name, addr);
     949          56 :         if (req == NULL) {
     950           0 :                 goto fail;
     951             :         }
     952          56 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     953           0 :                 goto fail;
     954             :         }
     955          56 :         status = node_status_query_recv(req, mem_ctx, pnode_status,
     956             :                                         pnum_names, extra);
     957          56 :  fail:
     958          56 :         TALLOC_FREE(frame);
     959          56 :         return status;
     960             : }
     961             : 
     962          56 : static bool name_status_lmhosts(const struct sockaddr_storage *paddr,
     963             :                                 int qname_type, fstring pname)
     964             : {
     965           0 :         FILE *f;
     966           0 :         char *name;
     967           0 :         int name_type;
     968          56 :         struct samba_sockaddr addr_in = {0};
     969          56 :         struct samba_sockaddr addr = {0};
     970           0 :         bool ok;
     971             : 
     972          56 :         ok = sockaddr_storage_to_samba_sockaddr(&addr_in, paddr);
     973          56 :         if (!ok) {
     974           0 :                 return false;
     975             :         }
     976          56 :         if (addr_in.u.ss.ss_family != AF_INET) {
     977           0 :                 return false;
     978             :         }
     979             : 
     980          56 :         f = startlmhosts(get_dyn_LMHOSTSFILE());
     981          56 :         if (f == NULL) {
     982          56 :                 return false;
     983             :         }
     984             : 
     985           0 :         while (getlmhostsent(talloc_tos(), f, &name, &name_type, &addr.u.ss)) {
     986           0 :                 if (addr.u.ss.ss_family != AF_INET) {
     987           0 :                         continue;
     988             :                 }
     989           0 :                 if (name_type != qname_type) {
     990           0 :                         continue;
     991             :                 }
     992           0 :                 if (sockaddr_equal(&addr_in.u.sa, &addr.u.sa)) {
     993           0 :                         fstrcpy(pname, name);
     994           0 :                         endlmhosts(f);
     995           0 :                         return true;
     996             :                 }
     997             :         }
     998           0 :         endlmhosts(f);
     999           0 :         return false;
    1000             : }
    1001             : 
    1002             : /****************************************************************************
    1003             :  Find the first type XX name in a node status reply - used for finding
    1004             :  a servers name given its IP. Return the matched name in *name.
    1005             : **************************************************************************/
    1006             : 
    1007          60 : bool name_status_find(const char *q_name,
    1008             :                         int q_type,
    1009             :                         int type,
    1010             :                         const struct sockaddr_storage *to_ss,
    1011             :                         fstring name)
    1012             : {
    1013           0 :         char addr[INET6_ADDRSTRLEN];
    1014          60 :         struct node_status *addrs = NULL;
    1015           0 :         struct nmb_name nname;
    1016          60 :         size_t count = 0, i;
    1017          60 :         bool result = false;
    1018           0 :         NTSTATUS status;
    1019             : 
    1020          60 :         if (lp_disable_netbios()) {
    1021           0 :                 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
    1022             :                                         q_name, q_type));
    1023           0 :                 return False;
    1024             :         }
    1025             : 
    1026          60 :         print_sockaddr(addr, sizeof(addr), to_ss);
    1027             : 
    1028          60 :         DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
    1029             :                    q_type, addr));
    1030             : 
    1031             :         /* Check the cache first. */
    1032             : 
    1033          60 :         if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
    1034           4 :                 return True;
    1035             :         }
    1036             : 
    1037          56 :         if (to_ss->ss_family != AF_INET) {
    1038             :                 /* Can't do node status to IPv6 */
    1039           0 :                 return false;
    1040             :         }
    1041             : 
    1042          56 :         result = name_status_lmhosts(to_ss, type, name);
    1043          56 :         if (result) {
    1044           0 :                 DBG_DEBUG("Found name %s in lmhosts\n", name);
    1045           0 :                 namecache_status_store(q_name, q_type, type, to_ss, name);
    1046           0 :                 return true;
    1047             :         }
    1048             : 
    1049             :         /* W2K PDC's seem not to respond to '*'#0. JRA */
    1050          56 :         make_nmb_name(&nname, q_name, q_type);
    1051          56 :         status = node_status_query(talloc_tos(), &nname, to_ss,
    1052             :                                    &addrs, &count, NULL);
    1053          56 :         if (!NT_STATUS_IS_OK(status)) {
    1054           0 :                 goto done;
    1055             :         }
    1056             : 
    1057         184 :         for (i=0;i<count;i++) {
    1058             :                 /* Find first one of the requested type that's not a GROUP. */
    1059         184 :                 if (addrs[i].type == type && ! (addrs[i].flags & 0x80))
    1060          56 :                         break;
    1061             :         }
    1062          56 :         if (i == count)
    1063           0 :                 goto done;
    1064             : 
    1065          56 :         pull_ascii_nstring(name, sizeof(fstring), addrs[i].name);
    1066             : 
    1067             :         /* Store the result in the cache. */
    1068             :         /* but don't store an entry for 0x1c names here.  Here we have
    1069             :            a single host and DOMAIN<0x1c> names should be a list of hosts */
    1070             : 
    1071          56 :         if ( q_type != 0x1c ) {
    1072          38 :                 namecache_status_store(q_name, q_type, type, to_ss, name);
    1073             :         }
    1074             : 
    1075          56 :         result = true;
    1076             : 
    1077          56 :  done:
    1078          56 :         TALLOC_FREE(addrs);
    1079             : 
    1080          56 :         DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
    1081             : 
    1082          56 :         if (result)
    1083          56 :                 DEBUGADD(10, (", name %s ip address is %s", name, addr));
    1084             : 
    1085          56 :         DEBUG(10, ("\n"));
    1086             : 
    1087          56 :         return result;
    1088             : }
    1089             : 
    1090             : /*
    1091             :  * comparison function used by sort_addr_list
    1092             :  *
    1093             :  * This comparison is intransitive in sort if a socket has an invalid
    1094             :  * family (i.e., not IPv4 or IPv6), or an interface doesn't support
    1095             :  * the family. Say we have sockaddrs with IP versions {4,5,6}, of
    1096             :  * which 5 is invalid. By this function, 4 == 5 and 6 == 5, but 4 !=
    1097             :  * 6. This is of course a consequence of cmp() being unable to
    1098             :  * communicate error.
    1099             :  */
    1100             : 
    1101          26 : static int addr_compare(const struct sockaddr_storage *ss1,
    1102             :                         const struct sockaddr_storage *ss2)
    1103             : {
    1104          26 :         int max_bits1=0, max_bits2=0;
    1105          26 :         int num_interfaces = iface_count();
    1106           0 :         int i;
    1107           0 :         struct samba_sockaddr sa1;
    1108           0 :         struct samba_sockaddr sa2;
    1109           0 :         bool ok;
    1110             : 
    1111          26 :         ok = sockaddr_storage_to_samba_sockaddr(&sa1, ss1);
    1112          26 :         if (!ok) {
    1113           0 :                 return 0; /* No change. */
    1114             :         }
    1115             : 
    1116          26 :         ok = sockaddr_storage_to_samba_sockaddr(&sa2, ss2);
    1117          26 :         if (!ok) {
    1118           0 :                 return 0; /* No change. */
    1119             :         }
    1120             : 
    1121             :         /* Sort IPv4 addresses first. */
    1122          26 :         if (sa1.u.ss.ss_family != sa2.u.ss.ss_family) {
    1123           0 :                 if (sa2.u.ss.ss_family == AF_INET) {
    1124           0 :                         return 1;
    1125             :                 } else {
    1126           0 :                         return -1;
    1127             :                 }
    1128             :         }
    1129             : 
    1130             :         /* Here we know both addresses are of the same
    1131             :          * family. */
    1132             : 
    1133         178 :         for (i=0;i<num_interfaces;i++) {
    1134         152 :                 struct samba_sockaddr sif = {0};
    1135         152 :                 const unsigned char *p_ss1 = NULL;
    1136         152 :                 const unsigned char *p_ss2 = NULL;
    1137         152 :                 const unsigned char *p_if = NULL;
    1138         152 :                 size_t len = 0;
    1139           0 :                 int bits1, bits2;
    1140             : 
    1141         152 :                 ok = sockaddr_storage_to_samba_sockaddr(&sif, iface_n_bcast(i));
    1142         152 :                 if (!ok) {
    1143           0 :                         return 0; /* No change. */
    1144             :                 }
    1145         152 :                 if (sif.u.ss.ss_family != sa1.u.ss.ss_family) {
    1146             :                         /* Ignore interfaces of the wrong type. */
    1147          26 :                         continue;
    1148             :                 }
    1149         126 :                 if (sif.u.ss.ss_family == AF_INET) {
    1150         126 :                         p_if = (const unsigned char *)&sif.u.in.sin_addr;
    1151         126 :                         p_ss1 = (const unsigned char *)&sa1.u.in.sin_addr;
    1152         126 :                         p_ss2 = (const unsigned char *)&sa2.u.in.sin_addr;
    1153         126 :                         len = 4;
    1154             :                 }
    1155             : #if defined(HAVE_IPV6)
    1156         126 :                 if (sif.u.ss.ss_family == AF_INET6) {
    1157           0 :                         p_if = (const unsigned char *)&sif.u.in6.sin6_addr;
    1158           0 :                         p_ss1 = (const unsigned char *)&sa1.u.in6.sin6_addr;
    1159           0 :                         p_ss2 = (const unsigned char *)&sa2.u.in6.sin6_addr;
    1160           0 :                         len = 16;
    1161             :                 }
    1162             : #endif
    1163         126 :                 if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
    1164           0 :                         continue;
    1165             :                 }
    1166         126 :                 bits1 = matching_len_bits(p_ss1, p_if, len);
    1167         126 :                 bits2 = matching_len_bits(p_ss2, p_if, len);
    1168         126 :                 max_bits1 = MAX(bits1, max_bits1);
    1169         126 :                 max_bits2 = MAX(bits2, max_bits2);
    1170             :         }
    1171             : 
    1172             :         /* Bias towards directly reachable IPs */
    1173          26 :         if (iface_local(&sa1.u.sa)) {
    1174          26 :                 if (sa1.u.ss.ss_family == AF_INET) {
    1175          26 :                         max_bits1 += 32;
    1176             :                 } else {
    1177           0 :                         max_bits1 += 128;
    1178             :                 }
    1179             :         }
    1180          26 :         if (iface_local(&sa2.u.sa)) {
    1181          26 :                 if (sa2.u.ss.ss_family == AF_INET) {
    1182          26 :                         max_bits2 += 32;
    1183             :                 } else {
    1184           0 :                         max_bits2 += 128;
    1185             :                 }
    1186             :         }
    1187          26 :         return NUMERIC_CMP(max_bits2, max_bits1);
    1188             : }
    1189             : 
    1190             : /*
    1191             :   sort an IP list so that names that are close to one of our interfaces
    1192             :   are at the top. This prevents the problem where a WINS server returns an IP
    1193             :   that is not reachable from our subnet as the first match
    1194             : */
    1195             : 
    1196         288 : static void sort_addr_list(struct sockaddr_storage *sslist, size_t count)
    1197             : {
    1198         288 :         if (count <= 1) {
    1199         282 :                 return;
    1200             :         }
    1201             : 
    1202           6 :         TYPESAFE_QSORT(sslist, count, addr_compare);
    1203             : }
    1204             : 
    1205           0 : static int samba_sockaddr_compare(struct samba_sockaddr *sa1,
    1206             :                                 struct samba_sockaddr *sa2)
    1207             : {
    1208           0 :         return addr_compare(&sa1->u.ss, &sa2->u.ss);
    1209             : }
    1210             : 
    1211           0 : static void sort_sa_list(struct samba_sockaddr *salist, size_t count)
    1212             : {
    1213           0 :         if (count <= 1) {
    1214           0 :                 return;
    1215             :         }
    1216             : 
    1217           0 :         TYPESAFE_QSORT(salist, count, samba_sockaddr_compare);
    1218             : }
    1219             : 
    1220             : /**********************************************************************
    1221             :  Remove any duplicate address/port pairs in the samba_sockaddr array.
    1222             :  *********************************************************************/
    1223             : 
    1224       10686 : size_t remove_duplicate_addrs2(struct samba_sockaddr *salist, size_t count )
    1225             : {
    1226           1 :         size_t i, j;
    1227             : 
    1228       10686 :         DBG_DEBUG("looking for duplicate address/port pairs\n");
    1229             : 
    1230             :         /* One loop to set duplicates to a zero addr. */
    1231       32193 :         for (i=0; i < count; i++) {
    1232       21507 :                 if (is_zero_addr(&salist[i].u.ss)) {
    1233         599 :                         continue;
    1234             :                 }
    1235             : 
    1236       31905 :                 for (j=i+1; j<count; j++) {
    1237       10997 :                         if (sockaddr_equal(&salist[i].u.sa, &salist[j].u.sa)) {
    1238         589 :                                 zero_sockaddr(&salist[j].u.ss);
    1239             :                         }
    1240             :                 }
    1241             :         }
    1242             : 
    1243             :         /* Now remove any addresses set to zero above. */
    1244       31699 :         for (i = 0; i < count; i++) {
    1245       43090 :                 while (i < count &&
    1246       21507 :                                 is_zero_addr(&salist[i].u.ss)) {
    1247         628 :                         ARRAY_DEL_ELEMENT(salist, i, count);
    1248         585 :                         count--;
    1249             :                 }
    1250             :         }
    1251             : 
    1252       10686 :         return count;
    1253             : }
    1254             : 
    1255         744 : static bool prioritize_ipv4_list(struct samba_sockaddr *salist, size_t count)
    1256             : {
    1257         744 :         TALLOC_CTX *frame = talloc_stackframe();
    1258         744 :         struct samba_sockaddr *salist_new = talloc_array(frame,
    1259             :                                                 struct samba_sockaddr,
    1260             :                                                 count);
    1261           0 :         size_t i, j;
    1262             : 
    1263         744 :         if (salist_new == NULL) {
    1264           0 :                 TALLOC_FREE(frame);
    1265           0 :                 return false;
    1266             :         }
    1267             : 
    1268         744 :         j = 0;
    1269             : 
    1270             :         /* Copy IPv4 first. */
    1271        2062 :         for (i = 0; i < count; i++) {
    1272        1318 :                 if (salist[i].u.ss.ss_family == AF_INET) {
    1273         752 :                         salist_new[j++] = salist[i];
    1274             :                 }
    1275             :         }
    1276             : 
    1277             :         /* Copy IPv6. */
    1278        2062 :         for (i = 0; i < count; i++) {
    1279        1318 :                 if (salist[i].u.ss.ss_family != AF_INET) {
    1280         566 :                         salist_new[j++] = salist[i];
    1281             :                 }
    1282             :         }
    1283             : 
    1284         744 :         memcpy(salist, salist_new, sizeof(struct samba_sockaddr)*count);
    1285         744 :         TALLOC_FREE(frame);
    1286         744 :         return true;
    1287             : }
    1288             : 
    1289             : /****************************************************************************
    1290             :  Do a netbios name query to find someones IP.
    1291             :  Returns an array of IP addresses or NULL if none.
    1292             :  *count will be set to the number of addresses returned.
    1293             :  *timed_out is set if we failed by timing out
    1294             : ****************************************************************************/
    1295             : 
    1296             : struct name_query_state {
    1297             :         struct samba_sockaddr my_addr;
    1298             :         struct samba_sockaddr addr;
    1299             :         bool bcast;
    1300             :         bool bcast_star_query;
    1301             : 
    1302             : 
    1303             :         uint8_t buf[1024];
    1304             :         ssize_t buflen;
    1305             : 
    1306             :         NTSTATUS validate_error;
    1307             :         uint8_t flags;
    1308             : 
    1309             :         struct sockaddr_storage *addrs;
    1310             :         size_t num_addrs;
    1311             : };
    1312             : 
    1313             : static bool name_query_validator(struct packet_struct *p, void *private_data);
    1314             : static void name_query_done(struct tevent_req *subreq);
    1315             : 
    1316         789 : struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx,
    1317             :                                    struct tevent_context *ev,
    1318             :                                    const char *name, int name_type,
    1319             :                                    bool bcast, bool recurse,
    1320             :                                    const struct sockaddr_storage *addr)
    1321             : {
    1322           0 :         struct tevent_req *req, *subreq;
    1323           0 :         struct name_query_state *state;
    1324           0 :         struct packet_struct p;
    1325         789 :         struct nmb_packet *nmb = &p.packet.nmb;
    1326           0 :         bool ok;
    1327             : 
    1328         789 :         req = tevent_req_create(mem_ctx, &state, struct name_query_state);
    1329         789 :         if (req == NULL) {
    1330           0 :                 return NULL;
    1331             :         }
    1332         789 :         state->bcast = bcast;
    1333             : 
    1334         789 :         if (addr->ss_family != AF_INET) {
    1335             :                 /* Can't do node status to IPv6 */
    1336           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
    1337           0 :                 return tevent_req_post(req, ev);
    1338             :         }
    1339             : 
    1340         789 :         if (lp_disable_netbios()) {
    1341           0 :                 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
    1342             :                                         name, name_type));
    1343           0 :                 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
    1344           0 :                 return tevent_req_post(req, ev);
    1345             :         }
    1346             : 
    1347         789 :         ok = sockaddr_storage_to_samba_sockaddr(&state->addr, addr);
    1348         789 :         if (!ok) {
    1349             :                 /* Node status must be IPv4 */
    1350           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
    1351           0 :                 return tevent_req_post(req, ev);
    1352             :         }
    1353         789 :         state->addr.u.in.sin_port = htons(NMB_PORT);
    1354             : 
    1355         789 :         set_socket_addr_v4(&state->my_addr);
    1356             : 
    1357         789 :         ZERO_STRUCT(p);
    1358         789 :         nmb->header.name_trn_id = generate_trn_id();
    1359         789 :         nmb->header.opcode = 0;
    1360         789 :         nmb->header.response = false;
    1361         789 :         nmb->header.nm_flags.bcast = bcast;
    1362         789 :         nmb->header.nm_flags.recursion_available = false;
    1363         789 :         nmb->header.nm_flags.recursion_desired = recurse;
    1364         789 :         nmb->header.nm_flags.trunc = false;
    1365         789 :         nmb->header.nm_flags.authoritative = false;
    1366         789 :         nmb->header.rcode = 0;
    1367         789 :         nmb->header.qdcount = 1;
    1368         789 :         nmb->header.ancount = 0;
    1369         789 :         nmb->header.nscount = 0;
    1370         789 :         nmb->header.arcount = 0;
    1371             : 
    1372         789 :         if (bcast && (strcmp(name, "*")==0)) {
    1373             :                 /*
    1374             :                  * We're doing a broadcast query for all
    1375             :                  * names in the area. Remember this so
    1376             :                  * we will wait for all names within
    1377             :                  * the timeout period.
    1378             :                  */
    1379           0 :                 state->bcast_star_query = true;
    1380             :         }
    1381             : 
    1382         789 :         make_nmb_name(&nmb->question.question_name,name,name_type);
    1383             : 
    1384         789 :         nmb->question.question_type = 0x20;
    1385         789 :         nmb->question.question_class = 0x1;
    1386             : 
    1387         789 :         state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
    1388             :                                      &p);
    1389         789 :         if (state->buflen == 0) {
    1390           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
    1391           0 :                 DEBUG(10, ("build_packet failed\n"));
    1392           0 :                 return tevent_req_post(req, ev);
    1393             :         }
    1394             : 
    1395         789 :         subreq = nb_trans_send(state,
    1396             :                                 ev,
    1397         789 :                                 &state->my_addr,
    1398         789 :                                 &state->addr,
    1399             :                                 bcast,
    1400         789 :                                 state->buf,
    1401         789 :                                 state->buflen,
    1402             :                                 NMB_PACKET,
    1403             :                                 nmb->header.name_trn_id,
    1404             :                                 name_query_validator,
    1405             :                                 state);
    1406         789 :         if (tevent_req_nomem(subreq, req)) {
    1407           0 :                 DEBUG(10, ("nb_trans_send failed\n"));
    1408           0 :                 return tevent_req_post(req, ev);
    1409             :         }
    1410         789 :         tevent_req_set_callback(subreq, name_query_done, req);
    1411         789 :         return req;
    1412             : }
    1413             : 
    1414         384 : static bool name_query_validator(struct packet_struct *p, void *private_data)
    1415             : {
    1416         384 :         struct name_query_state *state = talloc_get_type_abort(
    1417             :                 private_data, struct name_query_state);
    1418         384 :         struct nmb_packet *nmb = &p->packet.nmb;
    1419           0 :         struct sockaddr_storage *tmp_addrs;
    1420         384 :         bool got_unique_netbios_name = false;
    1421           0 :         int i;
    1422             : 
    1423         384 :         debug_nmb_packet(p);
    1424             : 
    1425             :         /*
    1426             :          * If we get a Negative Name Query Response from a WINS
    1427             :          * server, we should report it and give up.
    1428             :          */
    1429         384 :         if( 0 == nmb->header.opcode  /* A query response   */
    1430         384 :             && !state->bcast         /* from a WINS server */
    1431         129 :             && nmb->header.rcode     /* Error returned     */
    1432             :                 ) {
    1433             : 
    1434           0 :                 if( DEBUGLVL( 3 ) ) {
    1435             :                         /* Only executed if DEBUGLEVEL >= 3 */
    1436           0 :                         dbgtext( "Negative name query "
    1437             :                                  "response, rcode 0x%02x: ",
    1438             :                                  nmb->header.rcode );
    1439           0 :                         switch( nmb->header.rcode ) {
    1440           0 :                         case 0x01:
    1441           0 :                                 dbgtext("Request was invalidly formatted.\n");
    1442           0 :                                 break;
    1443           0 :                         case 0x02:
    1444           0 :                                 dbgtext("Problem with NBNS, cannot process "
    1445             :                                         "name.\n");
    1446           0 :                                 break;
    1447           0 :                         case 0x03:
    1448           0 :                                 dbgtext("The name requested does not "
    1449             :                                         "exist.\n");
    1450           0 :                                 break;
    1451           0 :                         case 0x04:
    1452           0 :                                 dbgtext("Unsupported request error.\n");
    1453           0 :                                 break;
    1454           0 :                         case 0x05:
    1455           0 :                                 dbgtext("Query refused error.\n");
    1456           0 :                                 break;
    1457           0 :                         default:
    1458           0 :                                 dbgtext("Unrecognized error code.\n" );
    1459           0 :                                 break;
    1460             :                         }
    1461             :                 }
    1462             : 
    1463             :                 /*
    1464             :                  * We accept this packet as valid, but tell the upper
    1465             :                  * layers that it's a negative response.
    1466             :                  */
    1467           0 :                 state->validate_error = NT_STATUS_NOT_FOUND;
    1468           0 :                 return true;
    1469             :         }
    1470             : 
    1471         384 :         if (nmb->header.opcode != 0 ||
    1472         384 :             nmb->header.nm_flags.bcast ||
    1473         384 :             nmb->header.rcode ||
    1474         384 :             !nmb->header.ancount) {
    1475             :                 /*
    1476             :                  * XXXX what do we do with this? Could be a redirect,
    1477             :                  * but we'll discard it for the moment.
    1478             :                  */
    1479           0 :                 return false;
    1480             :         }
    1481             : 
    1482         384 :         tmp_addrs = talloc_realloc(
    1483             :                 state, state->addrs, struct sockaddr_storage,
    1484             :                 state->num_addrs + nmb->answers->rdlength/6);
    1485         384 :         if (tmp_addrs == NULL) {
    1486           0 :                 state->validate_error = NT_STATUS_NO_MEMORY;
    1487           0 :                 return true;
    1488             :         }
    1489         384 :         state->addrs = tmp_addrs;
    1490             : 
    1491         384 :         DEBUG(2,("Got a positive name query response "
    1492             :                  "from %s ( ", inet_ntoa(p->ip)));
    1493             : 
    1494         768 :         for (i=0; i<nmb->answers->rdlength/6; i++) {
    1495           0 :                 uint16_t flags;
    1496           0 :                 struct in_addr ip;
    1497           0 :                 struct sockaddr_storage addr;
    1498         384 :                 struct samba_sockaddr sa = {0};
    1499           0 :                 bool ok;
    1500           0 :                 size_t j;
    1501             : 
    1502         384 :                 flags = RSVAL(&nmb->answers->rdata[i*6], 0);
    1503         384 :                 got_unique_netbios_name |= ((flags & 0x8000) == 0);
    1504             : 
    1505         384 :                 putip((char *)&ip,&nmb->answers->rdata[2+i*6]);
    1506         384 :                 in_addr_to_sockaddr_storage(&addr, ip);
    1507             : 
    1508         384 :                 ok = sockaddr_storage_to_samba_sockaddr(&sa, &addr);
    1509         384 :                 if (!ok) {
    1510           0 :                         continue;
    1511             :                 }
    1512             : 
    1513         384 :                 if (is_zero_addr(&sa.u.ss)) {
    1514           0 :                         continue;
    1515             :                 }
    1516             : 
    1517         534 :                 for (j=0; j<state->num_addrs; j++) {
    1518         150 :                         struct samba_sockaddr sa_j = {0};
    1519             : 
    1520         150 :                         ok = sockaddr_storage_to_samba_sockaddr(&sa_j,
    1521         150 :                                                 &state->addrs[j]);
    1522         150 :                         if (!ok) {
    1523           0 :                                 continue;
    1524             :                         }
    1525         150 :                         if (sockaddr_equal(&sa.u.sa, &sa_j.u.sa)) {
    1526           0 :                                 break;
    1527             :                         }
    1528             :                 }
    1529         384 :                 if (j < state->num_addrs) {
    1530             :                         /* Already got it */
    1531           0 :                         continue;
    1532             :                 }
    1533             : 
    1534         384 :                 DEBUGADD(2,("%s ",inet_ntoa(ip)));
    1535             : 
    1536         384 :                 state->addrs[state->num_addrs] = addr;
    1537             :                 /* wrap check. */
    1538         384 :                 if (state->num_addrs + 1 < state->num_addrs) {
    1539           0 :                         return false;
    1540             :                 }
    1541         384 :                 state->num_addrs += 1;
    1542             :         }
    1543         384 :         DEBUGADD(2,(")\n"));
    1544             : 
    1545             :         /* We add the flags back ... */
    1546         384 :         if (nmb->header.response)
    1547         384 :                 state->flags |= NM_FLAGS_RS;
    1548         384 :         if (nmb->header.nm_flags.authoritative)
    1549         384 :                 state->flags |= NM_FLAGS_AA;
    1550         384 :         if (nmb->header.nm_flags.trunc)
    1551           0 :                 state->flags |= NM_FLAGS_TC;
    1552         384 :         if (nmb->header.nm_flags.recursion_desired)
    1553         384 :                 state->flags |= NM_FLAGS_RD;
    1554         384 :         if (nmb->header.nm_flags.recursion_available)
    1555         384 :                 state->flags |= NM_FLAGS_RA;
    1556         384 :         if (nmb->header.nm_flags.bcast)
    1557           0 :                 state->flags |= NM_FLAGS_B;
    1558             : 
    1559         384 :         if (state->bcast) {
    1560             :                 /*
    1561             :                  * We have to collect all entries coming in from broadcast
    1562             :                  * queries. If we got a unique name and we are not querying
    1563             :                  * all names registered within broadcast area (query
    1564             :                  * for the name '*', so state->bcast_star_query is set),
    1565             :                  * we're done.
    1566             :                  */
    1567         255 :                 return (got_unique_netbios_name && !state->bcast_star_query);
    1568             :         }
    1569             :         /*
    1570             :          * WINS responses are accepted when they are received
    1571             :          */
    1572         129 :         return true;
    1573             : }
    1574             : 
    1575         313 : static void name_query_done(struct tevent_req *subreq)
    1576             : {
    1577         313 :         struct tevent_req *req = tevent_req_callback_data(
    1578             :                 subreq, struct tevent_req);
    1579         313 :         struct name_query_state *state = tevent_req_data(
    1580             :                 req, struct name_query_state);
    1581           0 :         NTSTATUS status;
    1582         313 :         struct packet_struct *p = NULL;
    1583             : 
    1584         313 :         status = nb_trans_recv(subreq, state, &p);
    1585         313 :         TALLOC_FREE(subreq);
    1586         313 :         if (tevent_req_nterror(req, status)) {
    1587          37 :                 return;
    1588             :         }
    1589         276 :         if (!NT_STATUS_IS_OK(state->validate_error)) {
    1590           0 :                 tevent_req_nterror(req, state->validate_error);
    1591           0 :                 return;
    1592             :         }
    1593         276 :         tevent_req_done(req);
    1594             : }
    1595             : 
    1596         564 : NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
    1597             :                          struct sockaddr_storage **addrs, size_t *num_addrs,
    1598             :                          uint8_t *flags)
    1599             : {
    1600         564 :         struct name_query_state *state = tevent_req_data(
    1601             :                 req, struct name_query_state);
    1602           0 :         NTSTATUS status;
    1603             : 
    1604         564 :         if (tevent_req_is_nterror(req, &status)) {
    1605         288 :                 if (state->bcast &&
    1606         251 :                     NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
    1607             :                         /*
    1608             :                          * In the broadcast case we collect replies until the
    1609             :                          * timeout.
    1610             :                          */
    1611         251 :                         status = NT_STATUS_OK;
    1612             :                 }
    1613         288 :                 if (!NT_STATUS_IS_OK(status)) {
    1614          37 :                         return status;
    1615             :                 }
    1616             :         }
    1617         527 :         if (state->num_addrs == 0) {
    1618         239 :                 return NT_STATUS_NOT_FOUND;
    1619             :         }
    1620         288 :         *addrs = talloc_move(mem_ctx, &state->addrs);
    1621         288 :         sort_addr_list(*addrs, state->num_addrs);
    1622         288 :         *num_addrs = state->num_addrs;
    1623         288 :         if (flags != NULL) {
    1624         288 :                 *flags = state->flags;
    1625             :         }
    1626         288 :         return NT_STATUS_OK;
    1627             : }
    1628             : 
    1629         129 : NTSTATUS name_query(const char *name, int name_type,
    1630             :                     bool bcast, bool recurse,
    1631             :                     const struct sockaddr_storage *to_ss,
    1632             :                     TALLOC_CTX *mem_ctx,
    1633             :                     struct sockaddr_storage **addrs,
    1634             :                     size_t *num_addrs, uint8_t *flags)
    1635             : {
    1636         129 :         TALLOC_CTX *frame = talloc_stackframe();
    1637           0 :         struct tevent_context *ev;
    1638           0 :         struct tevent_req *req;
    1639           0 :         struct timeval timeout;
    1640         129 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
    1641             : 
    1642         129 :         ev = samba_tevent_context_init(frame);
    1643         129 :         if (ev == NULL) {
    1644           0 :                 goto fail;
    1645             :         }
    1646         129 :         req = name_query_send(ev, ev, name, name_type, bcast, recurse, to_ss);
    1647         129 :         if (req == NULL) {
    1648           0 :                 goto fail;
    1649             :         }
    1650         129 :         if (bcast) {
    1651           0 :                 timeout = timeval_current_ofs(0, 250000);
    1652             :         } else {
    1653         129 :                 timeout = timeval_current_ofs(2, 0);
    1654             :         }
    1655         129 :         if (!tevent_req_set_endtime(req, ev, timeout)) {
    1656           0 :                 goto fail;
    1657             :         }
    1658         129 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    1659           0 :                 goto fail;
    1660             :         }
    1661         129 :         status = name_query_recv(req, mem_ctx, addrs, num_addrs, flags);
    1662         129 :  fail:
    1663         129 :         TALLOC_FREE(frame);
    1664         129 :         return status;
    1665             : }
    1666             : 
    1667             : struct name_queries_state {
    1668             :         struct tevent_context *ev;
    1669             :         const char *name;
    1670             :         int name_type;
    1671             :         bool bcast;
    1672             :         bool recurse;
    1673             :         const struct sockaddr_storage *addrs;
    1674             :         size_t num_addrs;
    1675             :         int wait_msec;
    1676             :         int timeout_msec;
    1677             : 
    1678             :         struct tevent_req **subreqs;
    1679             :         size_t num_received;
    1680             :         size_t num_sent;
    1681             : 
    1682             :         size_t received_index;
    1683             :         struct sockaddr_storage *result_addrs;
    1684             :         size_t num_result_addrs;
    1685             :         uint8_t flags;
    1686             : };
    1687             : 
    1688             : static void name_queries_done(struct tevent_req *subreq);
    1689             : static void name_queries_next(struct tevent_req *subreq);
    1690             : 
    1691             : /*
    1692             :  * Send a name query to multiple destinations with a wait time in between
    1693             :  */
    1694             : 
    1695         298 : static struct tevent_req *name_queries_send(
    1696             :         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
    1697             :         const char *name, int name_type,
    1698             :         bool bcast, bool recurse,
    1699             :         const struct sockaddr_storage *addrs,
    1700             :         size_t num_addrs, int wait_msec, int timeout_msec)
    1701             : {
    1702           0 :         struct tevent_req *req, *subreq;
    1703           0 :         struct name_queries_state *state;
    1704             : 
    1705         298 :         req = tevent_req_create(mem_ctx, &state,
    1706             :                                 struct name_queries_state);
    1707         298 :         if (req == NULL) {
    1708           0 :                 return NULL;
    1709             :         }
    1710         298 :         state->ev = ev;
    1711         298 :         state->name = name;
    1712         298 :         state->name_type = name_type;
    1713         298 :         state->bcast = bcast;
    1714         298 :         state->recurse = recurse;
    1715         298 :         state->addrs = addrs;
    1716         298 :         state->num_addrs = num_addrs;
    1717         298 :         state->wait_msec = wait_msec;
    1718         298 :         state->timeout_msec = timeout_msec;
    1719             : 
    1720         298 :         state->subreqs = talloc_zero_array(
    1721             :                 state, struct tevent_req *, num_addrs);
    1722         298 :         if (tevent_req_nomem(state->subreqs, req)) {
    1723           0 :                 return tevent_req_post(req, ev);
    1724             :         }
    1725         298 :         state->num_sent = 0;
    1726             : 
    1727         298 :         subreq = name_query_send(
    1728         298 :                 state->subreqs, state->ev, name, name_type, bcast, recurse,
    1729         298 :                 &state->addrs[state->num_sent]);
    1730         298 :         if (tevent_req_nomem(subreq, req)) {
    1731           0 :                 return tevent_req_post(req, ev);
    1732             :         }
    1733         298 :         if (!tevent_req_set_endtime(
    1734         298 :                     subreq, state->ev,
    1735         298 :                     timeval_current_ofs(0, state->timeout_msec * 1000))) {
    1736           0 :                 return tevent_req_post(req, ev);
    1737             :         }
    1738         298 :         tevent_req_set_callback(subreq, name_queries_done, req);
    1739             : 
    1740         298 :         state->subreqs[state->num_sent] = subreq;
    1741         298 :         state->num_sent += 1;
    1742             : 
    1743         298 :         if (state->num_sent < state->num_addrs) {
    1744         130 :                 subreq = tevent_wakeup_send(
    1745          65 :                         state, state->ev,
    1746          65 :                         timeval_current_ofs(0, state->wait_msec * 1000));
    1747          65 :                 if (tevent_req_nomem(subreq, req)) {
    1748           0 :                         return tevent_req_post(req, ev);
    1749             :                 }
    1750          65 :                 tevent_req_set_callback(subreq, name_queries_next, req);
    1751             :         }
    1752         298 :         return req;
    1753             : }
    1754             : 
    1755         398 : static void name_queries_done(struct tevent_req *subreq)
    1756             : {
    1757         398 :         struct tevent_req *req = tevent_req_callback_data(
    1758             :                 subreq, struct tevent_req);
    1759         398 :         struct name_queries_state *state = tevent_req_data(
    1760             :                 req, struct name_queries_state);
    1761           0 :         size_t i;
    1762           0 :         NTSTATUS status;
    1763             : 
    1764         398 :         status = name_query_recv(subreq, state, &state->result_addrs,
    1765             :                                  &state->num_result_addrs, &state->flags);
    1766             : 
    1767         698 :         for (i=0; i<state->num_sent; i++) {
    1768         698 :                 if (state->subreqs[i] == subreq) {
    1769         398 :                         break;
    1770             :                 }
    1771             :         }
    1772         398 :         if (i == state->num_sent) {
    1773           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
    1774           0 :                 return;
    1775             :         }
    1776         398 :         TALLOC_FREE(state->subreqs[i]);
    1777             : 
    1778             :         /* wrap check. */
    1779         398 :         if (state->num_received + 1 < state->num_received) {
    1780           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1781           0 :                 return;
    1782             :         }
    1783         398 :         state->num_received += 1;
    1784             : 
    1785         398 :         if (!NT_STATUS_IS_OK(status)) {
    1786             : 
    1787         239 :                 if (state->num_received >= state->num_addrs) {
    1788         139 :                         tevent_req_nterror(req, status);
    1789         139 :                         return;
    1790             :                 }
    1791             :                 /*
    1792             :                  * Still outstanding requests, just wait
    1793             :                  */
    1794         100 :                 return;
    1795             :         }
    1796         159 :         state->received_index = i;
    1797         159 :         tevent_req_done(req);
    1798             : }
    1799             : 
    1800         325 : static void name_queries_next(struct tevent_req *subreq)
    1801             : {
    1802         325 :         struct tevent_req *req = tevent_req_callback_data(
    1803             :                 subreq, struct tevent_req);
    1804         325 :         struct name_queries_state *state = tevent_req_data(
    1805             :                 req, struct name_queries_state);
    1806             : 
    1807         325 :         if (!tevent_wakeup_recv(subreq)) {
    1808           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
    1809           0 :                 return;
    1810             :         }
    1811             : 
    1812         325 :         subreq = name_query_send(
    1813         325 :                 state->subreqs, state->ev,
    1814         325 :                 state->name, state->name_type, state->bcast, state->recurse,
    1815         325 :                 &state->addrs[state->num_sent]);
    1816         325 :         if (tevent_req_nomem(subreq, req)) {
    1817           0 :                 return;
    1818             :         }
    1819         325 :         tevent_req_set_callback(subreq, name_queries_done, req);
    1820         325 :         if (!tevent_req_set_endtime(
    1821             :                     subreq, state->ev,
    1822         325 :                     timeval_current_ofs(0, state->timeout_msec * 1000))) {
    1823           0 :                 return;
    1824             :         }
    1825         325 :         state->subreqs[state->num_sent] = subreq;
    1826         325 :         state->num_sent += 1;
    1827             : 
    1828         325 :         if (state->num_sent < state->num_addrs) {
    1829         260 :                 subreq = tevent_wakeup_send(
    1830             :                         state, state->ev,
    1831         260 :                         timeval_current_ofs(0, state->wait_msec * 1000));
    1832         260 :                 if (tevent_req_nomem(subreq, req)) {
    1833           0 :                         return;
    1834             :                 }
    1835         260 :                 tevent_req_set_callback(subreq, name_queries_next, req);
    1836             :         }
    1837             : }
    1838             : 
    1839         298 : static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
    1840             :                                   struct sockaddr_storage **result_addrs,
    1841             :                                   size_t *num_result_addrs, uint8_t *flags,
    1842             :                                   size_t *received_index)
    1843             : {
    1844         298 :         struct name_queries_state *state = tevent_req_data(
    1845             :                 req, struct name_queries_state);
    1846           0 :         NTSTATUS status;
    1847             : 
    1848         298 :         if (tevent_req_is_nterror(req, &status)) {
    1849         139 :                 return status;
    1850             :         }
    1851             : 
    1852         159 :         if (result_addrs != NULL) {
    1853         159 :                 *result_addrs = talloc_move(mem_ctx, &state->result_addrs);
    1854             :         }
    1855         159 :         if (num_result_addrs != NULL) {
    1856         159 :                 *num_result_addrs = state->num_result_addrs;
    1857             :         }
    1858         159 :         if (flags != NULL) {
    1859           0 :                 *flags = state->flags;
    1860             :         }
    1861         159 :         if (received_index != NULL) {
    1862           0 :                 *received_index = state->received_index;
    1863             :         }
    1864         159 :         return NT_STATUS_OK;
    1865             : }
    1866             : 
    1867             : /********************************************************
    1868             :  Resolve via "bcast" method.
    1869             : *********************************************************/
    1870             : 
    1871             : struct name_resolve_bcast_state {
    1872             :         struct sockaddr_storage *addrs;
    1873             :         size_t num_addrs;
    1874             : };
    1875             : 
    1876             : static void name_resolve_bcast_done(struct tevent_req *subreq);
    1877             : 
    1878         298 : struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx,
    1879             :                                            struct tevent_context *ev,
    1880             :                                            const char *name,
    1881             :                                            int name_type)
    1882             : {
    1883           0 :         struct tevent_req *req, *subreq;
    1884           0 :         struct name_resolve_bcast_state *state;
    1885           0 :         struct sockaddr_storage *bcast_addrs;
    1886           0 :         size_t i, num_addrs, num_bcast_addrs;
    1887             : 
    1888         298 :         req = tevent_req_create(mem_ctx, &state,
    1889             :                                 struct name_resolve_bcast_state);
    1890         298 :         if (req == NULL) {
    1891           0 :                 return NULL;
    1892             :         }
    1893             : 
    1894         298 :         if (lp_disable_netbios()) {
    1895           0 :                 DEBUG(5, ("name_resolve_bcast(%s#%02x): netbios is disabled\n",
    1896             :                           name, name_type));
    1897           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1898           0 :                 return tevent_req_post(req, ev);
    1899             :         }
    1900             : 
    1901             :         /*
    1902             :          * "bcast" means do a broadcast lookup on all the local interfaces.
    1903             :          */
    1904             : 
    1905         298 :         DEBUG(3, ("name_resolve_bcast: Attempting broadcast lookup "
    1906             :                   "for name %s<0x%x>\n", name, name_type));
    1907             : 
    1908         298 :         num_addrs = iface_count();
    1909         298 :         bcast_addrs = talloc_array(state, struct sockaddr_storage, num_addrs);
    1910         298 :         if (tevent_req_nomem(bcast_addrs, req)) {
    1911           0 :                 return tevent_req_post(req, ev);
    1912             :         }
    1913             : 
    1914             :         /*
    1915             :          * Lookup the name on all the interfaces, return on
    1916             :          * the first successful match.
    1917             :          */
    1918         298 :         num_bcast_addrs = 0;
    1919             : 
    1920        1219 :         for (i=0; i<num_addrs; i++) {
    1921         921 :                 const struct sockaddr_storage *pss = iface_n_bcast(i);
    1922             : 
    1923         921 :                 if (pss->ss_family != AF_INET) {
    1924         298 :                         continue;
    1925             :                 }
    1926         623 :                 bcast_addrs[num_bcast_addrs] = *pss;
    1927         623 :                 num_bcast_addrs += 1;
    1928             :         }
    1929             : 
    1930         298 :         subreq = name_queries_send(state, ev, name, name_type, true, true,
    1931             :                                    bcast_addrs, num_bcast_addrs, 0, 250);
    1932         298 :         if (tevent_req_nomem(subreq, req)) {
    1933           0 :                 return tevent_req_post(req, ev);
    1934             :         }
    1935         298 :         tevent_req_set_callback(subreq, name_resolve_bcast_done, req);
    1936         298 :         return req;
    1937             : }
    1938             : 
    1939         298 : static void name_resolve_bcast_done(struct tevent_req *subreq)
    1940             : {
    1941         298 :         struct tevent_req *req = tevent_req_callback_data(
    1942             :                 subreq, struct tevent_req);
    1943         298 :         struct name_resolve_bcast_state *state = tevent_req_data(
    1944             :                 req, struct name_resolve_bcast_state);
    1945           0 :         NTSTATUS status;
    1946             : 
    1947         298 :         status = name_queries_recv(subreq, state,
    1948             :                                    &state->addrs, &state->num_addrs,
    1949             :                                    NULL, NULL);
    1950         298 :         TALLOC_FREE(subreq);
    1951         298 :         if (tevent_req_nterror(req, status)) {
    1952         139 :                 return;
    1953             :         }
    1954         159 :         tevent_req_done(req);
    1955             : }
    1956             : 
    1957         298 : NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
    1958             :                                  struct sockaddr_storage **addrs,
    1959             :                                  size_t *num_addrs)
    1960             : {
    1961         298 :         struct name_resolve_bcast_state *state = tevent_req_data(
    1962             :                 req, struct name_resolve_bcast_state);
    1963           0 :         NTSTATUS status;
    1964             : 
    1965         298 :         if (tevent_req_is_nterror(req, &status)) {
    1966         139 :                 return status;
    1967             :         }
    1968         159 :         *addrs = talloc_move(mem_ctx, &state->addrs);
    1969         159 :         *num_addrs = state->num_addrs;
    1970         159 :         return NT_STATUS_OK;
    1971             : }
    1972             : 
    1973         294 : NTSTATUS name_resolve_bcast(TALLOC_CTX *mem_ctx,
    1974             :                         const char *name,
    1975             :                         int name_type,
    1976             :                         struct sockaddr_storage **return_iplist,
    1977             :                         size_t *return_count)
    1978             : {
    1979         294 :         TALLOC_CTX *frame = talloc_stackframe();
    1980           0 :         struct tevent_context *ev;
    1981           0 :         struct tevent_req *req;
    1982         294 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
    1983             : 
    1984         294 :         ev = samba_tevent_context_init(frame);
    1985         294 :         if (ev == NULL) {
    1986           0 :                 goto fail;
    1987             :         }
    1988         294 :         req = name_resolve_bcast_send(frame, ev, name, name_type);
    1989         294 :         if (req == NULL) {
    1990           0 :                 goto fail;
    1991             :         }
    1992         294 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    1993           0 :                 goto fail;
    1994             :         }
    1995         294 :         status = name_resolve_bcast_recv(req, mem_ctx, return_iplist,
    1996             :                                          return_count);
    1997         294 :  fail:
    1998         294 :         TALLOC_FREE(frame);
    1999         294 :         return status;
    2000             : }
    2001             : 
    2002             : struct query_wins_list_state {
    2003             :         struct tevent_context *ev;
    2004             :         const char *name;
    2005             :         uint8_t name_type;
    2006             :         struct in_addr *servers;
    2007             :         size_t num_servers;
    2008             :         struct sockaddr_storage server;
    2009             :         size_t num_sent;
    2010             : 
    2011             :         struct sockaddr_storage *addrs;
    2012             :         size_t num_addrs;
    2013             :         uint8_t flags;
    2014             : };
    2015             : 
    2016             : static void query_wins_list_done(struct tevent_req *subreq);
    2017             : 
    2018             : /*
    2019             :  * Query a list of (replicating) wins servers in sequence, call them
    2020             :  * dead if they don't reply
    2021             :  */
    2022             : 
    2023          37 : static struct tevent_req *query_wins_list_send(
    2024             :         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
    2025             :         struct in_addr src_ip, const char *name, uint8_t name_type,
    2026             :         struct in_addr *servers, size_t num_servers)
    2027             : {
    2028           0 :         struct tevent_req *req, *subreq;
    2029           0 :         struct query_wins_list_state *state;
    2030             : 
    2031          37 :         req = tevent_req_create(mem_ctx, &state,
    2032             :                                 struct query_wins_list_state);
    2033          37 :         if (req == NULL) {
    2034           0 :                 return NULL;
    2035             :         }
    2036          37 :         state->ev = ev;
    2037          37 :         state->name = name;
    2038          37 :         state->name_type = name_type;
    2039          37 :         state->servers = servers;
    2040          37 :         state->num_servers = num_servers;
    2041             : 
    2042          37 :         if (state->num_servers == 0) {
    2043           0 :                 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
    2044           0 :                 return tevent_req_post(req, ev);
    2045             :         }
    2046             : 
    2047          37 :         in_addr_to_sockaddr_storage(
    2048          37 :                 &state->server, state->servers[state->num_sent]);
    2049             : 
    2050          37 :         subreq = name_query_send(state, state->ev,
    2051          37 :                                  state->name, state->name_type,
    2052          37 :                                  false, true, &state->server);
    2053             : 
    2054          37 :         if (tevent_req_nomem(subreq, req)) {
    2055           0 :                 return tevent_req_post(req, ev);
    2056             :         }
    2057             : 
    2058             :         /* wrap check */
    2059          37 :         if (state->num_sent + 1 < state->num_sent) {
    2060           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2061           0 :                 return tevent_req_post(req, ev);
    2062             :         }
    2063             : 
    2064          37 :         state->num_sent += 1;
    2065          37 :         if (!tevent_req_set_endtime(subreq, state->ev,
    2066             :                                     timeval_current_ofs(2, 0))) {
    2067           0 :                 return tevent_req_post(req, ev);
    2068             :         }
    2069          37 :         tevent_req_set_callback(subreq, query_wins_list_done, req);
    2070          37 :         return req;
    2071             : }
    2072             : 
    2073          37 : static void query_wins_list_done(struct tevent_req *subreq)
    2074             : {
    2075          37 :         struct tevent_req *req = tevent_req_callback_data(
    2076             :                 subreq, struct tevent_req);
    2077          37 :         struct query_wins_list_state *state = tevent_req_data(
    2078             :                 req, struct query_wins_list_state);
    2079           0 :         NTSTATUS status;
    2080             : 
    2081          37 :         status = name_query_recv(subreq, state,
    2082             :                                  &state->addrs, &state->num_addrs,
    2083             :                                  &state->flags);
    2084          37 :         TALLOC_FREE(subreq);
    2085          37 :         if (NT_STATUS_IS_OK(status)) {
    2086           0 :                 tevent_req_done(req);
    2087          37 :                 return;
    2088             :         }
    2089          37 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
    2090          37 :                 tevent_req_nterror(req, status);
    2091          37 :                 return;
    2092             :         }
    2093           0 :         wins_srv_died(state->servers[state->num_sent-1],
    2094             :                       my_socket_addr_v4());
    2095             : 
    2096           0 :         if (state->num_sent == state->num_servers) {
    2097           0 :                 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
    2098           0 :                 return;
    2099             :         }
    2100             : 
    2101           0 :         in_addr_to_sockaddr_storage(
    2102           0 :                 &state->server, state->servers[state->num_sent]);
    2103             : 
    2104           0 :         subreq = name_query_send(state, state->ev,
    2105           0 :                                  state->name, state->name_type,
    2106           0 :                                  false, true, &state->server);
    2107           0 :         state->num_sent += 1;
    2108           0 :         if (tevent_req_nomem(subreq, req)) {
    2109           0 :                 return;
    2110             :         }
    2111           0 :         if (!tevent_req_set_endtime(subreq, state->ev,
    2112             :                                     timeval_current_ofs(2, 0))) {
    2113           0 :                 return;
    2114             :         }
    2115           0 :         tevent_req_set_callback(subreq, query_wins_list_done, req);
    2116             : }
    2117             : 
    2118          37 : static NTSTATUS query_wins_list_recv(struct tevent_req *req,
    2119             :                                      TALLOC_CTX *mem_ctx,
    2120             :                                      struct sockaddr_storage **addrs,
    2121             :                                      size_t *num_addrs,
    2122             :                                      uint8_t *flags)
    2123             : {
    2124          37 :         struct query_wins_list_state *state = tevent_req_data(
    2125             :                 req, struct query_wins_list_state);
    2126           0 :         NTSTATUS status;
    2127             : 
    2128          37 :         if (tevent_req_is_nterror(req, &status)) {
    2129          37 :                 return status;
    2130             :         }
    2131           0 :         if (addrs != NULL) {
    2132           0 :                 *addrs = talloc_move(mem_ctx, &state->addrs);
    2133             :         }
    2134           0 :         if (num_addrs != NULL) {
    2135           0 :                 *num_addrs = state->num_addrs;
    2136             :         }
    2137           0 :         if (flags != NULL) {
    2138           0 :                 *flags = state->flags;
    2139             :         }
    2140           0 :         return NT_STATUS_OK;
    2141             : }
    2142             : 
    2143             : struct resolve_wins_state {
    2144             :         size_t num_sent;
    2145             :         size_t num_received;
    2146             : 
    2147             :         struct sockaddr_storage *addrs;
    2148             :         size_t num_addrs;
    2149             :         uint8_t flags;
    2150             : };
    2151             : 
    2152             : static void resolve_wins_done(struct tevent_req *subreq);
    2153             : 
    2154         409 : struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx,
    2155             :                                      struct tevent_context *ev,
    2156             :                                      const char *name,
    2157             :                                      int name_type)
    2158             : {
    2159           0 :         struct tevent_req *req, *subreq;
    2160           0 :         struct resolve_wins_state *state;
    2161         409 :         char **wins_tags = NULL;
    2162           0 :         struct sockaddr_storage src_ss;
    2163         409 :         struct samba_sockaddr src_sa = {0};
    2164           0 :         struct in_addr src_ip;
    2165           0 :         size_t i, num_wins_tags;
    2166           0 :         bool ok;
    2167             : 
    2168         409 :         req = tevent_req_create(mem_ctx, &state,
    2169             :                                 struct resolve_wins_state);
    2170         409 :         if (req == NULL) {
    2171           0 :                 return NULL;
    2172             :         }
    2173             : 
    2174         409 :         if (wins_srv_count() < 1) {
    2175         369 :                 DEBUG(3,("resolve_wins: WINS server resolution selected "
    2176             :                         "and no WINS servers listed.\n"));
    2177         369 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2178         369 :                 goto fail;
    2179             :         }
    2180             : 
    2181             :         /* the address we will be sending from */
    2182          40 :         if (!interpret_string_addr(&src_ss, lp_nbt_client_socket_address(),
    2183             :                                 AI_NUMERICHOST|AI_PASSIVE)) {
    2184           0 :                 zero_sockaddr(&src_ss);
    2185             :         }
    2186             : 
    2187          40 :         ok = sockaddr_storage_to_samba_sockaddr(&src_sa, &src_ss);
    2188          40 :         if (!ok) {
    2189           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2190           0 :                 goto fail;
    2191             :         }
    2192             : 
    2193          40 :         if (src_sa.u.ss.ss_family != AF_INET) {
    2194           0 :                 char addr[INET6_ADDRSTRLEN];
    2195           0 :                 print_sockaddr(addr, sizeof(addr), &src_sa.u.ss);
    2196           0 :                 DEBUG(3,("resolve_wins: cannot receive WINS replies "
    2197             :                         "on IPv6 address %s\n",
    2198             :                         addr));
    2199           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2200           0 :                 goto fail;
    2201             :         }
    2202             : 
    2203          40 :         src_ip = src_sa.u.in.sin_addr;
    2204             : 
    2205          40 :         wins_tags = wins_srv_tags();
    2206          40 :         if (wins_tags == NULL) {
    2207           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2208           0 :                 goto fail;
    2209             :         }
    2210             : 
    2211          40 :         num_wins_tags = 0;
    2212          80 :         while (wins_tags[num_wins_tags] != NULL) {
    2213             :                 /* wrap check. */
    2214          40 :                 if (num_wins_tags + 1 < num_wins_tags) {
    2215           0 :                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2216           0 :                         goto fail;
    2217             :                 }
    2218          40 :                 num_wins_tags += 1;
    2219             :         }
    2220             : 
    2221          80 :         for (i=0; i<num_wins_tags; i++) {
    2222           0 :                 size_t num_servers, num_alive;
    2223           0 :                 struct in_addr *servers, *alive;
    2224           0 :                 size_t j;
    2225             : 
    2226          40 :                 if (!wins_server_tag_ips(wins_tags[i], talloc_tos(),
    2227             :                                          &servers, &num_servers)) {
    2228           3 :                         DEBUG(10, ("wins_server_tag_ips failed for tag %s\n",
    2229             :                                    wins_tags[i]));
    2230           3 :                         continue;
    2231             :                 }
    2232             : 
    2233          37 :                 alive = talloc_array(state, struct in_addr, num_servers);
    2234          37 :                 if (tevent_req_nomem(alive, req)) {
    2235           0 :                         goto fail;
    2236             :                 }
    2237             : 
    2238          37 :                 num_alive = 0;
    2239          74 :                 for (j=0; j<num_servers; j++) {
    2240          37 :                         struct in_addr wins_ip = servers[j];
    2241             : 
    2242          37 :                         if (global_in_nmbd && ismyip_v4(wins_ip)) {
    2243             :                                 /* yikes! we'll loop forever */
    2244           0 :                                 continue;
    2245             :                         }
    2246             :                         /* skip any that have been unresponsive lately */
    2247          37 :                         if (wins_srv_is_dead(wins_ip, src_ip)) {
    2248           0 :                                 continue;
    2249             :                         }
    2250          37 :                         DEBUG(3, ("resolve_wins: using WINS server %s "
    2251             :                                  "and tag '%s'\n",
    2252             :                                   inet_ntoa(wins_ip), wins_tags[i]));
    2253          37 :                         alive[num_alive] = wins_ip;
    2254          37 :                         num_alive += 1;
    2255             :                 }
    2256          37 :                 TALLOC_FREE(servers);
    2257             : 
    2258          37 :                 if (num_alive == 0) {
    2259           0 :                         continue;
    2260             :                 }
    2261             : 
    2262          37 :                 subreq = query_wins_list_send(
    2263             :                         state, ev, src_ip, name, name_type,
    2264             :                         alive, num_alive);
    2265          37 :                 if (tevent_req_nomem(subreq, req)) {
    2266           0 :                         goto fail;
    2267             :                 }
    2268          37 :                 tevent_req_set_callback(subreq, resolve_wins_done, req);
    2269          37 :                 state->num_sent += 1;
    2270             :         }
    2271             : 
    2272          40 :         if (state->num_sent == 0) {
    2273           3 :                 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
    2274           3 :                 goto fail;
    2275             :         }
    2276             : 
    2277          37 :         wins_srv_tags_free(wins_tags);
    2278          37 :         return req;
    2279         372 : fail:
    2280         372 :         wins_srv_tags_free(wins_tags);
    2281         372 :         return tevent_req_post(req, ev);
    2282             : }
    2283             : 
    2284          37 : static void resolve_wins_done(struct tevent_req *subreq)
    2285             : {
    2286          37 :         struct tevent_req *req = tevent_req_callback_data(
    2287             :                 subreq, struct tevent_req);
    2288          37 :         struct resolve_wins_state *state = tevent_req_data(
    2289             :                 req, struct resolve_wins_state);
    2290           0 :         NTSTATUS status;
    2291             : 
    2292          37 :         status = query_wins_list_recv(subreq, state, &state->addrs,
    2293             :                                       &state->num_addrs, &state->flags);
    2294          37 :         if (NT_STATUS_IS_OK(status)) {
    2295           0 :                 tevent_req_done(req);
    2296           0 :                 return;
    2297             :         }
    2298             : 
    2299             :         /* wrap check. */
    2300          37 :         if (state->num_received + 1 < state->num_received) {
    2301           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2302           0 :                 return;
    2303             :         }
    2304             : 
    2305          37 :         state->num_received += 1;
    2306             : 
    2307          37 :         if (state->num_received < state->num_sent) {
    2308             :                 /*
    2309             :                  * Wait for the others
    2310             :                  */
    2311           0 :                 return;
    2312             :         }
    2313          37 :         tevent_req_nterror(req, status);
    2314             : }
    2315             : 
    2316         409 : NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
    2317             :                            struct sockaddr_storage **addrs,
    2318             :                            size_t *num_addrs, uint8_t *flags)
    2319             : {
    2320         409 :         struct resolve_wins_state *state = tevent_req_data(
    2321             :                 req, struct resolve_wins_state);
    2322           0 :         NTSTATUS status;
    2323             : 
    2324         409 :         if (tevent_req_is_nterror(req, &status)) {
    2325         409 :                 return status;
    2326             :         }
    2327           0 :         if (addrs != NULL) {
    2328           0 :                 *addrs = talloc_move(mem_ctx, &state->addrs);
    2329             :         }
    2330           0 :         if (num_addrs != NULL) {
    2331           0 :                 *num_addrs = state->num_addrs;
    2332             :         }
    2333           0 :         if (flags != NULL) {
    2334           0 :                 *flags = state->flags;
    2335             :         }
    2336           0 :         return NT_STATUS_OK;
    2337             : }
    2338             : 
    2339             : /********************************************************
    2340             :  Resolve via "wins" method.
    2341             : *********************************************************/
    2342             : 
    2343         405 : NTSTATUS resolve_wins(TALLOC_CTX *mem_ctx,
    2344             :                 const char *name,
    2345             :                 int name_type,
    2346             :                 struct sockaddr_storage **return_iplist,
    2347             :                 size_t *return_count)
    2348             : {
    2349           0 :         struct tevent_context *ev;
    2350           0 :         struct tevent_req *req;
    2351         405 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
    2352             : 
    2353         405 :         ev = samba_tevent_context_init(talloc_tos());
    2354         405 :         if (ev == NULL) {
    2355           0 :                 goto fail;
    2356             :         }
    2357         405 :         req = resolve_wins_send(ev, ev, name, name_type);
    2358         405 :         if (req == NULL) {
    2359           0 :                 goto fail;
    2360             :         }
    2361         405 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    2362           0 :                 goto fail;
    2363             :         }
    2364         405 :         status = resolve_wins_recv(req, mem_ctx, return_iplist, return_count,
    2365             :                                    NULL);
    2366         405 : fail:
    2367         405 :         TALLOC_FREE(ev);
    2368         405 :         return status;
    2369             : }
    2370             : 
    2371             : 
    2372             : /********************************************************
    2373             :  Resolve via "hosts" method.
    2374             : *********************************************************/
    2375             : 
    2376         457 : static NTSTATUS resolve_hosts(TALLOC_CTX *mem_ctx,
    2377             :                               const char *name,
    2378             :                               int name_type,
    2379             :                               struct sockaddr_storage **return_iplist,
    2380             :                               size_t *return_count)
    2381             : {
    2382             :         /*
    2383             :          * "host" means do a localhost, or dns lookup.
    2384             :          */
    2385           0 :         struct addrinfo hints;
    2386         457 :         struct addrinfo *ailist = NULL;
    2387         457 :         struct addrinfo *res = NULL;
    2388         457 :         int ret = -1;
    2389         457 :         size_t i = 0;
    2390         457 :         size_t ret_count = 0;
    2391         457 :         struct sockaddr_storage *iplist = NULL;
    2392             : 
    2393         457 :         if ( name_type != 0x20 && name_type != 0x0) {
    2394          65 :                 DEBUG(5, ("resolve_hosts: not appropriate "
    2395             :                         "for name type <0x%x>\n",
    2396             :                         name_type));
    2397          65 :                 return NT_STATUS_INVALID_PARAMETER;
    2398             :         }
    2399             : 
    2400         392 :         DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
    2401             :                                 name, name_type));
    2402             : 
    2403         392 :         ZERO_STRUCT(hints);
    2404             :         /* By default make sure it supports TCP. */
    2405         392 :         hints.ai_socktype = SOCK_STREAM;
    2406         392 :         hints.ai_flags = AI_ADDRCONFIG;
    2407             : 
    2408             : #if !defined(HAVE_IPV6)
    2409             :         /* Unless we have IPv6, we really only want IPv4 addresses back. */
    2410             :         hints.ai_family = AF_INET;
    2411             : #endif
    2412             : 
    2413         392 :         ret = getaddrinfo(name,
    2414             :                         NULL,
    2415             :                         &hints,
    2416             :                         &ailist);
    2417         392 :         if (ret) {
    2418          12 :                 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
    2419             :                         name,
    2420             :                         gai_strerror(ret) ));
    2421             :         }
    2422             : 
    2423        1152 :         for (res = ailist; res; res = res->ai_next) {
    2424         760 :                 struct sockaddr_storage ss = {0};
    2425         760 :                 struct sockaddr_storage *tmp = NULL;
    2426             : 
    2427         760 :                 if ((res->ai_addr == NULL) ||
    2428         760 :                     (res->ai_addrlen == 0) ||
    2429         760 :                     (res->ai_addrlen > sizeof(ss))) {
    2430           0 :                         continue;
    2431             :                 }
    2432             : 
    2433         760 :                 memcpy(&ss, res->ai_addr, res->ai_addrlen);
    2434             : 
    2435         760 :                 if (is_zero_addr(&ss)) {
    2436           0 :                         continue;
    2437             :                 }
    2438             : 
    2439             :                 /* wrap check. */
    2440         760 :                 if (ret_count + 1 < ret_count) {
    2441           0 :                         freeaddrinfo(ailist);
    2442           0 :                         TALLOC_FREE(iplist);
    2443           0 :                         return NT_STATUS_INVALID_PARAMETER;
    2444             :                 }
    2445         760 :                 ret_count += 1;
    2446             : 
    2447         760 :                 tmp = talloc_realloc(
    2448             :                         mem_ctx, iplist, struct sockaddr_storage,
    2449             :                         ret_count);
    2450         760 :                 if (tmp == NULL) {
    2451           0 :                         DEBUG(3,("resolve_hosts: malloc fail !\n"));
    2452           0 :                         freeaddrinfo(ailist);
    2453           0 :                         TALLOC_FREE(iplist);
    2454           0 :                         return NT_STATUS_NO_MEMORY;
    2455             :                 }
    2456         760 :                 iplist = tmp;
    2457         760 :                 iplist[i] = ss;
    2458         760 :                 i++;
    2459             :         }
    2460         392 :         if (ailist) {
    2461         380 :                 freeaddrinfo(ailist);
    2462             :         }
    2463         392 :         if (ret_count == 0) {
    2464          12 :                 return NT_STATUS_UNSUCCESSFUL;
    2465             :         }
    2466         380 :         *return_count = ret_count;
    2467         380 :         *return_iplist = iplist;
    2468         380 :         return NT_STATUS_OK;
    2469             : }
    2470             : 
    2471             : /********************************************************
    2472             :  Resolve via "ADS" method.
    2473             : *********************************************************/
    2474             : 
    2475             : /* Special name type used to cause a _kerberos DNS lookup. */
    2476             : #define KDC_NAME_TYPE 0xDCDC
    2477             : 
    2478         389 : static NTSTATUS resolve_ads(TALLOC_CTX *ctx,
    2479             :                             const char *name,
    2480             :                             int name_type,
    2481             :                             const char *sitename,
    2482             :                             struct sockaddr_storage **return_addrs,
    2483             :                             size_t *return_count)
    2484             : {
    2485           0 :         size_t                  i;
    2486           0 :         NTSTATUS                status;
    2487         389 :         struct dns_rr_srv       *dcs = NULL;
    2488         389 :         size_t                  numdcs = 0;
    2489         389 :         size_t num_srv_addrs = 0;
    2490         389 :         struct sockaddr_storage *srv_addrs = NULL;
    2491         389 :         char *query = NULL;
    2492             : 
    2493         389 :         if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
    2494             :             (name_type != 0x1b)) {
    2495           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2496             :         }
    2497             : 
    2498         389 :         status = NT_STATUS_OK;
    2499             : 
    2500         389 :         switch (name_type) {
    2501           0 :                 case 0x1b:
    2502           0 :                         DEBUG(5,("resolve_ads: Attempting to resolve "
    2503             :                                  "PDC for %s using DNS\n", name));
    2504           0 :                         query = ads_dns_query_string_pdc(ctx, name);
    2505           0 :                         break;
    2506             : 
    2507          13 :                 case 0x1c:
    2508          13 :                         DEBUG(5,("resolve_ads: Attempting to resolve "
    2509             :                                  "DCs for %s using DNS\n", name));
    2510          13 :                         query = ads_dns_query_string_dcs(ctx, name);
    2511          13 :                         break;
    2512         376 :                 case KDC_NAME_TYPE:
    2513         376 :                         DEBUG(5,("resolve_ads: Attempting to resolve "
    2514             :                                  "KDCs for %s using DNS\n", name));
    2515         376 :                         query = ads_dns_query_string_kdcs(ctx, name);
    2516         376 :                         break;
    2517           0 :                 default:
    2518           0 :                         status = NT_STATUS_INVALID_PARAMETER;
    2519           0 :                         break;
    2520             :         }
    2521             : 
    2522         389 :         if (!NT_STATUS_IS_OK(status)) {
    2523           0 :                 return status;
    2524             :         }
    2525         389 :         if (query == NULL) {
    2526           0 :                 return NT_STATUS_NO_MEMORY;
    2527             :         }
    2528             : 
    2529         389 :         DBG_DEBUG("SRV query for %s\n", query);
    2530             : 
    2531         389 :         status = ads_dns_query_srv(
    2532             :                 ctx,
    2533             :                 lp_get_async_dns_timeout(),
    2534             :                 sitename,
    2535             :                 query,
    2536             :                 &dcs,
    2537             :                 &numdcs);
    2538         389 :         if (!NT_STATUS_IS_OK(status)) {
    2539           0 :                 return status;
    2540             :         }
    2541             : 
    2542         389 :         if (numdcs == 0) {
    2543           0 :                 *return_addrs = NULL;
    2544           0 :                 *return_count = 0;
    2545           0 :                 TALLOC_FREE(dcs);
    2546           0 :                 return NT_STATUS_OK;
    2547             :         }
    2548             : 
    2549             :         /* First count the sizes of each array. */
    2550         778 :         for(i = 0; i < numdcs; i++) {
    2551         389 :                 if (dcs[i].ss_s == NULL) {
    2552             :                         /*
    2553             :                          * Nothing received or timeout in A/AAAA reqs
    2554             :                          */
    2555           0 :                         continue;
    2556             :                 }
    2557             : 
    2558         389 :                 if (num_srv_addrs + dcs[i].num_ips < num_srv_addrs) {
    2559             :                         /* Wrap check. */
    2560           0 :                         TALLOC_FREE(dcs);
    2561           0 :                         return NT_STATUS_INVALID_PARAMETER;
    2562             :                 }
    2563             :                 /* Add in the number of addresses we got. */
    2564         389 :                 num_srv_addrs += dcs[i].num_ips;
    2565             :         }
    2566             : 
    2567             :         /* Allocate the list of IP addresses we already have. */
    2568         389 :         srv_addrs = talloc_zero_array(ctx,
    2569             :                                 struct sockaddr_storage,
    2570             :                                 num_srv_addrs);
    2571         389 :         if (srv_addrs == NULL) {
    2572           0 :                 TALLOC_FREE(dcs);
    2573           0 :                 return NT_STATUS_NO_MEMORY;
    2574             :         }
    2575             : 
    2576         389 :         num_srv_addrs = 0;
    2577         778 :         for(i = 0; i < numdcs; i++) {
    2578             :                 /* Copy all the IP addresses from the SRV response */
    2579             :                 size_t j;
    2580        1167 :                 for (j = 0; j < dcs[i].num_ips; j++) {
    2581           0 :                         char addr[INET6_ADDRSTRLEN];
    2582             : 
    2583         778 :                         srv_addrs[num_srv_addrs] = dcs[i].ss_s[j];
    2584         778 :                         if (is_zero_addr(&srv_addrs[num_srv_addrs])) {
    2585           0 :                                 continue;
    2586             :                         }
    2587             : 
    2588         778 :                         DBG_DEBUG("SRV lookup %s got IP[%zu] %s\n",
    2589             :                                 name,
    2590             :                                 j,
    2591             :                                 print_sockaddr(addr,
    2592             :                                         sizeof(addr),
    2593             :                                         &srv_addrs[num_srv_addrs]));
    2594             : 
    2595         778 :                         num_srv_addrs++;
    2596             :                 }
    2597             :         }
    2598             : 
    2599         389 :         TALLOC_FREE(dcs);
    2600             : 
    2601         389 :         *return_addrs = srv_addrs;
    2602         389 :         *return_count = num_srv_addrs;
    2603         389 :         return NT_STATUS_OK;
    2604             : }
    2605             : 
    2606         429 : static const char **filter_out_nbt_lookup(TALLOC_CTX *mem_ctx,
    2607             :                                           const char **resolve_order)
    2608             : {
    2609           0 :         size_t i, len, result_idx;
    2610           0 :         const char **result;
    2611             : 
    2612         429 :         len = 0;
    2613         978 :         while (resolve_order[len] != NULL) {
    2614         549 :                 len += 1;
    2615             :         }
    2616             : 
    2617         429 :         result = talloc_array(mem_ctx, const char *, len+1);
    2618         429 :         if (result == NULL) {
    2619           0 :                 return NULL;
    2620             :         }
    2621             : 
    2622         429 :         result_idx = 0;
    2623             : 
    2624         978 :         for (i=0; i<len; i++) {
    2625         549 :                 const char *tok = resolve_order[i];
    2626             : 
    2627        1018 :                 if (strequal(tok, "lmhosts") || strequal(tok, "wins") ||
    2628         469 :                     strequal(tok, "bcast")) {
    2629         120 :                         continue;
    2630             :                 }
    2631         429 :                 result[result_idx++] = tok;
    2632             :         }
    2633         429 :         result[result_idx] = NULL;
    2634             : 
    2635         429 :         return result;
    2636             : }
    2637             : 
    2638             : /*******************************************************************
    2639             :  Samba interface to resolve a name into an IP address.
    2640             :  Use this function if the string is either an IP address, DNS
    2641             :  or host name or NetBIOS name. This uses the name switch in the
    2642             :  smb.conf to determine the order of name resolution.
    2643             : 
    2644             :  Added support for ip addr/port to support ADS ldap servers.
    2645             :  the only place we currently care about the port is in the
    2646             :  resolve_hosts() when looking up DC's via SRV RR entries in DNS
    2647             : **********************************************************************/
    2648             : 
    2649        9965 : NTSTATUS internal_resolve_name(TALLOC_CTX *ctx,
    2650             :                                 const char *name,
    2651             :                                 int name_type,
    2652             :                                 const char *sitename,
    2653             :                                 struct samba_sockaddr **return_salist,
    2654             :                                 size_t *return_count,
    2655             :                                 const char **resolve_order)
    2656             : {
    2657        9965 :         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    2658           0 :         size_t i;
    2659        9965 :         size_t nc_count = 0;
    2660        9965 :         size_t ret_count = 0;
    2661           0 :         bool ok;
    2662        9965 :         struct sockaddr_storage *ss_list = NULL;
    2663        9965 :         struct samba_sockaddr *sa_list = NULL;
    2664        9965 :         TALLOC_CTX *frame = talloc_stackframe();
    2665             : 
    2666        9965 :         DBG_DEBUG("looking up %s#%x (sitename %s)\n",
    2667             :                 name, name_type, sitename ? sitename : "(null)");
    2668             : 
    2669        9965 :         if (is_ipaddress(name)) {
    2670           0 :                 struct sockaddr_storage ss;
    2671             : 
    2672             :                 /* if it's in the form of an IP address then get the lib to interpret it */
    2673           0 :                 ok = interpret_string_addr(&ss, name, AI_NUMERICHOST);
    2674           0 :                 if (!ok) {
    2675           0 :                         DBG_WARNING("interpret_string_addr failed on %s\n",
    2676             :                                 name);
    2677           0 :                         TALLOC_FREE(frame);
    2678           0 :                         return NT_STATUS_INVALID_PARAMETER;
    2679             :                 }
    2680           0 :                 if (is_zero_addr(&ss)) {
    2681           0 :                         TALLOC_FREE(frame);
    2682           0 :                         return NT_STATUS_UNSUCCESSFUL;
    2683             :                 }
    2684             : 
    2685           0 :                 status = sockaddr_array_to_samba_sockaddr_array(frame,
    2686             :                                                         &sa_list,
    2687             :                                                         &ret_count,
    2688             :                                                         &ss,
    2689             :                                                         1);
    2690           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2691           0 :                         TALLOC_FREE(frame);
    2692           0 :                         return status;
    2693             :                 }
    2694             : 
    2695           0 :                 *return_salist = talloc_move(ctx, &sa_list);
    2696           0 :                 *return_count = 1;
    2697           0 :                 TALLOC_FREE(frame);
    2698           0 :                 return NT_STATUS_OK;
    2699             :         }
    2700             : 
    2701             :         /* Check name cache */
    2702             : 
    2703        9965 :         ok = namecache_fetch(frame,
    2704             :                                 name,
    2705             :                                 name_type,
    2706             :                                 &sa_list,
    2707             :                                 &nc_count);
    2708        9965 :         if (ok) {
    2709             :                 /*
    2710             :                  * remove_duplicate_addrs2() has the
    2711             :                  * side effect of removing zero addresses,
    2712             :                  * so use it here.
    2713             :                  */
    2714        9110 :                 nc_count = remove_duplicate_addrs2(sa_list, nc_count);
    2715        9110 :                 if (nc_count == 0) {
    2716           0 :                         TALLOC_FREE(sa_list);
    2717           0 :                         TALLOC_FREE(frame);
    2718           0 :                         return NT_STATUS_UNSUCCESSFUL;
    2719             :                 }
    2720        9110 :                 *return_count = nc_count;
    2721        9110 :                 *return_salist = talloc_move(ctx, &sa_list);
    2722        9110 :                 TALLOC_FREE(frame);
    2723        9110 :                 return NT_STATUS_OK;
    2724             :         }
    2725             : 
    2726             :         /* set the name resolution order */
    2727             : 
    2728         855 :         if (resolve_order && strcmp(resolve_order[0], "NULL") == 0) {
    2729           0 :                 DBG_DEBUG("all lookups disabled\n");
    2730           0 :                 TALLOC_FREE(frame);
    2731           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2732             :         }
    2733             : 
    2734         855 :         if (!resolve_order || !resolve_order[0]) {
    2735           0 :                 static const char *host_order[] = { "host", NULL };
    2736           0 :                 resolve_order = host_order;
    2737             :         }
    2738             : 
    2739         855 :         if ((strlen(name) > MAX_NETBIOSNAME_LEN - 1) ||
    2740         426 :             (strchr(name, '.') != NULL)) {
    2741             :                 /*
    2742             :                  * Don't do NBT lookup, the name would not fit anyway
    2743             :                  */
    2744         429 :                 resolve_order = filter_out_nbt_lookup(frame, resolve_order);
    2745         429 :                 if (resolve_order == NULL) {
    2746           0 :                         TALLOC_FREE(frame);
    2747           0 :                         return NT_STATUS_NO_MEMORY;
    2748             :                 }
    2749             :         }
    2750             : 
    2751             :         /* iterate through the name resolution backends */
    2752             : 
    2753        1808 :         for (i=0; resolve_order[i]; i++) {
    2754        1784 :                 const char *tok = resolve_order[i];
    2755             : 
    2756        1784 :                 if ((strequal(tok, "host") || strequal(tok, "hosts"))) {
    2757         457 :                         status = resolve_hosts(talloc_tos(),
    2758             :                                                name,
    2759             :                                                name_type,
    2760             :                                                &ss_list,
    2761             :                                                &ret_count);
    2762         457 :                         if (!NT_STATUS_IS_OK(status)) {
    2763          77 :                                 continue;
    2764             :                         }
    2765         380 :                         goto done;
    2766             :                 }
    2767             : 
    2768        1327 :                 if (strequal(tok, "kdc")) {
    2769             :                         /* deal with KDC_NAME_TYPE names here.
    2770             :                          * This will result in a SRV record lookup */
    2771         376 :                         status = resolve_ads(talloc_tos(),
    2772             :                                              name,
    2773             :                                              KDC_NAME_TYPE,
    2774             :                                              sitename,
    2775             :                                              &ss_list,
    2776             :                                              &ret_count);
    2777         376 :                         if (!NT_STATUS_IS_OK(status)) {
    2778           0 :                                 continue;
    2779             :                         }
    2780             :                         /* Ensure we don't namecache
    2781             :                          * this with the KDC port. */
    2782         376 :                         name_type = KDC_NAME_TYPE;
    2783         376 :                         goto done;
    2784             :                 }
    2785             : 
    2786         951 :                 if (strequal(tok, "ads")) {
    2787             :                         /* deal with 0x1c and 0x1b names here.
    2788             :                          * This will result in a SRV record lookup */
    2789          13 :                         status = resolve_ads(talloc_tos(),
    2790             :                                              name,
    2791             :                                              name_type,
    2792             :                                              sitename,
    2793             :                                              &ss_list,
    2794             :                                              &ret_count);
    2795          13 :                         if (!NT_STATUS_IS_OK(status)) {
    2796           0 :                                 continue;
    2797             :                         }
    2798          13 :                         goto done;
    2799             :                 }
    2800             : 
    2801         938 :                 if (strequal(tok, "lmhosts")) {
    2802         426 :                         status = resolve_lmhosts_file_as_sockaddr(
    2803             :                                 talloc_tos(),
    2804             :                                 get_dyn_LMHOSTSFILE(),
    2805             :                                 name,
    2806             :                                 name_type,
    2807             :                                 &ss_list,
    2808             :                                 &ret_count);
    2809         426 :                         if (!NT_STATUS_IS_OK(status)) {
    2810         426 :                                 continue;
    2811             :                         }
    2812           0 :                         goto done;
    2813             :                 }
    2814             : 
    2815         512 :                 if (strequal(tok, "wins")) {
    2816             :                         /* don't resolve 1D via WINS */
    2817         426 :                         if (name_type == 0x1D) {
    2818          21 :                                 continue;
    2819             :                         }
    2820         405 :                         status = resolve_wins(talloc_tos(),
    2821             :                                               name,
    2822             :                                               name_type,
    2823             :                                               &ss_list,
    2824             :                                               &ret_count);
    2825         405 :                         if (!NT_STATUS_IS_OK(status)) {
    2826         405 :                                 continue;
    2827             :                         }
    2828           0 :                         goto done;
    2829             :                 }
    2830             : 
    2831          86 :                 if (strequal(tok, "bcast")) {
    2832          86 :                         status = name_resolve_bcast(
    2833             :                                                 talloc_tos(),
    2834             :                                                 name,
    2835             :                                                 name_type,
    2836             :                                                 &ss_list,
    2837             :                                                 &ret_count);
    2838          86 :                         if (!NT_STATUS_IS_OK(status)) {
    2839          24 :                                 continue;
    2840             :                         }
    2841          62 :                         goto done;
    2842             :                 }
    2843             : 
    2844           0 :                 DBG_ERR("unknown name switch type %s\n", tok);
    2845             :         }
    2846             : 
    2847             :         /* All of the resolve_* functions above have returned false. */
    2848             : 
    2849          24 :         TALLOC_FREE(frame);
    2850          24 :         *return_count = 0;
    2851             : 
    2852          24 :         return status;
    2853             : 
    2854         831 :   done:
    2855             : 
    2856         831 :         status = sockaddr_array_to_samba_sockaddr_array(frame,
    2857             :                                                         &sa_list,
    2858             :                                                         &ret_count,
    2859             :                                                         ss_list,
    2860             :                                                         ret_count);
    2861         831 :         if (!NT_STATUS_IS_OK(status)) {
    2862           0 :                 TALLOC_FREE(frame);
    2863           0 :                 return NT_STATUS_NO_MEMORY;
    2864             :         }
    2865             : 
    2866             :         /* Remove duplicate entries.  Some queries, notably #1c (domain
    2867             :         controllers) return the PDC in iplist[0] and then all domain
    2868             :         controllers including the PDC in iplist[1..n].  Iterating over
    2869             :         the iplist when the PDC is down will cause two sets of timeouts. */
    2870             : 
    2871         831 :         ret_count = remove_duplicate_addrs2(sa_list, ret_count);
    2872             : 
    2873             :         /* Save in name cache */
    2874         831 :         if ( DEBUGLEVEL >= 100 ) {
    2875           0 :                 for (i = 0; i < ret_count && DEBUGLEVEL == 100; i++) {
    2876           0 :                         char addr[INET6_ADDRSTRLEN];
    2877           0 :                         print_sockaddr(addr, sizeof(addr),
    2878           0 :                                         &sa_list[i].u.ss);
    2879           0 :                         DEBUG(100, ("Storing name %s of type %d (%s:0)\n",
    2880             :                                         name,
    2881             :                                         name_type,
    2882             :                                         addr));
    2883             :                 }
    2884             :         }
    2885             : 
    2886         831 :         if (ret_count) {
    2887         831 :                 namecache_store(name,
    2888             :                                 name_type,
    2889             :                                 ret_count,
    2890             :                                 sa_list);
    2891             :         }
    2892             : 
    2893             :         /* Display some debugging info */
    2894             : 
    2895         831 :         if ( DEBUGLEVEL >= 10 ) {
    2896           0 :                 DBG_DEBUG("returning %zu addresses: ",
    2897             :                                 ret_count);
    2898             : 
    2899           0 :                 for (i = 0; i < ret_count; i++) {
    2900           0 :                         char addr[INET6_ADDRSTRLEN];
    2901           0 :                         print_sockaddr(addr, sizeof(addr),
    2902           0 :                                         &sa_list[i].u.ss);
    2903           0 :                         DEBUGADD(10, ("%s ", addr));
    2904             :                 }
    2905           0 :                 DEBUG(10, ("\n"));
    2906             :         }
    2907             : 
    2908         831 :         *return_count = ret_count;
    2909         831 :         *return_salist = talloc_move(ctx, &sa_list);
    2910             : 
    2911         831 :         TALLOC_FREE(frame);
    2912         831 :         return status;
    2913             : }
    2914             : 
    2915             : /********************************************************
    2916             :  Internal interface to resolve a name into one IP address.
    2917             :  Use this function if the string is either an IP address, DNS
    2918             :  or host name or NetBIOS name. This uses the name switch in the
    2919             :  smb.conf to determine the order of name resolution.
    2920             : *********************************************************/
    2921             : 
    2922        1149 : bool resolve_name(const char *name,
    2923             :                 struct sockaddr_storage *return_ss,
    2924             :                 int name_type,
    2925             :                 bool prefer_ipv4)
    2926             : {
    2927        1149 :         struct samba_sockaddr *sa_list = NULL;
    2928        1149 :         char *sitename = NULL;
    2929        1149 :         size_t count = 0;
    2930           0 :         NTSTATUS status;
    2931        1149 :         TALLOC_CTX *frame = NULL;
    2932             : 
    2933        1149 :         if (is_ipaddress(name)) {
    2934         146 :                 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
    2935             :         }
    2936             : 
    2937        1003 :         frame = talloc_stackframe();
    2938             : 
    2939        1003 :         sitename = sitename_fetch(frame, lp_realm()); /* wild guess */
    2940             : 
    2941        1003 :         status = internal_resolve_name(frame,
    2942             :                                         name,
    2943             :                                         name_type,
    2944             :                                         sitename,
    2945             :                                         &sa_list,
    2946             :                                         &count,
    2947             :                                         lp_name_resolve_order());
    2948        1003 :         if (NT_STATUS_IS_OK(status)) {
    2949           0 :                 size_t i;
    2950             : 
    2951         993 :                 if (prefer_ipv4) {
    2952         795 :                         for (i=0; i<count; i++) {
    2953         795 :                                 if (!is_broadcast_addr(&sa_list[i].u.sa) &&
    2954         795 :                                                 (sa_list[i].u.ss.ss_family == AF_INET)) {
    2955         795 :                                         *return_ss = sa_list[i].u.ss;
    2956         795 :                                         TALLOC_FREE(sa_list);
    2957         795 :                                         TALLOC_FREE(frame);
    2958         795 :                                         return True;
    2959             :                                 }
    2960             :                         }
    2961             :                 }
    2962             : 
    2963             :                 /* only return valid addresses for TCP connections */
    2964         198 :                 for (i=0; i<count; i++) {
    2965         198 :                         if (!is_broadcast_addr(&sa_list[i].u.sa)) {
    2966         198 :                                 *return_ss = sa_list[i].u.ss;
    2967         198 :                                 TALLOC_FREE(sa_list);
    2968         198 :                                 TALLOC_FREE(frame);
    2969         198 :                                 return True;
    2970             :                         }
    2971             :                 }
    2972             :         }
    2973             : 
    2974          10 :         TALLOC_FREE(sa_list);
    2975          10 :         TALLOC_FREE(frame);
    2976          10 :         return False;
    2977             : }
    2978             : 
    2979             : /********************************************************
    2980             :  Internal interface to resolve a name into a list of IP addresses.
    2981             :  Use this function if the string is either an IP address, DNS
    2982             :  or host name or NetBIOS name. This uses the name switch in the
    2983             :  smb.conf to determine the order of name resolution.
    2984             : *********************************************************/
    2985             : 
    2986        9931 : NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
    2987             :                 const char *name,
    2988             :                 int name_type,
    2989             :                 struct sockaddr_storage **return_ss_arr,
    2990             :                 unsigned int *p_num_entries)
    2991             : {
    2992        9931 :         struct samba_sockaddr *sa_list = NULL;
    2993        9931 :         char *sitename = NULL;
    2994        9931 :         size_t count = 0;
    2995           0 :         size_t i;
    2996        9931 :         unsigned int num_entries = 0;
    2997        9931 :         struct sockaddr_storage *result_arr = NULL;
    2998           0 :         NTSTATUS status;
    2999             : 
    3000        9931 :         if (is_ipaddress(name)) {
    3001        1582 :                 result_arr = talloc(ctx, struct sockaddr_storage);
    3002        1582 :                 if (result_arr == NULL) {
    3003           0 :                         return NT_STATUS_NO_MEMORY;
    3004             :                 }
    3005        1582 :                 if (!interpret_string_addr(result_arr, name, AI_NUMERICHOST)) {
    3006           0 :                         TALLOC_FREE(result_arr);
    3007           0 :                         return NT_STATUS_BAD_NETWORK_NAME;
    3008             :                 }
    3009        1582 :                 *p_num_entries = 1;
    3010        1582 :                 *return_ss_arr = result_arr;
    3011        1582 :                 return NT_STATUS_OK;
    3012             :         }
    3013             : 
    3014        8349 :         sitename = sitename_fetch(ctx, lp_realm()); /* wild guess */
    3015             : 
    3016        8349 :         status = internal_resolve_name(ctx,
    3017             :                                         name,
    3018             :                                         name_type,
    3019             :                                         sitename,
    3020             :                                         &sa_list,
    3021             :                                         &count,
    3022             :                                         lp_name_resolve_order());
    3023        8349 :         TALLOC_FREE(sitename);
    3024             : 
    3025        8349 :         if (!NT_STATUS_IS_OK(status)) {
    3026           6 :                 return status;
    3027             :         }
    3028             : 
    3029             :         /* only return valid addresses for TCP connections */
    3030       24904 :         for (i=0, num_entries = 0; i<count; i++) {
    3031       16561 :                 if (!is_zero_addr(&sa_list[i].u.ss) &&
    3032       16561 :                     !is_broadcast_addr(&sa_list[i].u.sa)) {
    3033       16561 :                         num_entries++;
    3034             :                 }
    3035             :         }
    3036        8343 :         if (num_entries == 0) {
    3037           0 :                 status = NT_STATUS_BAD_NETWORK_NAME;
    3038           0 :                 goto done;
    3039             :         }
    3040             : 
    3041        8343 :         result_arr = talloc_array(ctx,
    3042             :                                 struct sockaddr_storage,
    3043             :                                 num_entries);
    3044        8343 :         if (result_arr == NULL) {
    3045           0 :                 status = NT_STATUS_NO_MEMORY;
    3046           0 :                 goto done;
    3047             :         }
    3048             : 
    3049       24904 :         for (i=0, num_entries = 0; i<count; i++) {
    3050       16561 :                 if (!is_zero_addr(&sa_list[i].u.ss) &&
    3051       16561 :                     !is_broadcast_addr(&sa_list[i].u.sa)) {
    3052       16561 :                         result_arr[num_entries++] = sa_list[i].u.ss;
    3053             :                 }
    3054             :         }
    3055             : 
    3056        8343 :         if (num_entries == 0) {
    3057           0 :                 TALLOC_FREE(result_arr);
    3058           0 :                 status = NT_STATUS_BAD_NETWORK_NAME;
    3059           0 :                 goto done;
    3060             :         }
    3061             : 
    3062        8343 :         status = NT_STATUS_OK;
    3063        8343 :         *p_num_entries = num_entries;
    3064        8343 :         *return_ss_arr = result_arr;
    3065        8343 : done:
    3066        8343 :         TALLOC_FREE(sa_list);
    3067        8343 :         return status;
    3068             : }
    3069             : 
    3070             : /********************************************************
    3071             :  Find the IP address of the master browser or DMB for a workgroup.
    3072             : *********************************************************/
    3073             : 
    3074          16 : bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
    3075             : {
    3076          16 :         struct samba_sockaddr *sa_list = NULL;
    3077          16 :         size_t count = 0;
    3078           0 :         NTSTATUS status;
    3079             : 
    3080          16 :         if (lp_disable_netbios()) {
    3081           0 :                 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
    3082           0 :                 return false;
    3083             :         }
    3084             : 
    3085          16 :         status = internal_resolve_name(talloc_tos(),
    3086             :                                         group,
    3087             :                                         0x1D,
    3088             :                                         NULL,
    3089             :                                         &sa_list,
    3090             :                                         &count,
    3091             :                                         lp_name_resolve_order());
    3092          16 :         if (NT_STATUS_IS_OK(status)) {
    3093          12 :                 *master_ss = sa_list[0].u.ss;
    3094          12 :                 TALLOC_FREE(sa_list);
    3095          12 :                 return true;
    3096             :         }
    3097             : 
    3098           4 :         TALLOC_FREE(sa_list);
    3099             : 
    3100           4 :         status = internal_resolve_name(talloc_tos(),
    3101             :                                         group,
    3102             :                                         0x1B,
    3103             :                                         NULL,
    3104             :                                         &sa_list,
    3105             :                                         &count,
    3106             :                                         lp_name_resolve_order());
    3107           4 :         if (NT_STATUS_IS_OK(status)) {
    3108           4 :                 *master_ss = sa_list[0].u.ss;
    3109           4 :                 TALLOC_FREE(sa_list);
    3110           4 :                 return true;
    3111             :         }
    3112             : 
    3113           0 :         TALLOC_FREE(sa_list);
    3114           0 :         return false;
    3115             : }
    3116             : 
    3117             : /********************************************************
    3118             :  Get the IP address list of the primary domain controller
    3119             :  for a domain.
    3120             : *********************************************************/
    3121             : 
    3122          12 : bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
    3123             : {
    3124          12 :         struct samba_sockaddr *sa_list = NULL;
    3125          12 :         size_t count = 0;
    3126          12 :         NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
    3127           0 :         static const char *ads_order[] = { "ads", NULL };
    3128             :         /* Look up #1B name */
    3129             : 
    3130          12 :         if (lp_security() == SEC_ADS) {
    3131           0 :                 status = internal_resolve_name(talloc_tos(),
    3132             :                                                 domain,
    3133             :                                                 0x1b,
    3134             :                                                 NULL,
    3135             :                                                 &sa_list,
    3136             :                                                 &count,
    3137             :                                                 ads_order);
    3138             :         }
    3139             : 
    3140          12 :         if (!NT_STATUS_IS_OK(status) || count == 0) {
    3141          12 :                 TALLOC_FREE(sa_list);
    3142          12 :                 status = internal_resolve_name(talloc_tos(),
    3143             :                                                 domain,
    3144             :                                                 0x1b,
    3145             :                                                 NULL,
    3146             :                                                 &sa_list,
    3147             :                                                 &count,
    3148             :                                                 lp_name_resolve_order());
    3149          12 :                 if (!NT_STATUS_IS_OK(status)) {
    3150           0 :                         TALLOC_FREE(sa_list);
    3151           0 :                         return false;
    3152             :                 }
    3153             :         }
    3154             : 
    3155             :         /* if we get more than 1 IP back we have to assume it is a
    3156             :            multi-homed PDC and not a mess up */
    3157             : 
    3158          12 :         if ( count > 1 ) {
    3159           0 :                 DBG_INFO("PDC has %zu IP addresses!\n", count);
    3160           0 :                 sort_sa_list(sa_list, count);
    3161             :         }
    3162             : 
    3163          12 :         *pss = sa_list[0].u.ss;
    3164          12 :         TALLOC_FREE(sa_list);
    3165          12 :         return true;
    3166             : }
    3167             : 
    3168             : /* Private enum type for lookups. */
    3169             : 
    3170             : enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
    3171             : 
    3172             : /********************************************************
    3173             :  Get the IP address list of the domain controllers for
    3174             :  a domain.
    3175             : *********************************************************/
    3176             : 
    3177         744 : static NTSTATUS get_dc_list(TALLOC_CTX *ctx,
    3178             :                         const char *domain,
    3179             :                         const char *sitename,
    3180             :                         struct samba_sockaddr **sa_list_ret,
    3181             :                         size_t *ret_count,
    3182             :                         enum dc_lookup_type lookup_type,
    3183             :                         bool *ordered)
    3184             : {
    3185         744 :         const char **resolve_order = NULL;
    3186         744 :         char *saf_servername = NULL;
    3187         744 :         char *pserver = NULL;
    3188           0 :         const char *p;
    3189           0 :         char *name;
    3190         744 :         size_t num_addresses = 0;
    3191         744 :         size_t local_count = 0;
    3192           0 :         size_t i;
    3193         744 :         struct samba_sockaddr *auto_sa_list = NULL;
    3194         744 :         struct samba_sockaddr *return_salist = NULL;
    3195         744 :         bool done_auto_lookup = false;
    3196         744 :         size_t auto_count = 0;
    3197           0 :         NTSTATUS status;
    3198         744 :         TALLOC_CTX *frame = talloc_stackframe();
    3199         744 :         int auto_name_type = 0x1C;
    3200             : 
    3201         744 :         *ordered = False;
    3202             : 
    3203             :         /* if we are restricted to solely using DNS for looking
    3204             :            up a domain controller, make sure that host lookups
    3205             :            are enabled for the 'name resolve order'.  If host lookups
    3206             :            are disabled and ads_only is True, then set the string to
    3207             :            NULL. */
    3208             : 
    3209         744 :         resolve_order = lp_name_resolve_order();
    3210         744 :         if (!resolve_order) {
    3211           0 :                 status = NT_STATUS_NO_MEMORY;
    3212           0 :                 goto out;
    3213             :         }
    3214         744 :         if (lookup_type == DC_ADS_ONLY)  {
    3215         238 :                 if (str_list_check_ci(resolve_order, "host")) {
    3216           0 :                         static const char *ads_order[] = { "ads", NULL };
    3217         238 :                         resolve_order = ads_order;
    3218             : 
    3219             :                         /* DNS SRV lookups used by the ads resolver
    3220             :                            are already sorted by priority and weight */
    3221         238 :                         *ordered = true;
    3222             :                 } else {
    3223             :                         /* this is quite bizarre! */
    3224             :                         static const char *null_order[] = { "NULL", NULL };
    3225           0 :                         resolve_order = null_order;
    3226             :                 }
    3227         506 :         } else if (lookup_type == DC_KDC_ONLY) {
    3228           0 :                 static const char *kdc_order[] = { "kdc", NULL };
    3229             :                 /* DNS SRV lookups used by the ads/kdc resolver
    3230             :                    are already sorted by priority and weight */
    3231         498 :                 *ordered = true;
    3232         498 :                 resolve_order = kdc_order;
    3233         498 :                 auto_name_type = KDC_NAME_TYPE;
    3234             :         }
    3235             : 
    3236             :         /* fetch the server we have affinity for.  Add the
    3237             :            'password server' list to a search for our domain controllers */
    3238             : 
    3239         744 :         saf_servername = saf_fetch(frame, domain);
    3240             : 
    3241         744 :         if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
    3242         744 :                 pserver = talloc_asprintf(frame, "%s, %s",
    3243             :                         saf_servername ? saf_servername : "",
    3244             :                         lp_password_server());
    3245             :         } else {
    3246           0 :                 pserver = talloc_asprintf(frame, "%s, *",
    3247             :                         saf_servername ? saf_servername : "");
    3248             :         }
    3249             : 
    3250         744 :         TALLOC_FREE(saf_servername);
    3251         744 :         if (!pserver) {
    3252           0 :                 status = NT_STATUS_NO_MEMORY;
    3253           0 :                 goto out;
    3254             :         }
    3255             : 
    3256         744 :         DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
    3257             : 
    3258             :         /*
    3259             :          * if '*' appears in the "password server" list then add
    3260             :          * an auto lookup to the list of manually configured
    3261             :          * DC's.  If any DC is listed by name, then the list should be
    3262             :          * considered to be ordered
    3263             :          */
    3264             : 
    3265         744 :         p = pserver;
    3266        2081 :         while (next_token_talloc(frame, &p, &name, LIST_SEP)) {
    3267        1337 :                 if (!done_auto_lookup && strequal(name, "*")) {
    3268         566 :                         done_auto_lookup = true;
    3269             : 
    3270         566 :                         status = internal_resolve_name(frame,
    3271             :                                                         domain,
    3272             :                                                         auto_name_type,
    3273             :                                                         sitename,
    3274             :                                                         &auto_sa_list,
    3275             :                                                         &auto_count,
    3276             :                                                         resolve_order);
    3277         566 :                         if (!NT_STATUS_IS_OK(status)) {
    3278           0 :                                 continue;
    3279             :                         }
    3280             :                         /* Wrap check. */
    3281         566 :                         if (num_addresses + auto_count < num_addresses) {
    3282           0 :                                 TALLOC_FREE(auto_sa_list);
    3283           0 :                                 status = NT_STATUS_INVALID_PARAMETER;
    3284           0 :                                 goto out;
    3285             :                         }
    3286         566 :                         num_addresses += auto_count;
    3287         566 :                         DBG_DEBUG("Adding %zu DC's from auto lookup\n",
    3288             :                                                 auto_count);
    3289             :                 } else  {
    3290             :                         /* Wrap check. */
    3291         771 :                         if (num_addresses + 1 < num_addresses) {
    3292           0 :                                 TALLOC_FREE(auto_sa_list);
    3293           0 :                                 status = NT_STATUS_INVALID_PARAMETER;
    3294           0 :                                 goto out;
    3295             :                         }
    3296         771 :                         num_addresses++;
    3297             :                 }
    3298             :         }
    3299             : 
    3300             :         /* if we have no addresses and haven't done the auto lookup, then
    3301             :            just return the list of DC's.  Or maybe we just failed. */
    3302             : 
    3303         744 :         if (num_addresses == 0) {
    3304           0 :                 struct samba_sockaddr *dc_salist = NULL;
    3305           0 :                 size_t dc_count = 0;
    3306             : 
    3307           0 :                 if (done_auto_lookup) {
    3308           0 :                         DEBUG(4,("get_dc_list: no servers found\n"));
    3309           0 :                         status = NT_STATUS_NO_LOGON_SERVERS;
    3310           0 :                         goto out;
    3311             :                 }
    3312             :                 /* talloc off frame, only move to ctx on success. */
    3313           0 :                 status = internal_resolve_name(frame,
    3314             :                                                 domain,
    3315             :                                                 auto_name_type,
    3316             :                                                 sitename,
    3317             :                                                 &dc_salist,
    3318             :                                                 &dc_count,
    3319             :                                                 resolve_order);
    3320           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3321           0 :                         goto out;
    3322             :                 }
    3323           0 :                 return_salist = dc_salist;
    3324           0 :                 local_count = dc_count;
    3325           0 :                 goto out;
    3326             :         }
    3327             : 
    3328         744 :         return_salist = talloc_zero_array(frame,
    3329             :                                         struct samba_sockaddr,
    3330             :                                         num_addresses);
    3331         744 :         if (return_salist == NULL) {
    3332           0 :                 DEBUG(3,("get_dc_list: malloc fail !\n"));
    3333           0 :                 status = NT_STATUS_NO_MEMORY;
    3334           0 :                 goto out;
    3335             :         }
    3336             : 
    3337         744 :         p = pserver;
    3338         744 :         local_count = 0;
    3339             : 
    3340             :         /* fill in the return list now with real IP's */
    3341             : 
    3342        3418 :         while ((local_count<num_addresses) &&
    3343        1337 :                         next_token_talloc(frame, &p, &name, LIST_SEP)) {
    3344        1337 :                 struct samba_sockaddr name_sa = {0};
    3345             : 
    3346             :                 /* copy any addresses from the auto lookup */
    3347             : 
    3348        1337 :                 if (strequal(name, "*")) {
    3349             :                         size_t j;
    3350        1698 :                         for (j=0; j<auto_count; j++) {
    3351           0 :                                 char addr[INET6_ADDRSTRLEN];
    3352        1132 :                                 print_sockaddr(addr,
    3353             :                                                 sizeof(addr),
    3354        1132 :                                                 &auto_sa_list[j].u.ss);
    3355             :                                 /* Check for and don't copy any
    3356             :                                  * known bad DC IP's. */
    3357        1132 :                                 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
    3358             :                                                 domain,
    3359             :                                                 addr))) {
    3360           0 :                                         DEBUG(5,("get_dc_list: "
    3361             :                                                 "negative entry %s removed "
    3362             :                                                 "from DC list\n",
    3363             :                                                 addr));
    3364           0 :                                         continue;
    3365             :                                 }
    3366        1132 :                                 return_salist[local_count] = auto_sa_list[j];
    3367        1132 :                                 local_count++;
    3368             :                         }
    3369         566 :                         continue;
    3370             :                 }
    3371             : 
    3372             :                 /* explicit lookup; resolve_name() will
    3373             :                  * handle names & IP addresses */
    3374         771 :                 if (resolve_name(name, &name_sa.u.ss, 0x20, true)) {
    3375           0 :                         char addr[INET6_ADDRSTRLEN];
    3376           0 :                         bool ok;
    3377             : 
    3378             :                         /*
    3379             :                          * Ensure we set sa_socklen correctly.
    3380             :                          * Doesn't matter now, but eventually we
    3381             :                          * will remove ip_service and return samba_sockaddr
    3382             :                          * arrays directly.
    3383             :                          */
    3384         771 :                         ok = sockaddr_storage_to_samba_sockaddr(
    3385             :                                         &name_sa,
    3386             :                                         &name_sa.u.ss);
    3387         771 :                         if (!ok) {
    3388           0 :                                 status = NT_STATUS_INVALID_ADDRESS;
    3389           0 :                                 goto out;
    3390             :                         }
    3391             : 
    3392         771 :                         print_sockaddr(addr,
    3393             :                                         sizeof(addr),
    3394             :                                         &name_sa.u.ss);
    3395             : 
    3396             :                         /* Check for and don't copy any known bad DC IP's. */
    3397         771 :                         if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
    3398             :                                                         addr)) ) {
    3399           0 :                                 DEBUG(5,("get_dc_list: negative entry %s "
    3400             :                                         "removed from DC list\n",
    3401             :                                         name ));
    3402           0 :                                 continue;
    3403             :                         }
    3404             : 
    3405         771 :                         return_salist[local_count] = name_sa;
    3406         771 :                         local_count++;
    3407         771 :                         *ordered = true;
    3408             :                 }
    3409             :         }
    3410             : 
    3411             :         /* need to remove duplicates in the list if we have any
    3412             :            explicit password servers */
    3413             : 
    3414         744 :         local_count = remove_duplicate_addrs2(return_salist, local_count );
    3415             : 
    3416             :         /* For DC's we always prioritize IPv4 due to W2K3 not
    3417             :          * supporting LDAP, KRB5 or CLDAP over IPv6. */
    3418             : 
    3419         744 :         if (local_count && return_salist != NULL) {
    3420         744 :                 prioritize_ipv4_list(return_salist, local_count);
    3421             :         }
    3422             : 
    3423         744 :         if ( DEBUGLEVEL >= 4 ) {
    3424           3 :                 DEBUG(4,("get_dc_list: returning %zu ip addresses "
    3425             :                                 "in an %sordered list\n",
    3426             :                                 local_count,
    3427             :                                 *ordered ? "":"un"));
    3428           3 :                 DEBUG(4,("get_dc_list: "));
    3429           6 :                 for ( i=0; i<local_count; i++ ) {
    3430           0 :                         char addr[INET6_ADDRSTRLEN];
    3431           3 :                         print_sockaddr(addr,
    3432             :                                         sizeof(addr),
    3433           3 :                                         &return_salist[i].u.ss);
    3434           3 :                         DEBUGADD(4,("%s ", addr));
    3435             :                 }
    3436           3 :                 DEBUGADD(4,("\n"));
    3437             :         }
    3438             : 
    3439         744 :         status = (local_count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS);
    3440             : 
    3441         744 :   out:
    3442             : 
    3443         744 :         if (NT_STATUS_IS_OK(status)) {
    3444         744 :                 *sa_list_ret = talloc_move(ctx, &return_salist);
    3445         744 :                 *ret_count = local_count;
    3446             :         }
    3447         744 :         TALLOC_FREE(return_salist);
    3448         744 :         TALLOC_FREE(auto_sa_list);
    3449         744 :         TALLOC_FREE(frame);
    3450         744 :         return status;
    3451             : }
    3452             : 
    3453             : /*********************************************************************
    3454             :  Small wrapper function to get the DC list and sort it if necessary.
    3455             :  Returns a samba_sockaddr array.
    3456             : *********************************************************************/
    3457             : 
    3458         246 : NTSTATUS get_sorted_dc_list(TALLOC_CTX *ctx,
    3459             :                                 const char *domain,
    3460             :                                 const char *sitename,
    3461             :                                 struct samba_sockaddr **sa_list_ret,
    3462             :                                 size_t *ret_count,
    3463             :                                 bool ads_only)
    3464             : {
    3465         246 :         bool ordered = false;
    3466           0 :         NTSTATUS status;
    3467         246 :         enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
    3468         246 :         struct samba_sockaddr *sa_list = NULL;
    3469         246 :         size_t count = 0;
    3470             : 
    3471         246 :         DBG_INFO("attempting lookup for name %s (sitename %s)\n",
    3472             :                 domain,
    3473             :                 sitename ? sitename : "NULL");
    3474             : 
    3475         246 :         if (ads_only) {
    3476         238 :                 lookup_type = DC_ADS_ONLY;
    3477             :         }
    3478             : 
    3479         246 :         status = get_dc_list(ctx,
    3480             :                         domain,
    3481             :                         sitename,
    3482             :                         &sa_list,
    3483             :                         &count,
    3484             :                         lookup_type,
    3485             :                         &ordered);
    3486         246 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
    3487           0 :                         && sitename) {
    3488           0 :                 DBG_WARNING("No server for domain '%s' available"
    3489             :                             " in site '%s', fallback to all servers\n",
    3490             :                             domain,
    3491             :                             sitename);
    3492           0 :                 status = get_dc_list(ctx,
    3493             :                                 domain,
    3494             :                                 NULL,
    3495             :                                 &sa_list,
    3496             :                                 &count,
    3497             :                                 lookup_type,
    3498             :                                 &ordered);
    3499             :         }
    3500             : 
    3501         246 :         if (!NT_STATUS_IS_OK(status)) {
    3502           0 :                 return status;
    3503             :         }
    3504             : 
    3505             :         /* only sort if we don't already have an ordered list */
    3506         246 :         if (!ordered) {
    3507           0 :                 sort_sa_list(sa_list, count);
    3508             :         }
    3509             : 
    3510         246 :         *ret_count = count;
    3511         246 :         *sa_list_ret = sa_list;
    3512         246 :         return status;
    3513             : }
    3514             : 
    3515             : /*********************************************************************
    3516             :  Get the KDC list - re-use all the logic in get_dc_list.
    3517             :  Returns a samba_sockaddr array.
    3518             : *********************************************************************/
    3519             : 
    3520         498 : NTSTATUS get_kdc_list(TALLOC_CTX *ctx,
    3521             :                         const char *realm,
    3522             :                         const char *sitename,
    3523             :                         struct samba_sockaddr **sa_list_ret,
    3524             :                         size_t *ret_count)
    3525             : {
    3526         498 :         size_t count = 0;
    3527         498 :         struct samba_sockaddr *sa_list = NULL;
    3528         498 :         bool ordered = false;
    3529           0 :         NTSTATUS status;
    3530             : 
    3531         498 :         status = get_dc_list(ctx,
    3532             :                         realm,
    3533             :                         sitename,
    3534             :                         &sa_list,
    3535             :                         &count,
    3536             :                         DC_KDC_ONLY,
    3537             :                         &ordered);
    3538             : 
    3539         498 :         if (!NT_STATUS_IS_OK(status)) {
    3540           0 :                 return status;
    3541             :         }
    3542             : 
    3543             :         /* only sort if we don't already have an ordered list */
    3544         498 :         if (!ordered ) {
    3545           0 :                 sort_sa_list(sa_list, count);
    3546             :         }
    3547             : 
    3548         498 :         *ret_count = count;
    3549         498 :         *sa_list_ret = sa_list;
    3550         498 :         return status;
    3551             : }

Generated by: LCOV version 1.14