r25407: Revert Longhorn join patch as it is not correct for the 3.2 tree.
[metze/samba/wip.git] / source3 / libsmb / namequery.c
1 /* 
2    Unix SMB/CIFS implementation.
3    name query routines
4    Copyright (C) Andrew Tridgell 1994-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.   
18 */
19
20 #include "includes.h"
21
22 /* nmbd.c sets this to True. */
23 BOOL global_in_nmbd = False;
24
25 /****************************
26  * SERVER AFFINITY ROUTINES *
27  ****************************/
28  
29  /* Server affinity is the concept of preferring the last domain 
30     controller with whom you had a successful conversation */
31  
32 /****************************************************************************
33 ****************************************************************************/
34 #define SAFKEY_FMT      "SAF/DOMAIN/%s"
35 #define SAF_TTL         900
36
37 static char *saf_key(const char *domain)
38 {
39         char *keystr;
40         
41         asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) );
42
43         return keystr;
44 }
45
46 /****************************************************************************
47 ****************************************************************************/
48
49 BOOL saf_store( const char *domain, const char *servername )
50 {
51         char *key;
52         time_t expire;
53         BOOL ret = False;
54         
55         if ( !domain || !servername ) {
56                 DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n"));
57                 return False;
58         }
59
60         if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
61                 DEBUG(0,("saf_store: refusing to store 0 length domain or servername!\n"));
62                 return False;
63         }
64         
65         if ( !gencache_init() ) 
66                 return False;
67         
68         key = saf_key( domain );
69         expire = time( NULL ) + SAF_TTL;
70         
71         
72         DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
73                 domain, servername, (unsigned int)expire ));
74                 
75         ret = gencache_set( key, servername, expire );
76         
77         SAFE_FREE( key );
78         
79         return ret;
80 }
81
82 BOOL saf_delete( const char *domain )
83 {
84         char *key;
85         BOOL ret = False;
86         
87         if ( !domain ) {
88                 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));             
89                 return False;
90         }
91         
92         if ( !gencache_init() ) 
93                 return False;
94         
95         key = saf_key(domain);
96         ret = gencache_del(key);
97         
98         if (ret) {
99                 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));             
100         }
101
102         SAFE_FREE( key );
103
104         return ret;
105 }
106
107 /****************************************************************************
108 ****************************************************************************/
109
110 char *saf_fetch( const char *domain )
111 {
112         char *server = NULL;
113         time_t timeout;
114         BOOL ret = False;
115         char *key = NULL;
116
117         if ( !domain || strlen(domain) == 0) {
118                 DEBUG(2,("saf_fetch: Empty domain name!\n"));
119                 return NULL;
120         }
121         
122         if ( !gencache_init() ) 
123                 return False;
124         
125         key = saf_key( domain );
126         
127         ret = gencache_get( key, &server, &timeout );
128         
129         SAFE_FREE( key );
130         
131         if ( !ret ) {
132                 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n", domain ));
133         } else {
134                 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n", 
135                         server, domain ));
136         }
137                 
138         return server;
139 }
140
141 /****************************************************************************
142  Generate a random trn_id.
143 ****************************************************************************/
144
145 static int generate_trn_id(void)
146 {
147         uint16 id;
148
149         generate_random_buffer((uint8 *)&id, sizeof(id));
150
151         return id % (unsigned)0x7FFF;
152 }
153
154 /****************************************************************************
155  Parse a node status response into an array of structures.
156 ****************************************************************************/
157
158 static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct node_status_extra *extra)
159 {
160         NODE_STATUS_STRUCT *ret;
161         int i;
162
163         *num_names = CVAL(p,0);
164
165         if (*num_names == 0)
166                 return NULL;
167
168         ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);
169         if (!ret)
170                 return NULL;
171
172         p++;
173         for (i=0;i< *num_names;i++) {
174                 StrnCpy(ret[i].name,p,15);
175                 trim_char(ret[i].name,'\0',' ');
176                 ret[i].type = CVAL(p,15);
177                 ret[i].flags = p[16];
178                 p += 18;
179                 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, 
180                            ret[i].type, ret[i].flags));
181         }
182         /*
183          * Also, pick up the MAC address ...
184          */
185         if (extra) {
186                 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
187         }
188         return ret;
189 }
190
191
192 /****************************************************************************
193  Do a NBT node status query on an open socket and return an array of
194  structures holding the returned names or NULL if the query failed.
195 **************************************************************************/
196
197 NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
198                                       struct in_addr to_ip, int *num_names,
199                                       struct node_status_extra *extra)
200 {
201         BOOL found=False;
202         int retries = 2;
203         int retry_time = 2000;
204         struct timeval tval;
205         struct packet_struct p;
206         struct packet_struct *p2;
207         struct nmb_packet *nmb = &p.packet.nmb;
208         NODE_STATUS_STRUCT *ret;
209
210         ZERO_STRUCT(p);
211
212         nmb->header.name_trn_id = generate_trn_id();
213         nmb->header.opcode = 0;
214         nmb->header.response = False;
215         nmb->header.nm_flags.bcast = False;
216         nmb->header.nm_flags.recursion_available = False;
217         nmb->header.nm_flags.recursion_desired = False;
218         nmb->header.nm_flags.trunc = False;
219         nmb->header.nm_flags.authoritative = False;
220         nmb->header.rcode = 0;
221         nmb->header.qdcount = 1;
222         nmb->header.ancount = 0;
223         nmb->header.nscount = 0;
224         nmb->header.arcount = 0;
225         nmb->question.question_name = *name;
226         nmb->question.question_type = 0x21;
227         nmb->question.question_class = 0x1;
228
229         p.ip = to_ip;
230         p.port = NMB_PORT;
231         p.fd = fd;
232         p.timestamp = time(NULL);
233         p.packet_type = NMB_PACKET;
234         
235         GetTimeOfDay(&tval);
236   
237         if (!send_packet(&p)) 
238                 return NULL;
239
240         retries--;
241
242         while (1) {
243                 struct timeval tval2;
244                 GetTimeOfDay(&tval2);
245                 if (TvalDiff(&tval,&tval2) > retry_time) {
246                         if (!retries)
247                                 break;
248                         if (!found && !send_packet(&p))
249                                 return NULL;
250                         GetTimeOfDay(&tval);
251                         retries--;
252                 }
253
254                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
255                         struct nmb_packet *nmb2 = &p2->packet.nmb;
256                         debug_nmb_packet(p2);
257                         
258                         if (nmb2->header.opcode != 0 ||
259                             nmb2->header.nm_flags.bcast ||
260                             nmb2->header.rcode ||
261                             !nmb2->header.ancount ||
262                             nmb2->answers->rr_type != 0x21) {
263                                 /* XXXX what do we do with this? could be a
264                                    redirect, but we'll discard it for the
265                                    moment */
266                                 free_packet(p2);
267                                 continue;
268                         }
269
270                         ret = parse_node_status(&nmb2->answers->rdata[0], num_names, extra);
271                         free_packet(p2);
272                         return ret;
273                 }
274         }
275         
276         return NULL;
277 }
278
279 /****************************************************************************
280  Find the first type XX name in a node status reply - used for finding
281  a servers name given its IP. Return the matched name in *name.
282 **************************************************************************/
283
284 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name)
285 {
286         NODE_STATUS_STRUCT *status = NULL;
287         struct nmb_name nname;
288         int count, i;
289         int sock;
290         BOOL result = False;
291
292         if (lp_disable_netbios()) {
293                 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
294                 return False;
295         }
296
297         DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, 
298                    q_type, inet_ntoa(to_ip)));
299
300         /* Check the cache first. */
301
302         if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
303                 return True;
304
305         sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
306         if (sock == -1)
307                 goto done;
308
309         /* W2K PDC's seem not to respond to '*'#0. JRA */
310         make_nmb_name(&nname, q_name, q_type);
311         status = node_status_query(sock, &nname, to_ip, &count, NULL);
312         close(sock);
313         if (!status)
314                 goto done;
315
316         for (i=0;i<count;i++) {
317                 if (status[i].type == type)
318                         break;
319         }
320         if (i == count)
321                 goto done;
322
323         pull_ascii_nstring(name, sizeof(fstring), status[i].name);
324
325         /* Store the result in the cache. */
326         /* but don't store an entry for 0x1c names here.  Here we have 
327            a single host and DOMAIN<0x1c> names should be a list of hosts */
328            
329         if ( q_type != 0x1c )
330                 namecache_status_store(q_name, q_type, type, to_ip, name);
331
332         result = True;
333
334  done:
335         SAFE_FREE(status);
336
337         DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
338
339         if (result)
340                 DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
341
342         DEBUG(10, ("\n"));      
343
344         return result;
345 }
346
347 /*
348   comparison function used by sort_ip_list
349 */
350
351 static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
352 {
353         int max_bits1=0, max_bits2=0;
354         int num_interfaces = iface_count();
355         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 NTSTATUS name_resolve_bcast(const char *name, int name_type,
781                             struct ip_service **return_iplist,
782                             int *return_count)
783 {
784         int sock, i;
785         int num_interfaces = iface_count();
786         struct in_addr *ip_list;
787         NTSTATUS status;
788
789         if (lp_disable_netbios()) {
790                 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
791                 return NT_STATUS_INVALID_PARAMETER;
792         }
793
794         *return_iplist = NULL;
795         *return_count = 0;
796         
797         /*
798          * "bcast" means do a broadcast lookup on all the local interfaces.
799          */
800
801         DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
802
803         sock = open_socket_in( SOCK_DGRAM, 0, 3,
804                                interpret_addr(lp_socket_address()), True );
805
806         if (sock == -1) return NT_STATUS_UNSUCCESSFUL;
807
808         set_socket_options(sock,"SO_BROADCAST");
809         /*
810          * Lookup the name on all the interfaces, return on
811          * the first successful match.
812          */
813         for( i = num_interfaces-1; i >= 0; i--) {
814                 struct in_addr sendto_ip;
815                 int flags;
816                 /* Done this way to fix compiler error on IRIX 5.x */
817                 sendto_ip = *iface_n_bcast(i);
818                 ip_list = name_query(sock, name, name_type, True, 
819                                     True, sendto_ip, return_count, &flags, NULL);
820                 if( ip_list ) 
821                         goto success;
822         }
823         
824         /* failed - no response */
825         
826         close(sock);
827         return NT_STATUS_UNSUCCESSFUL;
828         
829 success:
830         status = NT_STATUS_OK;
831         if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
832                 status = NT_STATUS_INVALID_PARAMETER;
833         
834         SAFE_FREE( ip_list );
835         close(sock);
836         return status;
837 }
838
839 /********************************************************
840  Resolve via "wins" method.
841 *********************************************************/
842
843 NTSTATUS resolve_wins(const char *name, int name_type,
844                       struct ip_service **return_iplist,
845                       int *return_count)
846 {
847         int sock, t, i;
848         char **wins_tags;
849         struct in_addr src_ip, *ip_list = NULL;
850         NTSTATUS status;
851
852         if (lp_disable_netbios()) {
853                 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
854                 return NT_STATUS_INVALID_PARAMETER;
855         }
856
857         *return_iplist = NULL;
858         *return_count = 0;
859         
860         DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
861
862         if (wins_srv_count() < 1) {
863                 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
864                 return NT_STATUS_INVALID_PARAMETER;
865         }
866
867         /* we try a lookup on each of the WINS tags in turn */
868         wins_tags = wins_srv_tags();
869
870         if (!wins_tags) {
871                 /* huh? no tags?? give up in disgust */
872                 return NT_STATUS_INVALID_PARAMETER;
873         }
874
875         /* the address we will be sending from */
876         src_ip = *interpret_addr2(lp_socket_address());
877
878         /* in the worst case we will try every wins server with every
879            tag! */
880         for (t=0; wins_tags && wins_tags[t]; t++) {
881                 int srv_count = wins_srv_count_tag(wins_tags[t]);
882                 for (i=0; i<srv_count; i++) {
883                         struct in_addr wins_ip;
884                         int flags;
885                         BOOL timed_out;
886
887                         wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
888
889                         if (global_in_nmbd && ismyip(wins_ip)) {
890                                 /* yikes! we'll loop forever */
891                                 continue;
892                         }
893
894                         /* skip any that have been unresponsive lately */
895                         if (wins_srv_is_dead(wins_ip, src_ip)) {
896                                 continue;
897                         }
898
899                         DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
900
901                         sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
902                         if (sock == -1) {
903                                 continue;
904                         }
905
906                         ip_list = name_query(sock,name,name_type, False, 
907                                                     True, wins_ip, return_count, &flags, 
908                                                     &timed_out);
909                                                     
910                         /* exit loop if we got a list of addresses */
911                         
912                         if ( ip_list ) 
913                                 goto success;
914                                 
915                         close(sock);
916
917                         if (timed_out) {
918                                 /* Timed out wating for WINS server to respond.  Mark it dead. */
919                                 wins_srv_died(wins_ip, src_ip);
920                         } else {
921                                 /* The name definately isn't in this
922                                    group of WINS servers. goto the next group  */
923                                 break;
924                         }
925                 }
926         }
927
928         wins_srv_tags_free(wins_tags);
929         return NT_STATUS_NO_LOGON_SERVERS;
930
931 success:
932         status = NT_STATUS_OK;
933         if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
934                 status = NT_STATUS_INVALID_PARAMETER;
935         
936         SAFE_FREE( ip_list );
937         wins_srv_tags_free(wins_tags);
938         close(sock);
939         
940         return status;
941 }
942
943 /********************************************************
944  Resolve via "lmhosts" method.
945 *********************************************************/
946
947 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
948                                 struct ip_service **return_iplist,
949                                 int *return_count)
950 {
951         /*
952          * "lmhosts" means parse the local lmhosts file.
953          */
954         
955         XFILE *fp;
956         pstring lmhost_name;
957         int name_type2;
958         struct in_addr return_ip;
959         NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
960
961         *return_iplist = NULL;
962         *return_count = 0;
963
964         DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
965
966         fp = startlmhosts(dyn_LMHOSTSFILE);
967
968         if ( fp == NULL )
969                 return NT_STATUS_NO_SUCH_FILE;
970
971         while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) 
972         {
973
974                 if (!strequal(name, lmhost_name))
975                         continue;
976
977                 if ((name_type2 != -1) && (name_type != name_type2))
978                         continue;
979
980                 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), struct ip_service,
981                                         (*return_count)+1);
982
983                 if ((*return_iplist) == NULL) {
984                         endlmhosts(fp);
985                         DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
986                         return NT_STATUS_NO_MEMORY;
987                 }
988
989                 (*return_iplist)[*return_count].ip   = return_ip;
990                 (*return_iplist)[*return_count].port = PORT_NONE;
991                 *return_count += 1;
992
993                 /* we found something */
994                 status = NT_STATUS_OK;
995
996                 /* Multiple names only for DC lookup */
997                 if (name_type != 0x1c)
998                         break;
999         }
1000
1001         endlmhosts(fp);
1002
1003         return status;
1004 }
1005
1006
1007 /********************************************************
1008  Resolve via "hosts" method.
1009 *********************************************************/
1010
1011 static NTSTATUS resolve_hosts(const char *name, int name_type,
1012                               struct ip_service **return_iplist,
1013                               int *return_count)
1014 {
1015         /*
1016          * "host" means do a localhost, or dns lookup.
1017          */
1018         struct hostent *hp;
1019         
1020         if ( name_type != 0x20 && name_type != 0x0) {
1021                 DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type));
1022                 return NT_STATUS_INVALID_PARAMETER;
1023         }
1024
1025         *return_iplist = NULL;
1026         *return_count = 0;
1027
1028         DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type));
1029         
1030         if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
1031                 struct in_addr return_ip;
1032                 putip((char *)&return_ip,(char *)hp->h_addr);
1033                 *return_iplist = SMB_MALLOC_P(struct ip_service);
1034                 if(*return_iplist == NULL) {
1035                         DEBUG(3,("resolve_hosts: malloc fail !\n"));
1036                         return NT_STATUS_NO_MEMORY;
1037                 }
1038                 (*return_iplist)->ip   = return_ip;
1039                 (*return_iplist)->port = PORT_NONE;
1040                 *return_count = 1;
1041                 return NT_STATUS_OK;
1042         }
1043         return NT_STATUS_UNSUCCESSFUL;
1044 }
1045
1046 /********************************************************
1047  Resolve via "ADS" method.
1048 *********************************************************/
1049
1050 NTSTATUS resolve_ads(const char *name, int name_type,
1051                      const char *sitename,
1052                      struct ip_service **return_iplist,
1053                      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             (name_type != 0x1b)) {
1064                 return NT_STATUS_INVALID_PARAMETER;
1065         }
1066
1067         if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1068                 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1069                 return NT_STATUS_NO_MEMORY;
1070         }
1071
1072         switch (name_type) {
1073                 case 0x1b:
1074                         DEBUG(5,("resolve_ads: Attempting to resolve "
1075                                  "PDC for %s using DNS\n", name));
1076                         status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
1077                         break;
1078
1079                 case 0x1c:
1080                         DEBUG(5,("resolve_ads: Attempting to resolve "
1081                                  "DCs for %s using DNS\n", name));
1082                         status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
1083                                                    &numdcs);
1084                         break;
1085                 case KDC_NAME_TYPE:
1086                         DEBUG(5,("resolve_ads: Attempting to resolve "
1087                                  "KDCs for %s using DNS\n", name));
1088                         status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
1089                                                     &numdcs);
1090                         break;
1091                 default:
1092                         status = NT_STATUS_INVALID_PARAMETER;
1093                         break;
1094         }
1095
1096         if ( !NT_STATUS_IS_OK( status ) ) {
1097                 talloc_destroy(ctx);
1098                 return status;
1099         }
1100
1101         for (i=0;i<numdcs;i++) {
1102                 numaddrs += MAX(dcs[i].num_ips,1);
1103         }
1104                 
1105         if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
1106                 DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
1107                 talloc_destroy(ctx);
1108                 return NT_STATUS_NO_MEMORY;
1109         }
1110         
1111         /* now unroll the list of IP addresses */
1112
1113         *return_count = 0;
1114         i = 0;
1115         j = 0;
1116         while ( i < numdcs && (*return_count<numaddrs) ) {
1117                 struct ip_service *r = &(*return_iplist)[*return_count];
1118
1119                 r->port = dcs[i].port;
1120                 
1121                 /* If we don't have an IP list for a name, lookup it up */
1122                 
1123                 if ( !dcs[i].ips ) {
1124                         r->ip = *interpret_addr2(dcs[i].hostname);
1125                         i++;
1126                         j = 0;
1127                 } else {
1128                         /* use the IP addresses from the SRV sresponse */
1129                         
1130                         if ( j >= dcs[i].num_ips ) {
1131                                 i++;
1132                                 j = 0;
1133                                 continue;
1134                         }
1135                         
1136                         r->ip = dcs[i].ips[j];
1137                         j++;
1138                 }
1139                         
1140                 /* make sure it is a valid IP.  I considered checking the negative
1141                    connection cache, but this is the wrong place for it.  Maybe only
1142                    as a hac.  After think about it, if all of the IP addresses retuend
1143                    from DNS are dead, what hope does a netbios name lookup have?
1144                    The standard reason for falling back to netbios lookups is that 
1145                    our DNS server doesn't know anything about the DC's   -- jerry */    
1146                            
1147                 if ( ! is_zero_ip(r->ip) )
1148                         (*return_count)++;
1149         }
1150                 
1151         talloc_destroy(ctx);
1152         return NT_STATUS_OK;
1153 }
1154
1155 /*******************************************************************
1156  Internal interface to resolve a name into an IP address.
1157  Use this function if the string is either an IP address, DNS
1158  or host name or NetBIOS name. This uses the name switch in the
1159  smb.conf to determine the order of name resolution.
1160  
1161  Added support for ip addr/port to support ADS ldap servers.
1162  the only place we currently care about the port is in the 
1163  resolve_hosts() when looking up DC's via SRV RR entries in DNS
1164 **********************************************************************/
1165
1166 NTSTATUS internal_resolve_name(const char *name, int name_type,
1167                                const char *sitename,
1168                                struct ip_service **return_iplist,
1169                                int *return_count, const char *resolve_order)
1170 {
1171         pstring name_resolve_list;
1172         fstring tok;
1173         const char *ptr;
1174         BOOL allones = (strcmp(name,"255.255.255.255") == 0);
1175         BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
1176         BOOL is_address = is_ipaddress(name);
1177         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1178         int i;
1179
1180         *return_iplist = NULL;
1181         *return_count = 0;
1182
1183         DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1184                         name, name_type, sitename ? sitename : NULL));
1185
1186         if (allzeros || allones || is_address) {
1187   
1188                 if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) {
1189                         DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1190                         return NT_STATUS_NO_MEMORY;
1191                 }
1192         
1193                 if(is_address) { 
1194                         /* ignore the port here */
1195                         (*return_iplist)->port = PORT_NONE;
1196                 
1197                         /* if it's in the form of an IP address then get the lib to interpret it */
1198                         if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
1199                                 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
1200                                 SAFE_FREE(*return_iplist);
1201                                 return NT_STATUS_INVALID_PARAMETER;
1202                         }
1203                 } else {
1204                         (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
1205                 }
1206                 *return_count = 1;
1207                 return NT_STATUS_OK;
1208         }
1209   
1210         /* Check name cache */
1211
1212         if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1213                 /* This could be a negative response */
1214                 if (*return_count > 0) {
1215                         return NT_STATUS_OK;
1216                 } else {
1217                         return NT_STATUS_UNSUCCESSFUL;
1218                 }
1219         }
1220
1221         /* set the name resolution order */
1222
1223         if ( strcmp( resolve_order, "NULL") == 0 ) {
1224                 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1225                 return NT_STATUS_INVALID_PARAMETER;
1226         }
1227   
1228         if ( !resolve_order ) {
1229                 pstrcpy(name_resolve_list, lp_name_resolve_order());
1230         } else {
1231                 pstrcpy(name_resolve_list, resolve_order);
1232         }
1233
1234         if ( !name_resolve_list[0] ) {
1235                 ptr = "host";
1236         } else {
1237                 ptr = name_resolve_list;
1238         }
1239
1240         /* iterate through the name resolution backends */
1241   
1242         while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
1243                 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1244                         status = resolve_hosts(name, name_type, return_iplist,
1245                                                return_count);
1246                         if (NT_STATUS_IS_OK(status)) {
1247                                 goto done;
1248                         }
1249                 } else if(strequal( tok, "kdc")) {
1250                         /* deal with KDC_NAME_TYPE names here.  This will result in a
1251                                 SRV record lookup */
1252                         status = resolve_ads(name, KDC_NAME_TYPE, sitename,
1253                                              return_iplist, return_count);
1254                         if (NT_STATUS_IS_OK(status)) {
1255                                 /* Ensure we don't namecache this with the KDC port. */
1256                                 name_type = KDC_NAME_TYPE;
1257                                 goto done;
1258                         }
1259                 } else if(strequal( tok, "ads")) {
1260                         /* deal with 0x1c and 0x1b names here.  This will result in a
1261                                 SRV record lookup */
1262                         status = resolve_ads(name, name_type, sitename,
1263                                              return_iplist, return_count);
1264                         if (NT_STATUS_IS_OK(status)) {
1265                                 goto done;
1266                         }
1267                 } else if(strequal( tok, "lmhosts")) {
1268                         status = resolve_lmhosts(name, name_type,
1269                                                  return_iplist, return_count);
1270                         if (NT_STATUS_IS_OK(status)) {
1271                                 goto done;
1272                         }
1273                 } else if(strequal( tok, "wins")) {
1274                         /* don't resolve 1D via WINS */
1275                         if (name_type != 0x1D) {
1276                                 status = resolve_wins(name, name_type,
1277                                                       return_iplist,
1278                                                       return_count);
1279                                 if (NT_STATUS_IS_OK(status)) {
1280                                         goto done;
1281                                 }
1282                         }
1283                 } else if(strequal( tok, "bcast")) {
1284                         status = name_resolve_bcast(name, name_type,
1285                                                     return_iplist,
1286                                                     return_count);
1287                         if (NT_STATUS_IS_OK(status)) {
1288                                 goto done;
1289                         }
1290                 } else {
1291                         DEBUG(0,("resolve_name: unknown name switch type %s\n",
1292                                 tok));
1293                 }
1294         }
1295
1296         /* All of the resolve_* functions above have returned false. */
1297
1298         SAFE_FREE(*return_iplist);
1299         *return_count = 0;
1300
1301         return NT_STATUS_UNSUCCESSFUL;
1302
1303   done:
1304
1305         /* Remove duplicate entries.  Some queries, notably #1c (domain
1306         controllers) return the PDC in iplist[0] and then all domain
1307         controllers including the PDC in iplist[1..n].  Iterating over
1308         the iplist when the PDC is down will cause two sets of timeouts. */
1309
1310         if ( *return_count ) {
1311                 *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
1312         }
1313  
1314         /* Save in name cache */
1315         if ( DEBUGLEVEL >= 100 ) {
1316                 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
1317                         DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
1318                                 name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1319         }
1320    
1321         namecache_store(name, name_type, *return_count, *return_iplist);
1322
1323         /* Display some debugging info */
1324
1325         if ( DEBUGLEVEL >= 10 ) {
1326                 DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
1327
1328                 for (i = 0; i < *return_count; i++) {
1329                         DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1330                 }
1331                 DEBUG(10, ("\n"));
1332         }
1333   
1334         return status;
1335 }
1336
1337 /********************************************************
1338  Internal interface to resolve a name into one IP address.
1339  Use this function if the string is either an IP address, DNS
1340  or host name or NetBIOS name. This uses the name switch in the
1341  smb.conf to determine the order of name resolution.
1342 *********************************************************/
1343
1344 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
1345 {
1346         struct ip_service *ip_list = NULL;
1347         char *sitename = sitename_fetch(lp_realm()); /* wild guess */
1348         int count = 0;
1349
1350         if (is_ipaddress(name)) {
1351                 *return_ip = *interpret_addr2(name);
1352                 SAFE_FREE(sitename);
1353                 return True;
1354         }
1355
1356         if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
1357                                                   &ip_list, &count,
1358                                                   lp_name_resolve_order()))) {
1359                 int i;
1360                 
1361                 /* only return valid addresses for TCP connections */
1362                 for (i=0; i<count; i++) {
1363                         char *ip_str = inet_ntoa(ip_list[i].ip);
1364                         if (ip_str &&
1365                             strcmp(ip_str, "255.255.255.255") != 0 &&
1366                             strcmp(ip_str, "0.0.0.0") != 0) 
1367                         {
1368                                 *return_ip = ip_list[i].ip;
1369                                 SAFE_FREE(ip_list);
1370                                 SAFE_FREE(sitename);
1371                                 return True;
1372                         }
1373                 }
1374         }
1375         
1376         SAFE_FREE(ip_list);
1377         SAFE_FREE(sitename);
1378         return False;
1379 }
1380
1381 /********************************************************
1382  Find the IP address of the master browser or DMB for a workgroup.
1383 *********************************************************/
1384
1385 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
1386 {
1387         struct ip_service *ip_list = NULL;
1388         int count = 0;
1389         NTSTATUS status;
1390
1391         if (lp_disable_netbios()) {
1392                 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1393                 return False;
1394         }
1395
1396         status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
1397                                        lp_name_resolve_order());
1398         if (NT_STATUS_IS_OK(status)) {
1399                 *master_ip = ip_list[0].ip;
1400                 SAFE_FREE(ip_list);
1401                 return True;
1402         }
1403
1404         status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
1405                                        lp_name_resolve_order());
1406         if (NT_STATUS_IS_OK(status)) {
1407                 *master_ip = ip_list[0].ip;
1408                 SAFE_FREE(ip_list);
1409                 return True;
1410         }
1411
1412         SAFE_FREE(ip_list);
1413         return False;
1414 }
1415
1416 /********************************************************
1417  Get the IP address list of the primary domain controller
1418  for a domain.
1419 *********************************************************/
1420
1421 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1422 {
1423         struct ip_service *ip_list = NULL;
1424         int count = 0;
1425         NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1426
1427         /* Look up #1B name */
1428
1429         if (lp_security() == SEC_ADS) {
1430                 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1431                                                &count, "ads");
1432         }
1433
1434         if (!NT_STATUS_IS_OK(status) || count == 0) {
1435                 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1436                                                &count,
1437                                                lp_name_resolve_order());
1438                 if (!NT_STATUS_IS_OK(status)) {
1439                         return False;
1440                 }
1441         }
1442
1443         /* if we get more than 1 IP back we have to assume it is a
1444            multi-homed PDC and not a mess up */
1445
1446         if ( count > 1 ) {
1447                 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));             
1448                 sort_ip_list2( ip_list, count );
1449         }
1450
1451         *ip = ip_list[0].ip;
1452         
1453         SAFE_FREE(ip_list);
1454
1455         return True;
1456 }
1457
1458 /* Private enum type for lookups. */
1459
1460 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
1461
1462 /********************************************************
1463  Get the IP address list of the domain controllers for
1464  a domain.
1465 *********************************************************/
1466
1467 static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_service **ip_list, 
1468                             int *count, enum dc_lookup_type lookup_type, int *ordered)
1469 {
1470         fstring resolve_order;
1471         char *saf_servername;
1472         pstring pserver;
1473         const char *p;
1474         char *port_str;
1475         int port;
1476         fstring name;
1477         int num_addresses = 0;
1478         int  local_count, i, j;
1479         struct ip_service *return_iplist = NULL;
1480         struct ip_service *auto_ip_list = NULL;
1481         BOOL done_auto_lookup = False;
1482         int auto_count = 0;
1483         NTSTATUS status;
1484
1485         *ordered = False;
1486
1487         /* if we are restricted to solely using DNS for looking
1488            up a domain controller, make sure that host lookups
1489            are enabled for the 'name resolve order'.  If host lookups
1490            are disabled and ads_only is True, then set the string to
1491            NULL. */
1492
1493         fstrcpy( resolve_order, lp_name_resolve_order() );
1494         strlower_m( resolve_order );
1495         if ( lookup_type == DC_ADS_ONLY)  {
1496                 if ( strstr( resolve_order, "host" ) ) {
1497                         fstrcpy( resolve_order, "ads" );
1498
1499                         /* DNS SRV lookups used by the ads resolver
1500                            are already sorted by priority and weight */
1501                         *ordered = True;
1502                 } else {
1503                         fstrcpy( resolve_order, "NULL" );
1504                 }
1505         } else if (lookup_type == DC_KDC_ONLY) {
1506                 /* DNS SRV lookups used by the ads/kdc resolver
1507                    are already sorted by priority and weight */
1508                 *ordered = True;
1509                 fstrcpy( resolve_order, "kdc" );
1510         }
1511
1512         /* fetch the server we have affinity for.  Add the 
1513            'password server' list to a search for our domain controllers */
1514         
1515         saf_servername = saf_fetch( domain);
1516         
1517         if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
1518                 pstr_sprintf( pserver, "%s, %s", 
1519                         saf_servername ? saf_servername : "",
1520                         lp_passwordserver() );
1521         } else {
1522                 pstr_sprintf( pserver, "%s, *", 
1523                         saf_servername ? saf_servername : "" );
1524         }
1525
1526         SAFE_FREE( saf_servername );
1527
1528         /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1529
1530         if ( !*pserver ) {
1531                 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1532                 return internal_resolve_name(domain, 0x1C, sitename, ip_list,
1533                                              count, resolve_order);
1534         }
1535
1536         DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1537         
1538         /*
1539          * if '*' appears in the "password server" list then add
1540          * an auto lookup to the list of manually configured
1541          * DC's.  If any DC is listed by name, then the list should be 
1542          * considered to be ordered 
1543          */
1544
1545         p = pserver;
1546         while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1547                 if (strequal(name, "*")) {
1548                         status = internal_resolve_name(domain, 0x1C, sitename,
1549                                                        &auto_ip_list,
1550                                                        &auto_count,
1551                                                        resolve_order);
1552                         if (NT_STATUS_IS_OK(status)) {
1553                                 num_addresses += auto_count;
1554                         }
1555                         done_auto_lookup = True;
1556                         DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1557                 } else  {
1558                         num_addresses++;
1559                 }
1560         }
1561
1562         /* if we have no addresses and haven't done the auto lookup, then
1563            just return the list of DC's.  Or maybe we just failed. */
1564                    
1565         if ( (num_addresses == 0) ) {
1566                 if ( done_auto_lookup ) {
1567                         DEBUG(4,("get_dc_list: no servers found\n")); 
1568                         SAFE_FREE(auto_ip_list);
1569                         return NT_STATUS_NO_LOGON_SERVERS;
1570                 }
1571                 return internal_resolve_name(domain, 0x1C, sitename, ip_list,
1572                                              count, resolve_order);
1573         }
1574
1575         if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
1576                 DEBUG(3,("get_dc_list: malloc fail !\n"));
1577                 SAFE_FREE(auto_ip_list);
1578                 return NT_STATUS_NO_MEMORY;
1579         }
1580
1581         p = pserver;
1582         local_count = 0;
1583
1584         /* fill in the return list now with real IP's */
1585                                 
1586         while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1587                 struct in_addr name_ip;
1588                         
1589                 /* copy any addersses from the auto lookup */
1590                         
1591                 if ( strequal(name, "*") ) {
1592                         for ( j=0; j<auto_count; j++ ) {
1593                                 /* Check for and don't copy any known bad DC IP's. */
1594                                 if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain, 
1595                                                 inet_ntoa(auto_ip_list[j].ip)))) {
1596                                         DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
1597                                                 inet_ntoa(auto_ip_list[j].ip) ));
1598                                         continue;
1599                                 }
1600                                 return_iplist[local_count].ip   = auto_ip_list[j].ip;
1601                                 return_iplist[local_count].port = auto_ip_list[j].port;
1602                                 local_count++;
1603                         }
1604                         continue;
1605                 }
1606                         
1607                         
1608                 /* added support for address:port syntax for ads (not that I think 
1609                    anyone will ever run the LDAP server in an AD domain on something 
1610                    other than port 389 */
1611                         
1612                 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1613                 if ( (port_str=strchr(name, ':')) != NULL ) {
1614                         *port_str = '\0';
1615                         port_str++;
1616                         port = atoi( port_str );
1617                 }
1618
1619                 /* explicit lookup; resolve_name() will handle names & IP addresses */
1620                 if ( resolve_name( name, &name_ip, 0x20 ) ) {
1621
1622                         /* Check for and don't copy any known bad DC IP's. */
1623                         if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
1624                                 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
1625                                 continue;
1626                         }
1627
1628                         return_iplist[local_count].ip   = name_ip;
1629                         return_iplist[local_count].port = port;
1630                         local_count++;
1631                         *ordered = True;
1632                 }
1633         }
1634                                 
1635         SAFE_FREE(auto_ip_list);
1636
1637         /* need to remove duplicates in the list if we have any 
1638            explicit password servers */
1639            
1640         if ( local_count ) {
1641                 local_count = remove_duplicate_addrs2( return_iplist, local_count );
1642         }
1643                 
1644         if ( DEBUGLEVEL >= 4 ) {
1645                 DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, 
1646                         *ordered ? "":"un"));
1647                 DEBUG(4,("get_dc_list: "));
1648                 for ( i=0; i<local_count; i++ )
1649                         DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
1650                 DEBUGADD(4,("\n"));
1651         }
1652                         
1653         *ip_list = return_iplist;
1654         *count = local_count;
1655
1656         return ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
1657 }
1658
1659 /*********************************************************************
1660  Small wrapper function to get the DC list and sort it if neccessary.
1661 *********************************************************************/
1662
1663 NTSTATUS get_sorted_dc_list( const char *domain, const char *sitename, struct ip_service **ip_list, int *count, BOOL ads_only )
1664 {
1665         BOOL ordered;
1666         NTSTATUS status;
1667         enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
1668
1669         DEBUG(8,("get_sorted_dc_list: attempting lookup for name %s (sitename %s) "
1670                 "using [%s]\n",
1671                 domain,
1672                 sitename ? sitename : "NULL",
1673                 (ads_only ? "ads" : lp_name_resolve_order())));
1674         
1675         if (ads_only) {
1676                 lookup_type = DC_ADS_ONLY;
1677         }
1678
1679         status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered);
1680         if (!NT_STATUS_IS_OK(status)) {
1681                 return status; 
1682         }
1683                 
1684         /* only sort if we don't already have an ordered list */
1685         if ( !ordered ) {
1686                 sort_ip_list2( *ip_list, *count );
1687         }
1688                 
1689         return NT_STATUS_OK;
1690 }
1691
1692 /*********************************************************************
1693  Get the KDC list - re-use all the logic in get_dc_list.
1694 *********************************************************************/
1695
1696 NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_service **ip_list, int *count)
1697 {
1698         BOOL ordered;
1699         NTSTATUS status;
1700
1701         *count = 0;
1702         *ip_list = NULL;
1703
1704         status = get_dc_list(realm, sitename, ip_list, count, DC_KDC_ONLY, &ordered);
1705
1706         if (!NT_STATUS_IS_OK(status)) {
1707                 return status; 
1708         }
1709
1710         /* only sort if we don't already have an ordered list */
1711         if ( !ordered ) {
1712                 sort_ip_list2( *ip_list, *count );
1713         }
1714
1715         return NT_STATUS_OK;
1716 }