RIP BOOL. Convert BOOL -> bool. I found a few interesting
[ira/wip.git] / source3 / libsmb / namequery.c
1 /* 
2    Unix SMB/CIFS implementation.
3    name query routines
4    Copyright (C) Andrew Tridgell 1994-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.   
18 */
19
20 #include "includes.h"
21
22 /* nmbd.c sets this to True. */
23 bool global_in_nmbd = False;
24
25 /****************************
26  * SERVER AFFINITY ROUTINES *
27  ****************************/
28  
29  /* Server affinity is the concept of preferring the last domain 
30     controller with whom you had a successful conversation */
31  
32 /****************************************************************************
33 ****************************************************************************/
34 #define SAFKEY_FMT      "SAF/DOMAIN/%s"
35 #define SAF_TTL         900
36
37 static char *saf_key(const char *domain)
38 {
39         char *keystr;
40         
41         asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) );
42
43         return keystr;
44 }
45
46 /****************************************************************************
47 ****************************************************************************/
48
49 bool saf_store( const char *domain, const char *servername )
50 {
51         char *key;
52         time_t expire;
53         bool ret = False;
54         
55         if ( !domain || !servername ) {
56                 DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n"));
57                 return False;
58         }
59
60         if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
61                 DEBUG(0,("saf_store: refusing to store 0 length domain or servername!\n"));
62                 return False;
63         }
64         
65         if ( !gencache_init() ) 
66                 return False;
67         
68         key = saf_key( domain );
69         expire = time( NULL ) + SAF_TTL;
70         
71         
72         DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
73                 domain, servername, (unsigned int)expire ));
74                 
75         ret = gencache_set( key, servername, expire );
76         
77         SAFE_FREE( key );
78         
79         return ret;
80 }
81
82 bool saf_delete( const char *domain )
83 {
84         char *key;
85         bool ret = False;
86         
87         if ( !domain ) {
88                 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));             
89                 return False;
90         }
91         
92         if ( !gencache_init() ) 
93                 return False;
94         
95         key = saf_key(domain);
96         ret = gencache_del(key);
97         
98         if (ret) {
99                 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));             
100         }
101
102         SAFE_FREE( key );
103
104         return ret;
105 }
106
107 /****************************************************************************
108 ****************************************************************************/
109
110 char *saf_fetch( const char *domain )
111 {
112         char *server = NULL;
113         time_t timeout;
114         bool ret = False;
115         char *key = NULL;
116
117         if ( !domain || strlen(domain) == 0) {
118                 DEBUG(2,("saf_fetch: Empty domain name!\n"));
119                 return NULL;
120         }
121         
122         if ( !gencache_init() ) 
123                 return False;
124         
125         key = saf_key( domain );
126         
127         ret = gencache_get( key, &server, &timeout );
128         
129         SAFE_FREE( key );
130         
131         if ( !ret ) {
132                 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n", domain ));
133         } else {
134                 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n", 
135                         server, domain ));
136         }
137                 
138         return server;
139 }
140
141 /****************************************************************************
142  Generate a random trn_id.
143 ****************************************************************************/
144
145 static int generate_trn_id(void)
146 {
147         uint16 id;
148
149         generate_random_buffer((uint8 *)&id, sizeof(id));
150
151         return id % (unsigned)0x7FFF;
152 }
153
154 /****************************************************************************
155  Parse a node status response into an array of structures.
156 ****************************************************************************/
157
158 static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct node_status_extra *extra)
159 {
160         NODE_STATUS_STRUCT *ret;
161         int i;
162
163         *num_names = CVAL(p,0);
164
165         if (*num_names == 0)
166                 return NULL;
167
168         ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);
169         if (!ret)
170                 return NULL;
171
172         p++;
173         for (i=0;i< *num_names;i++) {
174                 StrnCpy(ret[i].name,p,15);
175                 trim_char(ret[i].name,'\0',' ');
176                 ret[i].type = CVAL(p,15);
177                 ret[i].flags = p[16];
178                 p += 18;
179                 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, 
180                            ret[i].type, ret[i].flags));
181         }
182         /*
183          * Also, pick up the MAC address ...
184          */
185         if (extra) {
186                 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
187         }
188         return ret;
189 }
190
191
192 /****************************************************************************
193  Do a NBT node status query on an open socket and return an array of
194  structures holding the returned names or NULL if the query failed.
195 **************************************************************************/
196
197 NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
198                                       struct in_addr to_ip, int *num_names,
199                                       struct node_status_extra *extra)
200 {
201         bool found=False;
202         int retries = 2;
203         int retry_time = 2000;
204         struct timeval tval;
205         struct packet_struct p;
206         struct packet_struct *p2;
207         struct nmb_packet *nmb = &p.packet.nmb;
208         NODE_STATUS_STRUCT *ret;
209
210         ZERO_STRUCT(p);
211
212         nmb->header.name_trn_id = generate_trn_id();
213         nmb->header.opcode = 0;
214         nmb->header.response = False;
215         nmb->header.nm_flags.bcast = False;
216         nmb->header.nm_flags.recursion_available = False;
217         nmb->header.nm_flags.recursion_desired = False;
218         nmb->header.nm_flags.trunc = False;
219         nmb->header.nm_flags.authoritative = False;
220         nmb->header.rcode = 0;
221         nmb->header.qdcount = 1;
222         nmb->header.ancount = 0;
223         nmb->header.nscount = 0;
224         nmb->header.arcount = 0;
225         nmb->question.question_name = *name;
226         nmb->question.question_type = 0x21;
227         nmb->question.question_class = 0x1;
228
229         p.ip = to_ip;
230         p.port = NMB_PORT;
231         p.fd = fd;
232         p.timestamp = time(NULL);
233         p.packet_type = NMB_PACKET;
234         
235         GetTimeOfDay(&tval);
236   
237         if (!send_packet(&p)) 
238                 return NULL;
239
240         retries--;
241
242         while (1) {
243                 struct timeval tval2;
244                 GetTimeOfDay(&tval2);
245                 if (TvalDiff(&tval,&tval2) > retry_time) {
246                         if (!retries)
247                                 break;
248                         if (!found && !send_packet(&p))
249                                 return NULL;
250                         GetTimeOfDay(&tval);
251                         retries--;
252                 }
253
254                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
255                         struct nmb_packet *nmb2 = &p2->packet.nmb;
256                         debug_nmb_packet(p2);
257                         
258                         if (nmb2->header.opcode != 0 ||
259                             nmb2->header.nm_flags.bcast ||
260                             nmb2->header.rcode ||
261                             !nmb2->header.ancount ||
262                             nmb2->answers->rr_type != 0x21) {
263                                 /* XXXX what do we do with this? could be a
264                                    redirect, but we'll discard it for the
265                                    moment */
266                                 free_packet(p2);
267                                 continue;
268                         }
269
270                         ret = parse_node_status(&nmb2->answers->rdata[0], num_names, extra);
271                         free_packet(p2);
272                         return ret;
273                 }
274         }
275         
276         return NULL;
277 }
278
279 /****************************************************************************
280  Find the first type XX name in a node status reply - used for finding
281  a servers name given its IP. Return the matched name in *name.
282 **************************************************************************/
283
284 bool name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name)
285 {
286         NODE_STATUS_STRUCT *status = NULL;
287         struct nmb_name nname;
288         int count, i;
289         int sock;
290         bool result = False;
291
292         if (lp_disable_netbios()) {
293                 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
294                 return False;
295         }
296
297         DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, 
298                    q_type, inet_ntoa(to_ip)));
299
300         /* Check the cache first. */
301
302         if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
303                 return True;
304
305         sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
306         if (sock == -1)
307                 goto done;
308
309         /* W2K PDC's seem not to respond to '*'#0. JRA */
310         make_nmb_name(&nname, q_name, q_type);
311         status = node_status_query(sock, &nname, to_ip, &count, NULL);
312         close(sock);
313         if (!status)
314                 goto done;
315
316         for (i=0;i<count;i++) {
317                 if (status[i].type == type)
318                         break;
319         }
320         if (i == count)
321                 goto done;
322
323         pull_ascii_nstring(name, sizeof(fstring), status[i].name);
324
325         /* Store the result in the cache. */
326         /* but don't store an entry for 0x1c names here.  Here we have 
327            a single host and DOMAIN<0x1c> names should be a list of hosts */
328            
329         if ( q_type != 0x1c )
330                 namecache_status_store(q_name, q_type, type, to_ip, name);
331
332         result = True;
333
334  done:
335         SAFE_FREE(status);
336
337         DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
338
339         if (result)
340                 DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
341
342         DEBUG(10, ("\n"));      
343
344         return result;
345 }
346
347 /*
348   comparison function used by sort_ip_list
349 */
350
351 static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
352 {
353         int max_bits1=0, max_bits2=0;
354         int num_interfaces = iface_count();
355         struct sockaddr_storage ss;
356         int i;
357
358         for (i=0;i<num_interfaces;i++) {
359                 const struct sockaddr_storage *pss = iface_n_bcast(i);
360                 struct in_addr ip;
361                 int bits1, bits2;
362
363                 if (pss->ss_family != AF_INET) {
364                         continue;
365                 }
366                 ip = ((const struct sockaddr_in *)pss)->sin_addr;
367                 bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
368                 bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
369                 max_bits1 = MAX(bits1, max_bits1);
370                 max_bits2 = MAX(bits2, max_bits2);
371         }       
372         
373         /* bias towards directly reachable IPs */
374         in_addr_to_sockaddr_storage(&ss, *ip1);
375         if (iface_local(&ss)) {
376                 max_bits1 += 32;
377         }
378         in_addr_to_sockaddr_storage(&ss, *ip1);
379         if (iface_local(&ss)) {
380                 max_bits2 += 32;
381         }
382
383         return max_bits2 - max_bits1;
384 }
385
386 /*******************************************************************
387  compare 2 ldap IPs by nearness to our interfaces - used in qsort
388 *******************************************************************/
389
390 int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
391 {
392         int result;
393         
394         if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
395                 return result;
396                 
397         if ( ip1->port > ip2->port )
398                 return 1;
399         
400         if ( ip1->port < ip2->port )
401                 return -1;
402                 
403         return 0;
404 }
405
406 /*
407   sort an IP list so that names that are close to one of our interfaces 
408   are at the top. This prevents the problem where a WINS server returns an IP that
409   is not reachable from our subnet as the first match
410 */
411
412 static void sort_ip_list(struct in_addr *iplist, int count)
413 {
414         if (count <= 1) {
415                 return;
416         }
417
418         qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);    
419 }
420
421 static void sort_ip_list2(struct ip_service *iplist, int count)
422 {
423         if (count <= 1) {
424                 return;
425         }
426
427         qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare); 
428 }
429
430 /**********************************************************************
431  Remove any duplicate address/port pairs in the list 
432  *********************************************************************/
433
434 static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
435 {
436         int i, j;
437         
438         DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
439         
440         /* one loop to remove duplicates */
441         for ( i=0; i<count; i++ ) {
442                 if ( is_zero_ip_v4(iplist[i].ip) )
443                         continue;
444                                         
445                 for ( j=i+1; j<count; j++ ) {
446                         if ( ip_service_equal(iplist[i], iplist[j]) )
447                                 zero_ip_v4(&iplist[j].ip);
448                 }
449         }
450                         
451         /* one loop to clean up any holes we left */
452         /* first ip should never be a zero_ip() */
453         for (i = 0; i<count; ) {
454                 if ( is_zero_ip_v4(iplist[i].ip) ) {
455                         if (i != count-1 )
456                                 memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
457                         count--;
458                         continue;
459                 }
460                 i++;
461         }
462
463         return count;
464 }
465
466 /****************************************************************************
467  Do a netbios name query to find someones IP.
468  Returns an array of IP addresses or NULL if none.
469  *count will be set to the number of addresses returned.
470  *timed_out is set if we failed by timing out
471 ****************************************************************************/
472
473 struct in_addr *name_query(int fd,const char *name,int name_type, 
474                            bool bcast,bool recurse,
475                            struct in_addr to_ip, int *count, int *flags,
476                            bool *timed_out)
477 {
478         bool found=False;
479         int i, retries = 3;
480         int retry_time = bcast?250:2000;
481         struct timeval tval;
482         struct packet_struct p;
483         struct packet_struct *p2;
484         struct nmb_packet *nmb = &p.packet.nmb;
485         struct in_addr *ip_list = NULL;
486
487         if (lp_disable_netbios()) {
488                 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
489                 return NULL;
490         }
491
492         if (timed_out) {
493                 *timed_out = False;
494         }
495         
496         memset((char *)&p,'\0',sizeof(p));
497         (*count) = 0;
498         (*flags) = 0;
499         
500         nmb->header.name_trn_id = generate_trn_id();
501         nmb->header.opcode = 0;
502         nmb->header.response = False;
503         nmb->header.nm_flags.bcast = bcast;
504         nmb->header.nm_flags.recursion_available = False;
505         nmb->header.nm_flags.recursion_desired = recurse;
506         nmb->header.nm_flags.trunc = False;
507         nmb->header.nm_flags.authoritative = False;
508         nmb->header.rcode = 0;
509         nmb->header.qdcount = 1;
510         nmb->header.ancount = 0;
511         nmb->header.nscount = 0;
512         nmb->header.arcount = 0;
513         
514         make_nmb_name(&nmb->question.question_name,name,name_type);
515         
516         nmb->question.question_type = 0x20;
517         nmb->question.question_class = 0x1;
518         
519         p.ip = to_ip;
520         p.port = NMB_PORT;
521         p.fd = fd;
522         p.timestamp = time(NULL);
523         p.packet_type = NMB_PACKET;
524         
525         GetTimeOfDay(&tval);
526         
527         if (!send_packet(&p)) 
528                 return NULL;
529         
530         retries--;
531         
532         while (1) {
533                 struct timeval tval2;
534                 
535                 GetTimeOfDay(&tval2);
536                 if (TvalDiff(&tval,&tval2) > retry_time) {
537                         if (!retries)
538                                 break;
539                         if (!found && !send_packet(&p))
540                                 return NULL;
541                         GetTimeOfDay(&tval);
542                         retries--;
543                 }
544                 
545                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
546                         struct nmb_packet *nmb2 = &p2->packet.nmb;
547                         debug_nmb_packet(p2);
548                         
549                         /* If we get a Negative Name Query Response from a WINS
550                          * server, we should report it and give up.
551                          */
552                         if( 0 == nmb2->header.opcode            /* A query response   */
553                             && !(bcast)                 /* from a WINS server */
554                             && nmb2->header.rcode               /* Error returned     */
555                                 ) {
556                                 
557                                 if( DEBUGLVL( 3 ) ) {
558                                         /* Only executed if DEBUGLEVEL >= 3 */
559                                         dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
560                                         switch( nmb2->header.rcode ) {
561                                         case 0x01:
562                                                 dbgtext( "Request was invalidly formatted.\n" );
563                                                 break;
564                                         case 0x02:
565                                                 dbgtext( "Problem with NBNS, cannot process name.\n");
566                                                 break;
567                                         case 0x03:
568                                                 dbgtext( "The name requested does not exist.\n" );
569                                                 break;
570                                         case 0x04:
571                                                 dbgtext( "Unsupported request error.\n" );
572                                                 break;
573                                         case 0x05:
574                                                 dbgtext( "Query refused error.\n" );
575                                                 break;
576                                         default:
577                                                 dbgtext( "Unrecognized error code.\n" );
578                                                 break;
579                                         }
580                                 }
581                                 free_packet(p2);
582                                 return( NULL );
583                         }
584                         
585                         if (nmb2->header.opcode != 0 ||
586                             nmb2->header.nm_flags.bcast ||
587                             nmb2->header.rcode ||
588                             !nmb2->header.ancount) {
589                                 /* 
590                                  * XXXX what do we do with this? Could be a
591                                  * redirect, but we'll discard it for the
592                                  * moment.
593                                  */
594                                 free_packet(p2);
595                                 continue;
596                         }
597                         
598                         ip_list = SMB_REALLOC_ARRAY( ip_list, struct in_addr,
599                                                 (*count) + nmb2->answers->rdlength/6 );
600                         
601                         if (!ip_list) {
602                                 DEBUG(0,("name_query: Realloc failed.\n"));
603                                 free_packet(p2);
604                                 return( NULL );
605                         }
606                         
607                         DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
608                         for (i=0;i<nmb2->answers->rdlength/6;i++) {
609                                 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
610                                 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
611                                 (*count)++;
612                         }
613                         DEBUGADD(2,(")\n"));
614                         
615                         found=True;
616                         retries=0;
617                         /* We add the flags back ... */
618                         if (nmb2->header.response)
619                                 (*flags) |= NM_FLAGS_RS;
620                         if (nmb2->header.nm_flags.authoritative)
621                                 (*flags) |= NM_FLAGS_AA;
622                         if (nmb2->header.nm_flags.trunc)
623                                 (*flags) |= NM_FLAGS_TC;
624                         if (nmb2->header.nm_flags.recursion_desired)
625                                 (*flags) |= NM_FLAGS_RD;
626                         if (nmb2->header.nm_flags.recursion_available)
627                                 (*flags) |= NM_FLAGS_RA;
628                         if (nmb2->header.nm_flags.bcast)
629                                 (*flags) |= NM_FLAGS_B;
630                         free_packet(p2);
631                         /*
632                          * If we're doing a unicast lookup we only
633                          * expect one reply. Don't wait the full 2
634                          * seconds if we got one. JRA.
635                          */
636                         if(!bcast && found)
637                                 break;
638                 }
639         }
640
641         /* only set timed_out if we didn't fund what we where looking for*/
642         
643         if ( !found && timed_out ) {
644                 *timed_out = True;
645         }
646
647         /* sort the ip list so we choose close servers first if possible */
648         sort_ip_list(ip_list, *count);
649
650         return ip_list;
651 }
652
653 /********************************************************
654  Start parsing the lmhosts file.
655 *********************************************************/
656
657 XFILE *startlmhosts(const char *fname)
658 {
659         XFILE *fp = x_fopen(fname,O_RDONLY, 0);
660         if (!fp) {
661                 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
662                          fname, strerror(errno)));
663                 return NULL;
664         }
665         return fp;
666 }
667
668 /********************************************************
669  Parse the next line in the lmhosts file.
670 *********************************************************/
671
672 bool getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
673 {
674         pstring line;
675
676         while(!x_feof(fp) && !x_ferror(fp)) {
677                 pstring ip,flags,extra;
678                 const char *ptr;
679                 char *ptr1;
680                 int count = 0;
681
682                 *name_type = -1;
683
684                 if (!fgets_slash(line,sizeof(pstring),fp)) {
685                         continue;
686                 }
687
688                 if (*line == '#') {
689                         continue;
690                 }
691
692                 pstrcpy(ip,"");
693                 pstrcpy(name,"");
694                 pstrcpy(flags,"");
695
696                 ptr = line;
697
698                 if (next_token(&ptr,ip   ,NULL,sizeof(ip)))
699                         ++count;
700                 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
701                         ++count;
702                 if (next_token(&ptr,flags,NULL, sizeof(flags)))
703                         ++count;
704                 if (next_token(&ptr,extra,NULL, sizeof(extra)))
705                         ++count;
706
707                 if (count <= 0)
708                         continue;
709
710                 if (count > 0 && count < 2) {
711                         DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
712                         continue;
713                 }
714
715                 if (count >= 4) {
716                         DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
717                         continue;
718                 }
719
720                 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
721
722                 if (strchr_m(flags,'G') || strchr_m(flags,'S')) {
723                         DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
724                         continue;
725                 }
726
727                 *ipaddr = *interpret_addr2(ip);
728
729                 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
730                         then only add that name type. */
731                 if((ptr1 = strchr_m(name, '#')) != NULL) {
732                         char *endptr;
733                         ptr1++;
734
735                         *name_type = (int)strtol(ptr1, &endptr, 16);
736                         if(!*ptr1 || (endptr == ptr1)) {
737                                 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
738                                 continue;
739                         }
740
741                         *(--ptr1) = '\0'; /* Truncate at the '#' */
742                 }
743
744                 return True;
745         }
746
747         return False;
748 }
749
750 /********************************************************
751  Finish parsing the lmhosts file.
752 *********************************************************/
753
754 void endlmhosts(XFILE *fp)
755 {
756         x_fclose(fp);
757 }
758
759 /********************************************************
760  convert an array if struct in_addrs to struct ip_service
761  return False on failure.  Port is set to PORT_NONE;
762 *********************************************************/
763
764 static bool convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
765 {
766         int i;
767
768         if ( count==0 || !ip_list )
769                 return False;
770                 
771         /* copy the ip address; port will be PORT_NONE */
772         if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
773                 DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count ));
774                 return False;
775         }
776         
777         for ( i=0; i<count; i++ ) {
778                 (*return_iplist)[i].ip   = ip_list[i];
779                 (*return_iplist)[i].port = PORT_NONE;
780         }
781
782         return True;
783 }       
784 /********************************************************
785  Resolve via "bcast" method.
786 *********************************************************/
787
788 NTSTATUS name_resolve_bcast(const char *name, int name_type,
789                             struct ip_service **return_iplist,
790                             int *return_count)
791 {
792         int sock, i;
793         int num_interfaces = iface_count();
794         struct in_addr *ip_list;
795         NTSTATUS status;
796
797         if (lp_disable_netbios()) {
798                 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
799                 return NT_STATUS_INVALID_PARAMETER;
800         }
801
802         *return_iplist = NULL;
803         *return_count = 0;
804         
805         /*
806          * "bcast" means do a broadcast lookup on all the local interfaces.
807          */
808
809         DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
810
811         sock = open_socket_in( SOCK_DGRAM, 0, 3,
812                                interpret_addr(lp_socket_address()), True );
813
814         if (sock == -1) return NT_STATUS_UNSUCCESSFUL;
815
816         set_socket_options(sock,"SO_BROADCAST");
817         /*
818          * Lookup the name on all the interfaces, return on
819          * the first successful match.
820          */
821         for( i = num_interfaces-1; i >= 0; i--) {
822                 struct in_addr sendto_ip;
823                 const struct sockaddr_storage *ss = iface_n_bcast(i);
824                 int flags;
825
826                 /* Done this way to fix compiler error on IRIX 5.x */
827                 if (!ss || ss->ss_family != AF_INET) {
828                         continue;
829                 }
830                 sendto_ip = ((const struct sockaddr_in *)ss)->sin_addr;
831                 ip_list = name_query(sock, name, name_type, True, 
832                                     True, sendto_ip, return_count, &flags, NULL);
833                 if( ip_list ) 
834                         goto success;
835         }
836         
837         /* failed - no response */
838         
839         close(sock);
840         return NT_STATUS_UNSUCCESSFUL;
841         
842 success:
843         status = NT_STATUS_OK;
844         if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
845                 status = NT_STATUS_INVALID_PARAMETER;
846         
847         SAFE_FREE( ip_list );
848         close(sock);
849         return status;
850 }
851
852 /********************************************************
853  Resolve via "wins" method.
854 *********************************************************/
855
856 NTSTATUS resolve_wins(const char *name, int name_type,
857                       struct ip_service **return_iplist,
858                       int *return_count)
859 {
860         int sock, t, i;
861         char **wins_tags;
862         struct in_addr src_ip, *ip_list = NULL;
863         NTSTATUS status;
864
865         if (lp_disable_netbios()) {
866                 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
867                 return NT_STATUS_INVALID_PARAMETER;
868         }
869
870         *return_iplist = NULL;
871         *return_count = 0;
872         
873         DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
874
875         if (wins_srv_count() < 1) {
876                 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
877                 return NT_STATUS_INVALID_PARAMETER;
878         }
879
880         /* we try a lookup on each of the WINS tags in turn */
881         wins_tags = wins_srv_tags();
882
883         if (!wins_tags) {
884                 /* huh? no tags?? give up in disgust */
885                 return NT_STATUS_INVALID_PARAMETER;
886         }
887
888         /* the address we will be sending from */
889         src_ip = *interpret_addr2(lp_socket_address());
890
891         /* in the worst case we will try every wins server with every
892            tag! */
893         for (t=0; wins_tags && wins_tags[t]; t++) {
894                 int srv_count = wins_srv_count_tag(wins_tags[t]);
895                 for (i=0; i<srv_count; i++) {
896                         struct in_addr wins_ip;
897                         int flags;
898                         bool timed_out;
899
900                         wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
901
902                         if (global_in_nmbd && ismyip_v4(wins_ip)) {
903                                 /* yikes! we'll loop forever */
904                                 continue;
905                         }
906
907                         /* skip any that have been unresponsive lately */
908                         if (wins_srv_is_dead(wins_ip, src_ip)) {
909                                 continue;
910                         }
911
912                         DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
913
914                         sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
915                         if (sock == -1) {
916                                 continue;
917                         }
918
919                         ip_list = name_query(sock,name,name_type, False, 
920                                                     True, wins_ip, return_count, &flags, 
921                                                     &timed_out);
922                                                     
923                         /* exit loop if we got a list of addresses */
924                         
925                         if ( ip_list ) 
926                                 goto success;
927                                 
928                         close(sock);
929
930                         if (timed_out) {
931                                 /* Timed out wating for WINS server to respond.  Mark it dead. */
932                                 wins_srv_died(wins_ip, src_ip);
933                         } else {
934                                 /* The name definately isn't in this
935                                    group of WINS servers. goto the next group  */
936                                 break;
937                         }
938                 }
939         }
940
941         wins_srv_tags_free(wins_tags);
942         return NT_STATUS_NO_LOGON_SERVERS;
943
944 success:
945         status = NT_STATUS_OK;
946         if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
947                 status = NT_STATUS_INVALID_PARAMETER;
948         
949         SAFE_FREE( ip_list );
950         wins_srv_tags_free(wins_tags);
951         close(sock);
952         
953         return status;
954 }
955
956 /********************************************************
957  Resolve via "lmhosts" method.
958 *********************************************************/
959
960 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
961                                 struct ip_service **return_iplist,
962                                 int *return_count)
963 {
964         /*
965          * "lmhosts" means parse the local lmhosts file.
966          */
967         
968         XFILE *fp;
969         pstring lmhost_name;
970         int name_type2;
971         struct in_addr return_ip;
972         NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
973
974         *return_iplist = NULL;
975         *return_count = 0;
976
977         DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
978
979         fp = startlmhosts(dyn_LMHOSTSFILE);
980
981         if ( fp == NULL )
982                 return NT_STATUS_NO_SUCH_FILE;
983
984         while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) 
985         {
986
987                 if (!strequal(name, lmhost_name))
988                         continue;
989
990                 if ((name_type2 != -1) && (name_type != name_type2))
991                         continue;
992
993                 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), struct ip_service,
994                                         (*return_count)+1);
995
996                 if ((*return_iplist) == NULL) {
997                         endlmhosts(fp);
998                         DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
999                         return NT_STATUS_NO_MEMORY;
1000                 }
1001
1002                 (*return_iplist)[*return_count].ip   = return_ip;
1003                 (*return_iplist)[*return_count].port = PORT_NONE;
1004                 *return_count += 1;
1005
1006                 /* we found something */
1007                 status = NT_STATUS_OK;
1008
1009                 /* Multiple names only for DC lookup */
1010                 if (name_type != 0x1c)
1011                         break;
1012         }
1013
1014         endlmhosts(fp);
1015
1016         return status;
1017 }
1018
1019
1020 /********************************************************
1021  Resolve via "hosts" method.
1022 *********************************************************/
1023
1024 static NTSTATUS resolve_hosts(const char *name, int name_type,
1025                               struct ip_service **return_iplist,
1026                               int *return_count)
1027 {
1028         /*
1029          * "host" means do a localhost, or dns lookup.
1030          */
1031         struct addrinfo hints;
1032         struct addrinfo *ailist = NULL;
1033         struct addrinfo *res = NULL;
1034         int ret = -1;
1035         int i = 0;
1036
1037         if ( name_type != 0x20 && name_type != 0x0) {
1038                 DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type));
1039                 return NT_STATUS_INVALID_PARAMETER;
1040         }
1041
1042         *return_iplist = NULL;
1043         *return_count = 0;
1044
1045         DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type));
1046
1047         ZERO_STRUCT(hints);
1048         /* By default make sure it supports TCP. */
1049         hints.ai_socktype = SOCK_STREAM;
1050         hints.ai_flags = AI_ADDRCONFIG;
1051
1052         ret = getaddrinfo(name,
1053                         NULL,
1054                         &hints,
1055                         &ailist);
1056         if (ret) {
1057                 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
1058                         name,
1059                         gai_strerror(ret) ));
1060         }
1061
1062         for (res = ailist; res; res = res->ai_next) {
1063                 struct in_addr return_ip;
1064
1065                 /* IPv4 only for now until I convert ip_service */
1066                 if (res->ai_family != AF_INET) {
1067                         continue;
1068                 }
1069                 if (!res->ai_addr) {
1070                         continue;
1071                 }
1072
1073                 putip((char *)&return_ip,
1074                         &((struct sockaddr_in *)res->ai_addr)->sin_addr);
1075
1076                 *return_count += 1;
1077                 i++;
1078
1079                 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
1080                                                 struct ip_service,
1081                                                 *return_count);
1082                 if (!*return_iplist) {
1083                         DEBUG(3,("resolve_hosts: malloc fail !\n"));
1084                         freeaddrinfo(ailist);
1085                         return NT_STATUS_NO_MEMORY;
1086                 }
1087                 (*return_iplist)[i].ip   = return_ip;
1088                 (*return_iplist)[i].port = PORT_NONE;
1089         }
1090         if (ailist) {
1091                 freeaddrinfo(ailist);
1092         }
1093         if (*return_count) {
1094                 return NT_STATUS_OK;
1095         }
1096         return NT_STATUS_UNSUCCESSFUL;
1097 }
1098
1099 /********************************************************
1100  Resolve via "ADS" method.
1101 *********************************************************/
1102
1103 NTSTATUS resolve_ads(const char *name, int name_type,
1104                      const char *sitename,
1105                      struct ip_service **return_iplist,
1106                      int *return_count)
1107 {
1108         int                     i, j;
1109         NTSTATUS                status;
1110         TALLOC_CTX              *ctx;
1111         struct dns_rr_srv       *dcs = NULL;
1112         int                     numdcs = 0;
1113         int                     numaddrs = 0;
1114
1115         if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
1116             (name_type != 0x1b)) {
1117                 return NT_STATUS_INVALID_PARAMETER;
1118         }
1119
1120         if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1121                 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1122                 return NT_STATUS_NO_MEMORY;
1123         }
1124
1125         switch (name_type) {
1126                 case 0x1b:
1127                         DEBUG(5,("resolve_ads: Attempting to resolve "
1128                                  "PDC for %s using DNS\n", name));
1129                         status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
1130                         break;
1131
1132                 case 0x1c:
1133                         DEBUG(5,("resolve_ads: Attempting to resolve "
1134                                  "DCs for %s using DNS\n", name));
1135                         status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
1136                                                    &numdcs);
1137                         break;
1138                 case KDC_NAME_TYPE:
1139                         DEBUG(5,("resolve_ads: Attempting to resolve "
1140                                  "KDCs for %s using DNS\n", name));
1141                         status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
1142                                                     &numdcs);
1143                         break;
1144                 default:
1145                         status = NT_STATUS_INVALID_PARAMETER;
1146                         break;
1147         }
1148
1149         if ( !NT_STATUS_IS_OK( status ) ) {
1150                 talloc_destroy(ctx);
1151                 return status;
1152         }
1153
1154         for (i=0;i<numdcs;i++) {
1155                 numaddrs += MAX(dcs[i].num_ips,1);
1156         }
1157                 
1158         if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
1159                 DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
1160                 talloc_destroy(ctx);
1161                 return NT_STATUS_NO_MEMORY;
1162         }
1163         
1164         /* now unroll the list of IP addresses */
1165
1166         *return_count = 0;
1167         i = 0;
1168         j = 0;
1169         while ( i < numdcs && (*return_count<numaddrs) ) {
1170                 struct ip_service *r = &(*return_iplist)[*return_count];
1171
1172                 r->port = dcs[i].port;
1173                 
1174                 /* If we don't have an IP list for a name, lookup it up */
1175                 
1176                 if ( !dcs[i].ips ) {
1177                         r->ip = *interpret_addr2(dcs[i].hostname);
1178                         i++;
1179                         j = 0;
1180                 } else {
1181                         /* use the IP addresses from the SRV sresponse */
1182                         
1183                         if ( j >= dcs[i].num_ips ) {
1184                                 i++;
1185                                 j = 0;
1186                                 continue;
1187                         }
1188                         
1189                         r->ip = dcs[i].ips[j];
1190                         j++;
1191                 }
1192                         
1193                 /* make sure it is a valid IP.  I considered checking the negative
1194                    connection cache, but this is the wrong place for it.  Maybe only
1195                    as a hac.  After think about it, if all of the IP addresses retuend
1196                    from DNS are dead, what hope does a netbios name lookup have?
1197                    The standard reason for falling back to netbios lookups is that 
1198                    our DNS server doesn't know anything about the DC's   -- jerry */    
1199                            
1200                 if ( ! is_zero_ip_v4(r->ip) )
1201                         (*return_count)++;
1202         }
1203                 
1204         talloc_destroy(ctx);
1205         return NT_STATUS_OK;
1206 }
1207
1208 /*******************************************************************
1209  Internal interface to resolve a name into an IP address.
1210  Use this function if the string is either an IP address, DNS
1211  or host name or NetBIOS name. This uses the name switch in the
1212  smb.conf to determine the order of name resolution.
1213  
1214  Added support for ip addr/port to support ADS ldap servers.
1215  the only place we currently care about the port is in the 
1216  resolve_hosts() when looking up DC's via SRV RR entries in DNS
1217 **********************************************************************/
1218
1219 NTSTATUS internal_resolve_name(const char *name, int name_type,
1220                                const char *sitename,
1221                                struct ip_service **return_iplist,
1222                                int *return_count, const char *resolve_order)
1223 {
1224         pstring name_resolve_list;
1225         fstring tok;
1226         const char *ptr;
1227         bool allones = (strcmp(name,"255.255.255.255") == 0);
1228         bool allzeros = (strcmp(name,"0.0.0.0") == 0);
1229         bool is_address = is_ipaddress_v4(name);
1230         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1231         int i;
1232
1233         *return_iplist = NULL;
1234         *return_count = 0;
1235
1236         DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1237                         name, name_type, sitename ? sitename : NULL));
1238
1239         if (allzeros || allones || is_address) {
1240   
1241                 if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) {
1242                         DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1243                         return NT_STATUS_NO_MEMORY;
1244                 }
1245         
1246                 if(is_address) { 
1247                         /* ignore the port here */
1248                         (*return_iplist)->port = PORT_NONE;
1249                 
1250                         /* if it's in the form of an IP address then get the lib to interpret it */
1251                         if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
1252                                 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
1253                                 SAFE_FREE(*return_iplist);
1254                                 return NT_STATUS_INVALID_PARAMETER;
1255                         }
1256                 } else {
1257                         (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
1258                 }
1259                 *return_count = 1;
1260                 return NT_STATUS_OK;
1261         }
1262   
1263         /* Check name cache */
1264
1265         if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1266                 /* This could be a negative response */
1267                 if (*return_count > 0) {
1268                         return NT_STATUS_OK;
1269                 } else {
1270                         return NT_STATUS_UNSUCCESSFUL;
1271                 }
1272         }
1273
1274         /* set the name resolution order */
1275
1276         if ( strcmp( resolve_order, "NULL") == 0 ) {
1277                 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1278                 return NT_STATUS_INVALID_PARAMETER;
1279         }
1280   
1281         if ( !resolve_order ) {
1282                 pstrcpy(name_resolve_list, lp_name_resolve_order());
1283         } else {
1284                 pstrcpy(name_resolve_list, resolve_order);
1285         }
1286
1287         if ( !name_resolve_list[0] ) {
1288                 ptr = "host";
1289         } else {
1290                 ptr = name_resolve_list;
1291         }
1292
1293         /* iterate through the name resolution backends */
1294   
1295         while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
1296                 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1297                         status = resolve_hosts(name, name_type, return_iplist,
1298                                                return_count);
1299                         if (NT_STATUS_IS_OK(status)) {
1300                                 goto done;
1301                         }
1302                 } else if(strequal( tok, "kdc")) {
1303                         /* deal with KDC_NAME_TYPE names here.  This will result in a
1304                                 SRV record lookup */
1305                         status = resolve_ads(name, KDC_NAME_TYPE, sitename,
1306                                              return_iplist, return_count);
1307                         if (NT_STATUS_IS_OK(status)) {
1308                                 /* Ensure we don't namecache this with the KDC port. */
1309                                 name_type = KDC_NAME_TYPE;
1310                                 goto done;
1311                         }
1312                 } else if(strequal( tok, "ads")) {
1313                         /* deal with 0x1c and 0x1b names here.  This will result in a
1314                                 SRV record lookup */
1315                         status = resolve_ads(name, name_type, sitename,
1316                                              return_iplist, return_count);
1317                         if (NT_STATUS_IS_OK(status)) {
1318                                 goto done;
1319                         }
1320                 } else if(strequal( tok, "lmhosts")) {
1321                         status = resolve_lmhosts(name, name_type,
1322                                                  return_iplist, return_count);
1323                         if (NT_STATUS_IS_OK(status)) {
1324                                 goto done;
1325                         }
1326                 } else if(strequal( tok, "wins")) {
1327                         /* don't resolve 1D via WINS */
1328                         if (name_type != 0x1D) {
1329                                 status = resolve_wins(name, name_type,
1330                                                       return_iplist,
1331                                                       return_count);
1332                                 if (NT_STATUS_IS_OK(status)) {
1333                                         goto done;
1334                                 }
1335                         }
1336                 } else if(strequal( tok, "bcast")) {
1337                         status = name_resolve_bcast(name, name_type,
1338                                                     return_iplist,
1339                                                     return_count);
1340                         if (NT_STATUS_IS_OK(status)) {
1341                                 goto done;
1342                         }
1343                 } else {
1344                         DEBUG(0,("resolve_name: unknown name switch type %s\n",
1345                                 tok));
1346                 }
1347         }
1348
1349         /* All of the resolve_* functions above have returned false. */
1350
1351         SAFE_FREE(*return_iplist);
1352         *return_count = 0;
1353
1354         return NT_STATUS_UNSUCCESSFUL;
1355
1356   done:
1357
1358         /* Remove duplicate entries.  Some queries, notably #1c (domain
1359         controllers) return the PDC in iplist[0] and then all domain
1360         controllers including the PDC in iplist[1..n].  Iterating over
1361         the iplist when the PDC is down will cause two sets of timeouts. */
1362
1363         if ( *return_count ) {
1364                 *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
1365         }
1366  
1367         /* Save in name cache */
1368         if ( DEBUGLEVEL >= 100 ) {
1369                 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
1370                         DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
1371                                 name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1372         }
1373    
1374         namecache_store(name, name_type, *return_count, *return_iplist);
1375
1376         /* Display some debugging info */
1377
1378         if ( DEBUGLEVEL >= 10 ) {
1379                 DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
1380
1381                 for (i = 0; i < *return_count; i++) {
1382                         DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1383                 }
1384                 DEBUG(10, ("\n"));
1385         }
1386   
1387         return status;
1388 }
1389
1390 /********************************************************
1391  Internal interface to resolve a name into one IP address.
1392  Use this function if the string is either an IP address, DNS
1393  or host name or NetBIOS name. This uses the name switch in the
1394  smb.conf to determine the order of name resolution.
1395 *********************************************************/
1396
1397 bool resolve_name(const char *name, struct in_addr *return_ip, int name_type)
1398 {
1399         struct ip_service *ip_list = NULL;
1400         char *sitename = sitename_fetch(lp_realm()); /* wild guess */
1401         int count = 0;
1402
1403         if (is_ipaddress_v4(name)) {
1404                 *return_ip = *interpret_addr2(name);
1405                 SAFE_FREE(sitename);
1406                 return True;
1407         }
1408
1409         if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
1410                                                   &ip_list, &count,
1411                                                   lp_name_resolve_order()))) {
1412                 int i;
1413                 
1414                 /* only return valid addresses for TCP connections */
1415                 for (i=0; i<count; i++) {
1416                         char *ip_str = inet_ntoa(ip_list[i].ip);
1417                         if (ip_str &&
1418                             strcmp(ip_str, "255.255.255.255") != 0 &&
1419                             strcmp(ip_str, "0.0.0.0") != 0) 
1420                         {
1421                                 *return_ip = ip_list[i].ip;
1422                                 SAFE_FREE(ip_list);
1423                                 SAFE_FREE(sitename);
1424                                 return True;
1425                         }
1426                 }
1427         }
1428         
1429         SAFE_FREE(ip_list);
1430         SAFE_FREE(sitename);
1431         return False;
1432 }
1433
1434 /********************************************************
1435  Find the IP address of the master browser or DMB for a workgroup.
1436 *********************************************************/
1437
1438 bool find_master_ip(const char *group, struct in_addr *master_ip)
1439 {
1440         struct ip_service *ip_list = NULL;
1441         int count = 0;
1442         NTSTATUS status;
1443
1444         if (lp_disable_netbios()) {
1445                 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1446                 return False;
1447         }
1448
1449         status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
1450                                        lp_name_resolve_order());
1451         if (NT_STATUS_IS_OK(status)) {
1452                 *master_ip = ip_list[0].ip;
1453                 SAFE_FREE(ip_list);
1454                 return True;
1455         }
1456
1457         status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
1458                                        lp_name_resolve_order());
1459         if (NT_STATUS_IS_OK(status)) {
1460                 *master_ip = ip_list[0].ip;
1461                 SAFE_FREE(ip_list);
1462                 return True;
1463         }
1464
1465         SAFE_FREE(ip_list);
1466         return False;
1467 }
1468
1469 /********************************************************
1470  Get the IP address list of the primary domain controller
1471  for a domain.
1472 *********************************************************/
1473
1474 bool get_pdc_ip(const char *domain, struct in_addr *ip)
1475 {
1476         struct ip_service *ip_list = NULL;
1477         int count = 0;
1478         NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1479
1480         /* Look up #1B name */
1481
1482         if (lp_security() == SEC_ADS) {
1483                 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1484                                                &count, "ads");
1485         }
1486
1487         if (!NT_STATUS_IS_OK(status) || count == 0) {
1488                 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1489                                                &count,
1490                                                lp_name_resolve_order());
1491                 if (!NT_STATUS_IS_OK(status)) {
1492                         return False;
1493                 }
1494         }
1495
1496         /* if we get more than 1 IP back we have to assume it is a
1497            multi-homed PDC and not a mess up */
1498
1499         if ( count > 1 ) {
1500                 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));             
1501                 sort_ip_list2( ip_list, count );
1502         }
1503
1504         *ip = ip_list[0].ip;
1505         
1506         SAFE_FREE(ip_list);
1507
1508         return True;
1509 }
1510
1511 /* Private enum type for lookups. */
1512
1513 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
1514
1515 /********************************************************
1516  Get the IP address list of the domain controllers for
1517  a domain.
1518 *********************************************************/
1519
1520 static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_service **ip_list, 
1521                             int *count, enum dc_lookup_type lookup_type, bool *ordered)
1522 {
1523         fstring resolve_order;
1524         char *saf_servername;
1525         pstring pserver;
1526         const char *p;
1527         char *port_str;
1528         int port;
1529         fstring name;
1530         int num_addresses = 0;
1531         int  local_count, i, j;
1532         struct ip_service *return_iplist = NULL;
1533         struct ip_service *auto_ip_list = NULL;
1534         bool done_auto_lookup = False;
1535         int auto_count = 0;
1536         NTSTATUS status;
1537
1538         *ordered = False;
1539
1540         /* if we are restricted to solely using DNS for looking
1541            up a domain controller, make sure that host lookups
1542            are enabled for the 'name resolve order'.  If host lookups
1543            are disabled and ads_only is True, then set the string to
1544            NULL. */
1545
1546         fstrcpy( resolve_order, lp_name_resolve_order() );
1547         strlower_m( resolve_order );
1548         if ( lookup_type == DC_ADS_ONLY)  {
1549                 if ( strstr( resolve_order, "host" ) ) {
1550                         fstrcpy( resolve_order, "ads" );
1551
1552                         /* DNS SRV lookups used by the ads resolver
1553                            are already sorted by priority and weight */
1554                         *ordered = True;
1555                 } else {
1556                         fstrcpy( resolve_order, "NULL" );
1557                 }
1558         } else if (lookup_type == DC_KDC_ONLY) {
1559                 /* DNS SRV lookups used by the ads/kdc resolver
1560                    are already sorted by priority and weight */
1561                 *ordered = True;
1562                 fstrcpy( resolve_order, "kdc" );
1563         }
1564
1565         /* fetch the server we have affinity for.  Add the 
1566            'password server' list to a search for our domain controllers */
1567         
1568         saf_servername = saf_fetch( domain);
1569         
1570         if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
1571                 pstr_sprintf( pserver, "%s, %s", 
1572                         saf_servername ? saf_servername : "",
1573                         lp_passwordserver() );
1574         } else {
1575                 pstr_sprintf( pserver, "%s, *", 
1576                         saf_servername ? saf_servername : "" );
1577         }
1578
1579         SAFE_FREE( saf_servername );
1580
1581         /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1582
1583         if ( !*pserver ) {
1584                 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1585                 return internal_resolve_name(domain, 0x1C, sitename, ip_list,
1586                                              count, resolve_order);
1587         }
1588
1589         DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1590         
1591         /*
1592          * if '*' appears in the "password server" list then add
1593          * an auto lookup to the list of manually configured
1594          * DC's.  If any DC is listed by name, then the list should be 
1595          * considered to be ordered 
1596          */
1597
1598         p = pserver;
1599         while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1600                 if (strequal(name, "*")) {
1601                         status = internal_resolve_name(domain, 0x1C, sitename,
1602                                                        &auto_ip_list,
1603                                                        &auto_count,
1604                                                        resolve_order);
1605                         if (NT_STATUS_IS_OK(status)) {
1606                                 num_addresses += auto_count;
1607                         }
1608                         done_auto_lookup = True;
1609                         DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1610                 } else  {
1611                         num_addresses++;
1612                 }
1613         }
1614
1615         /* if we have no addresses and haven't done the auto lookup, then
1616            just return the list of DC's.  Or maybe we just failed. */
1617                    
1618         if ( (num_addresses == 0) ) {
1619                 if ( done_auto_lookup ) {
1620                         DEBUG(4,("get_dc_list: no servers found\n")); 
1621                         SAFE_FREE(auto_ip_list);
1622                         return NT_STATUS_NO_LOGON_SERVERS;
1623                 }
1624                 return internal_resolve_name(domain, 0x1C, sitename, ip_list,
1625                                              count, resolve_order);
1626         }
1627
1628         if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
1629                 DEBUG(3,("get_dc_list: malloc fail !\n"));
1630                 SAFE_FREE(auto_ip_list);
1631                 return NT_STATUS_NO_MEMORY;
1632         }
1633
1634         p = pserver;
1635         local_count = 0;
1636
1637         /* fill in the return list now with real IP's */
1638                                 
1639         while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1640                 struct in_addr name_ip;
1641                         
1642                 /* copy any addersses from the auto lookup */
1643                         
1644                 if ( strequal(name, "*") ) {
1645                         for ( j=0; j<auto_count; j++ ) {
1646                                 /* Check for and don't copy any known bad DC IP's. */
1647                                 if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain, 
1648                                                 inet_ntoa(auto_ip_list[j].ip)))) {
1649                                         DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
1650                                                 inet_ntoa(auto_ip_list[j].ip) ));
1651                                         continue;
1652                                 }
1653                                 return_iplist[local_count].ip   = auto_ip_list[j].ip;
1654                                 return_iplist[local_count].port = auto_ip_list[j].port;
1655                                 local_count++;
1656                         }
1657                         continue;
1658                 }
1659                         
1660                         
1661                 /* added support for address:port syntax for ads (not that I think 
1662                    anyone will ever run the LDAP server in an AD domain on something 
1663                    other than port 389 */
1664                         
1665                 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1666                 if ( (port_str=strchr(name, ':')) != NULL ) {
1667                         *port_str = '\0';
1668                         port_str++;
1669                         port = atoi( port_str );
1670                 }
1671
1672                 /* explicit lookup; resolve_name() will handle names & IP addresses */
1673                 if ( resolve_name( name, &name_ip, 0x20 ) ) {
1674
1675                         /* Check for and don't copy any known bad DC IP's. */
1676                         if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
1677                                 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
1678                                 continue;
1679                         }
1680
1681                         return_iplist[local_count].ip   = name_ip;
1682                         return_iplist[local_count].port = port;
1683                         local_count++;
1684                         *ordered = True;
1685                 }
1686         }
1687                                 
1688         SAFE_FREE(auto_ip_list);
1689
1690         /* need to remove duplicates in the list if we have any 
1691            explicit password servers */
1692            
1693         if ( local_count ) {
1694                 local_count = remove_duplicate_addrs2( return_iplist, local_count );
1695         }
1696                 
1697         if ( DEBUGLEVEL >= 4 ) {
1698                 DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, 
1699                         *ordered ? "":"un"));
1700                 DEBUG(4,("get_dc_list: "));
1701                 for ( i=0; i<local_count; i++ )
1702                         DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
1703                 DEBUGADD(4,("\n"));
1704         }
1705                         
1706         *ip_list = return_iplist;
1707         *count = local_count;
1708
1709         return ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
1710 }
1711
1712 /*********************************************************************
1713  Small wrapper function to get the DC list and sort it if neccessary.
1714 *********************************************************************/
1715
1716 NTSTATUS get_sorted_dc_list( const char *domain, const char *sitename, struct ip_service **ip_list, int *count, bool ads_only )
1717 {
1718         bool ordered;
1719         NTSTATUS status;
1720         enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
1721
1722         DEBUG(8,("get_sorted_dc_list: attempting lookup for name %s (sitename %s) "
1723                 "using [%s]\n",
1724                 domain,
1725                 sitename ? sitename : "NULL",
1726                 (ads_only ? "ads" : lp_name_resolve_order())));
1727         
1728         if (ads_only) {
1729                 lookup_type = DC_ADS_ONLY;
1730         }
1731
1732         status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered);
1733         if (!NT_STATUS_IS_OK(status)) {
1734                 return status; 
1735         }
1736                 
1737         /* only sort if we don't already have an ordered list */
1738         if ( !ordered ) {
1739                 sort_ip_list2( *ip_list, *count );
1740         }
1741                 
1742         return NT_STATUS_OK;
1743 }
1744
1745 /*********************************************************************
1746  Get the KDC list - re-use all the logic in get_dc_list.
1747 *********************************************************************/
1748
1749 NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_service **ip_list, int *count)
1750 {
1751         bool ordered;
1752         NTSTATUS status;
1753
1754         *count = 0;
1755         *ip_list = NULL;
1756
1757         status = get_dc_list(realm, sitename, ip_list, count, DC_KDC_ONLY, &ordered);
1758
1759         if (!NT_STATUS_IS_OK(status)) {
1760                 return status; 
1761         }
1762
1763         /* only sort if we don't already have an ordered list */
1764         if ( !ordered ) {
1765                 sort_ip_list2( *ip_list, *count );
1766         }
1767
1768         return NT_STATUS_OK;
1769 }