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