source: branches/samba-3.3.x/source/libsmb/namequery.c@ 221

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

Update Samba 3.3 to 3.3.1

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