r24737: Remove older TODO: Convert internal_resolve_name() and friends to NTSTATUS.
[nivanova/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 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                 return NT_STATUS_INVALID_PARAMETER;
1064         }
1065
1066         if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1067                 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1068                 return NT_STATUS_NO_MEMORY;
1069         }
1070
1071         switch (name_type) {
1072                 case 0x1c:
1073                         DEBUG(5,("resolve_ads: Attempting to resolve "
1074                                  "DCs for %s using DNS\n", name));
1075                         status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
1076                                                    &numdcs);
1077                         break;
1078                 case KDC_NAME_TYPE:
1079                         DEBUG(5,("resolve_ads: Attempting to resolve "
1080                                  "KDCs for %s using DNS\n", name));
1081                         status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
1082                                                     &numdcs);
1083                         break;
1084                 default:
1085                         status = NT_STATUS_INVALID_PARAMETER;
1086                         break;
1087         }
1088
1089         if ( !NT_STATUS_IS_OK( status ) ) {
1090                 talloc_destroy(ctx);
1091                 return status;
1092         }
1093
1094         for (i=0;i<numdcs;i++) {
1095                 numaddrs += MAX(dcs[i].num_ips,1);
1096         }
1097                 
1098         if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
1099                 DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
1100                 talloc_destroy(ctx);
1101                 return NT_STATUS_NO_MEMORY;
1102         }
1103         
1104         /* now unroll the list of IP addresses */
1105
1106         *return_count = 0;
1107         i = 0;
1108         j = 0;
1109         while ( i < numdcs && (*return_count<numaddrs) ) {
1110                 struct ip_service *r = &(*return_iplist)[*return_count];
1111
1112                 r->port = dcs[i].port;
1113                 
1114                 /* If we don't have an IP list for a name, lookup it up */
1115                 
1116                 if ( !dcs[i].ips ) {
1117                         r->ip = *interpret_addr2(dcs[i].hostname);
1118                         i++;
1119                         j = 0;
1120                 } else {
1121                         /* use the IP addresses from the SRV sresponse */
1122                         
1123                         if ( j >= dcs[i].num_ips ) {
1124                                 i++;
1125                                 j = 0;
1126                                 continue;
1127                         }
1128                         
1129                         r->ip = dcs[i].ips[j];
1130                         j++;
1131                 }
1132                         
1133                 /* make sure it is a valid IP.  I considered checking the negative
1134                    connection cache, but this is the wrong place for it.  Maybe only
1135                    as a hac.  After think about it, if all of the IP addresses retuend
1136                    from DNS are dead, what hope does a netbios name lookup have?
1137                    The standard reason for falling back to netbios lookups is that 
1138                    our DNS server doesn't know anything about the DC's   -- jerry */    
1139                            
1140                 if ( ! is_zero_ip(r->ip) )
1141                         (*return_count)++;
1142         }
1143                 
1144         talloc_destroy(ctx);
1145         return NT_STATUS_OK;
1146 }
1147
1148 /*******************************************************************
1149  Internal interface to resolve a name into an IP address.
1150  Use this function if the string is either an IP address, DNS
1151  or host name or NetBIOS name. This uses the name switch in the
1152  smb.conf to determine the order of name resolution.
1153  
1154  Added support for ip addr/port to support ADS ldap servers.
1155  the only place we currently care about the port is in the 
1156  resolve_hosts() when looking up DC's via SRV RR entries in DNS
1157 **********************************************************************/
1158
1159 NTSTATUS internal_resolve_name(const char *name, int name_type,
1160                                const char *sitename,
1161                                struct ip_service **return_iplist,
1162                                int *return_count, const char *resolve_order)
1163 {
1164         pstring name_resolve_list;
1165         fstring tok;
1166         const char *ptr;
1167         BOOL allones = (strcmp(name,"255.255.255.255") == 0);
1168         BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
1169         BOOL is_address = is_ipaddress(name);
1170         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1171         int i;
1172
1173         *return_iplist = NULL;
1174         *return_count = 0;
1175
1176         DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1177                         name, name_type, sitename ? sitename : NULL));
1178
1179         if (allzeros || allones || is_address) {
1180   
1181                 if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) {
1182                         DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1183                         return NT_STATUS_NO_MEMORY;
1184                 }
1185         
1186                 if(is_address) { 
1187                         /* ignore the port here */
1188                         (*return_iplist)->port = PORT_NONE;
1189                 
1190                         /* if it's in the form of an IP address then get the lib to interpret it */
1191                         if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
1192                                 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
1193                                 SAFE_FREE(*return_iplist);
1194                                 return NT_STATUS_INVALID_PARAMETER;
1195                         }
1196                 } else {
1197                         (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
1198                 }
1199                 *return_count = 1;
1200                 return NT_STATUS_OK;
1201         }
1202   
1203         /* Check name cache */
1204
1205         if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1206                 /* This could be a negative response */
1207                 if (*return_count > 0) {
1208                         return NT_STATUS_OK;
1209                 } else {
1210                         return NT_STATUS_UNSUCCESSFUL;
1211                 }
1212         }
1213
1214         /* set the name resolution order */
1215
1216         if ( strcmp( resolve_order, "NULL") == 0 ) {
1217                 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1218                 return NT_STATUS_INVALID_PARAMETER;
1219         }
1220   
1221         if ( !resolve_order ) {
1222                 pstrcpy(name_resolve_list, lp_name_resolve_order());
1223         } else {
1224                 pstrcpy(name_resolve_list, resolve_order);
1225         }
1226
1227         if ( !name_resolve_list[0] ) {
1228                 ptr = "host";
1229         } else {
1230                 ptr = name_resolve_list;
1231         }
1232
1233         /* iterate through the name resolution backends */
1234   
1235         while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
1236                 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1237                         status = resolve_hosts(name, name_type, return_iplist,
1238                                                return_count);
1239                         if (NT_STATUS_IS_OK(status)) {
1240                                 goto done;
1241                         }
1242                 } else if(strequal( tok, "kdc")) {
1243                         /* deal with KDC_NAME_TYPE names here.  This will result in a
1244                                 SRV record lookup */
1245                         status = resolve_ads(name, KDC_NAME_TYPE, sitename,
1246                                              return_iplist, return_count);
1247                         if (NT_STATUS_IS_OK(status)) {
1248                                 /* Ensure we don't namecache this with the KDC port. */
1249                                 name_type = KDC_NAME_TYPE;
1250                                 goto done;
1251                         }
1252                 } else if(strequal( tok, "ads")) {
1253                         /* deal with 0x1c and 0x1b names here.  This will result in a
1254                                 SRV record lookup */
1255                         status = resolve_ads(name, name_type, sitename,
1256                                              return_iplist, return_count);
1257                         if (NT_STATUS_IS_OK(status)) {
1258                                 goto done;
1259                         }
1260                 } else if(strequal( tok, "lmhosts")) {
1261                         status = resolve_lmhosts(name, name_type,
1262                                                  return_iplist, return_count);
1263                         if (NT_STATUS_IS_OK(status)) {
1264                                 goto done;
1265                         }
1266                 } else if(strequal( tok, "wins")) {
1267                         /* don't resolve 1D via WINS */
1268                         if (name_type != 0x1D) {
1269                                 status = resolve_wins(name, name_type,
1270                                                       return_iplist,
1271                                                       return_count);
1272                                 if (NT_STATUS_IS_OK(status)) {
1273                                         goto done;
1274                                 }
1275                         }
1276                 } else if(strequal( tok, "bcast")) {
1277                         status = name_resolve_bcast(name, name_type,
1278                                                     return_iplist,
1279                                                     return_count);
1280                         if (NT_STATUS_IS_OK(status)) {
1281                                 goto done;
1282                         }
1283                 } else {
1284                         DEBUG(0,("resolve_name: unknown name switch type %s\n",
1285                                 tok));
1286                 }
1287         }
1288
1289         /* All of the resolve_* functions above have returned false. */
1290
1291         SAFE_FREE(*return_iplist);
1292         *return_count = 0;
1293
1294         return NT_STATUS_UNSUCCESSFUL;
1295
1296   done:
1297
1298         /* Remove duplicate entries.  Some queries, notably #1c (domain
1299         controllers) return the PDC in iplist[0] and then all domain
1300         controllers including the PDC in iplist[1..n].  Iterating over
1301         the iplist when the PDC is down will cause two sets of timeouts. */
1302
1303         if ( *return_count ) {
1304                 *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
1305         }
1306  
1307         /* Save in name cache */
1308         if ( DEBUGLEVEL >= 100 ) {
1309                 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
1310                         DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
1311                                 name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1312         }
1313    
1314         namecache_store(name, name_type, *return_count, *return_iplist);
1315
1316         /* Display some debugging info */
1317
1318         if ( DEBUGLEVEL >= 10 ) {
1319                 DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
1320
1321                 for (i = 0; i < *return_count; i++) {
1322                         DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1323                 }
1324                 DEBUG(10, ("\n"));
1325         }
1326   
1327         return status;
1328 }
1329
1330 /********************************************************
1331  Internal interface to resolve a name into one IP address.
1332  Use this function if the string is either an IP address, DNS
1333  or host name or NetBIOS name. This uses the name switch in the
1334  smb.conf to determine the order of name resolution.
1335 *********************************************************/
1336
1337 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
1338 {
1339         struct ip_service *ip_list = NULL;
1340         char *sitename = sitename_fetch(lp_realm()); /* wild guess */
1341         int count = 0;
1342
1343         if (is_ipaddress(name)) {
1344                 *return_ip = *interpret_addr2(name);
1345                 SAFE_FREE(sitename);
1346                 return True;
1347         }
1348
1349         if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
1350                                                   &ip_list, &count,
1351                                                   lp_name_resolve_order()))) {
1352                 int i;
1353                 
1354                 /* only return valid addresses for TCP connections */
1355                 for (i=0; i<count; i++) {
1356                         char *ip_str = inet_ntoa(ip_list[i].ip);
1357                         if (ip_str &&
1358                             strcmp(ip_str, "255.255.255.255") != 0 &&
1359                             strcmp(ip_str, "0.0.0.0") != 0) 
1360                         {
1361                                 *return_ip = ip_list[i].ip;
1362                                 SAFE_FREE(ip_list);
1363                                 SAFE_FREE(sitename);
1364                                 return True;
1365                         }
1366                 }
1367         }
1368         
1369         SAFE_FREE(ip_list);
1370         SAFE_FREE(sitename);
1371         return False;
1372 }
1373
1374 /********************************************************
1375  Find the IP address of the master browser or DMB for a workgroup.
1376 *********************************************************/
1377
1378 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
1379 {
1380         struct ip_service *ip_list = NULL;
1381         int count = 0;
1382         NTSTATUS status;
1383
1384         if (lp_disable_netbios()) {
1385                 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1386                 return False;
1387         }
1388
1389         status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
1390                                        lp_name_resolve_order());
1391         if (NT_STATUS_IS_OK(status)) {
1392                 *master_ip = ip_list[0].ip;
1393                 SAFE_FREE(ip_list);
1394                 return True;
1395         }
1396
1397         status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
1398                                        lp_name_resolve_order());
1399         if (NT_STATUS_IS_OK(status)) {
1400                 *master_ip = ip_list[0].ip;
1401                 SAFE_FREE(ip_list);
1402                 return True;
1403         }
1404
1405         SAFE_FREE(ip_list);
1406         return False;
1407 }
1408
1409 /********************************************************
1410  Get the IP address list of the primary domain controller
1411  for a domain.
1412 *********************************************************/
1413
1414 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1415 {
1416         struct ip_service *ip_list = NULL;
1417         int count = 0;
1418         NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1419
1420         /* Look up #1B name */
1421
1422         status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1423                                        &count,
1424                                        lp_name_resolve_order());
1425         if (!NT_STATUS_IS_OK(status)) {
1426                 return False;
1427         }
1428
1429         /* if we get more than 1 IP back we have to assume it is a
1430            multi-homed PDC and not a mess up */
1431
1432         if ( count > 1 ) {
1433                 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));             
1434                 sort_ip_list2( ip_list, count );
1435         }
1436
1437         *ip = ip_list[0].ip;
1438         
1439         SAFE_FREE(ip_list);
1440
1441         return True;
1442 }
1443
1444 /* Private enum type for lookups. */
1445
1446 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
1447
1448 /********************************************************
1449  Get the IP address list of the domain controllers for
1450  a domain.
1451 *********************************************************/
1452
1453 static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_service **ip_list, 
1454                             int *count, enum dc_lookup_type lookup_type, int *ordered)
1455 {
1456         fstring resolve_order;
1457         char *saf_servername;
1458         pstring pserver;
1459         const char *p;
1460         char *port_str;
1461         int port;
1462         fstring name;
1463         int num_addresses = 0;
1464         int  local_count, i, j;
1465         struct ip_service *return_iplist = NULL;
1466         struct ip_service *auto_ip_list = NULL;
1467         BOOL done_auto_lookup = False;
1468         int auto_count = 0;
1469         NTSTATUS status;
1470
1471         *ordered = False;
1472
1473         /* if we are restricted to solely using DNS for looking
1474            up a domain controller, make sure that host lookups
1475            are enabled for the 'name resolve order'.  If host lookups
1476            are disabled and ads_only is True, then set the string to
1477            NULL. */
1478
1479         fstrcpy( resolve_order, lp_name_resolve_order() );
1480         strlower_m( resolve_order );
1481         if ( lookup_type == DC_ADS_ONLY)  {
1482                 if ( strstr( resolve_order, "host" ) ) {
1483                         fstrcpy( resolve_order, "ads" );
1484
1485                         /* DNS SRV lookups used by the ads resolver
1486                            are already sorted by priority and weight */
1487                         *ordered = True;
1488                 } else {
1489                         fstrcpy( resolve_order, "NULL" );
1490                 }
1491         } else if (lookup_type == DC_KDC_ONLY) {
1492                 /* DNS SRV lookups used by the ads/kdc resolver
1493                    are already sorted by priority and weight */
1494                 *ordered = True;
1495                 fstrcpy( resolve_order, "kdc" );
1496         }
1497
1498         /* fetch the server we have affinity for.  Add the 
1499            'password server' list to a search for our domain controllers */
1500         
1501         saf_servername = saf_fetch( domain);
1502         
1503         if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
1504                 pstr_sprintf( pserver, "%s, %s", 
1505                         saf_servername ? saf_servername : "",
1506                         lp_passwordserver() );
1507         } else {
1508                 pstr_sprintf( pserver, "%s, *", 
1509                         saf_servername ? saf_servername : "" );
1510         }
1511
1512         SAFE_FREE( saf_servername );
1513
1514         /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1515
1516         if ( !*pserver ) {
1517                 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1518                 return internal_resolve_name(domain, 0x1C, sitename, ip_list,
1519                                              count, resolve_order);
1520         }
1521
1522         DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1523         
1524         /*
1525          * if '*' appears in the "password server" list then add
1526          * an auto lookup to the list of manually configured
1527          * DC's.  If any DC is listed by name, then the list should be 
1528          * considered to be ordered 
1529          */
1530
1531         p = pserver;
1532         while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1533                 if (strequal(name, "*")) {
1534                         status = internal_resolve_name(domain, 0x1C, sitename,
1535                                                        &auto_ip_list,
1536                                                        &auto_count,
1537                                                        resolve_order);
1538                         if (NT_STATUS_IS_OK(status)) {
1539                                 num_addresses += auto_count;
1540                         }
1541                         done_auto_lookup = True;
1542                         DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1543                 } else  {
1544                         num_addresses++;
1545                 }
1546         }
1547
1548         /* if we have no addresses and haven't done the auto lookup, then
1549            just return the list of DC's.  Or maybe we just failed. */
1550                    
1551         if ( (num_addresses == 0) ) {
1552                 if ( done_auto_lookup ) {
1553                         DEBUG(4,("get_dc_list: no servers found\n")); 
1554                         SAFE_FREE(auto_ip_list);
1555                         return NT_STATUS_NO_LOGON_SERVERS;
1556                 }
1557                 return internal_resolve_name(domain, 0x1C, sitename, ip_list,
1558                                              count, resolve_order);
1559         }
1560
1561         if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
1562                 DEBUG(3,("get_dc_list: malloc fail !\n"));
1563                 SAFE_FREE(auto_ip_list);
1564                 return NT_STATUS_NO_MEMORY;
1565         }
1566
1567         p = pserver;
1568         local_count = 0;
1569
1570         /* fill in the return list now with real IP's */
1571                                 
1572         while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1573                 struct in_addr name_ip;
1574                         
1575                 /* copy any addersses from the auto lookup */
1576                         
1577                 if ( strequal(name, "*") ) {
1578                         for ( j=0; j<auto_count; j++ ) {
1579                                 /* Check for and don't copy any known bad DC IP's. */
1580                                 if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain, 
1581                                                 inet_ntoa(auto_ip_list[j].ip)))) {
1582                                         DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
1583                                                 inet_ntoa(auto_ip_list[j].ip) ));
1584                                         continue;
1585                                 }
1586                                 return_iplist[local_count].ip   = auto_ip_list[j].ip;
1587                                 return_iplist[local_count].port = auto_ip_list[j].port;
1588                                 local_count++;
1589                         }
1590                         continue;
1591                 }
1592                         
1593                         
1594                 /* added support for address:port syntax for ads (not that I think 
1595                    anyone will ever run the LDAP server in an AD domain on something 
1596                    other than port 389 */
1597                         
1598                 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1599                 if ( (port_str=strchr(name, ':')) != NULL ) {
1600                         *port_str = '\0';
1601                         port_str++;
1602                         port = atoi( port_str );
1603                 }
1604
1605                 /* explicit lookup; resolve_name() will handle names & IP addresses */
1606                 if ( resolve_name( name, &name_ip, 0x20 ) ) {
1607
1608                         /* Check for and don't copy any known bad DC IP's. */
1609                         if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
1610                                 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
1611                                 continue;
1612                         }
1613
1614                         return_iplist[local_count].ip   = name_ip;
1615                         return_iplist[local_count].port = port;
1616                         local_count++;
1617                         *ordered = True;
1618                 }
1619         }
1620                                 
1621         SAFE_FREE(auto_ip_list);
1622
1623         /* need to remove duplicates in the list if we have any 
1624            explicit password servers */
1625            
1626         if ( local_count ) {
1627                 local_count = remove_duplicate_addrs2( return_iplist, local_count );
1628         }
1629                 
1630         if ( DEBUGLEVEL >= 4 ) {
1631                 DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, 
1632                         *ordered ? "":"un"));
1633                 DEBUG(4,("get_dc_list: "));
1634                 for ( i=0; i<local_count; i++ )
1635                         DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
1636                 DEBUGADD(4,("\n"));
1637         }
1638                         
1639         *ip_list = return_iplist;
1640         *count = local_count;
1641
1642         return ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
1643 }
1644
1645 /*********************************************************************
1646  Small wrapper function to get the DC list and sort it if neccessary.
1647 *********************************************************************/
1648
1649 NTSTATUS get_sorted_dc_list( const char *domain, const char *sitename, struct ip_service **ip_list, int *count, BOOL ads_only )
1650 {
1651         BOOL ordered;
1652         NTSTATUS status;
1653         enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
1654
1655         DEBUG(8,("get_sorted_dc_list: attempting lookup for name %s (sitename %s) "
1656                 "using [%s]\n",
1657                 domain,
1658                 sitename ? sitename : "NULL",
1659                 (ads_only ? "ads" : lp_name_resolve_order())));
1660         
1661         if (ads_only) {
1662                 lookup_type = DC_ADS_ONLY;
1663         }
1664
1665         status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered);
1666         if (!NT_STATUS_IS_OK(status)) {
1667                 return status; 
1668         }
1669                 
1670         /* only sort if we don't already have an ordered list */
1671         if ( !ordered ) {
1672                 sort_ip_list2( *ip_list, *count );
1673         }
1674                 
1675         return NT_STATUS_OK;
1676 }
1677
1678 /*********************************************************************
1679  Get the KDC list - re-use all the logic in get_dc_list.
1680 *********************************************************************/
1681
1682 NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_service **ip_list, int *count)
1683 {
1684         BOOL ordered;
1685         NTSTATUS status;
1686
1687         *count = 0;
1688         *ip_list = NULL;
1689
1690         status = get_dc_list(realm, sitename, ip_list, count, DC_KDC_ONLY, &ordered);
1691
1692         if (!NT_STATUS_IS_OK(status)) {
1693                 return status; 
1694         }
1695
1696         /* only sort if we don't already have an ordered list */
1697         if ( !ordered ) {
1698                 sort_ip_list2( *ip_list, *count );
1699         }
1700
1701         return NT_STATUS_OK;
1702 }