2 Unix SMB/Netbios implementation.
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.
25 /* nmbd.c sets this to True. */
26 BOOL global_in_nmbd = False;
28 /****************************************************************************
29 generate a random trn_id
30 ****************************************************************************/
31 static int generate_trn_id(void)
36 sys_srandom(sys_getpid());
39 trn_id = sys_random();
41 return trn_id % (unsigned)0x7FFF;
45 /****************************************************************************
46 parse a node status response into an array of structures
47 ****************************************************************************/
48 static struct node_status *parse_node_status(char *p, int *num_names)
50 struct node_status *ret;
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;
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);
67 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
68 ret[i].type, ret[i].flags));
74 /****************************************************************************
75 do a NBT node status query on an open socket and return an array of
76 structures holding the returned names or NULL if the query failed
77 **************************************************************************/
78 struct node_status *node_status_query(int fd,struct nmb_name *name,
79 struct in_addr to_ip, int *num_names)
83 int retry_time = 2000;
85 struct packet_struct p;
86 struct packet_struct *p2;
87 struct nmb_packet *nmb = &p.packet.nmb;
88 struct node_status *ret;
92 nmb->header.name_trn_id = generate_trn_id();
93 nmb->header.opcode = 0;
94 nmb->header.response = False;
95 nmb->header.nm_flags.bcast = False;
96 nmb->header.nm_flags.recursion_available = False;
97 nmb->header.nm_flags.recursion_desired = False;
98 nmb->header.nm_flags.trunc = False;
99 nmb->header.nm_flags.authoritative = False;
100 nmb->header.rcode = 0;
101 nmb->header.qdcount = 1;
102 nmb->header.ancount = 0;
103 nmb->header.nscount = 0;
104 nmb->header.arcount = 0;
105 nmb->question.question_name = *name;
106 nmb->question.question_type = 0x21;
107 nmb->question.question_class = 0x1;
112 p.timestamp = time(NULL);
113 p.packet_type = NMB_PACKET;
117 if (!send_packet(&p))
123 struct timeval tval2;
124 GetTimeOfDay(&tval2);
125 if (TvalDiff(&tval,&tval2) > retry_time) {
128 if (!found && !send_packet(&p))
134 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
135 struct nmb_packet *nmb2 = &p2->packet.nmb;
136 debug_nmb_packet(p2);
138 if (nmb2->header.opcode != 0 ||
139 nmb2->header.nm_flags.bcast ||
140 nmb2->header.rcode ||
141 !nmb2->header.ancount ||
142 nmb2->answers->rr_type != 0x21) {
143 /* XXXX what do we do with this? could be a
144 redirect, but we'll discard it for the
150 ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
160 /****************************************************************************
161 find the first type XX name in a node status reply - used for finding
162 a servers name given its IP
163 return the matched name in *name
164 **************************************************************************/
166 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name)
168 struct node_status *status = NULL;
169 struct nmb_name nname;
174 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
175 q_type, inet_ntoa(to_ip)));
177 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
181 /* W2K PDC's seem not to respond to '*'#0. JRA */
182 make_nmb_name(&nname, q_name, q_type);
183 status = node_status_query(sock, &nname, to_ip, &count);
188 for (i=0;i<count;i++) {
189 if (status[i].type == type)
195 pull_ascii(name, status[i].name, 15, 0, STR_TERMINATE);
201 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
204 DEBUGADD(10, (", ip address is %s", inet_ntoa(to_ip)));
211 /****************************************************************************
212 Do a NetBIOS name registation to try to claim a name ...
213 ***************************************************************************/
214 BOOL name_register(int fd, const char *name, int name_type,
215 struct in_addr name_ip, int opcode,
217 struct in_addr to_ip, int *count)
221 struct packet_struct p;
222 struct packet_struct *p2;
223 struct nmb_packet *nmb = &p.packet.nmb;
224 struct in_addr register_ip;
226 DEBUG(4, ("name_register: %s as %s on %s\n", name, inet_ntoa(name_ip), inet_ntoa(to_ip)));
228 register_ip.s_addr = name_ip.s_addr; /* Fix this ... */
230 memset((char *)&p, '\0', sizeof(p));
234 nmb->header.name_trn_id = generate_trn_id();
235 nmb->header.opcode = opcode;
236 nmb->header.response = False;
237 nmb->header.nm_flags.bcast = False;
238 nmb->header.nm_flags.recursion_available = False;
239 nmb->header.nm_flags.recursion_desired = True; /* ? */
240 nmb->header.nm_flags.trunc = False;
241 nmb->header.nm_flags.authoritative = True;
243 nmb->header.qdcount = 1;
244 nmb->header.ancount = 0;
245 nmb->header.nscount = 0;
246 nmb->header.arcount = 1;
248 make_nmb_name(&nmb->question.question_name, name, name_type);
250 nmb->question.question_type = 0x20;
251 nmb->question.question_class = 0x1;
253 /* Now, create the additional stuff for a registration request */
255 if ((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) {
257 DEBUG(0, ("name_register: malloc fail for additional record.\n"));
262 memset((char *)nmb->additional, '\0', sizeof(struct res_rec));
264 nmb->additional->rr_name = nmb->question.question_name;
265 nmb->additional->rr_type = RR_TYPE_NB;
266 nmb->additional->rr_class = RR_CLASS_IN;
268 /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
269 if (nmb->header.nm_flags.bcast)
270 nmb->additional->ttl = PERMANENT_TTL;
272 nmb->additional->ttl = lp_max_ttl();
274 nmb->additional->rdlength = 6;
276 nmb->additional->rdata[0] = NB_MFLAG & 0xFF;
278 /* Set the address for the name we are registering. */
279 putip(&nmb->additional->rdata[2], ®ister_ip);
284 p.timestamp = time(NULL);
285 p.packet_type = NMB_PACKET;
289 if (!send_packet(&p))
294 if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) {
295 debug_nmb_packet(p2);
296 SAFE_FREE(p2); /* No memory leaks ... */
302 /****************************************************************************
303 Do a netbios name query to find someones IP.
304 Returns an array of IP addresses or NULL if none.
305 *count will be set to the number of addresses returned.
306 ****************************************************************************/
307 struct in_addr *name_query(int fd,const char *name,int name_type,
308 BOOL bcast,BOOL recurse,
309 struct in_addr to_ip, int *count)
313 int retry_time = bcast?250:2000;
315 struct packet_struct p;
316 struct packet_struct *p2;
317 struct nmb_packet *nmb = &p.packet.nmb;
318 struct in_addr *ip_list = NULL;
320 memset((char *)&p,'\0',sizeof(p));
323 nmb->header.name_trn_id = generate_trn_id();
324 nmb->header.opcode = 0;
325 nmb->header.response = False;
326 nmb->header.nm_flags.bcast = bcast;
327 nmb->header.nm_flags.recursion_available = False;
328 nmb->header.nm_flags.recursion_desired = recurse;
329 nmb->header.nm_flags.trunc = False;
330 nmb->header.nm_flags.authoritative = False;
331 nmb->header.rcode = 0;
332 nmb->header.qdcount = 1;
333 nmb->header.ancount = 0;
334 nmb->header.nscount = 0;
335 nmb->header.arcount = 0;
337 make_nmb_name(&nmb->question.question_name,name,name_type);
339 nmb->question.question_type = 0x20;
340 nmb->question.question_class = 0x1;
345 p.timestamp = time(NULL);
346 p.packet_type = NMB_PACKET;
350 if (!send_packet(&p))
356 struct timeval tval2;
357 struct in_addr *tmp_ip_list;
359 GetTimeOfDay(&tval2);
360 if (TvalDiff(&tval,&tval2) > retry_time) {
363 if (!found && !send_packet(&p))
369 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
370 struct nmb_packet *nmb2 = &p2->packet.nmb;
371 debug_nmb_packet(p2);
373 /* If we get a Negative Name Query Response from a WINS
374 * server, we should report it and give up.
376 if( 0 == nmb2->header.opcode /* A query response */
377 && !(bcast) /* from a WINS server */
378 && nmb2->header.rcode /* Error returned */
381 if( DEBUGLVL( 3 ) ) {
382 /* Only executed if DEBUGLEVEL >= 3 */
383 dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
384 switch( nmb2->header.rcode ) {
386 dbgtext( "Request was invalidly formatted.\n" );
389 dbgtext( "Problem with NBNS, cannot process name.\n");
392 dbgtext( "The name requested does not exist.\n" );
395 dbgtext( "Unsupported request error.\n" );
398 dbgtext( "Query refused error.\n" );
401 dbgtext( "Unrecognized error code.\n" );
409 if (nmb2->header.opcode != 0 ||
410 nmb2->header.nm_flags.bcast ||
411 nmb2->header.rcode ||
412 !nmb2->header.ancount) {
414 * XXXX what do we do with this? Could be a
415 * redirect, but we'll discard it for the
422 tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
423 * ( (*count) + nmb2->answers->rdlength/6 ) );
426 DEBUG(0,("name_query: Realloc failed.\n"));
430 ip_list = tmp_ip_list;
433 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
434 for (i=0;i<nmb2->answers->rdlength/6;i++) {
435 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
436 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
446 * If we're doing a unicast lookup we only
447 * expect one reply. Don't wait the full 2
448 * seconds if we got one. JRA.
455 /* Reach here if we've timed out waiting for replies.. */
456 if( !bcast && !found ) {
457 /* Timed out wating for WINS server to respond. Mark it dead. */
458 wins_srv_died( to_ip );
464 /********************************************************
465 Start parsing the lmhosts file.
466 *********************************************************/
468 XFILE *startlmhosts(char *fname)
470 XFILE *fp = x_fopen(fname,O_RDONLY, 0);
472 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
473 fname, strerror(errno)));
479 /********************************************************
480 Parse the next line in the lmhosts file.
481 *********************************************************/
483 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
487 while(!x_feof(fp) && !x_ferror(fp)) {
488 pstring ip,flags,extra;
494 if (!fgets_slash(line,sizeof(pstring),fp))
506 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
508 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
510 if (next_token(&ptr,flags,NULL, sizeof(flags)))
512 if (next_token(&ptr,extra,NULL, sizeof(extra)))
518 if (count > 0 && count < 2)
520 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
526 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
530 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
532 if (strchr_m(flags,'G') || strchr_m(flags,'S'))
534 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
538 *ipaddr = *interpret_addr2(ip);
540 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
541 then only add that name type. */
542 if((ptr = strchr_m(name, '#')) != NULL)
547 *name_type = (int)strtol(ptr, &endptr, 16);
549 if(!*ptr || (endptr == ptr))
551 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
555 *(--ptr) = '\0'; /* Truncate at the '#' */
564 /********************************************************
565 Finish parsing the lmhosts file.
566 *********************************************************/
568 void endlmhosts(XFILE *fp)
573 BOOL name_register_wins(const char *name, int name_type)
575 int sock, i, return_count;
576 int num_interfaces = iface_count();
577 struct in_addr sendto_ip;
580 * Check if we have any interfaces, prevents a segfault later
583 if (num_interfaces <= 0)
584 return False; /* Should return some indication of the problem */
587 * Do a broadcast register ...
590 if (0 == wins_srv_count())
595 dbgtext( "name_register_wins: Registering my name %s ", name );
596 dbgtext( "with WINS server %s.\n", wins_srv_name() );
599 sock = open_socket_in( SOCK_DGRAM, 0, 3,
600 interpret_addr("0.0.0.0"), True );
602 if (sock == -1) return False;
604 set_socket_options(sock, "SO_BROADCAST"); /* ????! crh */
606 sendto_ip = wins_srv_ip();
608 if (num_interfaces > 1) {
610 for (i = 0; i < num_interfaces; i++) {
612 if (!name_register(sock, name, name_type, *iface_n_ip(i),
613 NMB_NAME_MULTIHOMED_REG_OPCODE,
614 True, sendto_ip, &return_count)) {
626 if (!name_register(sock, name, name_type, *iface_n_ip(0),
628 True, sendto_ip, &return_count)) {
643 /********************************************************
644 Resolve via "bcast" method.
645 *********************************************************/
647 BOOL name_resolve_bcast(const char *name, int name_type,
648 struct in_addr **return_ip_list, int *return_count)
651 int num_interfaces = iface_count();
653 *return_ip_list = NULL;
657 * "bcast" means do a broadcast lookup on all the local interfaces.
660 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
662 sock = open_socket_in( SOCK_DGRAM, 0, 3,
663 interpret_addr(lp_socket_address()), True );
665 if (sock == -1) return False;
667 set_socket_options(sock,"SO_BROADCAST");
669 * Lookup the name on all the interfaces, return on
670 * the first successful match.
672 for( i = num_interfaces-1; i >= 0; i--) {
673 struct in_addr sendto_ip;
674 /* Done this way to fix compiler error on IRIX 5.x */
675 sendto_ip = *iface_bcast(*iface_n_ip(i));
676 *return_ip_list = name_query(sock, name, name_type, True,
677 True, sendto_ip, return_count);
678 if(*return_ip_list != NULL) {
688 /********************************************************
689 Resolve via "wins" method.
690 *********************************************************/
692 static BOOL resolve_wins(const char *name, int name_type,
693 struct in_addr **return_iplist, int *return_count)
696 struct in_addr wins_ip;
699 *return_iplist = NULL;
703 * "wins" means do a unicast lookup to the WINS server.
704 * Ignore if there is no WINS server specified or if the
705 * WINS server is one of our interfaces (if we're being
706 * called from within nmbd - we can't do this call as we
710 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
712 if (lp_wins_support()) {
714 * We're providing WINS support. Call ourselves so
715 * long as we're not nmbd.
717 extern struct in_addr loopback_ip;
718 wins_ip = loopback_ip;
720 } else if( wins_srv_count() < 1 ) {
721 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
724 wins_ip = wins_srv_ip();
725 wins_ismyip = ismyip(wins_ip);
728 DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) );
729 if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) {
730 sock = open_socket_in( SOCK_DGRAM, 0, 3,
731 interpret_addr(lp_socket_address()),
734 *return_iplist = name_query( sock, name,
738 if(*return_iplist != NULL) {
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.
763 struct in_addr return_ip;
765 *return_iplist = NULL;
768 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
770 fp = startlmhosts(dyn_LMHOSTSFILE);
772 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
773 if (strequal(name, lmhost_name) &&
774 ((name_type2 == -1) || (name_type == name_type2))
777 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
778 if(*return_iplist == NULL) {
779 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
782 **return_iplist = return_ip;
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.
805 *return_iplist = NULL;
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 struct in_addr return_ip;
812 putip((char *)&return_ip,(char *)hp->h_addr);
813 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
814 if(*return_iplist == NULL) {
815 DEBUG(3,("resolve_hosts: malloc fail !\n"));
818 **return_iplist = return_ip;
825 /********************************************************
826 Internal interface to resolve a name into an IP address.
827 Use this function if the string is either an IP address, DNS
828 or host name or NetBIOS name. This uses the name switch in the
829 smb.conf to determine the order of name resolution.
830 *********************************************************/
832 static BOOL internal_resolve_name(const char *name, int name_type,
833 struct in_addr **return_iplist, int *return_count)
835 pstring name_resolve_list;
838 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
839 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
840 BOOL is_address = is_ipaddress(name);
842 struct in_addr *nodupes_iplist;
845 *return_iplist = NULL;
848 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
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"));
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);
860 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
866 pstrcpy(name_resolve_list, lp_name_resolve_order());
867 ptr = name_resolve_list;
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)) {
877 } else if(strequal( tok, "lmhosts")) {
878 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
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)) {
889 } else if(strequal( tok, "bcast")) {
890 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
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);
908 /* Remove duplicate entries. Some queries, notably #1c (domain
909 controllers) return the PDC in iplist[0] and then all domain
910 controllers including the PDC in iplist[1..n]. Iterating over
911 the iplist when the PDC is down will cause two sets of timeouts. */
913 if ((nodupes_iplist = (struct in_addr *)
914 malloc(sizeof(struct in_addr) * (*return_count)))) {
915 int nodupes_count = 0;
917 /* Iterate over return_iplist looking for duplicates */
919 for (i = 0; i < *return_count; i++) {
920 BOOL is_dupe = False;
923 for (j = i + 1; j < *return_count; j++) {
924 if (ip_equal((*return_iplist)[i],
925 (*return_iplist)[j])) {
933 /* This one not a duplicate */
935 nodupes_iplist[nodupes_count] = (*return_iplist)[i];
940 /* Switcheroo with original list */
942 free(*return_iplist);
944 *return_iplist = nodupes_iplist;
945 *return_count = nodupes_count;
948 /* Display some debugging info */
950 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
953 for (i = 0; i < *return_count; i++)
954 DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
961 /********************************************************
962 Internal interface to resolve a name into one IP address.
963 Use this function if the string is either an IP address, DNS
964 or host name or NetBIOS name. This uses the name switch in the
965 smb.conf to determine the order of name resolution.
966 *********************************************************/
968 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
970 struct in_addr *ip_list = NULL;
973 if (is_ipaddress(name)) {
974 *return_ip = *interpret_addr2(name);
978 if (internal_resolve_name(name, name_type, &ip_list, &count)) {
980 /* only return valid addresses for TCP connections */
981 for (i=0; i<count; i++) {
982 char *ip_str = inet_ntoa(ip_list[i]);
984 strcmp(ip_str, "255.255.255.255") != 0 &&
985 strcmp(ip_str, "0.0.0.0") != 0) {
986 *return_ip = ip_list[i];
997 /********************************************************
998 resolve a name of format \\server_name or \\ipaddress
999 into a name. also, cut the \\ from the front for us.
1000 *********************************************************/
1002 BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
1006 const char *sv_name = srv_name;
1008 DEBUG(10,("resolve_srv_name: %s\n", srv_name));
1010 if (srv_name == NULL || strequal("\\\\.", srv_name))
1012 extern pstring global_myname;
1013 fstrcpy(dest_host, global_myname);
1014 ip = interpret_addr2("127.0.0.1");
1018 if (strnequal("\\\\", srv_name, 2))
1020 sv_name = &srv_name[2];
1023 fstrcpy(dest_host, sv_name);
1024 /* treat the '*' name specially - it is a magic name for the PDC */
1025 if (strcmp(dest_host,"*") == 0) {
1026 extern pstring global_myname;
1027 ret = resolve_name(lp_workgroup(), ip, 0x1B);
1028 lookup_dc_name(global_myname, lp_workgroup(), ip, dest_host);
1030 ret = resolve_name(dest_host, ip, 0x20);
1033 if (is_ipaddress(dest_host))
1035 fstrcpy(dest_host, "*SMBSERVER");
1042 /********************************************************
1043 Find the IP address of the master browser or DMB for a workgroup.
1044 *********************************************************/
1046 BOOL find_master_ip(char *group, struct in_addr *master_ip)
1048 struct in_addr *ip_list = NULL;
1051 if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
1052 *master_ip = ip_list[0];
1056 if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
1057 *master_ip = ip_list[0];
1066 /********************************************************
1067 Lookup a DC name given a Domain name and IP address.
1068 *********************************************************/
1070 BOOL lookup_dc_name(const char *srcname, const char *domain,
1071 struct in_addr *dc_ip, char *ret_name)
1073 #if !defined(I_HATE_WINDOWS_REPLY_CODE)
1079 * Due to the fact win WinNT *sucks* we must do a node status
1080 * query here... JRA.
1085 ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1087 if(ret && *dc_name) {
1088 fstrcpy(ret_name, dc_name);
1094 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1096 JRA - This code is broken with BDC rollover - we need to do a full
1097 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1100 int retry_time = 2000;
1101 struct timeval tval;
1102 struct packet_struct p;
1103 struct dgram_packet *dgram = &p.packet.dgram;
1107 struct sockaddr_in sock_name;
1108 int sock_len = sizeof(sock_name);
1109 const char *mailslot = NET_LOGON_MAILSLOT;
1110 char *mailslot_name;
1113 int dgm_id = generate_trn_id();
1114 int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1119 /* Find out the transient UDP port we have been allocated. */
1120 if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1121 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1128 * Create the request data.
1131 memset(buffer,'\0',sizeof(buffer));
1133 SSVAL(bufp,0,QUERYFORPDC);
1135 fstrcpy(bufp,srcname);
1136 bufp += (strlen(bufp) + 1);
1137 slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1138 mailslot_name = bufp;
1139 bufp += (strlen(bufp) + 1);
1140 bufp = ALIGN2(bufp, buffer);
1141 bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
1144 SSVAL(bufp,4,0xFFFF);
1145 SSVAL(bufp,6,0xFFFF);
1147 len = PTR_DIFF(bufp,buffer);
1149 memset((char *)&p,'\0',sizeof(p));
1151 /* DIRECT GROUP or UNIQUE datagram. */
1152 dgram->header.msg_type = 0x10;
1153 dgram->header.flags.node_type = M_NODE;
1154 dgram->header.flags.first = True;
1155 dgram->header.flags.more = False;
1156 dgram->header.dgm_id = dgm_id;
1157 dgram->header.source_ip = *iface_ip(*pdc_ip);
1158 dgram->header.source_port = ntohs(sock_name.sin_port);
1159 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1160 dgram->header.packet_offset = 0;
1162 make_nmb_name(&dgram->source_name,srcname,0);
1163 make_nmb_name(&dgram->dest_name,domain,0x1C);
1165 ptr = &dgram->data[0];
1167 /* Setup the smb part. */
1168 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1170 set_message(ptr,17,17 + len,True);
1173 CVAL(ptr,smb_com) = SMBtrans;
1174 SSVAL(ptr,smb_vwv1,len);
1175 SSVAL(ptr,smb_vwv11,len);
1176 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1177 SSVAL(ptr,smb_vwv13,3);
1178 SSVAL(ptr,smb_vwv14,1);
1179 SSVAL(ptr,smb_vwv15,1);
1180 SSVAL(ptr,smb_vwv16,2);
1182 pstrcpy(p2,mailslot);
1183 p2 = skip_string(p2,1);
1185 memcpy(p2,buffer,len);
1188 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1191 p.port = DGRAM_PORT;
1193 p.timestamp = time(NULL);
1194 p.packet_type = DGRAM_PACKET;
1196 GetTimeOfDay(&tval);
1198 if (!send_packet(&p)) {
1199 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1207 struct timeval tval2;
1208 struct packet_struct *p_ret;
1210 GetTimeOfDay(&tval2);
1211 if (TvalDiff(&tval,&tval2) > retry_time) {
1214 if (!send_packet(&p)) {
1215 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1219 GetTimeOfDay(&tval);
1223 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1224 struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1228 buf = &dgram2->data[0];
1231 if (CVAL(buf,smb_com) != SMBtrans) {
1232 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1233 CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1238 len = SVAL(buf,smb_vwv11);
1239 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1242 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1247 DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1248 nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1249 inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1251 if(SVAL(buf2,0) != QUERYFORPDC_R) {
1252 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1253 (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1259 /* Note this is safe as it is a bounded strcpy. */
1260 fstrcpy(ret_name, buf2);
1261 ret_name[sizeof(fstring)-1] = '\0';
1270 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1274 /********************************************************
1275 Get the IP address list of the PDC/BDC's of a Domain.
1276 *********************************************************/
1278 BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count)
1280 int name_type = pdc_only ? 0x1B : 0x1C;
1283 * If it's our domain then
1284 * use the 'password server' parameter.
1287 if (strequal(group, lp_workgroup())) {
1289 char *pserver = lp_passwordserver();
1291 int num_adresses = 0;
1292 struct in_addr *return_iplist = NULL;
1295 return internal_resolve_name(group, name_type, ip_list, count);
1298 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1299 if (strequal(name, "*"))
1300 return internal_resolve_name(group, name_type, ip_list, count);
1303 if (num_adresses == 0)
1304 return internal_resolve_name(group, name_type, ip_list, count);
1306 return_iplist = (struct in_addr *)malloc(num_adresses * sizeof(struct in_addr));
1307 if(return_iplist == NULL) {
1308 DEBUG(3,("get_dc_list: malloc fail !\n"));
1313 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1314 struct in_addr name_ip;
1315 if (resolve_name( name, &name_ip, 0x20) == False)
1317 return_iplist[(*count)++] = name_ip;
1319 *ip_list = return_iplist;
1320 return (*count != 0);
1322 return internal_resolve_name(group, name_type, ip_list, count);
1325 /********************************************************
1326 Get the IP address list of the Local Master Browsers
1327 ********************************************************/
1328 BOOL get_lmb_list(struct in_addr **ip_list, int *count)
1330 return internal_resolve_name( MSBROWSE, 0x1, ip_list, count);