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

Generated by: LCOV version 1.14