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