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