Fixes to linker flags for AIX winbind client from Stephen Roylance.
[Samba/gebeck_regimport.git] / source3 / libsmb / namequery.c
blob18ce5e4bd9b3ea1e74c2f579b55df522e324deef
1 /*
2 Unix SMB/CIFS implementation.
3 name query routines
4 Copyright (C) Andrew Tridgell 1994-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 /* nmbd.c sets this to True. */
25 BOOL global_in_nmbd = False;
27 /****************************************************************************
28 generate a random trn_id
29 ****************************************************************************/
30 static int generate_trn_id(void)
32 static int trn_id;
34 if (trn_id == 0) {
35 sys_srandom(sys_getpid());
38 trn_id = sys_random();
40 return trn_id % (unsigned)0x7FFF;
44 /****************************************************************************
45 parse a node status response into an array of structures
46 ****************************************************************************/
47 static struct node_status *parse_node_status(char *p, int *num_names)
49 struct node_status *ret;
50 int i;
52 *num_names = CVAL(p,0);
54 if (*num_names == 0) return NULL;
56 ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names));
57 if (!ret) return NULL;
59 p++;
60 for (i=0;i< *num_names;i++) {
61 StrnCpy(ret[i].name,p,15);
62 trim_string(ret[i].name,NULL," ");
63 ret[i].type = CVAL(p,15);
64 ret[i].flags = p[16];
65 p += 18;
66 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
67 ret[i].type, ret[i].flags));
69 return ret;
73 /****************************************************************************
74 do a NBT node status query on an open socket and return an array of
75 structures holding the returned names or NULL if the query failed
76 **************************************************************************/
77 struct node_status *node_status_query(int fd,struct nmb_name *name,
78 struct in_addr to_ip, int *num_names)
80 BOOL found=False;
81 int retries = 2;
82 int retry_time = 2000;
83 struct timeval tval;
84 struct packet_struct p;
85 struct packet_struct *p2;
86 struct nmb_packet *nmb = &p.packet.nmb;
87 struct node_status *ret;
89 ZERO_STRUCT(p);
91 nmb->header.name_trn_id = generate_trn_id();
92 nmb->header.opcode = 0;
93 nmb->header.response = False;
94 nmb->header.nm_flags.bcast = False;
95 nmb->header.nm_flags.recursion_available = False;
96 nmb->header.nm_flags.recursion_desired = False;
97 nmb->header.nm_flags.trunc = False;
98 nmb->header.nm_flags.authoritative = False;
99 nmb->header.rcode = 0;
100 nmb->header.qdcount = 1;
101 nmb->header.ancount = 0;
102 nmb->header.nscount = 0;
103 nmb->header.arcount = 0;
104 nmb->question.question_name = *name;
105 nmb->question.question_type = 0x21;
106 nmb->question.question_class = 0x1;
108 p.ip = to_ip;
109 p.port = NMB_PORT;
110 p.fd = fd;
111 p.timestamp = time(NULL);
112 p.packet_type = NMB_PACKET;
114 GetTimeOfDay(&tval);
116 if (!send_packet(&p))
117 return NULL;
119 retries--;
121 while (1) {
122 struct timeval tval2;
123 GetTimeOfDay(&tval2);
124 if (TvalDiff(&tval,&tval2) > retry_time) {
125 if (!retries)
126 break;
127 if (!found && !send_packet(&p))
128 return NULL;
129 GetTimeOfDay(&tval);
130 retries--;
133 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
134 struct nmb_packet *nmb2 = &p2->packet.nmb;
135 debug_nmb_packet(p2);
137 if (nmb2->header.opcode != 0 ||
138 nmb2->header.nm_flags.bcast ||
139 nmb2->header.rcode ||
140 !nmb2->header.ancount ||
141 nmb2->answers->rr_type != 0x21) {
142 /* XXXX what do we do with this? could be a
143 redirect, but we'll discard it for the
144 moment */
145 free_packet(p2);
146 continue;
149 ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
150 free_packet(p2);
151 return ret;
155 return NULL;
159 /****************************************************************************
160 find the first type XX name in a node status reply - used for finding
161 a servers name given its IP
162 return the matched name in *name
163 **************************************************************************/
165 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name)
167 struct node_status *status = NULL;
168 struct nmb_name nname;
169 int count, i;
170 int sock;
171 BOOL result = False;
173 if (lp_disable_netbios()) {
174 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
175 return False;
178 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
179 q_type, inet_ntoa(to_ip)));
181 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
182 if (sock == -1)
183 goto done;
185 /* W2K PDC's seem not to respond to '*'#0. JRA */
186 make_nmb_name(&nname, q_name, q_type);
187 status = node_status_query(sock, &nname, to_ip, &count);
188 close(sock);
189 if (!status)
190 goto done;
192 for (i=0;i<count;i++) {
193 if (status[i].type == type)
194 break;
196 if (i == count)
197 goto done;
199 pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
200 result = True;
202 done:
203 SAFE_FREE(status);
205 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
207 if (result)
208 DEBUGADD(10, (", ip address is %s", inet_ntoa(to_ip)));
210 DEBUG(10, ("\n"));
212 return result;
217 comparison function used by sort_ip_list
219 int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
221 int max_bits1=0, max_bits2=0;
222 int num_interfaces = iface_count();
223 int i;
225 for (i=0;i<num_interfaces;i++) {
226 struct in_addr ip;
227 int bits1, bits2;
228 ip = *iface_n_bcast(i);
229 bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
230 bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
231 max_bits1 = MAX(bits1, max_bits1);
232 max_bits2 = MAX(bits2, max_bits2);
235 /* bias towards directly reachable IPs */
236 if (iface_local(*ip1)) {
237 max_bits1 += 32;
239 if (iface_local(*ip2)) {
240 max_bits2 += 32;
243 return max_bits2 - max_bits1;
247 sort an IP list so that names that are close to one of our interfaces
248 are at the top. This prevents the problem where a WINS server returns an IP that
249 is not reachable from our subnet as the first match
251 static void sort_ip_list(struct in_addr *iplist, int count)
253 if (count <= 1) {
254 return;
257 qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
261 /****************************************************************************
262 Do a netbios name query to find someones IP.
263 Returns an array of IP addresses or NULL if none.
264 *count will be set to the number of addresses returned.
265 *timed_out is set if we failed by timing out
266 ****************************************************************************/
267 struct in_addr *name_query(int fd,const char *name,int name_type,
268 BOOL bcast,BOOL recurse,
269 struct in_addr to_ip, int *count, int *flags,
270 BOOL *timed_out)
272 BOOL found=False;
273 int i, retries = 3;
274 int retry_time = bcast?250:2000;
275 struct timeval tval;
276 struct packet_struct p;
277 struct packet_struct *p2;
278 struct nmb_packet *nmb = &p.packet.nmb;
279 struct in_addr *ip_list = NULL;
281 if (lp_disable_netbios()) {
282 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
283 return NULL;
286 if (timed_out) {
287 *timed_out = False;
290 memset((char *)&p,'\0',sizeof(p));
291 (*count) = 0;
292 (*flags) = 0;
294 nmb->header.name_trn_id = generate_trn_id();
295 nmb->header.opcode = 0;
296 nmb->header.response = False;
297 nmb->header.nm_flags.bcast = bcast;
298 nmb->header.nm_flags.recursion_available = False;
299 nmb->header.nm_flags.recursion_desired = recurse;
300 nmb->header.nm_flags.trunc = False;
301 nmb->header.nm_flags.authoritative = False;
302 nmb->header.rcode = 0;
303 nmb->header.qdcount = 1;
304 nmb->header.ancount = 0;
305 nmb->header.nscount = 0;
306 nmb->header.arcount = 0;
308 make_nmb_name(&nmb->question.question_name,name,name_type);
310 nmb->question.question_type = 0x20;
311 nmb->question.question_class = 0x1;
313 p.ip = to_ip;
314 p.port = NMB_PORT;
315 p.fd = fd;
316 p.timestamp = time(NULL);
317 p.packet_type = NMB_PACKET;
319 GetTimeOfDay(&tval);
321 if (!send_packet(&p))
322 return NULL;
324 retries--;
326 while (1) {
327 struct timeval tval2;
328 struct in_addr *tmp_ip_list;
330 GetTimeOfDay(&tval2);
331 if (TvalDiff(&tval,&tval2) > retry_time) {
332 if (!retries)
333 break;
334 if (!found && !send_packet(&p))
335 return NULL;
336 GetTimeOfDay(&tval);
337 retries--;
340 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
341 struct nmb_packet *nmb2 = &p2->packet.nmb;
342 debug_nmb_packet(p2);
344 /* If we get a Negative Name Query Response from a WINS
345 * server, we should report it and give up.
347 if( 0 == nmb2->header.opcode /* A query response */
348 && !(bcast) /* from a WINS server */
349 && nmb2->header.rcode /* Error returned */
352 if( DEBUGLVL( 3 ) ) {
353 /* Only executed if DEBUGLEVEL >= 3 */
354 dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
355 switch( nmb2->header.rcode ) {
356 case 0x01:
357 dbgtext( "Request was invalidly formatted.\n" );
358 break;
359 case 0x02:
360 dbgtext( "Problem with NBNS, cannot process name.\n");
361 break;
362 case 0x03:
363 dbgtext( "The name requested does not exist.\n" );
364 break;
365 case 0x04:
366 dbgtext( "Unsupported request error.\n" );
367 break;
368 case 0x05:
369 dbgtext( "Query refused error.\n" );
370 break;
371 default:
372 dbgtext( "Unrecognized error code.\n" );
373 break;
376 free_packet(p2);
377 return( NULL );
380 if (nmb2->header.opcode != 0 ||
381 nmb2->header.nm_flags.bcast ||
382 nmb2->header.rcode ||
383 !nmb2->header.ancount) {
385 * XXXX what do we do with this? Could be a
386 * redirect, but we'll discard it for the
387 * moment.
389 free_packet(p2);
390 continue;
393 tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
394 * ( (*count) + nmb2->answers->rdlength/6 ) );
396 if (!tmp_ip_list) {
397 DEBUG(0,("name_query: Realloc failed.\n"));
398 SAFE_FREE(ip_list);
401 ip_list = tmp_ip_list;
403 if (ip_list) {
404 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
405 for (i=0;i<nmb2->answers->rdlength/6;i++) {
406 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
407 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
408 (*count)++;
410 DEBUGADD(2,(")\n"));
413 found=True;
414 retries=0;
415 /* We add the flags back ... */
416 if (nmb2->header.response)
417 (*flags) |= NM_FLAGS_RS;
418 if (nmb2->header.nm_flags.authoritative)
419 (*flags) |= NM_FLAGS_AA;
420 if (nmb2->header.nm_flags.trunc)
421 (*flags) |= NM_FLAGS_TC;
422 if (nmb2->header.nm_flags.recursion_desired)
423 (*flags) |= NM_FLAGS_RD;
424 if (nmb2->header.nm_flags.recursion_available)
425 (*flags) |= NM_FLAGS_RA;
426 if (nmb2->header.nm_flags.bcast)
427 (*flags) |= NM_FLAGS_B;
428 free_packet(p2);
430 * If we're doing a unicast lookup we only
431 * expect one reply. Don't wait the full 2
432 * seconds if we got one. JRA.
434 if(!bcast && found)
435 break;
439 if (timed_out) {
440 *timed_out = True;
443 /* sort the ip list so we choose close servers first if possible */
444 sort_ip_list(ip_list, *count);
446 return ip_list;
449 /********************************************************
450 Start parsing the lmhosts file.
451 *********************************************************/
453 XFILE *startlmhosts(char *fname)
455 XFILE *fp = x_fopen(fname,O_RDONLY, 0);
456 if (!fp) {
457 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
458 fname, strerror(errno)));
459 return NULL;
461 return fp;
464 /********************************************************
465 Parse the next line in the lmhosts file.
466 *********************************************************/
468 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
470 pstring line;
472 while(!x_feof(fp) && !x_ferror(fp)) {
473 pstring ip,flags,extra;
474 const char *ptr;
475 char *ptr1;
476 int count = 0;
478 *name_type = -1;
480 if (!fgets_slash(line,sizeof(pstring),fp))
481 continue;
483 if (*line == '#')
484 continue;
486 pstrcpy(ip,"");
487 pstrcpy(name,"");
488 pstrcpy(flags,"");
490 ptr = line;
492 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
493 ++count;
494 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
495 ++count;
496 if (next_token(&ptr,flags,NULL, sizeof(flags)))
497 ++count;
498 if (next_token(&ptr,extra,NULL, sizeof(extra)))
499 ++count;
501 if (count <= 0)
502 continue;
504 if (count > 0 && count < 2)
506 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
507 continue;
510 if (count >= 4)
512 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
513 continue;
516 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
518 if (strchr_m(flags,'G') || strchr_m(flags,'S'))
520 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
521 continue;
524 *ipaddr = *interpret_addr2(ip);
526 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
527 then only add that name type. */
528 if((ptr1 = strchr_m(name, '#')) != NULL)
530 char *endptr;
532 ptr1++;
533 *name_type = (int)strtol(ptr1, &endptr, 16);
535 if(!*ptr1 || (endptr == ptr1))
537 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
538 continue;
541 *(--ptr1) = '\0'; /* Truncate at the '#' */
544 return True;
547 return False;
550 /********************************************************
551 Finish parsing the lmhosts file.
552 *********************************************************/
554 void endlmhosts(XFILE *fp)
556 x_fclose(fp);
560 /********************************************************
561 Resolve via "bcast" method.
562 *********************************************************/
564 BOOL name_resolve_bcast(const char *name, int name_type,
565 struct in_addr **return_ip_list, int *return_count)
567 int sock, i;
568 int num_interfaces = iface_count();
570 if (lp_disable_netbios()) {
571 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
572 return False;
575 *return_ip_list = NULL;
576 *return_count = 0;
579 * "bcast" means do a broadcast lookup on all the local interfaces.
582 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
584 sock = open_socket_in( SOCK_DGRAM, 0, 3,
585 interpret_addr(lp_socket_address()), True );
587 if (sock == -1) return False;
589 set_socket_options(sock,"SO_BROADCAST");
591 * Lookup the name on all the interfaces, return on
592 * the first successful match.
594 for( i = num_interfaces-1; i >= 0; i--) {
595 struct in_addr sendto_ip;
596 int flags;
597 /* Done this way to fix compiler error on IRIX 5.x */
598 sendto_ip = *iface_n_bcast(i);
599 *return_ip_list = name_query(sock, name, name_type, True,
600 True, sendto_ip, return_count, &flags, NULL);
601 if(*return_ip_list != NULL) {
602 close(sock);
603 return True;
607 close(sock);
608 return False;
611 /********************************************************
612 Resolve via "wins" method.
613 *********************************************************/
614 BOOL resolve_wins(const char *name, int name_type,
615 struct in_addr **return_iplist, int *return_count)
617 int sock, t, i;
618 char **wins_tags;
619 struct in_addr src_ip;
621 if (lp_disable_netbios()) {
622 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
623 return False;
626 *return_iplist = NULL;
627 *return_count = 0;
629 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
631 if (wins_srv_count() < 1) {
632 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
633 return False;
636 /* we try a lookup on each of the WINS tags in turn */
637 wins_tags = wins_srv_tags();
639 if (!wins_tags) {
640 /* huh? no tags?? give up in disgust */
641 return False;
644 /* the address we will be sending from */
645 src_ip = *interpret_addr2(lp_socket_address());
647 /* in the worst case we will try every wins server with every
648 tag! */
649 for (t=0; wins_tags && wins_tags[t]; t++) {
650 int srv_count = wins_srv_count_tag(wins_tags[t]);
651 for (i=0; i<srv_count; i++) {
652 struct in_addr wins_ip;
653 int flags;
654 BOOL timed_out;
656 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
658 if (global_in_nmbd && ismyip(wins_ip)) {
659 /* yikes! we'll loop forever */
660 continue;
663 /* skip any that have been unresponsive lately */
664 if (wins_srv_is_dead(wins_ip, src_ip)) {
665 continue;
668 DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
670 sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
671 if (sock == -1) {
672 continue;
675 *return_iplist = name_query(sock,name,name_type, False,
676 True, wins_ip, return_count, &flags,
677 &timed_out);
678 if (*return_iplist != NULL) {
679 goto success;
681 close(sock);
683 if (timed_out) {
684 /* Timed out wating for WINS server to respond. Mark it dead. */
685 wins_srv_died(wins_ip, src_ip);
686 } else {
687 /* The name definately isn't in this
688 group of WINS servers. goto the next group */
689 break;
694 wins_srv_tags_free(wins_tags);
695 return False;
697 success:
698 wins_srv_tags_free(wins_tags);
699 close(sock);
700 return True;
703 /********************************************************
704 Resolve via "lmhosts" method.
705 *********************************************************/
707 static BOOL resolve_lmhosts(const char *name, int name_type,
708 struct in_addr **return_iplist, int *return_count)
711 * "lmhosts" means parse the local lmhosts file.
714 XFILE *fp;
715 pstring lmhost_name;
716 int name_type2;
717 struct in_addr return_ip;
719 *return_iplist = NULL;
720 *return_count = 0;
722 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
724 fp = startlmhosts(dyn_LMHOSTSFILE);
725 if(fp) {
726 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
727 if (strequal(name, lmhost_name) &&
728 ((name_type2 == -1) || (name_type == name_type2))
730 endlmhosts(fp);
731 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
732 if(*return_iplist == NULL) {
733 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
734 return False;
736 **return_iplist = return_ip;
737 *return_count = 1;
738 return True;
741 endlmhosts(fp);
743 return False;
747 /********************************************************
748 Resolve via "hosts" method.
749 *********************************************************/
751 static BOOL resolve_hosts(const char *name,
752 struct in_addr **return_iplist, int *return_count)
755 * "host" means do a localhost, or dns lookup.
757 struct hostent *hp;
759 *return_iplist = NULL;
760 *return_count = 0;
762 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
764 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
765 struct in_addr return_ip;
766 putip((char *)&return_ip,(char *)hp->h_addr);
767 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
768 if(*return_iplist == NULL) {
769 DEBUG(3,("resolve_hosts: malloc fail !\n"));
770 return False;
772 **return_iplist = return_ip;
773 *return_count = 1;
774 return True;
776 return False;
779 /********************************************************
780 Internal interface to resolve a name into an IP address.
781 Use this function if the string is either an IP address, DNS
782 or host name or NetBIOS name. This uses the name switch in the
783 smb.conf to determine the order of name resolution.
784 *********************************************************/
786 static BOOL internal_resolve_name(const char *name, int name_type,
787 struct in_addr **return_iplist, int *return_count)
789 pstring name_resolve_list;
790 fstring tok;
791 const char *ptr;
792 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
793 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
794 BOOL is_address = is_ipaddress(name);
795 BOOL result = False;
796 struct in_addr *nodupes_iplist;
797 int i;
799 *return_iplist = NULL;
800 *return_count = 0;
802 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
804 if (allzeros || allones || is_address) {
805 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
806 if(*return_iplist == NULL) {
807 DEBUG(3,("internal_resolve_name: malloc fail !\n"));
808 return False;
810 if(is_address) {
811 /* if it's in the form of an IP address then get the lib to interpret it */
812 if (((*return_iplist)->s_addr = inet_addr(name)) == 0xFFFFFFFF ){
813 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
814 return False;
816 } else {
817 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
818 *return_count = 1;
820 return True;
823 /* Check netbios name cache */
825 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
827 /* This could be a negative response */
829 return (*return_count > 0);
832 pstrcpy(name_resolve_list, lp_name_resolve_order());
833 ptr = name_resolve_list;
834 if (!ptr || !*ptr)
835 ptr = "host";
837 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
838 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
839 if (name_type == 0x20) {
840 if (resolve_hosts(name, return_iplist, return_count)) {
841 result = True;
842 goto done;
845 } else if(strequal( tok, "lmhosts")) {
846 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
847 result = True;
848 goto done;
850 } else if(strequal( tok, "wins")) {
851 /* don't resolve 1D via WINS */
852 if (name_type != 0x1D &&
853 resolve_wins(name, name_type, return_iplist, return_count)) {
854 result = True;
855 goto done;
857 } else if(strequal( tok, "bcast")) {
858 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
859 result = True;
860 goto done;
862 } else {
863 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
867 /* All of the resolve_* functions above have returned false. */
869 SAFE_FREE(*return_iplist);
870 *return_count = 0;
872 return False;
874 done:
876 /* Remove duplicate entries. Some queries, notably #1c (domain
877 controllers) return the PDC in iplist[0] and then all domain
878 controllers including the PDC in iplist[1..n]. Iterating over
879 the iplist when the PDC is down will cause two sets of timeouts. */
881 if (*return_count && (nodupes_iplist = (struct in_addr *)
882 malloc(sizeof(struct in_addr) * (*return_count)))) {
883 int nodupes_count = 0;
885 /* Iterate over return_iplist looking for duplicates */
887 for (i = 0; i < *return_count; i++) {
888 BOOL is_dupe = False;
889 int j;
891 for (j = i + 1; j < *return_count; j++) {
892 if (ip_equal((*return_iplist)[i],
893 (*return_iplist)[j])) {
894 is_dupe = True;
895 break;
899 if (!is_dupe) {
901 /* This one not a duplicate */
903 nodupes_iplist[nodupes_count] = (*return_iplist)[i];
904 nodupes_count++;
908 /* Switcheroo with original list */
910 free(*return_iplist);
912 *return_iplist = nodupes_iplist;
913 *return_count = nodupes_count;
916 /* Save in name cache */
917 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
918 DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name,
919 name_type, inet_ntoa((*return_iplist)[i])));
921 namecache_store(name, name_type, *return_count, *return_iplist);
923 /* Display some debugging info */
925 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
926 *return_count));
928 for (i = 0; i < *return_count; i++)
929 DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
931 DEBUG(10, ("\n"));
933 return result;
936 /********************************************************
937 Internal interface to resolve a name into one IP address.
938 Use this function if the string is either an IP address, DNS
939 or host name or NetBIOS name. This uses the name switch in the
940 smb.conf to determine the order of name resolution.
941 *********************************************************/
943 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
945 struct in_addr *ip_list = NULL;
946 int count = 0;
948 if (is_ipaddress(name)) {
949 *return_ip = *interpret_addr2(name);
950 return True;
953 if (internal_resolve_name(name, name_type, &ip_list, &count)) {
954 int i;
955 /* only return valid addresses for TCP connections */
956 for (i=0; i<count; i++) {
957 char *ip_str = inet_ntoa(ip_list[i]);
958 if (ip_str &&
959 strcmp(ip_str, "255.255.255.255") != 0 &&
960 strcmp(ip_str, "0.0.0.0") != 0) {
961 *return_ip = ip_list[i];
962 SAFE_FREE(ip_list);
963 return True;
967 SAFE_FREE(ip_list);
968 return False;
971 /********************************************************
972 Find the IP address of the master browser or DMB for a workgroup.
973 *********************************************************/
975 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
977 struct in_addr *ip_list = NULL;
978 int count = 0;
980 if (lp_disable_netbios()) {
981 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
982 return False;
985 if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
986 *master_ip = ip_list[0];
987 SAFE_FREE(ip_list);
988 return True;
990 if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
991 *master_ip = ip_list[0];
992 SAFE_FREE(ip_list);
993 return True;
996 SAFE_FREE(ip_list);
997 return False;
1000 /********************************************************
1001 Lookup a DC name given a Domain name and IP address.
1002 *********************************************************/
1004 BOOL lookup_dc_name(const char *srcname, const char *domain,
1005 struct in_addr *dc_ip, char *ret_name)
1007 #if !defined(I_HATE_WINDOWS_REPLY_CODE)
1008 fstring dc_name;
1009 BOOL ret;
1011 if (lp_disable_netbios()) {
1012 DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
1013 return False;
1017 * Due to the fact win WinNT *sucks* we must do a node status
1018 * query here... JRA.
1021 *dc_name = '\0';
1023 ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1025 if(ret && *dc_name) {
1026 fstrcpy(ret_name, dc_name);
1027 return True;
1030 return False;
1032 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1034 JRA - This code is broken with BDC rollover - we need to do a full
1035 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1037 int retries = 3;
1038 int retry_time = 2000;
1039 struct timeval tval;
1040 struct packet_struct p;
1041 struct dgram_packet *dgram = &p.packet.dgram;
1042 char *ptr,*p2;
1043 char tmp[4];
1044 int len;
1045 struct sockaddr_in sock_name;
1046 int sock_len = sizeof(sock_name);
1047 const char *mailslot = NET_LOGON_MAILSLOT;
1048 char *mailslot_name;
1049 char buffer[1024];
1050 char *bufp;
1051 int dgm_id = generate_trn_id();
1052 int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1054 if(sock == -1)
1055 return False;
1057 /* Find out the transient UDP port we have been allocated. */
1058 if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1059 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1060 strerror(errno)));
1061 close(sock);
1062 return False;
1066 * Create the request data.
1069 memset(buffer,'\0',sizeof(buffer));
1070 bufp = buffer;
1071 SSVAL(bufp,0,QUERYFORPDC);
1072 bufp += 2;
1073 fstrcpy(bufp,srcname);
1074 bufp += (strlen(bufp) + 1);
1075 slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1076 mailslot_name = bufp;
1077 bufp += (strlen(bufp) + 1);
1078 bufp = ALIGN2(bufp, buffer);
1079 bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
1081 SIVAL(bufp,0,1);
1082 SSVAL(bufp,4,0xFFFF);
1083 SSVAL(bufp,6,0xFFFF);
1084 bufp += 8;
1085 len = PTR_DIFF(bufp,buffer);
1087 memset((char *)&p,'\0',sizeof(p));
1089 /* DIRECT GROUP or UNIQUE datagram. */
1090 dgram->header.msg_type = 0x10;
1091 dgram->header.flags.node_type = M_NODE;
1092 dgram->header.flags.first = True;
1093 dgram->header.flags.more = False;
1094 dgram->header.dgm_id = dgm_id;
1095 dgram->header.source_ip = *iface_ip(*pdc_ip);
1096 dgram->header.source_port = ntohs(sock_name.sin_port);
1097 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1098 dgram->header.packet_offset = 0;
1100 make_nmb_name(&dgram->source_name,srcname,0);
1101 make_nmb_name(&dgram->dest_name,domain,0x1C);
1103 ptr = &dgram->data[0];
1105 /* Setup the smb part. */
1106 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1107 memcpy(tmp,ptr,4);
1108 set_message(ptr,17,17 + len,True);
1109 memcpy(ptr,tmp,4);
1111 CVAL(ptr,smb_com) = SMBtrans;
1112 SSVAL(ptr,smb_vwv1,len);
1113 SSVAL(ptr,smb_vwv11,len);
1114 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1115 SSVAL(ptr,smb_vwv13,3);
1116 SSVAL(ptr,smb_vwv14,1);
1117 SSVAL(ptr,smb_vwv15,1);
1118 SSVAL(ptr,smb_vwv16,2);
1119 p2 = smb_buf(ptr);
1120 pstrcpy(p2,mailslot);
1121 p2 = skip_string(p2,1);
1123 memcpy(p2,buffer,len);
1124 p2 += len;
1126 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1128 p.ip = *pdc_ip;
1129 p.port = DGRAM_PORT;
1130 p.fd = sock;
1131 p.timestamp = time(NULL);
1132 p.packet_type = DGRAM_PACKET;
1134 GetTimeOfDay(&tval);
1136 if (!send_packet(&p)) {
1137 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1138 close(sock);
1139 return False;
1142 retries--;
1144 while (1) {
1145 struct timeval tval2;
1146 struct packet_struct *p_ret;
1148 GetTimeOfDay(&tval2);
1149 if (TvalDiff(&tval,&tval2) > retry_time) {
1150 if (!retries)
1151 break;
1152 if (!send_packet(&p)) {
1153 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1154 close(sock);
1155 return False;
1157 GetTimeOfDay(&tval);
1158 retries--;
1161 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1162 struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1163 char *buf;
1164 char *buf2;
1166 buf = &dgram2->data[0];
1167 buf -= 4;
1169 if (CVAL(buf,smb_com) != SMBtrans) {
1170 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1171 CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1172 free_packet(p_ret);
1173 continue;
1176 len = SVAL(buf,smb_vwv11);
1177 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1179 if (len <= 0) {
1180 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1181 free_packet(p_ret);
1182 continue;
1185 DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1186 nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1187 inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1189 if(SVAL(buf2,0) != QUERYFORPDC_R) {
1190 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1191 (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1192 free_packet(p_ret);
1193 continue;
1196 buf2 += 2;
1197 /* Note this is safe as it is a bounded strcpy. */
1198 fstrcpy(ret_name, buf2);
1199 ret_name[sizeof(fstring)-1] = '\0';
1200 close(sock);
1201 free_packet(p_ret);
1202 return True;
1206 close(sock);
1207 return False;
1208 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1211 /********************************************************
1212 Get the IP address list of the primary domain controller
1213 for a domain.
1214 *********************************************************/
1216 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1218 struct in_addr *ip_list;
1219 int count;
1220 int i = 0;
1222 /* Look up #1B name */
1224 if (!internal_resolve_name(domain, 0x1b, &ip_list, &count))
1225 return False;
1227 /* if we get more than 1 IP back we have to assume it is a
1228 multi-homed PDC and not a mess up */
1230 if ( count > 1 ) {
1231 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1233 /* look for a local net */
1234 for ( i=0; i<count; i++ ) {
1235 if ( is_local_net( ip_list[i] ) )
1236 break;
1239 /* if we hit then end then just grab the first
1240 one from the list */
1242 if ( i == count )
1243 i = 0;
1246 *ip = ip_list[i];
1248 SAFE_FREE(ip_list);
1250 return True;
1253 /********************************************************
1254 Get the IP address list of the domain controllers for
1255 a domain.
1256 *********************************************************/
1258 BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *ordered)
1261 *ordered = False;
1263 /* If it's our domain then use the 'password server' parameter. */
1265 if (strequal(domain, lp_workgroup())) {
1266 const char *p;
1267 char *pserver = lp_passwordserver(); /* UNIX charset. */
1268 fstring name;
1269 int num_addresses = 0;
1270 int local_count, i, j;
1271 struct in_addr *return_iplist = NULL;
1272 struct in_addr *auto_ip_list = NULL;
1273 BOOL done_auto_lookup = False;
1274 int auto_count = 0;
1277 if (!*pserver)
1278 return internal_resolve_name(
1279 domain, 0x1C, ip_list, count);
1281 p = pserver;
1284 * if '*' appears in the "password server" list then add
1285 * an auto lookup to the list of manually configured
1286 * DC's. If any DC is listed by name, then the list should be
1287 * considered to be ordered
1290 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1291 if (strequal(name, "*")) {
1292 if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count) )
1293 num_addresses += auto_count;
1294 done_auto_lookup = True;
1295 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1297 else
1298 num_addresses++;
1301 /* if we have no addresses and haven't done the auto lookup, then
1302 just return the list of DC's */
1304 if ( (num_addresses == 0) && !done_auto_lookup )
1305 return internal_resolve_name(domain, 0x1C, ip_list, count);
1307 return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr));
1309 if (return_iplist == NULL) {
1310 DEBUG(3,("get_dc_list: malloc fail !\n"));
1311 return False;
1314 p = pserver;
1315 local_count = 0;
1317 /* fill in the return list now with real IP's */
1319 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1320 struct in_addr name_ip;
1322 /* copy any addersses from the auto lookup */
1324 if ( strequal(name, "*") ) {
1325 for ( j=0; j<auto_count; j++ )
1326 return_iplist[local_count++] = auto_ip_list[j];
1327 continue;
1330 /* explicit lookup; resolve_name() will handle names & IP addresses */
1332 if ( resolve_name( name, &name_ip, 0x20) ) {
1333 return_iplist[local_count++] = name_ip;
1334 *ordered = True;
1339 SAFE_FREE(auto_ip_list);
1341 /* need to remove duplicates in the list if we have
1342 any explicit password servers */
1344 if ( *ordered ) {
1345 /* one loop to remove duplicates */
1346 for ( i=0; i<local_count; i++ ) {
1347 if ( is_zero_ip(return_iplist[i]) )
1348 continue;
1350 for ( j=i+1; j<local_count; j++ ) {
1351 if ( ip_equal( return_iplist[i], return_iplist[j]) )
1352 zero_ip(&return_iplist[j]);
1356 /* one loop to clean up any holes we left */
1357 /* first ip should never be a zero_ip() */
1358 for (i = 0; i<local_count; ) {
1359 if ( is_zero_ip(return_iplist[i]) ) {
1360 if (i != local_count-1 )
1361 memmove(&return_iplist[i], &return_iplist[i+1],
1362 (local_count - i - 1)*sizeof(return_iplist[i]));
1363 local_count--;
1364 continue;
1366 i++;
1370 *ip_list = return_iplist;
1371 *count = local_count;
1373 DEBUG(8,("get_dc_list: return %d ip addresses\n", *count));
1375 return (*count != 0);
1378 return internal_resolve_name(domain, 0x1C, ip_list, count);