2 Unix SMB/CIFS implementation.
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.
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)
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;
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;
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);
66 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
67 ret[i].type, ret[i].flags));
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)
82 int retry_time = 2000;
84 struct packet_struct p;
85 struct packet_struct *p2;
86 struct nmb_packet *nmb = &p.packet.nmb;
87 struct node_status *ret;
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;
111 p.timestamp = time(NULL);
112 p.packet_type = NMB_PACKET;
116 if (!send_packet(&p))
122 struct timeval tval2;
123 GetTimeOfDay(&tval2);
124 if (TvalDiff(&tval,&tval2) > retry_time) {
127 if (!found && !send_packet(&p))
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
149 ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
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;
173 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
174 q_type, inet_ntoa(to_ip)));
176 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
180 /* W2K PDC's seem not to respond to '*'#0. JRA */
181 make_nmb_name(&nname, q_name, q_type);
182 status = node_status_query(sock, &nname, to_ip, &count);
187 for (i=0;i<count;i++) {
188 if (status[i].type == type)
194 pull_ascii(name, status[i].name, 15, -1, STR_TERMINATE);
200 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
203 DEBUGADD(10, (", ip address is %s", inet_ntoa(to_ip)));
210 /****************************************************************************
211 Do a NetBIOS name registation to try to claim a name ...
212 ***************************************************************************/
213 BOOL name_register(int fd, const char *name, int name_type,
214 struct in_addr name_ip, int opcode,
216 struct in_addr to_ip, int *count)
220 struct packet_struct p;
221 struct packet_struct *p2;
222 struct nmb_packet *nmb = &p.packet.nmb;
223 struct in_addr register_ip;
225 DEBUG(4, ("name_register: %s as %s on %s\n", name, inet_ntoa(name_ip), inet_ntoa(to_ip)));
227 register_ip.s_addr = name_ip.s_addr; /* Fix this ... */
229 memset((char *)&p, '\0', sizeof(p));
233 nmb->header.name_trn_id = generate_trn_id();
234 nmb->header.opcode = opcode;
235 nmb->header.response = False;
236 nmb->header.nm_flags.bcast = False;
237 nmb->header.nm_flags.recursion_available = False;
238 nmb->header.nm_flags.recursion_desired = True; /* ? */
239 nmb->header.nm_flags.trunc = False;
240 nmb->header.nm_flags.authoritative = True;
242 nmb->header.qdcount = 1;
243 nmb->header.ancount = 0;
244 nmb->header.nscount = 0;
245 nmb->header.arcount = 1;
247 make_nmb_name(&nmb->question.question_name, name, name_type);
249 nmb->question.question_type = 0x20;
250 nmb->question.question_class = 0x1;
252 /* Now, create the additional stuff for a registration request */
254 if ((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) {
256 DEBUG(0, ("name_register: malloc fail for additional record.\n"));
261 memset((char *)nmb->additional, '\0', sizeof(struct res_rec));
263 nmb->additional->rr_name = nmb->question.question_name;
264 nmb->additional->rr_type = RR_TYPE_NB;
265 nmb->additional->rr_class = RR_CLASS_IN;
267 /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
268 if (nmb->header.nm_flags.bcast)
269 nmb->additional->ttl = PERMANENT_TTL;
271 nmb->additional->ttl = lp_max_ttl();
273 nmb->additional->rdlength = 6;
275 nmb->additional->rdata[0] = NB_MFLAG & 0xFF;
277 /* Set the address for the name we are registering. */
278 putip(&nmb->additional->rdata[2], ®ister_ip);
283 p.timestamp = time(NULL);
284 p.packet_type = NMB_PACKET;
288 if (!send_packet(&p))
293 if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) {
294 debug_nmb_packet(p2);
295 SAFE_FREE(p2); /* No memory leaks ... */
301 /****************************************************************************
302 Do a netbios name query to find someones IP.
303 Returns an array of IP addresses or NULL if none.
304 *count will be set to the number of addresses returned.
305 ****************************************************************************/
306 struct in_addr *name_query(int fd,const char *name,int name_type,
307 BOOL bcast,BOOL recurse,
308 struct in_addr to_ip, int *count)
312 int retry_time = bcast?250:2000;
314 struct packet_struct p;
315 struct packet_struct *p2;
316 struct nmb_packet *nmb = &p.packet.nmb;
317 struct in_addr *ip_list = NULL;
319 memset((char *)&p,'\0',sizeof(p));
322 nmb->header.name_trn_id = generate_trn_id();
323 nmb->header.opcode = 0;
324 nmb->header.response = False;
325 nmb->header.nm_flags.bcast = bcast;
326 nmb->header.nm_flags.recursion_available = False;
327 nmb->header.nm_flags.recursion_desired = recurse;
328 nmb->header.nm_flags.trunc = False;
329 nmb->header.nm_flags.authoritative = False;
330 nmb->header.rcode = 0;
331 nmb->header.qdcount = 1;
332 nmb->header.ancount = 0;
333 nmb->header.nscount = 0;
334 nmb->header.arcount = 0;
336 make_nmb_name(&nmb->question.question_name,name,name_type);
338 nmb->question.question_type = 0x20;
339 nmb->question.question_class = 0x1;
344 p.timestamp = time(NULL);
345 p.packet_type = NMB_PACKET;
349 if (!send_packet(&p))
355 struct timeval tval2;
356 struct in_addr *tmp_ip_list;
358 GetTimeOfDay(&tval2);
359 if (TvalDiff(&tval,&tval2) > retry_time) {
362 if (!found && !send_packet(&p))
368 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
369 struct nmb_packet *nmb2 = &p2->packet.nmb;
370 debug_nmb_packet(p2);
372 /* If we get a Negative Name Query Response from a WINS
373 * server, we should report it and give up.
375 if( 0 == nmb2->header.opcode /* A query response */
376 && !(bcast) /* from a WINS server */
377 && nmb2->header.rcode /* Error returned */
380 if( DEBUGLVL( 3 ) ) {
381 /* Only executed if DEBUGLEVEL >= 3 */
382 dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
383 switch( nmb2->header.rcode ) {
385 dbgtext( "Request was invalidly formatted.\n" );
388 dbgtext( "Problem with NBNS, cannot process name.\n");
391 dbgtext( "The name requested does not exist.\n" );
394 dbgtext( "Unsupported request error.\n" );
397 dbgtext( "Query refused error.\n" );
400 dbgtext( "Unrecognized error code.\n" );
408 if (nmb2->header.opcode != 0 ||
409 nmb2->header.nm_flags.bcast ||
410 nmb2->header.rcode ||
411 !nmb2->header.ancount) {
413 * XXXX what do we do with this? Could be a
414 * redirect, but we'll discard it for the
421 tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
422 * ( (*count) + nmb2->answers->rdlength/6 ) );
425 DEBUG(0,("name_query: Realloc failed.\n"));
429 ip_list = tmp_ip_list;
432 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
433 for (i=0;i<nmb2->answers->rdlength/6;i++) {
434 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
435 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
445 * If we're doing a unicast lookup we only
446 * expect one reply. Don't wait the full 2
447 * seconds if we got one. JRA.
454 /* Reach here if we've timed out waiting for replies.. */
455 if( !bcast && !found ) {
456 /* Timed out wating for WINS server to respond. Mark it dead. */
457 wins_srv_died( to_ip );
463 /********************************************************
464 Start parsing the lmhosts file.
465 *********************************************************/
467 XFILE *startlmhosts(char *fname)
469 XFILE *fp = x_fopen(fname,O_RDONLY, 0);
471 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
472 fname, strerror(errno)));
478 /********************************************************
479 Parse the next line in the lmhosts file.
480 *********************************************************/
482 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
486 while(!x_feof(fp) && !x_ferror(fp)) {
487 pstring ip,flags,extra;
493 if (!fgets_slash(line,sizeof(pstring),fp))
505 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
507 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
509 if (next_token(&ptr,flags,NULL, sizeof(flags)))
511 if (next_token(&ptr,extra,NULL, sizeof(extra)))
517 if (count > 0 && count < 2)
519 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
525 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
529 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
531 if (strchr_m(flags,'G') || strchr_m(flags,'S'))
533 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
537 *ipaddr = *interpret_addr2(ip);
539 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
540 then only add that name type. */
541 if((ptr = strchr_m(name, '#')) != NULL)
546 *name_type = (int)strtol(ptr, &endptr, 16);
548 if(!*ptr || (endptr == ptr))
550 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
554 *(--ptr) = '\0'; /* Truncate at the '#' */
563 /********************************************************
564 Finish parsing the lmhosts file.
565 *********************************************************/
567 void endlmhosts(XFILE *fp)
572 BOOL name_register_wins(const char *name, int name_type)
574 int sock, i, return_count;
575 int num_interfaces = iface_count();
576 struct in_addr sendto_ip;
579 * Check if we have any interfaces, prevents a segfault later
582 if (num_interfaces <= 0)
583 return False; /* Should return some indication of the problem */
586 * Do a broadcast register ...
589 if (0 == wins_srv_count())
594 dbgtext( "name_register_wins: Registering my name %s ", name );
595 dbgtext( "with WINS server %s.\n", wins_srv_name() );
598 sock = open_socket_in( SOCK_DGRAM, 0, 3,
599 interpret_addr("0.0.0.0"), True );
601 if (sock == -1) return False;
603 set_socket_options(sock, "SO_BROADCAST"); /* ????! crh */
605 sendto_ip = wins_srv_ip();
607 if (num_interfaces > 1) {
609 for (i = 0; i < num_interfaces; i++) {
611 if (!name_register(sock, name, name_type, *iface_n_ip(i),
612 NMB_NAME_MULTIHOMED_REG_OPCODE,
613 True, sendto_ip, &return_count)) {
625 if (!name_register(sock, name, name_type, *iface_n_ip(0),
627 True, sendto_ip, &return_count)) {
642 /********************************************************
643 Resolve via "bcast" method.
644 *********************************************************/
646 BOOL name_resolve_bcast(const char *name, int name_type,
647 struct in_addr **return_ip_list, int *return_count)
650 int num_interfaces = iface_count();
652 *return_ip_list = NULL;
656 * "bcast" means do a broadcast lookup on all the local interfaces.
659 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
661 sock = open_socket_in( SOCK_DGRAM, 0, 3,
662 interpret_addr(lp_socket_address()), True );
664 if (sock == -1) return False;
666 set_socket_options(sock,"SO_BROADCAST");
668 * Lookup the name on all the interfaces, return on
669 * the first successful match.
671 for( i = num_interfaces-1; i >= 0; i--) {
672 struct in_addr sendto_ip;
673 /* Done this way to fix compiler error on IRIX 5.x */
674 sendto_ip = *iface_n_bcast(i);
675 *return_ip_list = name_query(sock, name, name_type, True,
676 True, sendto_ip, return_count);
677 if(*return_ip_list != NULL) {
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)
695 struct in_addr wins_ip;
698 *return_iplist = NULL;
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
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;
719 } else if( wins_srv_count() < 1 ) {
720 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
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()),
733 *return_iplist = name_query( sock, name,
737 if(*return_iplist != NULL) {
748 /********************************************************
749 Resolve via "lmhosts" method.
750 *********************************************************/
752 static BOOL resolve_lmhosts(const char *name, int name_type,
753 struct in_addr **return_iplist, int *return_count)
756 * "lmhosts" means parse the local lmhosts file.
762 struct in_addr return_ip;
764 *return_iplist = NULL;
767 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
769 fp = startlmhosts(dyn_LMHOSTSFILE);
771 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
772 if (strequal(name, lmhost_name) &&
773 ((name_type2 == -1) || (name_type == name_type2))
776 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
777 if(*return_iplist == NULL) {
778 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
781 **return_iplist = return_ip;
792 /********************************************************
793 Resolve via "hosts" method.
794 *********************************************************/
796 static BOOL resolve_hosts(const char *name,
797 struct in_addr **return_iplist, int *return_count)
800 * "host" means do a localhost, or dns lookup.
804 *return_iplist = NULL;
807 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
809 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
810 struct in_addr return_ip;
811 putip((char *)&return_ip,(char *)hp->h_addr);
812 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
813 if(*return_iplist == NULL) {
814 DEBUG(3,("resolve_hosts: malloc fail !\n"));
817 **return_iplist = return_ip;
824 /********************************************************
825 Internal interface to resolve a name into an IP address.
826 Use this function if the string is either an IP address, DNS
827 or host name or NetBIOS name. This uses the name switch in the
828 smb.conf to determine the order of name resolution.
829 *********************************************************/
831 static BOOL internal_resolve_name(const char *name, int name_type,
832 struct in_addr **return_iplist, int *return_count)
834 pstring name_resolve_list;
837 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
838 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
839 BOOL is_address = is_ipaddress(name);
841 struct in_addr *nodupes_iplist;
844 *return_iplist = NULL;
847 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
849 if (allzeros || allones || is_address) {
850 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
851 if(*return_iplist == NULL) {
852 DEBUG(3,("internal_resolve_name: malloc fail !\n"));
856 /* if it's in the form of an IP address then get the lib to interpret it */
857 (*return_iplist)->s_addr = inet_addr(name);
859 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
865 pstrcpy(name_resolve_list, lp_name_resolve_order());
866 ptr = name_resolve_list;
870 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
871 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
872 if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
876 } else if(strequal( tok, "lmhosts")) {
877 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
881 } else if(strequal( tok, "wins")) {
882 /* don't resolve 1D via WINS */
883 if (name_type != 0x1D &&
884 resolve_wins(name, name_type, return_iplist, return_count)) {
888 } else if(strequal( tok, "bcast")) {
889 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
894 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
898 /* All of the resolve_* functions above have returned false. */
900 SAFE_FREE(*return_iplist);
907 /* Remove duplicate entries. Some queries, notably #1c (domain
908 controllers) return the PDC in iplist[0] and then all domain
909 controllers including the PDC in iplist[1..n]. Iterating over
910 the iplist when the PDC is down will cause two sets of timeouts. */
912 if (*return_count && (nodupes_iplist = (struct in_addr *)
913 malloc(sizeof(struct in_addr) * (*return_count)))) {
914 int nodupes_count = 0;
916 /* Iterate over return_iplist looking for duplicates */
918 for (i = 0; i < *return_count; i++) {
919 BOOL is_dupe = False;
922 for (j = i + 1; j < *return_count; j++) {
923 if (ip_equal((*return_iplist)[i],
924 (*return_iplist)[j])) {
932 /* This one not a duplicate */
934 nodupes_iplist[nodupes_count] = (*return_iplist)[i];
939 /* Switcheroo with original list */
941 free(*return_iplist);
943 *return_iplist = nodupes_iplist;
944 *return_count = nodupes_count;
947 /* Display some debugging info */
949 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
952 for (i = 0; i < *return_count; i++)
953 DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
960 /********************************************************
961 Internal interface to resolve a name into one IP address.
962 Use this function if the string is either an IP address, DNS
963 or host name or NetBIOS name. This uses the name switch in the
964 smb.conf to determine the order of name resolution.
965 *********************************************************/
967 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
969 struct in_addr *ip_list = NULL;
972 if (is_ipaddress(name)) {
973 *return_ip = *interpret_addr2(name);
977 if (internal_resolve_name(name, name_type, &ip_list, &count)) {
979 /* only return valid addresses for TCP connections */
980 for (i=0; i<count; i++) {
981 char *ip_str = inet_ntoa(ip_list[i]);
983 strcmp(ip_str, "255.255.255.255") != 0 &&
984 strcmp(ip_str, "0.0.0.0") != 0) {
985 *return_ip = ip_list[i];
996 /********************************************************
997 resolve a name of format \\server_name or \\ipaddress
998 into a name. also, cut the \\ from the front for us.
999 *********************************************************/
1001 BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
1005 const char *sv_name = srv_name;
1007 DEBUG(10,("resolve_srv_name: %s\n", srv_name));
1009 if (srv_name == NULL || strequal("\\\\.", srv_name))
1011 extern pstring global_myname;
1012 fstrcpy(dest_host, global_myname);
1013 ip = interpret_addr2("127.0.0.1");
1017 if (strnequal("\\\\", srv_name, 2))
1019 sv_name = &srv_name[2];
1022 fstrcpy(dest_host, sv_name);
1023 /* treat the '*' name specially - it is a magic name for the PDC */
1024 if (strcmp(dest_host,"*") == 0) {
1025 extern pstring global_myname;
1026 ret = resolve_name(lp_workgroup(), ip, 0x1B);
1027 lookup_dc_name(global_myname, lp_workgroup(), ip, dest_host);
1029 ret = resolve_name(dest_host, ip, 0x20);
1032 if (is_ipaddress(dest_host))
1034 fstrcpy(dest_host, "*SMBSERVER");
1041 /********************************************************
1042 Find the IP address of the master browser or DMB for a workgroup.
1043 *********************************************************/
1045 BOOL find_master_ip(char *group, struct in_addr *master_ip)
1047 struct in_addr *ip_list = NULL;
1050 if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
1051 *master_ip = ip_list[0];
1055 if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
1056 *master_ip = ip_list[0];
1065 /********************************************************
1066 Lookup a DC name given a Domain name and IP address.
1067 *********************************************************/
1069 BOOL lookup_dc_name(const char *srcname, const char *domain,
1070 struct in_addr *dc_ip, char *ret_name)
1072 #if !defined(I_HATE_WINDOWS_REPLY_CODE)
1078 * Due to the fact win WinNT *sucks* we must do a node status
1079 * query here... JRA.
1084 ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1086 if(ret && *dc_name) {
1087 fstrcpy(ret_name, dc_name);
1093 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1095 JRA - This code is broken with BDC rollover - we need to do a full
1096 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1099 int retry_time = 2000;
1100 struct timeval tval;
1101 struct packet_struct p;
1102 struct dgram_packet *dgram = &p.packet.dgram;
1106 struct sockaddr_in sock_name;
1107 int sock_len = sizeof(sock_name);
1108 const char *mailslot = NET_LOGON_MAILSLOT;
1109 char *mailslot_name;
1112 int dgm_id = generate_trn_id();
1113 int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1118 /* Find out the transient UDP port we have been allocated. */
1119 if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1120 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1127 * Create the request data.
1130 memset(buffer,'\0',sizeof(buffer));
1132 SSVAL(bufp,0,QUERYFORPDC);
1134 fstrcpy(bufp,srcname);
1135 bufp += (strlen(bufp) + 1);
1136 slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1137 mailslot_name = bufp;
1138 bufp += (strlen(bufp) + 1);
1139 bufp = ALIGN2(bufp, buffer);
1140 bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
1143 SSVAL(bufp,4,0xFFFF);
1144 SSVAL(bufp,6,0xFFFF);
1146 len = PTR_DIFF(bufp,buffer);
1148 memset((char *)&p,'\0',sizeof(p));
1150 /* DIRECT GROUP or UNIQUE datagram. */
1151 dgram->header.msg_type = 0x10;
1152 dgram->header.flags.node_type = M_NODE;
1153 dgram->header.flags.first = True;
1154 dgram->header.flags.more = False;
1155 dgram->header.dgm_id = dgm_id;
1156 dgram->header.source_ip = *iface_ip(*pdc_ip);
1157 dgram->header.source_port = ntohs(sock_name.sin_port);
1158 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1159 dgram->header.packet_offset = 0;
1161 make_nmb_name(&dgram->source_name,srcname,0);
1162 make_nmb_name(&dgram->dest_name,domain,0x1C);
1164 ptr = &dgram->data[0];
1166 /* Setup the smb part. */
1167 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1169 set_message(ptr,17,17 + len,True);
1172 CVAL(ptr,smb_com) = SMBtrans;
1173 SSVAL(ptr,smb_vwv1,len);
1174 SSVAL(ptr,smb_vwv11,len);
1175 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1176 SSVAL(ptr,smb_vwv13,3);
1177 SSVAL(ptr,smb_vwv14,1);
1178 SSVAL(ptr,smb_vwv15,1);
1179 SSVAL(ptr,smb_vwv16,2);
1181 pstrcpy(p2,mailslot);
1182 p2 = skip_string(p2,1);
1184 memcpy(p2,buffer,len);
1187 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1190 p.port = DGRAM_PORT;
1192 p.timestamp = time(NULL);
1193 p.packet_type = DGRAM_PACKET;
1195 GetTimeOfDay(&tval);
1197 if (!send_packet(&p)) {
1198 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1206 struct timeval tval2;
1207 struct packet_struct *p_ret;
1209 GetTimeOfDay(&tval2);
1210 if (TvalDiff(&tval,&tval2) > retry_time) {
1213 if (!send_packet(&p)) {
1214 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1218 GetTimeOfDay(&tval);
1222 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1223 struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1227 buf = &dgram2->data[0];
1230 if (CVAL(buf,smb_com) != SMBtrans) {
1231 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1232 CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1237 len = SVAL(buf,smb_vwv11);
1238 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1241 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1246 DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1247 nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1248 inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1250 if(SVAL(buf2,0) != QUERYFORPDC_R) {
1251 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1252 (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1258 /* Note this is safe as it is a bounded strcpy. */
1259 fstrcpy(ret_name, buf2);
1260 ret_name[sizeof(fstring)-1] = '\0';
1269 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1272 /********************************************************
1273 Get the IP address list of the Local Master Browsers
1274 ********************************************************/
1276 BOOL get_lmb_list(struct in_addr **ip_list, int *count)
1278 return internal_resolve_name( MSBROWSE, 0x1, ip_list, count);
1281 /********************************************************
1282 Get the IP address list of the PDC/BDC's of a Domain.
1283 *********************************************************/
1285 BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count)
1287 int name_type = pdc_only ? 0x1B : 0x1C;
1290 * If it's our domain then
1291 * use the 'password server' parameter.
1294 if (strequal(group, lp_workgroup())) {
1296 char *pserver = lp_passwordserver();
1298 int num_adresses = 0;
1299 struct in_addr *return_iplist = NULL;
1302 return internal_resolve_name(group, name_type, ip_list, count);
1305 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1306 if (strequal(name, "*"))
1307 return internal_resolve_name(group, name_type, ip_list, count);
1310 if (num_adresses == 0)
1311 return internal_resolve_name(group, name_type, ip_list, count);
1313 return_iplist = (struct in_addr *)malloc(num_adresses * sizeof(struct in_addr));
1314 if(return_iplist == NULL) {
1315 DEBUG(3,("get_dc_list: malloc fail !\n"));
1320 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1321 struct in_addr name_ip;
1322 if (resolve_name( name, &name_ip, 0x20) == False)
1324 return_iplist[(*count)++] = name_ip;
1326 *ip_list = return_iplist;
1327 return (*count != 0);
1329 return internal_resolve_name(group, name_type, ip_list, count);