source: branches/samba-3.2.x/source/libsmb/namequery.c@ 201

Last change on this file since 201 was 138, checked in by Paul Smedley, 17 years ago

Update source to 3.2.0 GA level

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