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