removed two unneeded files after Richard backed out these changes.
[Samba.git] / source / libsmb / namequery.c
blob09825ac6f1e0a023571d2786d5a3232a5133c8d9
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 name query routines
5 Copyright (C) Andrew Tridgell 1994-1998
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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
25 /* nmbd.c sets this to True. */
26 BOOL global_in_nmbd = False;
28 /****************************************************************************
29 Generate a random trn_id.
30 ****************************************************************************/
32 static int generate_trn_id(void)
34 static int trn_id;
36 if (trn_id == 0)
37 sys_srandom(sys_getpid());
39 trn_id = sys_random();
41 return trn_id % (unsigned)0x7FFF;
44 /****************************************************************************
45 Parse a node status response into an array of structures.
46 ****************************************************************************/
48 static struct node_status *parse_node_status(char *p, int *num_names)
50 struct node_status *ret;
51 int i;
53 *num_names = CVAL(p,0);
55 if (*num_names == 0) return NULL;
57 ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names));
58 if (!ret) return NULL;
60 p++;
61 for (i=0;i< *num_names;i++) {
62 StrnCpy(ret[i].name,p,15);
63 trim_string(ret[i].name,NULL," ");
64 ret[i].type = CVAL(p,15);
65 ret[i].flags = p[16];
66 p += 18;
68 return ret;
71 /****************************************************************************
72 Do a NBT node status query on an open socket and return an array of
73 structures holding the returned names or NULL if the query failed.
74 **************************************************************************/
76 struct node_status *node_status_query(int fd,struct nmb_name *name,
77 struct in_addr to_ip, int *num_names)
79 BOOL found=False;
80 int retries = 2;
81 int retry_time = 2000;
82 struct timeval tval;
83 struct packet_struct p;
84 struct packet_struct *p2;
85 struct nmb_packet *nmb = &p.packet.nmb;
86 struct node_status *ret;
88 ZERO_STRUCT(p);
90 nmb->header.name_trn_id = generate_trn_id();
91 nmb->header.opcode = 0;
92 nmb->header.response = False;
93 nmb->header.nm_flags.bcast = False;
94 nmb->header.nm_flags.recursion_available = False;
95 nmb->header.nm_flags.recursion_desired = False;
96 nmb->header.nm_flags.trunc = False;
97 nmb->header.nm_flags.authoritative = False;
98 nmb->header.rcode = 0;
99 nmb->header.qdcount = 1;
100 nmb->header.ancount = 0;
101 nmb->header.nscount = 0;
102 nmb->header.arcount = 0;
103 nmb->question.question_name = *name;
104 nmb->question.question_type = 0x21;
105 nmb->question.question_class = 0x1;
107 p.ip = to_ip;
108 p.port = NMB_PORT;
109 p.fd = fd;
110 p.timestamp = time(NULL);
111 p.packet_type = NMB_PACKET;
113 GetTimeOfDay(&tval);
115 if (!send_packet(&p))
116 return NULL;
118 retries--;
120 while (1) {
121 struct timeval tval2;
122 GetTimeOfDay(&tval2);
123 if (TvalDiff(&tval,&tval2) > retry_time) {
124 if (!retries)
125 break;
126 if (!found && !send_packet(&p))
127 return NULL;
128 GetTimeOfDay(&tval);
129 retries--;
132 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
133 struct nmb_packet *nmb2 = &p2->packet.nmb;
134 debug_nmb_packet(p2);
136 if (nmb2->header.opcode != 0 ||
137 nmb2->header.nm_flags.bcast ||
138 nmb2->header.rcode ||
139 !nmb2->header.ancount ||
140 nmb2->answers->rr_type != 0x21) {
141 /* XXXX what do we do with this? could be a
142 redirect, but we'll discard it for the
143 moment */
144 free_packet(p2);
145 continue;
148 ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
149 free_packet(p2);
150 return ret;
154 return NULL;
158 /****************************************************************************
159 find the first type XX name in a node status reply - used for finding
160 a servers name given its IP
161 return the matched name in *name
162 **************************************************************************/
164 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name)
166 struct node_status *status;
167 struct nmb_name nname;
168 int count, i;
169 int sock;
171 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
172 if (sock == -1)
173 return False;
175 /* W2K PDC's seem not to respond to '*'#0. JRA */
176 make_nmb_name(&nname, q_name, q_type);
177 status = node_status_query(sock, &nname, to_ip, &count);
178 close(sock);
179 if (!status)
180 return False;
182 for (i=0;i<count;i++) {
183 if (status[i].type == type)
184 break;
186 if (i == count)
187 return False;
189 StrnCpy(name, status[i].name, 15);
191 dos_to_unix(name);
193 SAFE_FREE(status);
194 return True;
197 /****************************************************************************
198 Do a NetBIOS name registation to try to claim a name ...
199 ***************************************************************************/
200 BOOL name_register(int fd, const char *name, int name_type,
201 struct in_addr name_ip, int opcode,
202 BOOL bcast,
203 struct in_addr to_ip, int *count)
205 int retries = 3;
206 struct timeval tval;
207 struct packet_struct p;
208 struct packet_struct *p2;
209 struct nmb_packet *nmb = &p.packet.nmb;
210 struct in_addr register_ip;
212 DEBUG(4, ("name_register: %s as %s on %s\n", name, inet_ntoa(name_ip), inet_ntoa(to_ip)));
214 register_ip.s_addr = name_ip.s_addr; /* Fix this ... */
216 memset((char *)&p, '\0', sizeof(p));
218 *count = 0;
220 nmb->header.name_trn_id = generate_trn_id();
221 nmb->header.opcode = opcode;
222 nmb->header.response = False;
223 nmb->header.nm_flags.bcast = False;
224 nmb->header.nm_flags.recursion_available = False;
225 nmb->header.nm_flags.recursion_desired = True; /* ? */
226 nmb->header.nm_flags.trunc = False;
227 nmb->header.nm_flags.authoritative = True;
229 nmb->header.qdcount = 1;
230 nmb->header.ancount = 0;
231 nmb->header.nscount = 0;
232 nmb->header.arcount = 1;
234 make_nmb_name(&nmb->question.question_name, name, name_type);
236 nmb->question.question_type = 0x20;
237 nmb->question.question_class = 0x1;
239 /* Now, create the additional stuff for a registration request */
241 if ((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) {
243 DEBUG(0, ("name_register: malloc fail for additional record.\n"));
244 return False;
248 memset((char *)nmb->additional, '\0', sizeof(struct res_rec));
250 nmb->additional->rr_name = nmb->question.question_name;
251 nmb->additional->rr_type = RR_TYPE_NB;
252 nmb->additional->rr_class = RR_CLASS_IN;
254 /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
255 if (nmb->header.nm_flags.bcast)
256 nmb->additional->ttl = PERMANENT_TTL;
257 else
258 nmb->additional->ttl = lp_max_ttl();
260 nmb->additional->rdlength = 6;
262 nmb->additional->rdata[0] = NB_MFLAG & 0xFF;
264 /* Set the address for the name we are registering. */
265 putip(&nmb->additional->rdata[2], &register_ip);
267 p.ip = to_ip;
268 p.port = NMB_PORT;
269 p.fd = fd;
270 p.timestamp = time(NULL);
271 p.packet_type = NMB_PACKET;
273 GetTimeOfDay(&tval);
275 if (!send_packet(&p))
276 return False;
278 retries--;
280 if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) {
281 debug_nmb_packet(p2);
282 SAFE_FREE(p2); /* No memory leaks ... */
285 return True;
288 /****************************************************************************
289 Do a netbios name query to find someones IP.
290 Returns an array of IP addresses or NULL if none.
291 *count will be set to the number of addresses returned.
292 ****************************************************************************/
293 struct in_addr *name_query(int fd,const char *name,int name_type,
294 BOOL bcast,BOOL recurse,
295 struct in_addr to_ip, int *count, int *flags)
297 BOOL found=False;
298 int i, retries = 3;
299 int retry_time = bcast?250:2000;
300 struct timeval tval;
301 struct packet_struct p;
302 struct packet_struct *p2;
303 struct nmb_packet *nmb = &p.packet.nmb;
304 struct in_addr *ip_list = NULL;
306 memset((char *)&p,'\0',sizeof(p));
307 (*count) = 0;
308 (*flags) = 0;
310 nmb->header.name_trn_id = generate_trn_id();
311 nmb->header.opcode = 0;
312 nmb->header.response = False;
313 nmb->header.nm_flags.bcast = bcast;
314 nmb->header.nm_flags.recursion_available = False;
315 nmb->header.nm_flags.recursion_desired = recurse;
316 nmb->header.nm_flags.trunc = False;
317 nmb->header.nm_flags.authoritative = False;
318 nmb->header.rcode = 0;
319 nmb->header.qdcount = 1;
320 nmb->header.ancount = 0;
321 nmb->header.nscount = 0;
322 nmb->header.arcount = 0;
324 make_nmb_name(&nmb->question.question_name,name,name_type);
326 nmb->question.question_type = 0x20;
327 nmb->question.question_class = 0x1;
329 p.ip = to_ip;
330 p.port = NMB_PORT;
331 p.fd = fd;
332 p.timestamp = time(NULL);
333 p.packet_type = NMB_PACKET;
335 GetTimeOfDay(&tval);
337 if (!send_packet(&p))
338 return NULL;
340 retries--;
342 while (1) {
343 struct timeval tval2;
344 struct in_addr *tmp_ip_list;
346 GetTimeOfDay(&tval2);
347 if (TvalDiff(&tval,&tval2) > retry_time) {
348 if (!retries)
349 break;
350 if (!found && !send_packet(&p))
351 return NULL;
352 GetTimeOfDay(&tval);
353 retries--;
356 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
357 struct nmb_packet *nmb2 = &p2->packet.nmb;
358 debug_nmb_packet(p2);
360 /* If we get a Negative Name Query Response from a WINS
361 * server, we should report it and give up.
363 if( 0 == nmb2->header.opcode /* A query response */
364 && !(bcast) /* from a WINS server */
365 && nmb2->header.rcode /* Error returned */
368 if( DEBUGLVL( 3 ) ) {
369 /* Only executed if DEBUGLEVEL >= 3 */
370 dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
371 switch( nmb2->header.rcode ) {
372 case 0x01:
373 dbgtext( "Request was invalidly formatted.\n" );
374 break;
375 case 0x02:
376 dbgtext( "Problem with NBNS, cannot process name.\n");
377 break;
378 case 0x03:
379 dbgtext( "The name requested does not exist.\n" );
380 break;
381 case 0x04:
382 dbgtext( "Unsupported request error.\n" );
383 break;
384 case 0x05:
385 dbgtext( "Query refused error.\n" );
386 break;
387 default:
388 dbgtext( "Unrecognized error code.\n" );
389 break;
393 free_packet(p2);
394 return( NULL );
397 if (nmb2->header.opcode != 0 ||
398 nmb2->header.nm_flags.bcast ||
399 nmb2->header.rcode ||
400 !nmb2->header.ancount) {
402 * XXXX what do we do with this? Could be a
403 * redirect, but we'll discard it for the
404 * moment.
406 free_packet(p2);
407 continue;
410 tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
411 * ( (*count) + nmb2->answers->rdlength/6 ) );
413 if (!tmp_ip_list) {
414 DEBUG(0,("name_query: Realloc failed.\n"));
415 SAFE_FREE(ip_list);
418 ip_list = tmp_ip_list;
420 if (ip_list) {
421 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
422 for (i=0;i<nmb2->answers->rdlength/6;i++) {
423 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
424 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
425 (*count)++;
427 DEBUGADD(2,(")\n"));
430 found=True;
431 retries=0;
432 /* We add the flags back ... */
433 if (nmb2->header.response)
434 (*flags) |= NM_FLAGS_RS;
435 if (nmb2->header.nm_flags.authoritative)
436 (*flags) |= NM_FLAGS_AA;
437 if (nmb2->header.nm_flags.trunc)
438 (*flags) |= NM_FLAGS_TC;
439 if (nmb2->header.nm_flags.recursion_desired)
440 (*flags) |= NM_FLAGS_RD;
441 if (nmb2->header.nm_flags.recursion_available)
442 (*flags) |= NM_FLAGS_RA;
443 if (nmb2->header.nm_flags.bcast)
444 (*flags) |= NM_FLAGS_B;
445 free_packet(p2);
448 * If we're doing a unicast lookup we only
449 * expect one reply. Don't wait the full 2
450 * seconds if we got one. JRA.
452 if(!bcast && found)
453 break;
457 /* Reach here if we've timed out waiting for replies.. */
458 if( !bcast && !found ) {
459 /* Timed out wating for WINS server to respond. Mark it dead. */
460 wins_srv_died( to_ip );
463 return ip_list;
466 /********************************************************
467 Start parsing the lmhosts file.
468 *********************************************************/
470 FILE *startlmhosts(char *fname)
472 FILE *fp = sys_fopen(fname,"r");
473 if (!fp) {
474 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
475 fname, strerror(errno)));
476 return NULL;
478 return fp;
481 /********************************************************
482 Parse the next line in the lmhosts file.
483 *********************************************************/
485 BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
487 pstring line;
489 while(!feof(fp) && !ferror(fp)) {
490 pstring ip,flags,extra;
491 char *ptr;
492 int count = 0;
494 *name_type = -1;
496 if (!fgets_slash(line,sizeof(pstring),fp))
497 continue;
499 if (*line == '#')
500 continue;
502 pstrcpy(ip,"");
503 pstrcpy(name,"");
504 pstrcpy(flags,"");
506 ptr = line;
508 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
509 ++count;
510 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
511 ++count;
512 if (next_token(&ptr,flags,NULL, sizeof(flags)))
513 ++count;
514 if (next_token(&ptr,extra,NULL, sizeof(extra)))
515 ++count;
517 if (count <= 0)
518 continue;
520 if (count > 0 && count < 2)
522 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
523 continue;
526 if (count >= 4)
528 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
529 continue;
532 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
534 if (strchr(flags,'G') || strchr(flags,'S'))
536 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
537 continue;
540 *ipaddr = *interpret_addr2(ip);
542 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
543 then only add that name type. */
544 if((ptr = strchr(name, '#')) != NULL)
546 char *endptr;
548 ptr++;
549 *name_type = (int)strtol(ptr, &endptr, 16);
551 if(!*ptr || (endptr == ptr))
553 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
554 continue;
557 *(--ptr) = '\0'; /* Truncate at the '#' */
560 return True;
563 return False;
566 /********************************************************
567 Finish parsing the lmhosts file.
568 *********************************************************/
570 void endlmhosts(FILE *fp)
572 fclose(fp);
575 BOOL name_register_wins(const char *name, int name_type)
577 int sock, i, return_count;
578 int num_interfaces = iface_count();
579 struct in_addr sendto_ip;
582 * Check if we have any interfaces, prevents a segfault later
585 if (num_interfaces <= 0)
586 return False; /* Should return some indication of the problem */
589 * Do a broadcast register ...
592 if (!lp_wins_server())
593 return False;
595 DEBUG(4, ("name_register_wins:Registering my name %s on %s\n", name, lp_wins_server()));
597 sock = open_socket_in(SOCK_DGRAM, 0, 3,
598 interpret_addr("0.0.0.0"), True);
600 if (sock == -1) return False;
602 set_socket_options(sock, "SO_BROADCAST");
604 sendto_ip.s_addr = inet_addr(lp_wins_server());
606 if (num_interfaces > 1) {
608 for (i = 0; i < num_interfaces; i++) {
610 if (!name_register(sock, name, name_type, *iface_n_ip(i),
611 NMB_NAME_MULTIHOMED_REG_OPCODE,
612 True, sendto_ip, &return_count)) {
614 close(sock);
615 return False;
622 else {
624 if (!name_register(sock, name, name_type, *iface_n_ip(0),
625 NMB_NAME_REG_OPCODE,
626 True, sendto_ip, &return_count)) {
628 close(sock);
629 return False;
635 close(sock);
637 return True;
641 /********************************************************
642 Resolve via "bcast" method.
643 *********************************************************/
645 BOOL name_resolve_bcast(const char *name, int name_type,
646 struct in_addr **return_ip_list, int *return_count)
648 int sock, i;
649 int num_interfaces = iface_count();
651 *return_ip_list = NULL;
652 *return_count = 0;
655 * "bcast" means do a broadcast lookup on all the local interfaces.
658 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
660 sock = open_socket_in( SOCK_DGRAM, 0, 3,
661 interpret_addr(lp_socket_address()), True );
663 if (sock == -1) return False;
665 set_socket_options(sock,"SO_BROADCAST");
667 * Lookup the name on all the interfaces, return on
668 * the first successful match.
670 for( i = num_interfaces-1; i >= 0; i--) {
671 struct in_addr sendto_ip;
672 int flags;
673 /* Done this way to fix compiler error on IRIX 5.x */
674 sendto_ip = *iface_bcast(*iface_n_ip(i));
675 *return_ip_list = name_query(sock, name, name_type, True,
676 True, sendto_ip, return_count, &flags);
677 if(*return_ip_list != NULL) {
678 close(sock);
679 return True;
683 close(sock);
684 return False;
687 /********************************************************
688 Resolve via "wins" method.
689 *********************************************************/
691 static BOOL resolve_wins(const char *name, int name_type,
692 struct in_addr **return_iplist, int *return_count)
694 int sock;
695 struct in_addr wins_ip;
696 BOOL wins_ismyip;
698 *return_iplist = NULL;
699 *return_count = 0;
702 * "wins" means do a unicast lookup to the WINS server.
703 * Ignore if there is no WINS server specified or if the
704 * WINS server is one of our interfaces (if we're being
705 * called from within nmbd - we can't do this call as we
706 * would then block).
709 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
711 if (lp_wins_support()) {
713 * We're providing WINS support. Call ourselves so
714 * long as we're not nmbd.
716 extern struct in_addr loopback_ip;
717 wins_ip = loopback_ip;
718 wins_ismyip = True;
719 } else if( wins_srv_count() < 1 ) {
720 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
721 return False;
722 } else {
723 wins_ip = wins_srv_ip();
724 wins_ismyip = ismyip(wins_ip);
727 DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) );
728 if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) {
729 sock = open_socket_in( SOCK_DGRAM, 0, 3,
730 interpret_addr(lp_socket_address()),
731 True );
732 if (sock != -1) {
733 int flags;
734 *return_iplist = name_query( sock, name,
735 name_type, False,
736 True, wins_ip,
737 return_count, &flags);
738 if(*return_iplist != NULL) {
739 close(sock);
740 return True;
742 close(sock);
746 return False;
749 /********************************************************
750 Resolve via "lmhosts" method.
751 *********************************************************/
753 static BOOL resolve_lmhosts(const char *name, int name_type,
754 struct in_addr **return_iplist, int *return_count)
757 * "lmhosts" means parse the local lmhosts file.
760 FILE *fp;
761 pstring lmhost_name;
762 int name_type2;
763 struct in_addr return_ip;
765 *return_iplist = NULL;
766 *return_count = 0;
768 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
770 fp = startlmhosts( LMHOSTSFILE );
771 if(fp) {
772 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
773 if (strequal(name, lmhost_name) &&
774 ((name_type2 == -1) || (name_type == name_type2))
776 endlmhosts(fp);
777 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
778 if(*return_iplist == NULL) {
779 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
780 return False;
782 **return_iplist = return_ip;
783 *return_count = 1;
784 return True;
787 endlmhosts(fp);
789 return False;
793 /********************************************************
794 Resolve via "hosts" method.
795 *********************************************************/
797 static BOOL resolve_hosts(const char *name,
798 struct in_addr **return_iplist, int *return_count)
801 * "host" means do a localhost, or dns lookup.
803 struct hostent *hp;
805 *return_iplist = NULL;
806 *return_count = 0;
808 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
810 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
811 int i = 0, j;
812 while (hp->h_addr_list[i]) i++;
813 DEBUG(10, ("%d addresses returned\n", i));
814 *return_iplist = (struct in_addr *)malloc(i*sizeof(struct in_addr));
815 if(*return_iplist == NULL) {
816 DEBUG(3,("resolve_hosts: malloc fail !\n"));
817 return False;
819 for (j = 0; j < i; j++)
820 putip(&(*return_iplist)[j], (char *)hp->h_addr_list[j]);
821 *return_count = i;
822 return True;
824 return False;
827 /********************************************************
828 Internal interface to resolve a name into an IP address.
829 Use this function if the string is either an IP address, DNS
830 or host name or NetBIOS name. This uses the name switch in the
831 smb.conf to determine the order of name resolution.
832 *********************************************************/
834 static BOOL internal_resolve_name(const char *name, int name_type,
835 struct in_addr **return_iplist, int *return_count)
837 pstring name_resolve_list;
838 fstring tok;
839 char *ptr;
840 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
841 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
842 BOOL is_address = is_ipaddress(name);
843 BOOL result = False;
844 struct in_addr *nodupes_iplist;
845 int i;
847 *return_iplist = NULL;
848 *return_count = 0;
850 if (allzeros || allones || is_address) {
851 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
852 if(*return_iplist == NULL) {
853 DEBUG(3,("internal_resolve_name: malloc fail !\n"));
854 return False;
856 if(is_address) {
857 /* if it's in the form of an IP address then get the lib to interpret it */
858 (*return_iplist)->s_addr = inet_addr(name);
859 } else {
860 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
861 *return_count = 1;
863 return True;
866 pstrcpy(name_resolve_list, lp_name_resolve_order());
867 ptr = name_resolve_list;
868 if (!ptr || !*ptr)
869 ptr = "host";
871 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
872 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
873 if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
874 result = True;
875 goto done;
877 } else if(strequal( tok, "lmhosts")) {
878 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
879 result = True;
880 goto done;
882 } else if(strequal( tok, "wins")) {
883 /* don't resolve 1D via WINS */
884 if (name_type != 0x1D &&
885 resolve_wins(name, name_type, return_iplist, return_count)) {
886 result = True;
887 goto done;
889 } else if(strequal( tok, "bcast")) {
890 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
891 result = True;
892 goto done;
894 } else {
895 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
899 /* All of the resolve_* functions above have returned false. */
901 SAFE_FREE(*return_iplist);
902 return False;
904 done:
906 /* Remove duplicate entries. Some queries, notably #1c (domain
907 controllers) return the PDC in iplist[0] and then all domain
908 controllers including the PDC in iplist[1..n]. Iterating over
909 the iplist when the PDC is down will cause two sets of timeouts. */
911 if (*return_count && (nodupes_iplist =
912 (struct in_addr *)malloc(sizeof(struct in_addr) * (*return_count)))) {
913 int nodupes_count = 0;
915 /* Iterate over return_iplist looking for duplicates */
917 for (i = 0; i < *return_count; i++) {
918 BOOL is_dupe = False;
919 int j;
921 for (j = i + 1; j < *return_count; j++) {
922 if (ip_equal((*return_iplist)[i],
923 (*return_iplist)[j])) {
924 is_dupe = True;
925 break;
929 if (!is_dupe) {
931 /* This one not a duplicate */
933 nodupes_iplist[nodupes_count] = (*return_iplist)[i];
934 nodupes_count++;
938 /* Switcheroo with original list */
940 free(*return_iplist);
942 *return_iplist = nodupes_iplist;
943 *return_count = nodupes_count;
946 /* Display some debugging info */
948 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
949 *return_count));
951 for (i = 0; i < *return_count; i++)
952 DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
954 DEBUG(10, ("\n"));
956 return result;
959 /********************************************************
960 Internal interface to resolve a name into one IP address.
961 Use this function if the string is either an IP address, DNS
962 or host name or NetBIOS name. This uses the name switch in the
963 smb.conf to determine the order of name resolution.
964 *********************************************************/
966 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
968 struct in_addr *ip_list = NULL;
969 int count = 0;
971 if (is_ipaddress(name)) {
972 *return_ip = *interpret_addr2(name);
973 return True;
976 if(internal_resolve_name(name, name_type, &ip_list, &count)) {
977 int i;
978 /* only return valid addresses for TCP connections */
979 for (i=0; i<count; i++) {
980 char *ip_str = inet_ntoa(ip_list[i]);
981 if (ip_str &&
982 strcmp(ip_str, "255.255.255.255") != 0 &&
983 strcmp(ip_str, "0.0.0.0") != 0) {
984 *return_ip = ip_list[i];
985 SAFE_FREE(ip_list);
986 return True;
990 SAFE_FREE(ip_list);
991 return False;
994 /**************************************************************************
995 Resolve a name to a list of addresses
996 **************************************************************************/
997 BOOL resolve_name_2(const char *name, struct in_addr **return_ip, int *count, int name_type)
1000 return internal_resolve_name(name, name_type, return_ip, count);
1004 /********************************************************
1005 resolve a name of format \\server_name or \\ipaddress
1006 into a name. also, cut the \\ from the front for us.
1007 *********************************************************/
1009 BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
1010 struct in_addr *ip)
1012 BOOL ret;
1013 const char *sv_name = srv_name;
1015 DEBUG(10,("resolve_srv_name: %s\n", srv_name));
1017 if (srv_name == NULL || strequal("\\\\.", srv_name))
1019 extern pstring global_myname;
1020 fstrcpy(dest_host, global_myname);
1021 ip = interpret_addr2("127.0.0.1");
1022 return True;
1025 if (strnequal("\\\\", srv_name, 2))
1027 sv_name = &srv_name[2];
1030 fstrcpy(dest_host, sv_name);
1031 /* treat the '*' name specially - it is a magic name for the PDC */
1032 if (strcmp(dest_host,"*") == 0) {
1033 extern pstring global_myname;
1034 ret = resolve_name(lp_workgroup(), ip, 0x1B);
1035 lookup_dc_name(global_myname, lp_workgroup(), ip, dest_host);
1036 } else {
1037 ret = resolve_name(dest_host, ip, 0x20);
1040 if (is_ipaddress(dest_host))
1042 fstrcpy(dest_host, "*SMBSERVER");
1045 return ret;
1049 /********************************************************
1050 Find the IP address of the master browser or DMB for a workgroup.
1051 *********************************************************/
1053 BOOL find_master_ip(char *group, struct in_addr *master_ip)
1055 struct in_addr *ip_list = NULL;
1056 int count = 0;
1058 if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
1059 *master_ip = ip_list[0];
1060 SAFE_FREE(ip_list);
1061 return True;
1063 if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
1064 *master_ip = ip_list[0];
1065 SAFE_FREE(ip_list);
1066 return True;
1069 SAFE_FREE(ip_list);
1070 return False;
1073 /********************************************************
1074 Lookup a DC name given a Domain name and IP address.
1075 *********************************************************/
1077 BOOL lookup_dc_name(const char *srcname, const char *domain,
1078 struct in_addr *dc_ip, char *ret_name)
1080 #if !defined(I_HATE_WINDOWS_REPLY_CODE)
1082 fstring dc_name;
1083 BOOL ret;
1086 * Due to the fact win WinNT *sucks* we must do a node status
1087 * query here... JRA.
1090 *dc_name = '\0';
1092 ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1094 if(ret && *dc_name) {
1095 fstrcpy(ret_name, dc_name);
1096 return True;
1099 return False;
1101 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1103 JRA - This code is broken with BDC rollover - we need to do a full
1104 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1106 int retries = 3;
1107 int retry_time = 2000;
1108 struct timeval tval;
1109 struct packet_struct p;
1110 struct dgram_packet *dgram = &p.packet.dgram;
1111 char *ptr,*p2;
1112 char tmp[4];
1113 int len;
1114 struct sockaddr_in sock_name;
1115 int sock_len = sizeof(sock_name);
1116 const char *mailslot = NET_LOGON_MAILSLOT;
1117 char *mailslot_name;
1118 char buffer[1024];
1119 char *bufp;
1120 int dgm_id = generate_trn_id();
1121 int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1123 if(sock == -1)
1124 return False;
1126 /* Find out the transient UDP port we have been allocated. */
1127 if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1128 DEBUG(0,("lookup_dc_name: Failed to get local UDP port. Error was %s\n",
1129 strerror(errno)));
1130 close(sock);
1131 return False;
1135 * Create the request data.
1138 memset(buffer,'\0',sizeof(buffer));
1139 bufp = buffer;
1140 SSVAL(bufp,0,QUERYFORPDC);
1141 bufp += 2;
1142 fstrcpy(bufp,srcname);
1143 bufp += (strlen(bufp) + 1);
1144 slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1145 mailslot_name = bufp;
1146 bufp += (strlen(bufp) + 1);
1147 bufp = ALIGN2(bufp, buffer);
1148 bufp += dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1, True);
1149 SIVAL(bufp,0,1);
1150 SSVAL(bufp,4,0xFFFF);
1151 SSVAL(bufp,6,0xFFFF);
1152 bufp += 8;
1153 len = PTR_DIFF(bufp,buffer);
1155 memset((char *)&p,'\0',sizeof(p));
1157 /* DIRECT GROUP or UNIQUE datagram. */
1158 dgram->header.msg_type = 0x10;
1159 dgram->header.flags.node_type = M_NODE;
1160 dgram->header.flags.first = True;
1161 dgram->header.flags.more = False;
1162 dgram->header.dgm_id = dgm_id;
1163 dgram->header.source_ip = *iface_ip(*pdc_ip);
1164 dgram->header.source_port = ntohs(sock_name.sin_port);
1165 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1166 dgram->header.packet_offset = 0;
1168 make_nmb_name(&dgram->source_name,srcname,0);
1169 make_nmb_name(&dgram->dest_name,domain,0x1C);
1171 ptr = &dgram->data[0];
1173 /* Setup the smb part. */
1174 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1175 memcpy(tmp,ptr,4);
1176 set_message(ptr,17,17 + len,True);
1177 memcpy(ptr,tmp,4);
1179 CVAL(ptr,smb_com) = SMBtrans;
1180 SSVAL(ptr,smb_vwv1,len);
1181 SSVAL(ptr,smb_vwv11,len);
1182 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1183 SSVAL(ptr,smb_vwv13,3);
1184 SSVAL(ptr,smb_vwv14,1);
1185 SSVAL(ptr,smb_vwv15,1);
1186 SSVAL(ptr,smb_vwv16,2);
1187 p2 = smb_buf(ptr);
1188 pstrcpy(p2,mailslot);
1189 p2 = skip_string(p2,1);
1191 memcpy(p2,buffer,len);
1192 p2 += len;
1194 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1196 p.ip = *pdc_ip;
1197 p.port = DGRAM_PORT;
1198 p.fd = sock;
1199 p.timestamp = time(NULL);
1200 p.packet_type = DGRAM_PACKET;
1202 GetTimeOfDay(&tval);
1204 if (!send_packet(&p)) {
1205 DEBUG(0,("lookup_dc_name: send_packet failed.\n"));
1206 close(sock);
1207 return False;
1210 retries--;
1212 while (1) {
1213 struct timeval tval2;
1214 struct packet_struct *p_ret;
1216 GetTimeOfDay(&tval2);
1217 if (TvalDiff(&tval,&tval2) > retry_time) {
1218 if (!retries)
1219 break;
1220 if (!send_packet(&p)) {
1221 DEBUG(0,("lookup_dc_name: send_packet failed.\n"));
1222 close(sock);
1223 return False;
1225 GetTimeOfDay(&tval);
1226 retries--;
1229 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1230 struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1231 char *buf;
1232 char *buf2;
1234 buf = &dgram2->data[0];
1235 buf -= 4;
1237 if (CVAL(buf,smb_com) != SMBtrans) {
1238 DEBUG(0,("lookup_dc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1239 CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1240 free_packet(p_ret);
1241 continue;
1244 len = SVAL(buf,smb_vwv11);
1245 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1247 if (len <= 0) {
1248 DEBUG(0,("lookup_dc_name: datagram len < 0 (%d)\n", len ));
1249 free_packet(p_ret);
1250 continue;
1253 DEBUG(4,("lookup_dc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1254 nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1255 inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1257 if(SVAL(buf2,0) != QUERYFORPDC_R) {
1258 DEBUG(0,("lookup_dc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1259 (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1260 free_packet(p_ret);
1261 continue;
1264 buf2 += 2;
1265 /* Note this is safe as it is a bounded strcpy. */
1266 fstrcpy(ret_name, buf2);
1267 ret_name[sizeof(fstring)-1] = '\0';
1268 close(sock);
1269 free_packet(p_ret);
1270 return True;
1274 close(sock);
1275 return False;
1276 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1280 /********************************************************
1281 Get the IP address list of the PDC/BDC's of a Domain.
1282 *********************************************************/
1284 BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count)
1286 int name_type = pdc_only ? 0x1B : 0x1C;
1289 * If it's our domain then
1290 * use the 'password server' parameter.
1293 if (strequal(group, lp_workgroup())) {
1294 char *p;
1295 char *pserver = lp_passwordserver();
1296 fstring name;
1297 int num_addresses = 0;
1298 struct in_addr *return_iplist = NULL;
1300 if (! *pserver)
1301 return internal_resolve_name(group, name_type, ip_list, count);
1303 p = pserver;
1304 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1305 if (strequal(name, "*")) {
1307 * Use 1C followed by 1B. This shouldn't work but with
1308 * broken WINS servers it might. JRA.
1310 if (!pdc_only && internal_resolve_name(group, 0x1C, ip_list, count))
1311 return True;
1312 return internal_resolve_name(group, 0x1B, ip_list, count);
1314 num_addresses++;
1316 if (num_addresses == 0)
1317 return internal_resolve_name(group, name_type, ip_list, count);
1319 return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr));
1320 if(return_iplist == NULL) {
1321 DEBUG(3,("get_dc_list: malloc fail !\n"));
1322 return False;
1324 p = pserver;
1325 *count = 0;
1326 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1327 struct in_addr *more_ip, *tmp;
1328 int count_more;
1329 if (resolve_name_2( name, &more_ip, &count_more, 0x20) == False)
1330 continue;
1331 tmp = (struct in_addr *)realloc(return_iplist,(num_addresses + count_more) * sizeof(struct in_addr));
1332 if (return_iplist == NULL) {
1333 DEBUG(3, ("realloc failed with %d addresses\n", num_addresses + count_more));
1334 SAFE_FREE(return_iplist);
1335 SAFE_FREE(more_ip);
1336 return False;
1338 return_iplist = tmp;
1339 memmove(&return_iplist[(*count)], more_ip, count_more * sizeof(struct in_addr));
1340 SAFE_FREE(more_ip); /* Done with this ... */
1341 *count += count_more;
1342 num_addresses += count_more - 1;
1344 *ip_list = return_iplist;
1345 return (*count != 0);
1346 } else
1347 return internal_resolve_name(group, name_type, ip_list, count);
1350 /********************************************************
1351 Get the IP address list of the Local Master Browsers
1352 ********************************************************/
1354 BOOL get_lmb_list(struct in_addr **ip_list, int *count)
1356 return internal_resolve_name( MSBROWSE, 0x1, ip_list, count);