source: branches/samba-3.0/source/libsmb/namequery.c@ 734

Last change on this file since 734 was 312, checked in by Herwig Bauernfeind, 16 years ago

Update 3.0 to final 3.0.36 (source)

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