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