root/source3/libsmb/namequery.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. saf_key
  2. saf_join_key
  3. saf_store
  4. saf_join_store
  5. saf_delete
  6. saf_fetch
  7. generate_trn_id
  8. parse_node_status
  9. node_status_query
  10. name_status_find
  11. addr_compare
  12. ip_service_compare
  13. sort_addr_list
  14. sort_service_list
  15. remove_duplicate_addrs2
  16. name_query
  17. startlmhosts
  18. getlmhostsent
  19. endlmhosts
  20. convert_ss2service
  21. name_resolve_bcast
  22. resolve_wins
  23. resolve_lmhosts
  24. resolve_hosts
  25. resolve_ads
  26. internal_resolve_name
  27. resolve_name
  28. resolve_name_list
  29. find_master_ip
  30. get_pdc_ip
  31. get_dc_list
  32. get_sorted_dc_list
  33. get_kdc_list

   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 
  23 /* nmbd.c sets this to True. */
  24 bool global_in_nmbd = False;
  25 
  26 /****************************
  27  * SERVER AFFINITY ROUTINES *
  28  ****************************/
  29 
  30  /* Server affinity is the concept of preferring the last domain
  31     controller with whom you had a successful conversation */
  32 
  33 /****************************************************************************
  34 ****************************************************************************/
  35 #define SAFKEY_FMT      "SAF/DOMAIN/%s"
  36 #define SAF_TTL         900
  37 #define SAFJOINKEY_FMT  "SAFJOIN/DOMAIN/%s"
  38 #define SAFJOIN_TTL     3600
  39 
  40 static char *saf_key(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
  41 {
  42         char *keystr;
  43 
  44         asprintf_strupper_m(&keystr, SAFKEY_FMT, domain);
  45 
  46         return keystr;
  47 }
  48 
  49 static char *saf_join_key(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
  50 {
  51         char *keystr;
  52 
  53         asprintf_strupper_m(&keystr, SAFJOINKEY_FMT, domain);
  54 
  55         return keystr;
  56 }
  57 
  58 /****************************************************************************
  59 ****************************************************************************/
  60 
  61 bool saf_store( const char *domain, const char *servername )
     /* [<][>][^][v][top][bottom][index][help] */
  62 {
  63         char *key;
  64         time_t expire;
  65         bool ret = False;
  66 
  67         if ( !domain || !servername ) {
  68                 DEBUG(2,("saf_store: "
  69                         "Refusing to store empty domain or servername!\n"));
  70                 return False;
  71         }
  72 
  73         if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
  74                 DEBUG(0,("saf_store: "
  75                         "refusing to store 0 length domain or servername!\n"));
  76                 return False;
  77         }
  78 
  79         if ( !gencache_init() )
  80                 return False;
  81 
  82         key = saf_key( domain );
  83         expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
  84 
  85         DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
  86                 domain, servername, (unsigned int)expire ));
  87 
  88         ret = gencache_set( key, servername, expire );
  89 
  90         SAFE_FREE( key );
  91 
  92         return ret;
  93 }
  94 
  95 bool saf_join_store( const char *domain, const char *servername )
     /* [<][>][^][v][top][bottom][index][help] */
  96 {
  97         char *key;
  98         time_t expire;
  99         bool ret = False;
 100 
 101         if ( !domain || !servername ) {
 102                 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
 103                 return False;
 104         }
 105 
 106         if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
 107                 DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
 108                 return False;
 109         }
 110 
 111         if ( !gencache_init() )
 112                 return False;
 113 
 114         key = saf_join_key( domain );
 115         expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
 116 
 117         DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
 118                 domain, servername, (unsigned int)expire ));
 119 
 120         ret = gencache_set( key, servername, expire );
 121 
 122         SAFE_FREE( key );
 123 
 124         return ret;
 125 }
 126 
 127 bool saf_delete( const char *domain )
     /* [<][>][^][v][top][bottom][index][help] */
 128 {
 129         char *key;
 130         bool ret = False;
 131 
 132         if ( !domain ) {
 133                 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
 134                 return False;
 135         }
 136 
 137         if ( !gencache_init() )
 138                 return False;
 139 
 140         key = saf_join_key(domain);
 141         ret = gencache_del(key);
 142         SAFE_FREE(key);
 143 
 144         if (ret) {
 145                 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain ));
 146         }
 147 
 148         key = saf_key(domain);
 149         ret = gencache_del(key);
 150         SAFE_FREE(key);
 151 
 152         if (ret) {
 153                 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
 154         }
 155 
 156         return ret;
 157 }
 158 
 159 /****************************************************************************
 160 ****************************************************************************/
 161 
 162 char *saf_fetch( const char *domain )
     /* [<][>][^][v][top][bottom][index][help] */
 163 {
 164         char *server = NULL;
 165         time_t timeout;
 166         bool ret = False;
 167         char *key = NULL;
 168 
 169         if ( !domain || strlen(domain) == 0) {
 170                 DEBUG(2,("saf_fetch: Empty domain name!\n"));
 171                 return NULL;
 172         }
 173 
 174         if ( !gencache_init() )
 175                 return False;
 176 
 177         key = saf_join_key( domain );
 178 
 179         ret = gencache_get( key, &server, &timeout );
 180 
 181         SAFE_FREE( key );
 182 
 183         if ( ret ) {
 184                 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
 185                         server, domain ));
 186                 return server;
 187         }
 188 
 189         key = saf_key( domain );
 190 
 191         ret = gencache_get( key, &server, &timeout );
 192 
 193         SAFE_FREE( key );
 194 
 195         if ( !ret ) {
 196                 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
 197                                         domain ));
 198         } else {
 199                 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
 200                         server, domain ));
 201         }
 202 
 203         return server;
 204 }
 205 
 206 /****************************************************************************
 207  Generate a random trn_id.
 208 ****************************************************************************/
 209 
 210 static int generate_trn_id(void)
     /* [<][>][^][v][top][bottom][index][help] */
 211 {
 212         uint16 id;
 213 
 214         generate_random_buffer((uint8 *)&id, sizeof(id));
 215 
 216         return id % (unsigned)0x7FFF;
 217 }
 218 
 219 /****************************************************************************
 220  Parse a node status response into an array of structures.
 221 ****************************************************************************/
 222 
 223 static NODE_STATUS_STRUCT *parse_node_status(char *p,
     /* [<][>][^][v][top][bottom][index][help] */
 224                                 int *num_names,
 225                                 struct node_status_extra *extra)
 226 {
 227         NODE_STATUS_STRUCT *ret;
 228         int i;
 229 
 230         *num_names = CVAL(p,0);
 231 
 232         if (*num_names == 0)
 233                 return NULL;
 234 
 235         ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);
 236         if (!ret)
 237                 return NULL;
 238 
 239         p++;
 240         for (i=0;i< *num_names;i++) {
 241                 StrnCpy(ret[i].name,p,15);
 242                 trim_char(ret[i].name,'\0',' ');
 243                 ret[i].type = CVAL(p,15);
 244                 ret[i].flags = p[16];
 245                 p += 18;
 246                 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
 247                            ret[i].type, ret[i].flags));
 248         }
 249         /*
 250          * Also, pick up the MAC address ...
 251          */
 252         if (extra) {
 253                 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
 254         }
 255         return ret;
 256 }
 257 
 258 
 259 /****************************************************************************
 260  Do a NBT node status query on an open socket and return an array of
 261  structures holding the returned names or NULL if the query failed.
 262 **************************************************************************/
 263 
 264 NODE_STATUS_STRUCT *node_status_query(int fd,
     /* [<][>][^][v][top][bottom][index][help] */
 265                                         struct nmb_name *name,
 266                                         const struct sockaddr_storage *to_ss,
 267                                         int *num_names,
 268                                         struct node_status_extra *extra)
 269 {
 270         bool found=False;
 271         int retries = 2;
 272         int retry_time = 2000;
 273         struct timeval tval;
 274         struct packet_struct p;
 275         struct packet_struct *p2;
 276         struct nmb_packet *nmb = &p.packet.nmb;
 277         NODE_STATUS_STRUCT *ret;
 278 
 279         ZERO_STRUCT(p);
 280 
 281         if (to_ss->ss_family != AF_INET) {
 282                 /* Can't do node status to IPv6 */
 283                 return NULL;
 284         }
 285         nmb->header.name_trn_id = generate_trn_id();
 286         nmb->header.opcode = 0;
 287         nmb->header.response = false;
 288         nmb->header.nm_flags.bcast = false;
 289         nmb->header.nm_flags.recursion_available = false;
 290         nmb->header.nm_flags.recursion_desired = false;
 291         nmb->header.nm_flags.trunc = false;
 292         nmb->header.nm_flags.authoritative = false;
 293         nmb->header.rcode = 0;
 294         nmb->header.qdcount = 1;
 295         nmb->header.ancount = 0;
 296         nmb->header.nscount = 0;
 297         nmb->header.arcount = 0;
 298         nmb->question.question_name = *name;
 299         nmb->question.question_type = 0x21;
 300         nmb->question.question_class = 0x1;
 301 
 302         p.ip = ((const struct sockaddr_in *)to_ss)->sin_addr;
 303         p.port = NMB_PORT;
 304         p.fd = fd;
 305         p.timestamp = time(NULL);
 306         p.packet_type = NMB_PACKET;
 307 
 308         GetTimeOfDay(&tval);
 309 
 310         if (!send_packet(&p))
 311                 return NULL;
 312 
 313         retries--;
 314 
 315         while (1) {
 316                 struct timeval tval2;
 317                 GetTimeOfDay(&tval2);
 318                 if (TvalDiff(&tval,&tval2) > retry_time) {
 319                         if (!retries)
 320                                 break;
 321                         if (!found && !send_packet(&p))
 322                                 return NULL;
 323                         GetTimeOfDay(&tval);
 324                         retries--;
 325                 }
 326 
 327                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
 328                         struct nmb_packet *nmb2 = &p2->packet.nmb;
 329                         debug_nmb_packet(p2);
 330 
 331                         if (nmb2->header.opcode != 0 ||
 332                             nmb2->header.nm_flags.bcast ||
 333                             nmb2->header.rcode ||
 334                             !nmb2->header.ancount ||
 335                             nmb2->answers->rr_type != 0x21) {
 336                                 /* XXXX what do we do with this? could be a
 337                                    redirect, but we'll discard it for the
 338                                    moment */
 339                                 free_packet(p2);
 340                                 continue;
 341                         }
 342 
 343                         ret = parse_node_status(&nmb2->answers->rdata[0],
 344                                         num_names, extra);
 345                         free_packet(p2);
 346                         return ret;
 347                 }
 348         }
 349 
 350         return NULL;
 351 }
 352 
 353 /****************************************************************************
 354  Find the first type XX name in a node status reply - used for finding
 355  a servers name given its IP. Return the matched name in *name.
 356 **************************************************************************/
 357 
 358 bool name_status_find(const char *q_name,
     /* [<][>][^][v][top][bottom][index][help] */
 359                         int q_type,
 360                         int type,
 361                         const struct sockaddr_storage *to_ss,
 362                         fstring name)
 363 {
 364         char addr[INET6_ADDRSTRLEN];
 365         struct sockaddr_storage ss;
 366         NODE_STATUS_STRUCT *status = NULL;
 367         struct nmb_name nname;
 368         int count, i;
 369         int sock;
 370         bool result = false;
 371 
 372         if (lp_disable_netbios()) {
 373                 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
 374                                         q_name, q_type));
 375                 return False;
 376         }
 377 
 378         print_sockaddr(addr, sizeof(addr), to_ss);
 379 
 380         DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
 381                    q_type, addr));
 382 
 383         /* Check the cache first. */
 384 
 385         if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
 386                 return True;
 387         }
 388 
 389         if (to_ss->ss_family != AF_INET) {
 390                 /* Can't do node status to IPv6 */
 391                 return false;
 392         }
 393 
 394         if (!interpret_string_addr(&ss, lp_socket_address(),
 395                                 AI_NUMERICHOST|AI_PASSIVE)) {
 396                 zero_sockaddr(&ss);
 397         }
 398 
 399         sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True);
 400         if (sock == -1)
 401                 goto done;
 402 
 403         /* W2K PDC's seem not to respond to '*'#0. JRA */
 404         make_nmb_name(&nname, q_name, q_type);
 405         status = node_status_query(sock, &nname, to_ss, &count, NULL);
 406         close(sock);
 407         if (!status)
 408                 goto done;
 409 
 410         for (i=0;i<count;i++) {
 411                 /* Find first one of the requested type that's not a GROUP. */
 412                 if (status[i].type == type && ! (status[i].flags & 0x80))
 413                         break;
 414         }
 415         if (i == count)
 416                 goto done;
 417 
 418         pull_ascii_nstring(name, sizeof(fstring), status[i].name);
 419 
 420         /* Store the result in the cache. */
 421         /* but don't store an entry for 0x1c names here.  Here we have
 422            a single host and DOMAIN<0x1c> names should be a list of hosts */
 423 
 424         if ( q_type != 0x1c ) {
 425                 namecache_status_store(q_name, q_type, type, to_ss, name);
 426         }
 427 
 428         result = true;
 429 
 430  done:
 431         SAFE_FREE(status);
 432 
 433         DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
 434 
 435         if (result)
 436                 DEBUGADD(10, (", name %s ip address is %s", name, addr));
 437 
 438         DEBUG(10, ("\n"));
 439 
 440         return result;
 441 }
 442 
 443 /*
 444   comparison function used by sort_addr_list
 445 */
 446 
 447 static int addr_compare(const struct sockaddr *ss1,
     /* [<][>][^][v][top][bottom][index][help] */
 448                 const struct sockaddr *ss2)
 449 {
 450         int max_bits1=0, max_bits2=0;
 451         int num_interfaces = iface_count();
 452         int i;
 453 
 454         /* Sort IPv6 addresses first. */
 455         if (ss1->sa_family != ss2->sa_family) {
 456                 if (ss2->sa_family == AF_INET) {
 457                         return -1;
 458                 } else {
 459                         return 1;
 460                 }
 461         }
 462 
 463         /* Here we know both addresses are of the same
 464          * family. */
 465 
 466         for (i=0;i<num_interfaces;i++) {
 467                 const struct sockaddr_storage *pss = iface_n_bcast(i);
 468                 unsigned char *p_ss1 = NULL;
 469                 unsigned char *p_ss2 = NULL;
 470                 unsigned char *p_if = NULL;
 471                 size_t len = 0;
 472                 int bits1, bits2;
 473 
 474                 if (pss->ss_family != ss1->sa_family) {
 475                         /* Ignore interfaces of the wrong type. */
 476                         continue;
 477                 }
 478                 if (pss->ss_family == AF_INET) {
 479                         p_if = (unsigned char *)
 480                                 &((const struct sockaddr_in *)pss)->sin_addr;
 481                         p_ss1 = (unsigned char *)
 482                                 &((const struct sockaddr_in *)ss1)->sin_addr;
 483                         p_ss2 = (unsigned char *)
 484                                 &((const struct sockaddr_in *)ss2)->sin_addr;
 485                         len = 4;
 486                 }
 487 #if defined(HAVE_IPV6)
 488                 if (pss->ss_family == AF_INET6) {
 489                         p_if = (unsigned char *)
 490                                 &((const struct sockaddr_in6 *)pss)->sin6_addr;
 491                         p_ss1 = (unsigned char *)
 492                                 &((const struct sockaddr_in6 *)ss1)->sin6_addr;
 493                         p_ss2 = (unsigned char *)
 494                                 &((const struct sockaddr_in6 *)ss2)->sin6_addr;
 495                         len = 16;
 496                 }
 497 #endif
 498                 if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
 499                         continue;
 500                 }
 501                 bits1 = matching_len_bits(p_ss1, p_if, len);
 502                 bits2 = matching_len_bits(p_ss2, p_if, len);
 503                 max_bits1 = MAX(bits1, max_bits1);
 504                 max_bits2 = MAX(bits2, max_bits2);
 505         }
 506 
 507         /* Bias towards directly reachable IPs */
 508         if (iface_local(ss1)) {
 509                 if (ss1->sa_family == AF_INET) {
 510                         max_bits1 += 32;
 511                 } else {
 512                         max_bits1 += 128;
 513                 }
 514         }
 515         if (iface_local(ss2)) {
 516                 if (ss2->sa_family == AF_INET) {
 517                         max_bits2 += 32;
 518                 } else {
 519                         max_bits2 += 128;
 520                 }
 521         }
 522         return max_bits2 - max_bits1;
 523 }
 524 
 525 /*******************************************************************
 526  compare 2 ldap IPs by nearness to our interfaces - used in qsort
 527 *******************************************************************/
 528 
 529 int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
     /* [<][>][^][v][top][bottom][index][help] */
 530 {
 531         int result;
 532 
 533         if ((result = addr_compare((struct sockaddr *)&ss1->ss, (struct sockaddr *)&ss2->ss)) != 0) {
 534                 return result;
 535         }
 536 
 537         if (ss1->port > ss2->port) {
 538                 return 1;
 539         }
 540 
 541         if (ss1->port < ss2->port) {
 542                 return -1;
 543         }
 544 
 545         return 0;
 546 }
 547 
 548 /*
 549   sort an IP list so that names that are close to one of our interfaces
 550   are at the top. This prevents the problem where a WINS server returns an IP
 551   that is not reachable from our subnet as the first match
 552 */
 553 
 554 static void sort_addr_list(struct sockaddr_storage *sslist, int count)
     /* [<][>][^][v][top][bottom][index][help] */
 555 {
 556         if (count <= 1) {
 557                 return;
 558         }
 559 
 560         qsort(sslist, count, sizeof(struct sockaddr_storage),
 561                         QSORT_CAST addr_compare);
 562 }
 563 
 564 static void sort_service_list(struct ip_service *servlist, int count)
     /* [<][>][^][v][top][bottom][index][help] */
 565 {
 566         if (count <= 1) {
 567                 return;
 568         }
 569 
 570         qsort(servlist, count, sizeof(struct ip_service),
 571                         QSORT_CAST ip_service_compare);
 572 }
 573 
 574 /**********************************************************************
 575  Remove any duplicate address/port pairs in the list
 576  *********************************************************************/
 577 
 578 static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
     /* [<][>][^][v][top][bottom][index][help] */
 579 {
 580         int i, j;
 581 
 582         DEBUG(10,("remove_duplicate_addrs2: "
 583                         "looking for duplicate address/port pairs\n"));
 584 
 585         /* one loop to remove duplicates */
 586         for ( i=0; i<count; i++ ) {
 587                 if ( is_zero_addr((struct sockaddr *)&iplist[i].ss)) {
 588                         continue;
 589                 }
 590 
 591                 for ( j=i+1; j<count; j++ ) {
 592                         if (sockaddr_equal((struct sockaddr *)&iplist[i].ss, (struct sockaddr *)&iplist[j].ss) &&
 593                                         iplist[i].port == iplist[j].port) {
 594                                 zero_sockaddr(&iplist[j].ss);
 595                         }
 596                 }
 597         }
 598 
 599         /* one loop to clean up any holes we left */
 600         /* first ip should never be a zero_ip() */
 601         for (i = 0; i<count; ) {
 602                 if (is_zero_addr((struct sockaddr *)&iplist[i].ss) ) {
 603                         if (i != count-1) {
 604                                 memmove(&iplist[i], &iplist[i+1],
 605                                         (count - i - 1)*sizeof(iplist[i]));
 606                         }
 607                         count--;
 608                         continue;
 609                 }
 610                 i++;
 611         }
 612 
 613         return count;
 614 }
 615 
 616 /****************************************************************************
 617  Do a netbios name query to find someones IP.
 618  Returns an array of IP addresses or NULL if none.
 619  *count will be set to the number of addresses returned.
 620  *timed_out is set if we failed by timing out
 621 ****************************************************************************/
 622 
 623 struct sockaddr_storage *name_query(int fd,
     /* [<][>][^][v][top][bottom][index][help] */
 624                         const char *name,
 625                         int name_type,
 626                         bool bcast,
 627                         bool recurse,
 628                         const struct sockaddr_storage *to_ss,
 629                         int *count,
 630                         int *flags,
 631                         bool *timed_out)
 632 {
 633         bool found=false;
 634         int i, retries = 3;
 635         int retry_time = bcast?250:2000;
 636         struct timeval tval;
 637         struct packet_struct p;
 638         struct packet_struct *p2;
 639         struct nmb_packet *nmb = &p.packet.nmb;
 640         struct sockaddr_storage *ss_list = NULL;
 641 
 642         if (lp_disable_netbios()) {
 643                 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
 644                                         name, name_type));
 645                 return NULL;
 646         }
 647 
 648         if (to_ss->ss_family != AF_INET) {
 649                 return NULL;
 650         }
 651 
 652         if (timed_out) {
 653                 *timed_out = false;
 654         }
 655 
 656         memset((char *)&p,'\0',sizeof(p));
 657         (*count) = 0;
 658         (*flags) = 0;
 659 
 660         nmb->header.name_trn_id = generate_trn_id();
 661         nmb->header.opcode = 0;
 662         nmb->header.response = false;
 663         nmb->header.nm_flags.bcast = bcast;
 664         nmb->header.nm_flags.recursion_available = false;
 665         nmb->header.nm_flags.recursion_desired = recurse;
 666         nmb->header.nm_flags.trunc = false;
 667         nmb->header.nm_flags.authoritative = false;
 668         nmb->header.rcode = 0;
 669         nmb->header.qdcount = 1;
 670         nmb->header.ancount = 0;
 671         nmb->header.nscount = 0;
 672         nmb->header.arcount = 0;
 673 
 674         make_nmb_name(&nmb->question.question_name,name,name_type);
 675 
 676         nmb->question.question_type = 0x20;
 677         nmb->question.question_class = 0x1;
 678 
 679         p.ip = ((struct sockaddr_in *)to_ss)->sin_addr;
 680         p.port = NMB_PORT;
 681         p.fd = fd;
 682         p.timestamp = time(NULL);
 683         p.packet_type = NMB_PACKET;
 684 
 685         GetTimeOfDay(&tval);
 686 
 687         if (!send_packet(&p))
 688                 return NULL;
 689 
 690         retries--;
 691 
 692         while (1) {
 693                 struct timeval tval2;
 694 
 695                 GetTimeOfDay(&tval2);
 696                 if (TvalDiff(&tval,&tval2) > retry_time) {
 697                         if (!retries)
 698                                 break;
 699                         if (!found && !send_packet(&p))
 700                                 return NULL;
 701                         GetTimeOfDay(&tval);
 702                         retries--;
 703                 }
 704 
 705                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
 706                         struct nmb_packet *nmb2 = &p2->packet.nmb;
 707                         debug_nmb_packet(p2);
 708 
 709                         /* If we get a Negative Name Query Response from a WINS
 710                          * server, we should report it and give up.
 711                          */
 712                         if( 0 == nmb2->header.opcode    /* A query response   */
 713                             && !(bcast)                 /* from a WINS server */
 714                             && nmb2->header.rcode       /* Error returned     */
 715                                 ) {
 716 
 717                                 if( DEBUGLVL( 3 ) ) {
 718                                         /* Only executed if DEBUGLEVEL >= 3 */
 719                                         dbgtext( "Negative name query "
 720                                                 "response, rcode 0x%02x: ",
 721                                                 nmb2->header.rcode );
 722                                         switch( nmb2->header.rcode ) {
 723                                         case 0x01:
 724                                                 dbgtext( "Request "
 725                                                 "was invalidly formatted.\n" );
 726                                                 break;
 727                                         case 0x02:
 728                                                 dbgtext( "Problem with NBNS, "
 729                                                 "cannot process name.\n");
 730                                                 break;
 731                                         case 0x03:
 732                                                 dbgtext( "The name requested "
 733                                                 "does not exist.\n" );
 734                                                 break;
 735                                         case 0x04:
 736                                                 dbgtext( "Unsupported request "
 737                                                 "error.\n" );
 738                                                 break;
 739                                         case 0x05:
 740                                                 dbgtext( "Query refused "
 741                                                 "error.\n" );
 742                                                 break;
 743                                         default:
 744                                                 dbgtext( "Unrecognized error "
 745                                                 "code.\n" );
 746                                                 break;
 747                                         }
 748                                 }
 749                                 free_packet(p2);
 750                                 return( NULL );
 751                         }
 752 
 753                         if (nmb2->header.opcode != 0 ||
 754                             nmb2->header.nm_flags.bcast ||
 755                             nmb2->header.rcode ||
 756                             !nmb2->header.ancount) {
 757                                 /*
 758                                  * XXXX what do we do with this? Could be a
 759                                  * redirect, but we'll discard it for the
 760                                  * moment.
 761                                  */
 762                                 free_packet(p2);
 763                                 continue;
 764                         }
 765 
 766                         ss_list = SMB_REALLOC_ARRAY(ss_list,
 767                                                 struct sockaddr_storage,
 768                                                 (*count) +
 769                                                 nmb2->answers->rdlength/6);
 770 
 771                         if (!ss_list) {
 772                                 DEBUG(0,("name_query: Realloc failed.\n"));
 773                                 free_packet(p2);
 774                                 return NULL;
 775                         }
 776 
 777                         DEBUG(2,("Got a positive name query response "
 778                                         "from %s ( ",
 779                                         inet_ntoa(p2->ip)));
 780 
 781                         for (i=0;i<nmb2->answers->rdlength/6;i++) {
 782                                 struct in_addr ip;
 783                                 putip((char *)&ip,&nmb2->answers->rdata[2+i*6]);
 784                                 in_addr_to_sockaddr_storage(&ss_list[(*count)],
 785                                                 ip);
 786                                 DEBUGADD(2,("%s ",inet_ntoa(ip)));
 787                                 (*count)++;
 788                         }
 789                         DEBUGADD(2,(")\n"));
 790 
 791                         found=true;
 792                         retries=0;
 793                         /* We add the flags back ... */
 794                         if (nmb2->header.response)
 795                                 (*flags) |= NM_FLAGS_RS;
 796                         if (nmb2->header.nm_flags.authoritative)
 797                                 (*flags) |= NM_FLAGS_AA;
 798                         if (nmb2->header.nm_flags.trunc)
 799                                 (*flags) |= NM_FLAGS_TC;
 800                         if (nmb2->header.nm_flags.recursion_desired)
 801                                 (*flags) |= NM_FLAGS_RD;
 802                         if (nmb2->header.nm_flags.recursion_available)
 803                                 (*flags) |= NM_FLAGS_RA;
 804                         if (nmb2->header.nm_flags.bcast)
 805                                 (*flags) |= NM_FLAGS_B;
 806                         free_packet(p2);
 807                         /*
 808                          * If we're doing a unicast lookup we only
 809                          * expect one reply. Don't wait the full 2
 810                          * seconds if we got one. JRA.
 811                          */
 812                         if(!bcast && found)
 813                                 break;
 814                 }
 815         }
 816 
 817         /* only set timed_out if we didn't fund what we where looking for*/
 818 
 819         if ( !found && timed_out ) {
 820                 *timed_out = true;
 821         }
 822 
 823         /* sort the ip list so we choose close servers first if possible */
 824         sort_addr_list(ss_list, *count);
 825 
 826         return ss_list;
 827 }
 828 
 829 /********************************************************
 830  Start parsing the lmhosts file.
 831 *********************************************************/
 832 
 833 XFILE *startlmhosts(const char *fname)
     /* [<][>][^][v][top][bottom][index][help] */
 834 {
 835         XFILE *fp = x_fopen(fname,O_RDONLY, 0);
 836         if (!fp) {
 837                 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. "
 838                         "Error was %s\n",
 839                         fname, strerror(errno)));
 840                 return NULL;
 841         }
 842         return fp;
 843 }
 844 
 845 /********************************************************
 846  Parse the next line in the lmhosts file.
 847 *********************************************************/
 848 
 849 bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type,
     /* [<][>][^][v][top][bottom][index][help] */
 850                 struct sockaddr_storage *pss)
 851 {
 852         char line[1024];
 853 
 854         *pp_name = NULL;
 855 
 856         while(!x_feof(fp) && !x_ferror(fp)) {
 857                 char *ip = NULL;
 858                 char *flags = NULL;
 859                 char *extra = NULL;
 860                 char *name = NULL;
 861                 const char *ptr;
 862                 char *ptr1 = NULL;
 863                 int count = 0;
 864 
 865                 *name_type = -1;
 866 
 867                 if (!fgets_slash(line,sizeof(line),fp)) {
 868                         continue;
 869                 }
 870 
 871                 if (*line == '#') {
 872                         continue;
 873                 }
 874 
 875                 ptr = line;
 876 
 877                 if (next_token_talloc(ctx, &ptr, &ip, NULL))
 878                         ++count;
 879                 if (next_token_talloc(ctx, &ptr, &name, NULL))
 880                         ++count;
 881                 if (next_token_talloc(ctx, &ptr, &flags, NULL))
 882                         ++count;
 883                 if (next_token_talloc(ctx, &ptr, &extra, NULL))
 884                         ++count;
 885 
 886                 if (count <= 0)
 887                         continue;
 888 
 889                 if (count > 0 && count < 2) {
 890                         DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",
 891                                                 line));
 892                         continue;
 893                 }
 894 
 895                 if (count >= 4) {
 896                         DEBUG(0,("getlmhostsent: too many columns "
 897                                 "in lmhosts file (obsolete syntax)\n"));
 898                         continue;
 899                 }
 900 
 901                 if (!flags) {
 902                         flags = talloc_strdup(ctx, "");
 903                         if (!flags) {
 904                                 continue;
 905                         }
 906                 }
 907 
 908                 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n",
 909                                         ip, name, flags));
 910 
 911                 if (strchr_m(flags,'G') || strchr_m(flags,'S')) {
 912                         DEBUG(0,("getlmhostsent: group flag "
 913                                 "in lmhosts ignored (obsolete)\n"));
 914                         continue;
 915                 }
 916 
 917                 if (!interpret_string_addr(pss, ip, AI_NUMERICHOST)) {
 918                         DEBUG(0,("getlmhostsent: invalid address "
 919                                 "%s.\n", ip));
 920                 }
 921 
 922                 /* Extra feature. If the name ends in '#XX',
 923                  * where XX is a hex number, then only add that name type. */
 924                 if((ptr1 = strchr_m(name, '#')) != NULL) {
 925                         char *endptr;
 926                         ptr1++;
 927 
 928                         *name_type = (int)strtol(ptr1, &endptr, 16);
 929                         if(!*ptr1 || (endptr == ptr1)) {
 930                                 DEBUG(0,("getlmhostsent: invalid name "
 931                                         "%s containing '#'.\n", name));
 932                                 continue;
 933                         }
 934 
 935                         *(--ptr1) = '\0'; /* Truncate at the '#' */
 936                 }
 937 
 938                 *pp_name = talloc_strdup(ctx, name);
 939                 if (!*pp_name) {
 940                         return false;
 941                 }
 942                 return true;
 943         }
 944 
 945         return false;
 946 }
 947 
 948 /********************************************************
 949  Finish parsing the lmhosts file.
 950 *********************************************************/
 951 
 952 void endlmhosts(XFILE *fp)
     /* [<][>][^][v][top][bottom][index][help] */
 953 {
 954         x_fclose(fp);
 955 }
 956 
 957 /********************************************************
 958  convert an array if struct sockaddr_storage to struct ip_service
 959  return false on failure.  Port is set to PORT_NONE;
 960 *********************************************************/
 961 
 962 static bool convert_ss2service(struct ip_service **return_iplist,
     /* [<][>][^][v][top][bottom][index][help] */
 963                 const struct sockaddr_storage *ss_list,
 964                 int count)
 965 {
 966         int i;
 967 
 968         if ( count==0 || !ss_list )
 969                 return False;
 970 
 971         /* copy the ip address; port will be PORT_NONE */
 972         if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) ==
 973                         NULL) {
 974                 DEBUG(0,("convert_ip2service: malloc failed "
 975                         "for %d enetries!\n", count ));
 976                 return False;
 977         }
 978 
 979         for ( i=0; i<count; i++ ) {
 980                 (*return_iplist)[i].ss   = ss_list[i];
 981                 (*return_iplist)[i].port = PORT_NONE;
 982         }
 983 
 984         return true;
 985 }
 986 
 987 /********************************************************
 988  Resolve via "bcast" method.
 989 *********************************************************/
 990 
 991 NTSTATUS name_resolve_bcast(const char *name,
     /* [<][>][^][v][top][bottom][index][help] */
 992                         int name_type,
 993                         struct ip_service **return_iplist,
 994                         int *return_count)
 995 {
 996         int sock, i;
 997         int num_interfaces = iface_count();
 998         struct sockaddr_storage *ss_list;
 999         struct sockaddr_storage ss;
1000         NTSTATUS status;
1001 
1002         if (lp_disable_netbios()) {
1003                 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n",
1004                                         name, name_type));
1005                 return NT_STATUS_INVALID_PARAMETER;
1006         }
1007 
1008         *return_iplist = NULL;
1009         *return_count = 0;
1010 
1011         /*
1012          * "bcast" means do a broadcast lookup on all the local interfaces.
1013          */
1014 
1015         DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
1016                 "for name %s<0x%x>\n", name, name_type));
1017 
1018         if (!interpret_string_addr(&ss, lp_socket_address(),
1019                                 AI_NUMERICHOST|AI_PASSIVE)) {
1020                 zero_sockaddr(&ss);
1021         }
1022 
1023         sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );
1024         if (sock == -1) {
1025                 return NT_STATUS_UNSUCCESSFUL;
1026         }
1027 
1028         set_socket_options(sock,"SO_BROADCAST");
1029         /*
1030          * Lookup the name on all the interfaces, return on
1031          * the first successful match.
1032          */
1033         for( i = num_interfaces-1; i >= 0; i--) {
1034                 const struct sockaddr_storage *pss = iface_n_bcast(i);
1035                 int flags;
1036 
1037                 /* Done this way to fix compiler error on IRIX 5.x */
1038                 if (!pss) {
1039                         continue;
1040                 }
1041                 ss_list = name_query(sock, name, name_type, true,
1042                                     true, pss, return_count, &flags, NULL);
1043                 if (ss_list) {
1044                         goto success;
1045                 }
1046         }
1047 
1048         /* failed - no response */
1049 
1050         close(sock);
1051         return NT_STATUS_UNSUCCESSFUL;
1052 
1053 success:
1054 
1055         status = NT_STATUS_OK;
1056         if (!convert_ss2service(return_iplist, ss_list, *return_count) )
1057                 status = NT_STATUS_INVALID_PARAMETER;
1058 
1059         SAFE_FREE(ss_list);
1060         close(sock);
1061         return status;
1062 }
1063 
1064 /********************************************************
1065  Resolve via "wins" method.
1066 *********************************************************/
1067 
1068 NTSTATUS resolve_wins(const char *name,
     /* [<][>][^][v][top][bottom][index][help] */
1069                 int name_type,
1070                 struct ip_service **return_iplist,
1071                 int *return_count)
1072 {
1073         int sock, t, i;
1074         char **wins_tags;
1075         struct sockaddr_storage src_ss, *ss_list = NULL;
1076         struct in_addr src_ip;
1077         NTSTATUS status;
1078 
1079         if (lp_disable_netbios()) {
1080                 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n",
1081                                         name, name_type));
1082                 return NT_STATUS_INVALID_PARAMETER;
1083         }
1084 
1085         *return_iplist = NULL;
1086         *return_count = 0;
1087 
1088         DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
1089                                 name, name_type));
1090 
1091         if (wins_srv_count() < 1) {
1092                 DEBUG(3,("resolve_wins: WINS server resolution selected "
1093                         "and no WINS servers listed.\n"));
1094                 return NT_STATUS_INVALID_PARAMETER;
1095         }
1096 
1097         /* we try a lookup on each of the WINS tags in turn */
1098         wins_tags = wins_srv_tags();
1099 
1100         if (!wins_tags) {
1101                 /* huh? no tags?? give up in disgust */
1102                 return NT_STATUS_INVALID_PARAMETER;
1103         }
1104 
1105         /* the address we will be sending from */
1106         if (!interpret_string_addr(&src_ss, lp_socket_address(),
1107                                 AI_NUMERICHOST|AI_PASSIVE)) {
1108                 zero_sockaddr(&src_ss);
1109         }
1110 
1111         if (src_ss.ss_family != AF_INET) {
1112                 char addr[INET6_ADDRSTRLEN];
1113                 print_sockaddr(addr, sizeof(addr), &src_ss);
1114                 DEBUG(3,("resolve_wins: cannot receive WINS replies "
1115                         "on IPv6 address %s\n",
1116                         addr));
1117                 wins_srv_tags_free(wins_tags);
1118                 return NT_STATUS_INVALID_PARAMETER;
1119         }
1120 
1121         src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr;
1122 
1123         /* in the worst case we will try every wins server with every
1124            tag! */
1125         for (t=0; wins_tags && wins_tags[t]; t++) {
1126                 int srv_count = wins_srv_count_tag(wins_tags[t]);
1127                 for (i=0; i<srv_count; i++) {
1128                         struct sockaddr_storage wins_ss;
1129                         struct in_addr wins_ip;
1130                         int flags;
1131                         bool timed_out;
1132 
1133                         wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
1134 
1135                         if (global_in_nmbd && ismyip_v4(wins_ip)) {
1136                                 /* yikes! we'll loop forever */
1137                                 continue;
1138                         }
1139 
1140                         /* skip any that have been unresponsive lately */
1141                         if (wins_srv_is_dead(wins_ip, src_ip)) {
1142                                 continue;
1143                         }
1144 
1145                         DEBUG(3,("resolve_wins: using WINS server %s "
1146                                 "and tag '%s'\n",
1147                                 inet_ntoa(wins_ip), wins_tags[t]));
1148 
1149                         sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);
1150                         if (sock == -1) {
1151                                 continue;
1152                         }
1153 
1154                         in_addr_to_sockaddr_storage(&wins_ss, wins_ip);
1155                         ss_list = name_query(sock,
1156                                                 name,
1157                                                 name_type,
1158                                                 false,
1159                                                 true,
1160                                                 &wins_ss,
1161                                                 return_count,
1162                                                 &flags,
1163                                                 &timed_out);
1164 
1165                         /* exit loop if we got a list of addresses */
1166 
1167                         if (ss_list)
1168                                 goto success;
1169 
1170                         close(sock);
1171 
1172                         if (timed_out) {
1173                                 /* Timed out wating for WINS server to respond.
1174                                  * Mark it dead. */
1175                                 wins_srv_died(wins_ip, src_ip);
1176                         } else {
1177                                 /* The name definately isn't in this
1178                                    group of WINS servers.
1179                                    goto the next group  */
1180                                 break;
1181                         }
1182                 }
1183         }
1184 
1185         wins_srv_tags_free(wins_tags);
1186         return NT_STATUS_NO_LOGON_SERVERS;
1187 
1188 success:
1189 
1190         status = NT_STATUS_OK;
1191         if (!convert_ss2service(return_iplist, ss_list, *return_count))
1192                 status = NT_STATUS_INVALID_PARAMETER;
1193 
1194         SAFE_FREE(ss_list);
1195         wins_srv_tags_free(wins_tags);
1196         close(sock);
1197 
1198         return status;
1199 }
1200 
1201 /********************************************************
1202  Resolve via "lmhosts" method.
1203 *********************************************************/
1204 
1205 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
     /* [<][>][^][v][top][bottom][index][help] */
