s3:libsmb/namequery.c: add saf_join_store() function
[Samba.git] / source / libsmb / namequery.c
blob112df1bc3058cd1aedccd5f5a6a8619dcda4376d
1 /*
2 Unix SMB/CIFS implementation.
3 name query routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2007.
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.
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.
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/>.
21 #include "includes.h"
23 /* nmbd.c sets this to True. */
24 bool global_in_nmbd = False;
26 /****************************
27 * SERVER AFFINITY ROUTINES *
28 ****************************/
30 /* Server affinity is the concept of preferring the last domain
31 controller with whom you had a successful conversation */
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
40 static char *saf_key(const char *domain)
42 char *keystr;
44 asprintf_strupper_m(&keystr, SAFKEY_FMT, domain);
46 return keystr;
49 static char *saf_join_key(const char *domain)
51 char *keystr;
53 asprintf_strupper_m(&keystr, SAFJOINKEY_FMT, domain);
55 return keystr;
58 /****************************************************************************
59 ****************************************************************************/
61 bool saf_store( const char *domain, const char *servername )
63 char *key;
64 time_t expire;
65 bool ret = False;
67 if ( !domain || !servername ) {
68 DEBUG(2,("saf_store: "
69 "Refusing to store empty domain or servername!\n"));
70 return False;
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;
79 if ( !gencache_init() )
80 return False;
82 key = saf_key( domain );
83 expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
85 DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
86 domain, servername, (unsigned int)expire ));
88 ret = gencache_set( key, servername, expire );
90 SAFE_FREE( key );
92 return ret;
95 bool saf_join_store( const char *domain, const char *servername )
97 char *key;
98 time_t expire;
99 bool ret = False;
101 if ( !domain || !servername ) {
102 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
103 return False;
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;
111 if ( !gencache_init() )
112 return False;
114 key = saf_join_key( domain );
115 expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
117 DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
118 domain, servername, (unsigned int)expire ));
120 ret = gencache_set( key, servername, expire );
122 SAFE_FREE( key );
124 return ret;
127 bool saf_delete( const char *domain )
129 char *key;
130 bool ret = False;
132 if ( !domain ) {
133 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
134 return False;
137 if ( !gencache_init() )
138 return False;
140 key = saf_join_key(domain);
141 ret = gencache_del(key);
142 SAFE_FREE(key);
144 if (ret) {
145 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain ));
148 key = saf_key(domain);
149 ret = gencache_del(key);
150 SAFE_FREE(key);
152 if (ret) {
153 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
156 return ret;
159 /****************************************************************************
160 ****************************************************************************/
162 char *saf_fetch( const char *domain )
164 char *server = NULL;
165 time_t timeout;
166 bool ret = False;
167 char *key = NULL;
169 if ( !domain || strlen(domain) == 0) {
170 DEBUG(2,("saf_fetch: Empty domain name!\n"));
171 return NULL;
174 if ( !gencache_init() )
175 return False;
177 key = saf_join_key( domain );
179 ret = gencache_get( key, &server, &timeout );
181 SAFE_FREE( key );
183 if ( ret ) {
184 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
185 server, domain ));
186 return server;
189 key = saf_key( domain );
191 ret = gencache_get( key, &server, &timeout );
193 SAFE_FREE( key );
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 ));
203 return server;
206 /****************************************************************************
207 Generate a random trn_id.
208 ****************************************************************************/
210 static int generate_trn_id(void)
212 uint16 id;
214 generate_random_buffer((uint8 *)&id, sizeof(id));
216 return id % (unsigned)0x7FFF;
219 /****************************************************************************
220 Parse a node status response into an array of structures.
221 ****************************************************************************/
223 static NODE_STATUS_STRUCT *parse_node_status(char *p,
224 int *num_names,
225 struct node_status_extra *extra)
227 NODE_STATUS_STRUCT *ret;
228 int i;
230 *num_names = CVAL(p,0);
232 if (*num_names == 0)
233 return NULL;
235 ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);
236 if (!ret)
237 return NULL;
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));
250 * Also, pick up the MAC address ...
252 if (extra) {
253 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
255 return ret;
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 **************************************************************************/
264 NODE_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)
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;
279 ZERO_STRUCT(p);
281 if (to_ss->ss_family != AF_INET) {
282 /* Can't do node status to IPv6 */
283 return NULL;
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;
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;
308 GetTimeOfDay(&tval);
310 if (!send_packet(&p))
311 return NULL;
313 retries--;
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--;
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);
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;
343 ret = parse_node_status(&nmb2->answers->rdata[0],
344 num_names, extra);
345 free_packet(p2);
346 return ret;
350 return NULL;
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 **************************************************************************/
358 bool name_status_find(const char *q_name,
359 int q_type,
360 int type,
361 const struct sockaddr_storage *to_ss,
362 fstring name)
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;
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;
378 print_sockaddr(addr, sizeof(addr), to_ss);
380 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
381 q_type, addr));
383 /* Check the cache first. */
385 if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
386 return True;
389 if (to_ss->ss_family != AF_INET) {
390 /* Can't do node status to IPv6 */
391 return false;
394 if (!interpret_string_addr(&ss, lp_socket_address(),
395 AI_NUMERICHOST|AI_PASSIVE)) {
396 zero_sockaddr(&ss);
399 sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True);
400 if (sock == -1)
401 goto done;
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;
410 for (i=0;i<count;i++) {
411 if (status[i].type == type)
412 break;
414 if (i == count)
415 goto done;
417 pull_ascii_nstring(name, sizeof(fstring), status[i].name);
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 */
423 if ( q_type != 0x1c ) {
424 namecache_status_store(q_name, q_type, type, to_ss, name);
427 result = true;
429 done:
430 SAFE_FREE(status);
432 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
434 if (result)
435 DEBUGADD(10, (", name %s ip address is %s", name, addr));
437 DEBUG(10, ("\n"));
439 return result;
443 comparison function used by sort_addr_list
446 static int addr_compare(const struct sockaddr_storage *ss1,
447 const struct sockaddr_storage *ss2)
449 int max_bits1=0, max_bits2=0;
450 int num_interfaces = iface_count();
451 int i;
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;
462 /* Here we know both addresses are of the same
463 * family. */
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;
473 if (pss->ss_family != ss1->ss_family) {
474 /* Ignore interfaces of the wrong type. */
475 continue;
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;
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;
496 #endif
497 if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
498 continue;
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);
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;
514 if (iface_local(ss2)) {
515 if (ss2->ss_family == AF_INET) {
516 max_bits2 += 32;
517 } else {
518 max_bits2 += 128;
521 return max_bits2 - max_bits1;
524 /*******************************************************************
525 compare 2 ldap IPs by nearness to our interfaces - used in qsort
526 *******************************************************************/
528 int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
530 int result;
532 if ((result = addr_compare(&ss1->ss, &ss2->ss)) != 0) {
533 return result;
536 if (ss1->port > ss2->port) {
537 return 1;
540 if (ss1->port < ss2->port) {
541 return -1;
544 return 0;
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
553 static void sort_addr_list(struct sockaddr_storage *sslist, int count)
555 if (count <= 1) {
556 return;
559 qsort(sslist, count, sizeof(struct sockaddr_storage),
560 QSORT_CAST addr_compare);
563 static void sort_service_list(struct ip_service *servlist, int count)
565 if (count <= 1) {
566 return;
569 qsort(servlist, count, sizeof(struct ip_service),
570 QSORT_CAST ip_service_compare);
573 /**********************************************************************
574 Remove any duplicate address/port pairs in the list
575 *********************************************************************/
577 static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
579 int i, j;
581 DEBUG(10,("remove_duplicate_addrs2: "
582 "looking for duplicate address/port pairs\n"));
584 /* one loop to remove duplicates */
585 for ( i=0; i<count; i++ ) {
586 if ( is_zero_addr(&iplist[i].ss)) {
587 continue;
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);
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]));
606 count--;
607 continue;
609 i++;
612 return count;
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 ****************************************************************************/
622 struct 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)
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;
641 if (lp_disable_netbios()) {
642 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
643 name, name_type));
644 return NULL;
647 if (to_ss->ss_family != AF_INET) {
648 return NULL;
651 if (timed_out) {
652 *timed_out = false;
655 memset((char *)&p,'\0',sizeof(p));
656 (*count) = 0;
657 (*flags) = 0;
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;
673 make_nmb_name(&nmb->question.question_name,name,name_type);
675 nmb->question.question_type = 0x20;
676 nmb->question.question_class = 0x1;
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;
684 GetTimeOfDay(&tval);
686 if (!send_packet(&p))
687 return NULL;
689 retries--;
691 while (1) {
692 struct timeval tval2;
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--;
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);
708 /* If we get a Negative Name Query Response from a WINS
709 * server, we should report it and give up.
711 if( 0 == nmb2->header.opcode /* A query response */
712 && !(bcast) /* from a WINS server */
713 && nmb2->header.rcode /* Error returned */
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;
748 free_packet(p2);
749 return( NULL );
752 if (nmb2->header.opcode != 0 ||
753 nmb2->header.nm_flags.bcast ||
754 nmb2->header.rcode ||
755 !nmb2->header.ancount) {
757 * XXXX what do we do with this? Could be a
758 * redirect, but we'll discard it for the
759 * moment.
761 free_packet(p2);
762 continue;
765 ss_list = SMB_REALLOC_ARRAY(ss_list,
766 struct sockaddr_storage,
767 (*count) +
768 nmb2->answers->rdlength/6);
770 if (!ss_list) {
771 DEBUG(0,("name_query: Realloc failed.\n"));
772 free_packet(p2);
773 return NULL;
776 DEBUG(2,("Got a positive name query response "
777 "from %s ( ",
778 inet_ntoa(p2->ip)));
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)++;
788 DEBUGADD(2,(")\n"));
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);
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.
811 if(!bcast && found)
812 break;
816 /* only set timed_out if we didn't fund what we where looking for*/
818 if ( !found && timed_out ) {
819 *timed_out = true;
822 /* sort the ip list so we choose close servers first if possible */
823 sort_addr_list(ss_list, *count);
825 return ss_list;
828 /********************************************************
829 Start parsing the lmhosts file.
830 *********************************************************/
832 XFILE *startlmhosts(const char *fname)
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;
841 return fp;
844 /********************************************************
845 Parse the next line in the lmhosts file.
846 *********************************************************/
848 bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type,
849 struct sockaddr_storage *pss)
851 char line[1024];
853 *pp_name = NULL;
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;
864 *name_type = -1;
866 if (!fgets_slash(line,sizeof(line),fp)) {
867 continue;
870 if (*line == '#') {
871 continue;
874 ptr = line;
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;
885 if (count <= 0)
886 continue;
888 if (count > 0 && count < 2) {
889 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",
890 line));
891 continue;
894 if (count >= 4) {
895 DEBUG(0,("getlmhostsent: too many columns "
896 "in lmhosts file (obsolete syntax)\n"));
897 continue;
900 if (!flags) {
901 flags = talloc_strdup(ctx, "");
902 if (!flags) {
903 continue;
907 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n",
908 ip, name, flags));
910 if (strchr_m(flags,'G') || strchr_m(flags,'S')) {
911 DEBUG(0,("getlmhostsent: group flag "
912 "in lmhosts ignored (obsolete)\n"));
913 continue;
916 if (!interpret_string_addr(pss, ip, AI_NUMERICHOST)) {
917 DEBUG(0,("getlmhostsent: invalid address "
918 "%s.\n", ip));
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++;
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;
934 *(--ptr1) = '\0'; /* Truncate at the '#' */
937 *pp_name = talloc_strdup(ctx, name);
938 if (!*pp_name) {
939 return false;
941 return true;
944 return false;
947 /********************************************************
948 Finish parsing the lmhosts file.
949 *********************************************************/
951 void endlmhosts(XFILE *fp)
953 x_fclose(fp);
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 *********************************************************/
961 static bool convert_ss2service(struct ip_service **return_iplist,
962 const struct sockaddr_storage *ss_list,
963 int count)
965 int i;
967 if ( count==0 || !ss_list )
968 return False;
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;
978 for ( i=0; i<count; i++ ) {
979 (*return_iplist)[i].ss = ss_list[i];
980 (*return_iplist)[i].port = PORT_NONE;
983 return true;
986 /********************************************************
987 Resolve via "bcast" method.
988 *********************************************************/
990 NTSTATUS name_resolve_bcast(const char *name,
991 int name_type,
992 struct ip_service **return_iplist,
993 int *return_count)
995 int sock, i;
996 int num_interfaces = iface_count();
997 struct sockaddr_storage *ss_list;
998 struct sockaddr_storage ss;
999 NTSTATUS status;
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;
1007 *return_iplist = NULL;
1008 *return_count = 0;
1011 * "bcast" means do a broadcast lookup on all the local interfaces.
1014 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
1015 "for name %s<0x%x>\n", name, name_type));
1017 if (!interpret_string_addr(&ss, lp_socket_address(),
1018 AI_NUMERICHOST|AI_PASSIVE)) {
1019 zero_sockaddr(&ss);
1022 sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );
1023 if (sock == -1) {
1024 return NT_STATUS_UNSUCCESSFUL;
1027 set_socket_options(sock,"SO_BROADCAST");
1029 * Lookup the name on all the interfaces, return on
1030 * the first successful match.
1032 for( i = num_interfaces-1; i >= 0; i--) {
1033 const struct sockaddr_storage *pss = iface_n_bcast(i);
1034 int flags;
1036 /* Done this way to fix compiler error on IRIX 5.x */
1037 if (!pss) {
1038 continue;
1040 ss_list = name_query(sock, name, name_type, true,
1041 true, pss, return_count, &flags, NULL);
1042 if (ss_list) {
1043 goto success;
1047 /* failed - no response */
1049 close(sock);
1050 return NT_STATUS_UNSUCCESSFUL;
1052 success:
1054 status = NT_STATUS_OK;
1055 if (!convert_ss2service(return_iplist, ss_list, *return_count) )
1056 status = NT_STATUS_INVALID_PARAMETER;
1058 SAFE_FREE(ss_list);
1059 close(sock);
1060 return status;
1063 /********************************************************
1064 Resolve via "wins" method.
1065 *********************************************************/
1067 NTSTATUS resolve_wins(const char *name,
1068 int name_type,
1069 struct ip_service **return_iplist,
1070 int *return_count)
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;
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;
1084 *return_iplist = NULL;
1085 *return_count = 0;
1087 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
1088 name, name_type));
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;
1096 /* we try a lookup on each of the WINS tags in turn */
1097 wins_tags = wins_srv_tags();
1099 if (!wins_tags) {
1100 /* huh? no tags?? give up in disgust */
1101 return NT_STATUS_INVALID_PARAMETER;
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);
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;
1120 src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr;
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;
1132 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
1134 if (global_in_nmbd && ismyip_v4(wins_ip)) {
1135 /* yikes! we'll loop forever */
1136 continue;
1139 /* skip any that have been unresponsive lately */
1140 if (wins_srv_is_dead(wins_ip, src_ip)) {
1141 continue;
1144 DEBUG(3,("resolve_wins: using WINS server %s "
1145 "and tag '%s'\n",
1146 inet_ntoa(wins_ip), wins_tags[t]));
1148 sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);
1149 if (sock == -1) {
1150 continue;
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);
1164 /* exit loop if we got a list of addresses */
1166 if (ss_list)
1167 goto success;
1169 close(sock);
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;
1184 wins_srv_tags_free(wins_tags);
1185 return NT_STATUS_NO_LOGON_SERVERS;
1187 success:
1189 status = NT_STATUS_OK;
1190 if (!convert_ss2service(return_iplist, ss_list, *return_count))
1191 status = NT_STATUS_INVALID_PARAMETER;
1193 SAFE_FREE(ss_list);
1194 wins_srv_tags_free(wins_tags);
1195 close(sock);
1197 return status;
1200 /********************************************************
1201 Resolve via "lmhosts" method.
1202 *********************************************************/
1204 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
1205 struct ip_service **return_iplist,
1206 int *return_count)
1209 * "lmhosts" means parse the local lmhosts file.
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;
1219 *return_iplist = NULL;
1220 *return_count = 0;
1222 DEBUG(3,("resolve_lmhosts: "
1223 "Attempting lmhosts lookup for name %s<0x%x>\n",
1224 name, name_type));
1226 fp = startlmhosts(get_dyn_LMHOSTSFILE());
1228 if ( fp == NULL )
1229 return NT_STATUS_NO_SUCH_FILE;
1231 ctx = talloc_init("resolve_lmhosts");
1232 if (!ctx) {
1233 endlmhosts(fp);
1234 return NT_STATUS_NO_MEMORY;
1237 while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) {
1239 if (!strequal(name, lmhost_name)) {
1240 TALLOC_FREE(lmhost_name);
1241 continue;
1244 if ((name_type2 != -1) && (name_type != name_type2)) {
1245 TALLOC_FREE(lmhost_name);
1246 continue;
1249 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist),
1250 struct ip_service,
1251 (*return_count)+1);
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;
1260 (*return_iplist)[*return_count].ss = return_ss;
1261 (*return_iplist)[*return_count].port = PORT_NONE;
1262 *return_count += 1;
1264 /* we found something */
1265 status = NT_STATUS_OK;
1267 /* Multiple names only for DC lookup */
1268 if (name_type != 0x1c)
1269 break;
1272 TALLOC_FREE(ctx);
1273 endlmhosts(fp);
1274 return status;
1278 /********************************************************
1279 Resolve via "hosts" method.
1280 *********************************************************/
1282 static NTSTATUS resolve_hosts(const char *name, int name_type,
1283 struct ip_service **return_iplist,
1284 int *return_count)
1287 * "host" means do a localhost, or dns lookup.
1289 struct addrinfo hints;
1290 struct addrinfo *ailist = NULL;
1291 struct addrinfo *res = NULL;
1292 int ret = -1;
1293 int i = 0;
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;
1302 *return_iplist = NULL;
1303 *return_count = 0;
1305 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
1306 name, name_type));
1308 ZERO_STRUCT(hints);
1309 /* By default make sure it supports TCP. */
1310 hints.ai_socktype = SOCK_STREAM;
1311 hints.ai_flags = AI_ADDRCONFIG;
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
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) ));
1328 for (res = ailist; res; res = res->ai_next) {
1329 struct sockaddr_storage ss;
1331 if (!res->ai_addr || res->ai_addrlen == 0) {
1332 continue;
1335 ZERO_STRUCT(ss);
1336 memcpy(&ss, res->ai_addr, res->ai_addrlen);
1338 *return_count += 1;
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;
1348 (*return_iplist)[i].ss = ss;
1349 (*return_iplist)[i].port = PORT_NONE;
1350 i++;
1352 if (ailist) {
1353 freeaddrinfo(ailist);
1355 if (*return_count) {
1356 return NT_STATUS_OK;
1358 return NT_STATUS_UNSUCCESSFUL;
1361 /********************************************************
1362 Resolve via "ADS" method.
1363 *********************************************************/
1365 static NTSTATUS resolve_ads(const char *name,
1366 int name_type,
1367 const char *sitename,
1368 struct ip_service **return_iplist,
1369 int *return_count)
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;
1378 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
1379 (name_type != 0x1b)) {
1380 return NT_STATUS_INVALID_PARAMETER;
1383 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1384 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1385 return NT_STATUS_NO_MEMORY;
1388 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
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;
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;
1414 if ( !NT_STATUS_IS_OK( status ) ) {
1415 talloc_destroy(ctx);
1416 return status;
1419 for (i=0;i<numdcs;i++) {
1420 numaddrs += MAX(dcs[i].num_ips,1);
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;
1431 /* now unroll the list of IP addresses */
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];
1439 r->port = dcs[i].port;
1441 /* If we don't have an IP list for a name, lookup it up */
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 */
1450 if ( j >= dcs[i].num_ips ) {
1451 i++;
1452 j = 0;
1453 continue;
1456 r->ss = dcs[i].ss_s[j];
1457 j++;
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 */
1468 if (!is_zero_addr(&r->ss)) {
1469 (*return_count)++;
1473 talloc_destroy(ctx);
1474 return NT_STATUS_OK;
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.
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 **********************************************************************/
1488 NTSTATUS 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)
1495 char *tok;
1496 const char *ptr;
1497 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1498 int i;
1499 TALLOC_CTX *frame = NULL;
1501 *return_iplist = NULL;
1502 *return_count = 0;
1504 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1505 name, name_type, sitename ? sitename : NULL));
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;
1514 /* ignore the port here */
1515 (*return_iplist)->port = PORT_NONE;
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;
1526 *return_count = 1;
1527 return NT_STATUS_OK;
1530 /* Check name cache */
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;
1541 /* set the name resolution order */
1543 if (strcmp( resolve_order, "NULL") == 0) {
1544 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1545 return NT_STATUS_INVALID_PARAMETER;
1548 if (!resolve_order[0]) {
1549 ptr = "host";
1550 } else {
1551 ptr = resolve_order;
1554 /* iterate through the name resolution backends */
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;
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;
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;
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;
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;
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;
1606 } else {
1607 DEBUG(0,("resolve_name: unknown name switch type %s\n",
1608 tok));
1612 /* All of the resolve_* functions above have returned false. */
1614 TALLOC_FREE(frame);
1615 SAFE_FREE(*return_iplist);
1616 *return_count = 0;
1618 return NT_STATUS_UNSUCCESSFUL;
1620 done:
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. */
1627 if ( *return_count ) {
1628 *return_count = remove_duplicate_addrs2(*return_iplist,
1629 *return_count );
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));
1646 namecache_store(name, name_type, *return_count, *return_iplist);
1648 /* Display some debugging info */
1650 if ( DEBUGLEVEL >= 10 ) {
1651 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
1652 *return_count));
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));
1662 DEBUG(10, ("\n"));
1665 TALLOC_FREE(frame);
1666 return status;
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 *********************************************************/
1676 bool resolve_name(const char *name,
1677 struct sockaddr_storage *return_ss,
1678 int name_type)
1680 struct ip_service *ss_list = NULL;
1681 char *sitename = NULL;
1682 int count = 0;
1684 if (is_ipaddress(name)) {
1685 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
1688 sitename = sitename_fetch(lp_realm()); /* wild guess */
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;
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;
1707 SAFE_FREE(ss_list);
1708 SAFE_FREE(sitename);
1709 return False;
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 *********************************************************/
1719 NTSTATUS 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)
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;
1732 *p_num_entries = 0;
1733 *return_ss_arr = NULL;
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;
1740 if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
1741 TALLOC_FREE(*return_ss_arr);
1742 return NT_STATUS_BAD_NETWORK_NAME;
1744 *p_num_entries = 1;
1745 return NT_STATUS_OK;
1748 sitename = sitename_fetch(lp_realm()); /* wild guess */
1750 status = internal_resolve_name(name, name_type, sitename,
1751 &ss_list, &count,
1752 lp_name_resolve_order());
1753 SAFE_FREE(sitename);
1755 if (!NT_STATUS_IS_OK(status)) {
1756 return status;
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++;
1766 if (num_entries == 0) {
1767 SAFE_FREE(ss_list);
1768 return NT_STATUS_BAD_NETWORK_NAME;
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;
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;
1786 status = NT_STATUS_OK;
1787 *p_num_entries = num_entries;
1789 SAFE_FREE(ss_list);
1790 return NT_STATUS_OK;
1793 /********************************************************
1794 Find the IP address of the master browser or DMB for a workgroup.
1795 *********************************************************/
1797 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
1799 struct ip_service *ip_list = NULL;
1800 int count = 0;
1801 NTSTATUS status;
1803 if (lp_disable_netbios()) {
1804 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1805 return false;
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;
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;
1824 SAFE_FREE(ip_list);
1825 return false;
1828 /********************************************************
1829 Get the IP address list of the primary domain controller
1830 for a domain.
1831 *********************************************************/
1833 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
1835 struct ip_service *ip_list = NULL;
1836 int count = 0;
1837 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1839 /* Look up #1B name */
1841 if (lp_security() == SEC_ADS) {
1842 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1843 &count, "ads");
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;
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 */
1858 if ( count > 1 ) {
1859 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1860 sort_service_list(ip_list, count);
1863 *pss = ip_list[0].ss;
1864 SAFE_FREE(ip_list);
1865 return true;
1868 /* Private enum type for lookups. */
1870 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
1872 /********************************************************
1873 Get the IP address list of the domain controllers for
1874 a domain.
1875 *********************************************************/
1877 static 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)
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");
1900 *ip_list = NULL;
1901 *count = 0;
1903 if (!ctx) {
1904 return NT_STATUS_NO_MEMORY;
1907 *ordered = False;
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. */
1915 resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
1916 if (!resolve_order) {
1917 status = NT_STATUS_NO_MEMORY;
1918 goto out;
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");
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");
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");
1937 if (!resolve_order) {
1938 status = NT_STATUS_NO_MEMORY;
1939 goto out;
1942 /* fetch the server we have affinity for. Add the
1943 'password server' list to a search for our domain controllers */
1945 saf_servername = saf_fetch( domain);
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 : "");
1956 SAFE_FREE(saf_servername);
1957 if (!pserver) {
1958 status = NT_STATUS_NO_MEMORY;
1959 goto out;
1962 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
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;
1971 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
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
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;
1990 done_auto_lookup = true;
1991 DEBUG(8,("Adding %d DC's from auto lookup\n",
1992 auto_count));
1993 } else {
1994 num_addresses++;
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. */
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;
2007 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
2008 count, resolve_order);
2009 goto out;
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;
2019 p = pserver;
2020 local_count = 0;
2022 /* fill in the return list now with real IP's */
2024 while ((local_count<num_addresses) &&
2025 next_token_talloc(ctx, &p, &name, LIST_SEP)) {
2026 struct sockaddr_storage name_ss;
2028 /* copy any addersses from the auto lookup */
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;
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++;
2053 continue;
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 */
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);
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);
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;
2085 return_iplist[local_count].ss = name_ss;
2086 return_iplist[local_count].port = port;
2087 local_count++;
2088 *ordered = true;
2092 /* need to remove duplicates in the list if we have any
2093 explicit password servers */
2095 if (local_count) {
2096 local_count = remove_duplicate_addrs2(return_iplist,
2097 local_count );
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 ));
2113 DEBUGADD(4,("\n"));
2116 *ip_list = return_iplist;
2117 *count = local_count;
2119 status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
2121 out:
2123 if (!NT_STATUS_IS_OK(status)) {
2124 SAFE_FREE(return_iplist);
2125 *ip_list = NULL;
2126 *count = 0;
2129 SAFE_FREE(auto_ip_list);
2130 TALLOC_FREE(ctx);
2131 return status;
2134 /*********************************************************************
2135 Small wrapper function to get the DC list and sort it if neccessary.
2136 *********************************************************************/
2138 NTSTATUS get_sorted_dc_list( const char *domain,
2139 const char *sitename,
2140 struct ip_service **ip_list,
2141 int *count,
2142 bool ads_only )
2144 bool ordered;
2145 NTSTATUS status;
2146 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
2148 *ip_list = NULL;
2149 *count = 0;
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())));
2157 if (ads_only) {
2158 lookup_type = DC_ADS_ONLY;
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);
2172 if (!NT_STATUS_IS_OK(status)) {
2173 SAFE_FREE(*ip_list);
2174 *count = 0;
2175 return status;
2178 /* only sort if we don't already have an ordered list */
2179 if (!ordered) {
2180 sort_service_list(*ip_list, *count);
2183 return NT_STATUS_OK;
2186 /*********************************************************************
2187 Get the KDC list - re-use all the logic in get_dc_list.
2188 *********************************************************************/
2190 NTSTATUS get_kdc_list( const char *realm,
2191 const char *sitename,
2192 struct ip_service **ip_list,
2193 int *count)
2195 bool ordered;
2196 NTSTATUS status;
2198 *count = 0;
2199 *ip_list = NULL;
2201 status = get_dc_list(realm, sitename, ip_list,
2202 count, DC_KDC_ONLY, &ordered);
2204 if (!NT_STATUS_IS_OK(status)) {
2205 SAFE_FREE(*ip_list);
2206 *count = 0;
2207 return status;
2210 /* only sort if we don't already have an ordered list */
2211 if ( !ordered ) {
2212 sort_service_list(*ip_list, *count);
2215 return NT_STATUS_OK;