1206                                 struct ip_service **return_iplist,
1207                                 int *return_count)
1208 {
1209         /*
1210          * "lmhosts" means parse the local lmhosts file.
1211          */
1212 
1213         XFILE *fp;
1214         char *lmhost_name = NULL;
1215         int name_type2;
1216         struct sockaddr_storage return_ss;
1217         NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1218         TALLOC_CTX *ctx = NULL;
1219 
1220         *return_iplist = NULL;
1221         *return_count = 0;
1222 
1223         DEBUG(3,("resolve_lmhosts: "
1224                 "Attempting lmhosts lookup for name %s<0x%x>\n",
1225                 name, name_type));
1226 
1227         fp = startlmhosts(get_dyn_LMHOSTSFILE());
1228 
1229         if ( fp == NULL )
1230                 return NT_STATUS_NO_SUCH_FILE;
1231 
1232         ctx = talloc_init("resolve_lmhosts");
1233         if (!ctx) {
1234                 endlmhosts(fp);
1235                 return NT_STATUS_NO_MEMORY;
1236         }
1237 
1238         while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) {
1239 
1240                 if (!strequal(name, lmhost_name)) {
1241                         TALLOC_FREE(lmhost_name);
1242                         continue;
1243                 }
1244 
1245                 if ((name_type2 != -1) && (name_type != name_type2)) {
1246                         TALLOC_FREE(lmhost_name);
1247                         continue;
1248                 }
1249 
1250                 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist),
1251                                         struct ip_service,
1252                                         (*return_count)+1);
1253 
1254                 if ((*return_iplist) == NULL) {
1255                         TALLOC_FREE(ctx);
1256                         endlmhosts(fp);
1257                         DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
1258                         return NT_STATUS_NO_MEMORY;
1259                 }
1260 
1261                 (*return_iplist)[*return_count].ss = return_ss;
1262                 (*return_iplist)[*return_count].port = PORT_NONE;
1263                 *return_count += 1;
1264 
1265                 /* we found something */
1266                 status = NT_STATUS_OK;
1267 
1268                 /* Multiple names only for DC lookup */
1269                 if (name_type != 0x1c)
1270                         break;
1271         }
1272 
1273         TALLOC_FREE(ctx);
1274         endlmhosts(fp);
1275         return status;
1276 }
1277 
1278 
1279 /********************************************************
1280  Resolve via "hosts" method.
1281 *********************************************************/
1282 
1283 static NTSTATUS resolve_hosts(const char *name, int name_type,
     /* [<][>][^][v][top][bottom][index][help] */
1284                               struct ip_service **return_iplist,
1285                               int *return_count)
1286 {
1287         /*
1288          * "host" means do a localhost, or dns lookup.
1289          */
1290         struct addrinfo hints;
1291         struct addrinfo *ailist = NULL;
1292         struct addrinfo *res = NULL;
1293         int ret = -1;
1294         int i = 0;
1295 
1296         if ( name_type != 0x20 && name_type != 0x0) {
1297                 DEBUG(5, ("resolve_hosts: not appropriate "
1298                         "for name type <0x%x>\n",
1299                         name_type));
1300                 return NT_STATUS_INVALID_PARAMETER;
1301         }
1302 
1303         *return_iplist = NULL;
1304         *return_count = 0;
1305 
1306         DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
1307                                 name, name_type));
1308 
1309         ZERO_STRUCT(hints);
1310         /* By default make sure it supports TCP. */
1311         hints.ai_socktype = SOCK_STREAM;
1312         hints.ai_flags = AI_ADDRCONFIG;
1313 
1314 #if !defined(HAVE_IPV6)
1315         /* Unless we have IPv6, we really only want IPv4 addresses back. */
1316         hints.ai_family = AF_INET;
1317 #endif
1318 
1319         ret = getaddrinfo(name,
1320                         NULL,
1321                         &hints,
1322                         &ailist);
1323         if (ret) {
1324                 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
1325                         name,
1326                         gai_strerror(ret) ));
1327         }
1328 
1329         for (res = ailist; res; res = res->ai_next) {
1330                 struct sockaddr_storage ss;
1331 
1332                 if (!res->ai_addr || res->ai_addrlen == 0) {
1333                         continue;
1334                 }
1335 
1336                 ZERO_STRUCT(ss);
1337                 memcpy(&ss, res->ai_addr, res->ai_addrlen);
1338 
1339                 *return_count += 1;
1340 
1341                 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
1342                                                 struct ip_service,
1343                                                 *return_count);
1344                 if (!*return_iplist) {
1345                         DEBUG(3,("resolve_hosts: malloc fail !\n"));
1346                         freeaddrinfo(ailist);
1347                         return NT_STATUS_NO_MEMORY;
1348                 }
1349                 (*return_iplist)[i].ss = ss;
1350                 (*return_iplist)[i].port = PORT_NONE;
1351                 i++;
1352         }
1353         if (ailist) {
1354                 freeaddrinfo(ailist);
1355         }
1356         if (*return_count) {
1357                 return NT_STATUS_OK;
1358         }
1359         return NT_STATUS_UNSUCCESSFUL;
1360 }
1361 
1362 /********************************************************
1363  Resolve via "ADS" method.
1364 *********************************************************/
1365 
1366 static NTSTATUS resolve_ads(const char *name,
     /* [<][>][^][v][top][bottom][index][help] */
1367                             int name_type,
1368                             const char *sitename,
1369                             struct ip_service **return_iplist,
1370                             int *return_count)
1371 {
1372         int                     i, j;
1373         NTSTATUS                status;
1374         TALLOC_CTX              *ctx;
1375         struct dns_rr_srv       *dcs = NULL;
1376         int                     numdcs = 0;
1377         int                     numaddrs = 0;
1378 
1379         if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
1380             (name_type != 0x1b)) {
1381                 return NT_STATUS_INVALID_PARAMETER;
1382         }
1383 
1384         if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1385                 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1386                 return NT_STATUS_NO_MEMORY;
1387         }
1388 
1389         /* The DNS code needs fixing to find IPv6 addresses... JRA. */
1390 
1391         switch (name_type) {
1392                 case 0x1b:
1393                         DEBUG(5,("resolve_ads: Attempting to resolve "
1394                                  "PDC for %s using DNS\n", name));
1395                         status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
1396                         break;
1397 
1398                 case 0x1c:
1399                         DEBUG(5,("resolve_ads: Attempting to resolve "
1400                                  "DCs for %s using DNS\n", name));
1401                         status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
1402                                                    &numdcs);
1403                         break;
1404                 case KDC_NAME_TYPE:
1405                         DEBUG(5,("resolve_ads: Attempting to resolve "
1406                                  "KDCs for %s using DNS\n", name));
1407                         status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
1408                                                     &numdcs);
1409                         break;
1410                 default:
1411                         status = NT_STATUS_INVALID_PARAMETER;
1412                         break;
1413         }
1414 
1415         if ( !NT_STATUS_IS_OK( status ) ) {
1416                 talloc_destroy(ctx);
1417                 return status;
1418         }
1419 
1420         for (i=0;i<numdcs;i++) {
1421                 numaddrs += MAX(dcs[i].num_ips,1);
1422         }
1423 
1424         if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
1425                         NULL ) {
1426                 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
1427                                         numaddrs ));
1428                 talloc_destroy(ctx);
1429                 return NT_STATUS_NO_MEMORY;
1430         }
1431 
1432         /* now unroll the list of IP addresses */
1433 
1434         *return_count = 0;
1435         i = 0;
1436         j = 0;
1437         while ( i < numdcs && (*return_count<numaddrs) ) {
1438                 struct ip_service *r = &(*return_iplist)[*return_count];
1439 
1440                 r->port = dcs[i].port;
1441 
1442                 /* If we don't have an IP list for a name, lookup it up */
1443 
1444                 if (!dcs[i].ss_s) {
1445                         interpret_string_addr(&r->ss, dcs[i].hostname, 0);
1446                         i++;
1447                         j = 0;
1448                 } else {
1449                         /* use the IP addresses from the SRV sresponse */
1450 
1451                         if ( j >= dcs[i].num_ips ) {
1452                                 i++;
1453                                 j = 0;
1454                                 continue;
1455                         }
1456 
1457                         r->ss = dcs[i].ss_s[j];
1458                         j++;
1459                 }
1460 
1461                 /* make sure it is a valid IP.  I considered checking the
1462                  * negative connection cache, but this is the wrong place
1463                  * for it. Maybe only as a hack. After think about it, if
1464                  * all of the IP addresses returned from DNS are dead, what
1465                  * hope does a netbios name lookup have ? The standard reason
1466                  * for falling back to netbios lookups is that our DNS server
1467                  * doesn't know anything about the DC's   -- jerry */
1468 
1469                 if (!is_zero_addr((struct sockaddr *)&r->ss)) {
1470                         (*return_count)++;
1471                 }
1472         }
1473 
1474         talloc_destroy(ctx);
1475         return NT_STATUS_OK;
1476 }
1477 
1478 /*******************************************************************
1479  Internal interface to resolve a name into an IP address.
1480  Use this function if the string is either an IP address, DNS
1481  or host name or NetBIOS name. This uses the name switch in the
1482  smb.conf to determine the order of name resolution.
1483 
1484  Added support for ip addr/port to support ADS ldap servers.
1485  the only place we currently care about the port is in the
1486  resolve_hosts() when looking up DC's via SRV RR entries in DNS
1487 **********************************************************************/
1488 
1489 NTSTATUS internal_resolve_name(const char *name,
     /* [<][>][^][v][top][bottom][index][help] */
1490                                 int name_type,
1491                                 const char *sitename,
1492                                 struct ip_service **return_iplist,
1493                                 int *return_count,
1494                                 const char *resolve_order)
1495 {
1496         char *tok;
1497         const char *ptr;
1498         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1499         int i;
1500         TALLOC_CTX *frame = NULL;
1501 
1502         *return_iplist = NULL;
1503         *return_count = 0;
1504 
1505         DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1506                         name, name_type, sitename ? sitename : "(null)"));
1507 
1508         if (is_ipaddress(name)) {
1509                 if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
1510                                 NULL) {
1511                         DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1512                         return NT_STATUS_NO_MEMORY;
1513                 }
1514 
1515                 /* ignore the port here */
1516                 (*return_iplist)->port = PORT_NONE;
1517 
1518                 /* if it's in the form of an IP address then get the lib to interpret it */
1519                 if (!interpret_string_addr(&(*return_iplist)->ss,
1520                                         name, AI_NUMERICHOST)) {
1521                         DEBUG(1,("internal_resolve_name: interpret_string_addr "
1522                                 "failed on %s\n",
1523                                 name));
1524                         SAFE_FREE(*return_iplist);
1525                         return NT_STATUS_INVALID_PARAMETER;
1526                 }
1527                 *return_count = 1;
1528                 return NT_STATUS_OK;
1529         }
1530 
1531         /* Check name cache */
1532 
1533         if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1534                 /* This could be a negative response */
1535                 if (*return_count > 0) {
1536                         return NT_STATUS_OK;
1537                 } else {
1538                         return NT_STATUS_UNSUCCESSFUL;
1539                 }
1540         }
1541 
1542         /* set the name resolution order */
1543 
1544         if (strcmp( resolve_order, "NULL") == 0) {
1545                 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1546                 return NT_STATUS_INVALID_PARAMETER;
1547         }
1548 
1549         if (!resolve_order[0]) {
1550                 ptr = "host";
1551         } else {
1552                 ptr = resolve_order;
1553         }
1554 
1555         /* iterate through the name resolution backends */
1556 
1557         frame = talloc_stackframe();
1558         while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) {
1559                 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1560                         status = resolve_hosts(name, name_type, return_iplist,
1561                                                return_count);
1562                         if (NT_STATUS_IS_OK(status)) {
1563                                 goto done;
1564                         }
1565                 } else if(strequal( tok, "kdc")) {
1566                         /* deal with KDC_NAME_TYPE names here.
1567                          * This will result in a SRV record lookup */
1568                         status = resolve_ads(name, KDC_NAME_TYPE, sitename,
1569                                              return_iplist, return_count);
1570                         if (NT_STATUS_IS_OK(status)) {
1571                                 /* Ensure we don't namecache
1572                                  * this with the KDC port. */
1573                                 name_type = KDC_NAME_TYPE;
1574                                 goto done;
1575                         }
1576                 } else if(strequal( tok, "ads")) {
1577                         /* deal with 0x1c and 0x1b names here.
1578                          * This will result in a SRV record lookup */
1579                         status = resolve_ads(name, name_type, sitename,
1580                                              return_iplist, return_count);
1581                         if (NT_STATUS_IS_OK(status)) {
1582                                 goto done;
1583                         }
1584                 } else if(strequal( tok, "lmhosts")) {
1585                         status = resolve_lmhosts(name, name_type,
1586                                                  return_iplist, return_count);
1587                         if (NT_STATUS_IS_OK(status)) {
1588                                 goto done;
1589                         }
1590                 } else if(strequal( tok, "wins")) {
1591                         /* don't resolve 1D via WINS */
1592                         if (name_type != 0x1D) {
1593                                 status = resolve_wins(name, name_type,
1594                                                       return_iplist,
1595                                                       return_count);
1596                                 if (NT_STATUS_IS_OK(status)) {
1597                                         goto done;
1598                                 }
1599                         }
1600                 } else if(strequal( tok, "bcast")) {
1601                         status = name_resolve_bcast(name, name_type,
1602                                                     return_iplist,
1603                                                     return_count);
1604                         if (NT_STATUS_IS_OK(status)) {
1605                                 goto done;
1606                         }
1607                 } else {
1608                         DEBUG(0,("resolve_name: unknown name switch type %s\n",
1609                                 tok));
1610                 }
1611         }
1612 
1613         /* All of the resolve_* functions above have returned false. */
1614 
1615         TALLOC_FREE(frame);
1616         SAFE_FREE(*return_iplist);
1617         *return_count = 0;
1618 
1619         return NT_STATUS_UNSUCCESSFUL;
1620 
1621   done:
1622 
1623         /* Remove duplicate entries.  Some queries, notably #1c (domain
1624         controllers) return the PDC in iplist[0] and then all domain
1625         controllers including the PDC in iplist[1..n].  Iterating over
1626         the iplist when the PDC is down will cause two sets of timeouts. */
1627 
1628         if ( *return_count ) {
1629                 *return_count = remove_duplicate_addrs2(*return_iplist,
1630                                         *return_count );
1631         }
1632 
1633         /* Save in name cache */
1634         if ( DEBUGLEVEL >= 100 ) {
1635                 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
1636                         char addr[INET6_ADDRSTRLEN];
1637                         print_sockaddr(addr, sizeof(addr),
1638                                         &(*return_iplist)[i].ss);
1639                         DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
1640                                         name,
1641                                         name_type,
1642                                         addr,
1643                                         (*return_iplist)[i].port));
1644                 }
1645         }
1646 
1647         namecache_store(name, name_type, *return_count, *return_iplist);
1648 
1649         /* Display some debugging info */
1650 
1651         if ( DEBUGLEVEL >= 10 ) {
1652                 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
1653                                         *return_count));
1654 
1655                 for (i = 0; i < *return_count; i++) {
1656                         char addr[INET6_ADDRSTRLEN];
1657                         print_sockaddr(addr, sizeof(addr),
1658                                         &(*return_iplist)[i].ss);
1659                         DEBUGADD(10, ("%s:%d ",
1660                                         addr,
1661                                         (*return_iplist)[i].port));
1662                 }
1663                 DEBUG(10, ("\n"));
1664         }
1665 
1666         TALLOC_FREE(frame);
1667         return status;
1668 }
1669 
1670 /********************************************************
1671  Internal interface to resolve a name into one IP address.
1672  Use this function if the string is either an IP address, DNS
1673  or host name or NetBIOS name. This uses the name switch in the
1674  smb.conf to determine the order of name resolution.
1675 *********************************************************/
1676 
1677 bool resolve_name(const char *name,
     /* [<][>][^][v][top][bottom][index][help] */
1678                 struct sockaddr_storage *return_ss,
1679                 int name_type)
1680 {
1681         struct ip_service *ss_list = NULL;
1682         char *sitename = NULL;
1683         int count = 0;
1684 
1685         if (is_ipaddress(name)) {
1686                 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
1687         }
1688 
1689         sitename = sitename_fetch(lp_realm()); /* wild guess */
1690 
1691         if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
1692                                                   &ss_list, &count,
1693                                                   lp_name_resolve_order()))) {
1694                 int i;
1695 
1696                 /* only return valid addresses for TCP connections */
1697                 for (i=0; i<count; i++) {
1698                         if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1699                                         !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1700                                 *return_ss = ss_list[i].ss;
1701                                 SAFE_FREE(ss_list);
1702                                 SAFE_FREE(sitename);
1703                                 return True;
1704                         }
1705                 }
1706         }
1707 
1708         SAFE_FREE(ss_list);
1709         SAFE_FREE(sitename);
1710         return False;
1711 }
1712 
1713 /********************************************************
1714  Internal interface to resolve a name into a list of IP addresses.
1715  Use this function if the string is either an IP address, DNS
1716  or host name or NetBIOS name. This uses the name switch in the
1717  smb.conf to determine the order of name resolution.
1718 *********************************************************/
1719 
1720 NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1721                 const char *name,
1722                 int name_type,
1723                 struct sockaddr_storage **return_ss_arr,
1724                 unsigned int *p_num_entries)
1725 {
1726         struct ip_service *ss_list = NULL;
1727         char *sitename = NULL;
1728         int count = 0;
1729         int i;
1730         unsigned int num_entries;
1731         NTSTATUS status;
1732 
1733         *p_num_entries = 0;
1734         *return_ss_arr = NULL;
1735 
1736         if (is_ipaddress(name)) {
1737                 *return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage);
1738                 if (!*return_ss_arr) {
1739                         return NT_STATUS_NO_MEMORY;
1740                 }
1741                 if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
1742                         TALLOC_FREE(*return_ss_arr);
1743                         return NT_STATUS_BAD_NETWORK_NAME;
1744                 }
1745                 *p_num_entries = 1;
1746                 return NT_STATUS_OK;
1747         }
1748 
1749         sitename = sitename_fetch(lp_realm()); /* wild guess */
1750 
1751         status = internal_resolve_name(name, name_type, sitename,
1752                                                   &ss_list, &count,
1753                                                   lp_name_resolve_order());
1754         SAFE_FREE(sitename);
1755 
1756         if (!NT_STATUS_IS_OK(status)) {
1757                 return status;
1758         }
1759 
1760         /* only return valid addresses for TCP connections */
1761         for (i=0, num_entries = 0; i<count; i++) {
1762                 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1763                                 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1764                         num_entries++;
1765                 }
1766         }
1767         if (num_entries == 0) {
1768                 SAFE_FREE(ss_list);
1769                 return NT_STATUS_BAD_NETWORK_NAME;
1770         }
1771 
1772         *return_ss_arr = TALLOC_ARRAY(ctx,
1773                                 struct sockaddr_storage,
1774                                 num_entries);
1775         if (!(*return_ss_arr)) {
1776                 SAFE_FREE(ss_list);
1777                 return NT_STATUS_NO_MEMORY;
1778         }
1779 
1780         for (i=0, num_entries = 0; i<count; i++) {
1781                 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1782                                 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1783                         (*return_ss_arr)[num_entries++] = ss_list[i].ss;
1784                 }
1785         }
1786 
1787         status = NT_STATUS_OK;
1788         *p_num_entries = num_entries;
1789 
1790         SAFE_FREE(ss_list);
1791         return NT_STATUS_OK;
1792 }
1793 
1794 /********************************************************
1795  Find the IP address of the master browser or DMB for a workgroup.
1796 *********************************************************/
1797 
1798 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
     /* [<][>][^][v][top][bottom][index][help] */
1799 {
1800         struct ip_service *ip_list = NULL;
1801         int count = 0;
1802         NTSTATUS status;
1803 
1804         if (lp_disable_netbios()) {
1805                 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1806                 return false;
1807         }
1808 
1809         status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
1810                                        lp_name_resolve_order());
1811         if (NT_STATUS_IS_OK(status)) {
1812                 *master_ss = ip_list[0].ss;
1813                 SAFE_FREE(ip_list);
1814                 return true;
1815         }
1816 
1817         status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
1818                                        lp_name_resolve_order());
1819         if (NT_STATUS_IS_OK(status)) {
1820                 *master_ss = ip_list[0].ss;
1821                 SAFE_FREE(ip_list);
1822                 return true;
1823         }
1824 
1825         SAFE_FREE(ip_list);
1826         return false;
1827 }
1828 
1829 /********************************************************
1830  Get the IP address list of the primary domain controller
1831  for a domain.
1832 *********************************************************/
1833 
1834 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
     /* [<][>][^][v][top][bottom][index][help] */
1835 {
1836         struct ip_service *ip_list = NULL;
1837         int count = 0;
1838         NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1839 
1840         /* Look up #1B name */
1841 
1842         if (lp_security() == SEC_ADS) {
1843                 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1844                                                &count, "ads");
1845         }
1846 
1847         if (!NT_STATUS_IS_OK(status) || count == 0) {
1848                 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1849                                                &count,
1850                                                lp_name_resolve_order());
1851                 if (!NT_STATUS_IS_OK(status)) {
1852                         return false;
1853                 }
1854         }
1855 
1856         /* if we get more than 1 IP back we have to assume it is a
1857            multi-homed PDC and not a mess up */
1858 
1859         if ( count > 1 ) {
1860                 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1861                 sort_service_list(ip_list, count);
1862         }
1863 
1864         *pss = ip_list[0].ss;
1865         SAFE_FREE(ip_list);
1866         return true;
1867 }
1868 
1869 /* Private enum type for lookups. */
1870 
1871 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
1872 
1873 /********************************************************
1874  Get the IP address list of the domain controllers for
1875  a domain.
1876 *********************************************************/
1877 
1878 static NTSTATUS get_dc_list(const char *domain,
     /* [<][>][^][v][top][bottom][index][help] */
1879                         const char *sitename,
1880                         struct ip_service **ip_list,
1881                         int *count,
1882                         enum dc_lookup_type lookup_type,
1883                         bool *ordered)
1884 {
1885         char *resolve_order = NULL;
1886         char *saf_servername = NULL;
1887         char *pserver = NULL;
1888         const char *p;
1889         char *port_str = NULL;
1890         int port;
1891         char *name;
1892         int num_addresses = 0;
1893         int  local_count, i, j;
1894         struct ip_service *return_iplist = NULL;
1895         struct ip_service *auto_ip_list = NULL;
1896         bool done_auto_lookup = false;
1897         int auto_count = 0;
1898         NTSTATUS status;
1899         TALLOC_CTX *ctx = talloc_init("get_dc_list");
1900 
1901         *ip_list = NULL;
1902         *count = 0;
1903 
1904         if (!ctx) {
1905                 return NT_STATUS_NO_MEMORY;
1906         }
1907 
1908         *ordered = False;
1909 
1910         /* if we are restricted to solely using DNS for looking
1911            up a domain controller, make sure that host lookups
1912            are enabled for the 'name resolve order'.  If host lookups
1913            are disabled and ads_only is True, then set the string to
1914            NULL. */
1915 
1916         resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
1917         if (!resolve_order) {
1918                 status = NT_STATUS_NO_MEMORY;
1919                 goto out;
1920         }
1921         strlower_m(resolve_order);
1922         if (lookup_type == DC_ADS_ONLY)  {
1923                 if (strstr( resolve_order, "host")) {
1924                         resolve_order = talloc_strdup(ctx, "ads");
1925 
1926                         /* DNS SRV lookups used by the ads resolver
1927                            are already sorted by priority and weight */
1928                         *ordered = true;
1929                 } else {
1930                         resolve_order = talloc_strdup(ctx, "NULL");
1931                 }
1932         } else if (lookup_type == DC_KDC_ONLY) {
1933                 /* DNS SRV lookups used by the ads/kdc resolver
1934                    are already sorted by priority and weight */
1935                 *ordered = true;
1936                 resolve_order = talloc_strdup(ctx, "kdc");
1937         }
1938         if (!resolve_order) {
1939                 status = NT_STATUS_NO_MEMORY;
1940                 goto out;
1941         }
1942 
1943         /* fetch the server we have affinity for.  Add the
1944            'password server' list to a search for our domain controllers */
1945 
1946         saf_servername = saf_fetch( domain);
1947 
1948         if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
1949                 pserver = talloc_asprintf(NULL, "%s, %s",
1950                         saf_servername ? saf_servername : "",
1951                         lp_passwordserver());
1952         } else {
1953                 pserver = talloc_asprintf(NULL, "%s, *",
1954                         saf_servername ? saf_servername : "");
1955         }
1956 
1957         SAFE_FREE(saf_servername);
1958         if (!pserver) {
1959                 status = NT_STATUS_NO_MEMORY;
1960                 goto out;
1961         }
1962 
1963         /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1964 
1965         if (!*pserver ) {
1966                 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1967                 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
1968                                              count, resolve_order);
1969                 goto out;
1970         }
1971 
1972         DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1973 
1974         /*
1975          * if '*' appears in the "password server" list then add
1976          * an auto lookup to the list of manually configured
1977          * DC's.  If any DC is listed by name, then the list should be
1978          * considered to be ordered
1979          */
1980 
1981         p = pserver;
1982         while (next_token_talloc(ctx, &p, &name, LIST_SEP)) {
1983                 if (!done_auto_lookup && strequal(name, "*")) {
1984                         status = internal_resolve_name(domain, 0x1C, sitename,
1985                                                        &auto_ip_list,
1986                                                        &auto_count,
1987                                                        resolve_order);
1988                         if (NT_STATUS_IS_OK(status)) {
1989                                 num_addresses += auto_count;
1990                         }
1991                         done_auto_lookup = true;
1992                         DEBUG(8,("Adding %d DC's from auto lookup\n",
1993                                                 auto_count));
1994                 } else  {
1995                         num_addresses++;
1996                 }
1997         }
1998 
1999         /* if we have no addresses and haven't done the auto lookup, then
2000            just return the list of DC's.  Or maybe we just failed. */
2001 
2002         if ((num_addresses == 0)) {
2003                 if (done_auto_lookup) {
2004                         DEBUG(4,("get_dc_list: no servers found\n"));
2005                         status = NT_STATUS_NO_LOGON_SERVERS;
2006                         goto out;
2007                 }
2008                 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
2009                                              count, resolve_order);
2010                 goto out;
2011         }
2012 
2013         if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
2014                                         num_addresses)) == NULL) {
2015                 DEBUG(3,("get_dc_list: malloc fail !\n"));
2016                 status = NT_STATUS_NO_MEMORY;
2017                 goto out;
2018         }
2019 
2020         p = pserver;
2021         local_count = 0;
2022 
2023         /* fill in the return list now with real IP's */
2024 
2025         while ((local_count<num_addresses) &&
2026                         next_token_talloc(ctx, &p, &name, LIST_SEP)) {
2027                 struct sockaddr_storage name_ss;
2028 
2029                 /* copy any addersses from the auto lookup */
2030 
2031                 if (strequal(name, "*")) {
2032                         for (j=0; j<auto_count; j++) {
2033                                 char addr[INET6_ADDRSTRLEN];
2034                                 print_sockaddr(addr,
2035                                                 sizeof(addr),
2036                                                 &auto_ip_list[j].ss);
2037                                 /* Check for and don't copy any
2038                                  * known bad DC IP's. */
2039                                 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
2040                                                 domain,
2041                                                 addr))) {
2042                                         DEBUG(5,("get_dc_list: "
2043                                                 "negative entry %s removed "
2044                                                 "from DC list\n",
2045                                                 addr));
2046                                         continue;
2047                                 }
2048                                 return_iplist[local_count].ss =
2049                                         auto_ip_list[j].ss;
2050                                 return_iplist[local_count].port =
2051                                         auto_ip_list[j].port;
2052                                 local_count++;
2053                         }
2054                         continue;
2055                 }
2056 
2057                 /* added support for address:port syntax for ads
2058                  * (not that I think anyone will ever run the LDAP
2059                  * server in an AD domain on something other than
2060                  * port 389 */
2061 
2062                 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
2063                 if ((port_str=strchr(name, ':')) != NULL) {
2064                         *port_str = '\0';
2065                         port_str++;
2066                         port = atoi(port_str);
2067                 }
2068 
2069                 /* explicit lookup; resolve_name() will
2070                  * handle names & IP addresses */
2071                 if (resolve_name( name, &name_ss, 0x20 )) {
2072                         char addr[INET6_ADDRSTRLEN];
2073                         print_sockaddr(addr,
2074                                         sizeof(addr),
2075                                         &name_ss);
2076 
2077                         /* Check for and don't copy any known bad DC IP's. */
2078                         if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
2079                                                         addr)) ) {
2080                                 DEBUG(5,("get_dc_list: negative entry %s "
2081                                         "removed from DC list\n",
2082                                         name ));
2083                                 continue;
2084                         }
2085 
2086                         return_iplist[local_count].ss = name_ss;
2087                         return_iplist[local_count].port = port;
2088                         local_count++;
2089                         *ordered = true;
2090                 }
2091         }
2092 
2093         /* need to remove duplicates in the list if we have any
2094            explicit password servers */
2095 
2096         if (local_count) {
2097                 local_count = remove_duplicate_addrs2(return_iplist,
2098                                 local_count );
2099         }
2100 
2101         if ( DEBUGLEVEL >= 4 ) {
2102                 DEBUG(4,("get_dc_list: returning %d ip addresses "
2103                                 "in an %sordered list\n",
2104                                 local_count,
2105                                 *ordered ? "":"un"));
2106                 DEBUG(4,("get_dc_list: "));
2107                 for ( i=0; i<local_count; i++ ) {
2108                         char addr[INET6_ADDRSTRLEN];
2109                         print_sockaddr(addr,
2110                                         sizeof(addr),
2111                                         &return_iplist[i].ss);
2112                         DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
2113                 }
2114                 DEBUGADD(4,("\n"));
2115         }
2116 
2117         *ip_list = return_iplist;
2118         *count = local_count;
2119 
2120         status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
2121 
2122   out:
2123 
2124         if (!NT_STATUS_IS_OK(status)) {
2125                 SAFE_FREE(return_iplist);
2126                 *ip_list = NULL;
2127                 *count = 0;
2128         }
2129 
2130         SAFE_FREE(auto_ip_list);
2131         TALLOC_FREE(ctx);
2132         return status;
2133 }
2134 
2135 /*********************************************************************
2136  Small wrapper function to get the DC list and sort it if neccessary.
2137 *********************************************************************/
2138 
2139 NTSTATUS get_sorted_dc_list( const char *domain,
     /* [<][>][^][v][top][bottom][index][help] */
2140                         const char *sitename,
2141                         struct ip_service **ip_list,
2142                         int *count,
2143                         bool ads_only )
2144 {
2145         bool ordered = false;
2146         NTSTATUS status;
2147         enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
2148 
2149         *ip_list = NULL;
2150         *count = 0;
2151 
2152         DEBUG(8,("get_sorted_dc_list: attempting lookup "
2153                 "for name %s (sitename %s) using [%s]\n",
2154                 domain,
2155                 sitename ? sitename : "NULL",
2156                 (ads_only ? "ads" : lp_name_resolve_order())));
2157 
2158         if (ads_only) {
2159                 lookup_type = DC_ADS_ONLY;
2160         }
2161 
2162         status = get_dc_list(domain, sitename, ip_list,
2163                         count, lookup_type, &ordered);
2164         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
2165             && sitename) {
2166                 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
2167                          " in site %s, fallback to all servers\n",
2168                          domain, sitename));
2169                 status = get_dc_list(domain, NULL, ip_list,
2170                                      count, lookup_type, &ordered);
2171         }
2172 
2173         if (!NT_STATUS_IS_OK(status)) {
2174                 SAFE_FREE(*ip_list);
2175                 *count = 0;
2176                 return status;
2177         }
2178 
2179         /* only sort if we don't already have an ordered list */
2180         if (!ordered) {
2181                 sort_service_list(*ip_list, *count);
2182         }
2183 
2184         return NT_STATUS_OK;
2185 }
2186 
2187 /*********************************************************************
2188  Get the KDC list - re-use all the logic in get_dc_list.
2189 *********************************************************************/
2190 
2191 NTSTATUS get_kdc_list( const char *realm,
     /* [<][>][^][v][top][bottom][index][help] */
2192                         const char *sitename,
2193                         struct ip_service **ip_list,
2194                         int *count)
2195 {
2196         bool ordered;
2197         NTSTATUS status;
2198 
2199         *count = 0;
2200         *ip_list = NULL;
2201 
2202         status = get_dc_list(realm, sitename, ip_list,
2203                         count, DC_KDC_ONLY, &ordered);
2204 
2205         if (!NT_STATUS_IS_OK(status)) {
2206                 SAFE_FREE(*ip_list);
2207                 *count = 0;
2208                 return status;
2209         }
2210 
2211         /* only sort if we don't already have an ordered list */
2212         if ( !ordered ) {
2213                 sort_service_list(*ip_list, *count);
2214         }
2215 
2216         return NT_STATUS_OK;
2217 }

/* [<][>][^][v][top][bottom][index][help] */