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);
72 /****************************************************************************
73 do a NBT node status query on an open socket and return an array of
74 structures holding the returned names or NULL if the query failed
75 **************************************************************************/
76 struct node_status *node_status_query(int fd,struct nmb_name *name,
77 struct in_addr to_ip, int *num_names)
81 int retry_time = 2000;
83 struct packet_struct p;
84 struct packet_struct *p2;
85 struct nmb_packet *nmb = &p.packet.nmb;
86 struct node_status *ret;
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;
110 p.timestamp = time(NULL);
111 p.packet_type = NMB_PACKET;
115 if (!send_packet(&p))
121 struct timeval tval2;
122 GetTimeOfDay(&tval2);
123 if (TvalDiff(&tval,&tval2) > retry_time) {
126 if (!found && !send_packet(&p))
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
148 ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
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;
171 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
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);
182 for (i=0;i<count;i++) {
183 if (status[i].type == type)
189 pull_ascii(name, status[i].name, 15, 0, STR_TERMINATE);
195 /****************************************************************************
196 Do a NetBIOS name registation to try to claim a name ...
197 ***************************************************************************/
198 BOOL name_register(int fd, const char *name, int name_type,
199 struct in_addr name_ip, int opcode,
201 struct in_addr to_ip, int *count)
205 struct packet_struct p;
206 struct packet_struct *p2;
207 struct nmb_packet *nmb = &p.packet.nmb;
208 struct in_addr register_ip;
210 DEBUG(4, ("name_register: %s as %s on %s\n", name, inet_ntoa(name_ip), inet_ntoa(to_ip)));
212 register_ip.s_addr = name_ip.s_addr; /* Fix this ... */
214 memset((char *)&p, '\0', sizeof(p));
218 nmb->header.name_trn_id = generate_trn_id();
219 nmb->header.opcode = opcode;
220 nmb->header.response = False;
221 nmb->header.nm_flags.bcast = False;
222 nmb->header.nm_flags.recursion_available = False;
223 nmb->header.nm_flags.recursion_desired = True; /* ? */
224 nmb->header.nm_flags.trunc = False;
225 nmb->header.nm_flags.authoritative = True;
227 nmb->header.qdcount = 1;
228 nmb->header.ancount = 0;
229 nmb->header.nscount = 0;
230 nmb->header.arcount = 1;
232 make_nmb_name(&nmb->question.question_name, name, name_type);
234 nmb->question.question_type = 0x20;
235 nmb->question.question_class = 0x1;
237 /* Now, create the additional stuff for a registration request */
239 if ((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) {
241 DEBUG(0, ("name_register: malloc fail for additional record.\n"));
246 memset((char *)nmb->additional, '\0', sizeof(struct res_rec));
248 nmb->additional->rr_name = nmb->question.question_name;
249 nmb->additional->rr_type = RR_TYPE_NB;
250 nmb->additional->rr_class = RR_CLASS_IN;
252 /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
253 if (nmb->header.nm_flags.bcast)
254 nmb->additional->ttl = PERMANENT_TTL;
256 nmb->additional->ttl = lp_max_ttl();
258 nmb->additional->rdlength = 6;
260 nmb->additional->rdata[0] = NB_MFLAG & 0xFF;
262 /* Set the address for the name we are registering. */
263 putip(&nmb->additional->rdata[2], ®ister_ip);
268 p.timestamp = time(NULL);
269 p.packet_type = NMB_PACKET;
273 if (!send_packet(&p))
278 if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) {
279 debug_nmb_packet(p2);
280 SAFE_FREE(p2); /* No memory leaks ... */
286 /****************************************************************************
287 Do a netbios name query to find someones IP.
288 Returns an array of IP addresses or NULL if none.
289 *count will be set to the number of addresses returned.
290 ****************************************************************************/
291 struct in_addr *name_query(int fd,const char *name,int name_type,
292 BOOL bcast,BOOL recurse,
293 struct in_addr to_ip, int *count)
297 int retry_time = bcast?250:2000;
299 struct packet_struct p;
300 struct packet_struct *p2;
301 struct nmb_packet *nmb = &p.packet.nmb;
302 struct in_addr *ip_list = NULL;
304 memset((char *)&p,'\0',sizeof(p));
307 nmb->header.name_trn_id = generate_trn_id();
308 nmb->header.opcode = 0;
309 nmb->header.response = False;
310 nmb->header.nm_flags.bcast = bcast;
311 nmb->header.nm_flags.recursion_available = False;
312 nmb->header.nm_flags.recursion_desired = recurse;
313 nmb->header.nm_flags.trunc = False;
314 nmb->header.nm_flags.authoritative = False;
315 nmb->header.rcode = 0;
316 nmb->header.qdcount = 1;
317 nmb->header.ancount = 0;
318 nmb->header.nscount = 0;
319 nmb->header.arcount = 0;
321 make_nmb_name(&nmb->question.question_name,name,name_type);
323 nmb->question.question_type = 0x20;
324 nmb->question.question_class = 0x1;
329 p.timestamp = time(NULL);
330 p.packet_type = NMB_PACKET;
334 if (!send_packet(&p))
340 struct timeval tval2;
341 struct in_addr *tmp_ip_list;
343 GetTimeOfDay(&tval2);
344 if (TvalDiff(&tval,&tval2) > retry_time) {
347 if (!found && !send_packet(&p))
353 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
354 struct nmb_packet *nmb2 = &p2->packet.nmb;
355 debug_nmb_packet(p2);
357 /* If we get a Negative Name Query Response from a WINS
358 * server, we should report it and give up.
360 if( 0 == nmb2->header.opcode /* A query response */
361 && !(bcast) /* from a WINS server */
362 && nmb2->header.rcode /* Error returned */
365 if( DEBUGLVL( 3 ) ) {
366 /* Only executed if DEBUGLEVEL >= 3 */
367 dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
368 switch( nmb2->header.rcode ) {
370 dbgtext( "Request was invalidly formatted.\n" );
373 dbgtext( "Problem with NBNS, cannot process name.\n");
376 dbgtext( "The name requested does not exist.\n" );
379 dbgtext( "Unsupported request error.\n" );
382 dbgtext( "Query refused error.\n" );
385 dbgtext( "Unrecognized error code.\n" );
393 if (nmb2->header.opcode != 0 ||
394 nmb2->header.nm_flags.bcast ||
395 nmb2->header.rcode ||
396 !nmb2->header.ancount) {
398 * XXXX what do we do with this? Could be a
399 * redirect, but we'll discard it for the
406 tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
407 * ( (*count) + nmb2->answers->rdlength/6 ) );
410 DEBUG(0,("name_query: Realloc failed.\n"));
414 ip_list = tmp_ip_list;
417 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
418 for (i=0;i<nmb2->answers->rdlength/6;i++) {
419 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
420 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
430 * If we're doing a unicast lookup we only
431 * expect one reply. Don't wait the full 2
432 * seconds if we got one. JRA.
439 /* Reach here if we've timed out waiting for replies.. */
440 if( !bcast && !found ) {
441 /* Timed out wating for WINS server to respond. Mark it dead. */
442 wins_srv_died( to_ip );
448 /********************************************************
449 Start parsing the lmhosts file.
450 *********************************************************/
452 XFILE *startlmhosts(char *fname)
454 XFILE *fp = x_fopen(fname,O_RDONLY, 0);
456 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
457 fname, strerror(errno)));
463 /********************************************************
464 Parse the next line in the lmhosts file.
465 *********************************************************/
467 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
471 while(!x_feof(fp) && !x_ferror(fp)) {
472 pstring ip,flags,extra;
478 if (!fgets_slash(line,sizeof(pstring),fp))
490 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
492 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
494 if (next_token(&ptr,flags,NULL, sizeof(flags)))
496 if (next_token(&ptr,extra,NULL, sizeof(extra)))
502 if (count > 0 && count < 2)
504 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
510 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
514 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
516 if (strchr_m(flags,'G') || strchr_m(flags,'S'))
518 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
522 *ipaddr = *interpret_addr2(ip);
524 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
525 then only add that name type. */
526 if((ptr = strchr_m(name, '#')) != NULL)
531 *name_type = (int)strtol(ptr, &endptr, 16);
533 if(!*ptr || (endptr == ptr))
535 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
539 *(--ptr) = '\0'; /* Truncate at the '#' */
548 /********************************************************
549 Finish parsing the lmhosts file.
550 *********************************************************/
552 void endlmhosts(XFILE *fp)
557 BOOL name_register_wins(const char *name, int name_type)
559 int sock, i, return_count;
560 int num_interfaces = iface_count();
561 struct in_addr sendto_ip;
564 * Check if we have any interfaces, prevents a segfault later
567 if (num_interfaces <= 0)
568 return False; /* Should return some indication of the problem */
571 * Do a broadcast register ...
574 if (0 == wins_srv_count())
579 dbgtext( "name_register_wins: Registering my name %s ", name );
580 dbgtext( "with WINS server %s.\n", wins_srv_name() );
583 sock = open_socket_in( SOCK_DGRAM, 0, 3,
584 interpret_addr("0.0.0.0"), True );
586 if (sock == -1) return False;
588 set_socket_options(sock, "SO_BROADCAST"); /* ????! crh */
590 sendto_ip = wins_srv_ip();
592 if (num_interfaces > 1) {
594 for (i = 0; i < num_interfaces; i++) {
596 if (!name_register(sock, name, name_type, *iface_n_ip(i),
597 NMB_NAME_MULTIHOMED_REG_OPCODE,
598 True, sendto_ip, &return_count)) {
610 if (!name_register(sock, name, name_type, *iface_n_ip(0),
612 True, sendto_ip, &return_count)) {
627 /********************************************************
628 Resolve via "bcast" method.
629 *********************************************************/
631 BOOL name_resolve_bcast(const char *name, int name_type,
632 struct in_addr **return_ip_list, int *return_count)
635 int num_interfaces = iface_count();
637 *return_ip_list = NULL;
641 * "bcast" means do a broadcast lookup on all the local interfaces.
644 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
646 sock = open_socket_in( SOCK_DGRAM, 0, 3,
647 interpret_addr(lp_socket_address()), True );
649 if (sock == -1) return False;
651 set_socket_options(sock,"SO_BROADCAST");
653 * Lookup the name on all the interfaces, return on
654 * the first successful match.
656 for( i = num_interfaces-1; i >= 0; i--) {
657 struct in_addr sendto_ip;
658 /* Done this way to fix compiler error on IRIX 5.x */
659 sendto_ip = *iface_bcast(*iface_n_ip(i));
660 *return_ip_list = name_query(sock, name, name_type, True,
661 True, sendto_ip, return_count);
662 if(*return_ip_list != NULL) {
672 /********************************************************
673 Resolve via "wins" method.
674 *********************************************************/
676 static BOOL resolve_wins(const char *name, int name_type,
677 struct in_addr **return_iplist, int *return_count)
680 struct in_addr wins_ip;
683 *return_iplist = NULL;
687 * "wins" means do a unicast lookup to the WINS server.
688 * Ignore if there is no WINS server specified or if the
689 * WINS server is one of our interfaces (if we're being
690 * called from within nmbd - we can't do this call as we
694 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
696 if (lp_wins_support()) {
698 * We're providing WINS support. Call ourselves so
699 * long as we're not nmbd.
701 extern struct in_addr loopback_ip;
702 wins_ip = loopback_ip;
704 } else if( wins_srv_count() < 1 ) {
705 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
708 wins_ip = wins_srv_ip();
709 wins_ismyip = ismyip(wins_ip);
712 DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) );
713 if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) {
714 sock = open_socket_in( SOCK_DGRAM, 0, 3,
715 interpret_addr(lp_socket_address()),
718 *return_iplist = name_query( sock, name,
722 if(*return_iplist != NULL) {
733 /********************************************************
734 Resolve via "lmhosts" method.
735 *********************************************************/
737 static BOOL resolve_lmhosts(const char *name, int name_type,
738 struct in_addr **return_iplist, int *return_count)
741 * "lmhosts" means parse the local lmhosts file.
747 struct in_addr return_ip;
749 *return_iplist = NULL;
752 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
754 fp = startlmhosts(dyn_LMHOSTSFILE);
756 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
757 if (strequal(name, lmhost_name) &&
758 ((name_type2 == -1) || (name_type == name_type2))
761 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
762 if(*return_iplist == NULL) {
763 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
766 **return_iplist = return_ip;
777 /********************************************************
778 Resolve via "hosts" method.
779 *********************************************************/
781 static BOOL resolve_hosts(const char *name,
782 struct in_addr **return_iplist, int *return_count)
785 * "host" means do a localhost, or dns lookup.
789 *return_iplist = NULL;
792 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
794 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
795 struct in_addr return_ip;
796 putip((char *)&return_ip,(char *)hp->h_addr);
797 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
798 if(*return_iplist == NULL) {
799 DEBUG(3,("resolve_hosts: malloc fail !\n"));
802 **return_iplist = return_ip;
809 /********************************************************
810 Internal interface to resolve a name into an IP address.
811 Use this function if the string is either an IP address, DNS
812 or host name or NetBIOS name. This uses the name switch in the
813 smb.conf to determine the order of name resolution.
814 *********************************************************/
816 static BOOL internal_resolve_name(const char *name, int name_type,
817 struct in_addr **return_iplist, int *return_count)
819 pstring name_resolve_list;
822 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
823 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
824 BOOL is_address = is_ipaddress(name);
826 struct in_addr *nodupes_iplist;
829 *return_iplist = NULL;
832 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
834 if (allzeros || allones || is_address) {
835 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
836 if(*return_iplist == NULL) {
837 DEBUG(3,("internal_resolve_name: malloc fail !\n"));
841 /* if it's in the form of an IP address then get the lib to interpret it */
842 (*return_iplist)->s_addr = inet_addr(name);
844 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
850 pstrcpy(name_resolve_list, lp_name_resolve_order());
851 ptr = name_resolve_list;
855 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
856 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
857 if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
861 } else if(strequal( tok, "lmhosts")) {
862 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
866 } else if(strequal( tok, "wins")) {
867 /* don't resolve 1D via WINS */
868 if (name_type != 0x1D &&
869 resolve_wins(name, name_type, return_iplist, return_count)) {
873 } else if(strequal( tok, "bcast")) {
874 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
879 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
883 /* All of the resolve_* functions above have returned false. */
885 SAFE_FREE(*return_iplist);
892 /* Remove duplicate entries. Some queries, notably #1c (domain
893 controllers) return the PDC in iplist[0] and then all domain
894 controllers including the PDC in iplist[1..n]. Iterating over
895 the iplist when the PDC is down will cause two sets of timeouts. */
897 if ((nodupes_iplist = (struct in_addr *)
898 malloc(sizeof(struct in_addr) * (*return_count)))) {
899 int nodupes_count = 0;
901 /* Iterate over return_iplist looking for duplicates */
903 for (i = 0; i < *return_count; i++) {
904 BOOL is_dupe = False;
907 for (j = i + 1; j < *return_count; j++) {
908 if (ip_equal((*return_iplist)[i],
909 (*return_iplist)[j])) {
917 /* This one not a duplicate */
919 nodupes_iplist[nodupes_count] = (*return_iplist)[i];
924 /* Switcheroo with original list */
926 free(*return_iplist);
928 *return_iplist = nodupes_iplist;
929 *return_count = nodupes_count;
932 /* Display some debugging info */
934 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
937 for (i = 0; i < *return_count; i++)
938 DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
945 /********************************************************
946 Internal interface to resolve a name into one IP address.
947 Use this function if the string is either an IP address, DNS
948 or host name or NetBIOS name. This uses the name switch in the
949 smb.conf to determine the order of name resolution.
950 *********************************************************/
952 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
954 struct in_addr *ip_list = NULL;
957 if (internal_resolve_name(name, name_type, &ip_list, &count)) {
959 /* only return valid addresses for TCP connections */
960 for (i=0; i<count; i++) {
961 char *ip_str = inet_ntoa(ip_list[i]);
963 strcmp(ip_str, "255.255.255.255") != 0 &&
964 strcmp(ip_str, "0.0.0.0") != 0) {
965 *return_ip = ip_list[i];
976 /********************************************************
977 resolve a name of format \\server_name or \\ipaddress
978 into a name. also, cut the \\ from the front for us.
979 *********************************************************/
981 BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
985 const char *sv_name = srv_name;
987 DEBUG(10,("resolve_srv_name: %s\n", srv_name));
989 if (srv_name == NULL || strequal("\\\\.", srv_name))
991 extern pstring global_myname;
992 fstrcpy(dest_host, global_myname);
993 ip = interpret_addr2("127.0.0.1");
997 if (strnequal("\\\\", srv_name, 2))
999 sv_name = &srv_name[2];
1002 fstrcpy(dest_host, sv_name);
1003 /* treat the '*' name specially - it is a magic name for the PDC */
1004 if (strcmp(dest_host,"*") == 0) {
1005 extern pstring global_myname;
1006 ret = resolve_name(lp_workgroup(), ip, 0x1B);
1007 lookup_dc_name(global_myname, lp_workgroup(), ip, dest_host);
1009 ret = resolve_name(dest_host, ip, 0x20);
1012 if (is_ipaddress(dest_host))
1014 fstrcpy(dest_host, "*SMBSERVER");
1021 /********************************************************
1022 Find the IP address of the master browser or DMB for a workgroup.
1023 *********************************************************/
1025 BOOL find_master_ip(char *group, struct in_addr *master_ip)
1027 struct in_addr *ip_list = NULL;
1030 if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
1031 *master_ip = ip_list[0];
1035 if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
1036 *master_ip = ip_list[0];
1045 /********************************************************
1046 Lookup a DC name given a Domain name and IP address.
1047 *********************************************************/
1049 BOOL lookup_dc_name(const char *srcname, const char *domain,
1050 struct in_addr *dc_ip, char *ret_name)
1052 #if !defined(I_HATE_WINDOWS_REPLY_CODE)
1058 * Due to the fact win WinNT *sucks* we must do a node status
1059 * query here... JRA.
1064 ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1066 if(ret && *dc_name) {
1067 fstrcpy(ret_name, dc_name);
1073 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1075 JRA - This code is broken with BDC rollover - we need to do a full
1076 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1079 int retry_time = 2000;
1080 struct timeval tval;
1081 struct packet_struct p;
1082 struct dgram_packet *dgram = &p.packet.dgram;
1086 struct sockaddr_in sock_name;
1087 int sock_len = sizeof(sock_name);
1088 const char *mailslot = NET_LOGON_MAILSLOT;
1089 char *mailslot_name;
1092 int dgm_id = generate_trn_id();
1093 int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1098 /* Find out the transient UDP port we have been allocated. */
1099 if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1100 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1107 * Create the request data.
1110 memset(buffer,'\0',sizeof(buffer));
1112 SSVAL(bufp,0,QUERYFORPDC);
1114 fstrcpy(bufp,srcname);
1115 bufp += (strlen(bufp) + 1);
1116 slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1117 mailslot_name = bufp;
1118 bufp += (strlen(bufp) + 1);
1119 bufp = ALIGN2(bufp, buffer);
1120 bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
1123 SSVAL(bufp,4,0xFFFF);
1124 SSVAL(bufp,6,0xFFFF);
1126 len = PTR_DIFF(bufp,buffer);
1128 memset((char *)&p,'\0',sizeof(p));
1130 /* DIRECT GROUP or UNIQUE datagram. */
1131 dgram->header.msg_type = 0x10;
1132 dgram->header.flags.node_type = M_NODE;
1133 dgram->header.flags.first = True;
1134 dgram->header.flags.more = False;
1135 dgram->header.dgm_id = dgm_id;
1136 dgram->header.source_ip = *iface_ip(*pdc_ip);
1137 dgram->header.source_port = ntohs(sock_name.sin_port);
1138 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1139 dgram->header.packet_offset = 0;
1141 make_nmb_name(&dgram->source_name,srcname,0);
1142 make_nmb_name(&dgram->dest_name,domain,0x1C);
1144 ptr = &dgram->data[0];
1146 /* Setup the smb part. */
1147 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1149 set_message(ptr,17,17 + len,True);
1152 CVAL(ptr,smb_com) = SMBtrans;
1153 SSVAL(ptr,smb_vwv1,len);
1154 SSVAL(ptr,smb_vwv11,len);
1155 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1156 SSVAL(ptr,smb_vwv13,3);
1157 SSVAL(ptr,smb_vwv14,1);
1158 SSVAL(ptr,smb_vwv15,1);
1159 SSVAL(ptr,smb_vwv16,2);
1161 pstrcpy(p2,mailslot);
1162 p2 = skip_string(p2,1);
1164 memcpy(p2,buffer,len);
1167 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1170 p.port = DGRAM_PORT;
1172 p.timestamp = time(NULL);
1173 p.packet_type = DGRAM_PACKET;
1175 GetTimeOfDay(&tval);
1177 if (!send_packet(&p)) {
1178 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1186 struct timeval tval2;
1187 struct packet_struct *p_ret;
1189 GetTimeOfDay(&tval2);
1190 if (TvalDiff(&tval,&tval2) > retry_time) {
1193 if (!send_packet(&p)) {
1194 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1198 GetTimeOfDay(&tval);
1202 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1203 struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1207 buf = &dgram2->data[0];
1210 if (CVAL(buf,smb_com) != SMBtrans) {
1211 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1212 CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1217 len = SVAL(buf,smb_vwv11);
1218 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1221 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1226 DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1227 nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1228 inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1230 if(SVAL(buf2,0) != QUERYFORPDC_R) {
1231 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1232 (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1238 /* Note this is safe as it is a bounded strcpy. */
1239 fstrcpy(ret_name, buf2);
1240 ret_name[sizeof(fstring)-1] = '\0';
1249 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1253 /********************************************************
1254 Get the IP address list of the PDC/BDC's of a Domain.
1255 *********************************************************/
1257 BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count)
1259 int name_type = pdc_only ? 0x1B : 0x1C;
1262 * If it's our domain then
1263 * use the 'password server' parameter.
1266 if (strequal(group, lp_workgroup())) {
1268 char *pserver = lp_passwordserver();
1270 int num_adresses = 0;
1271 struct in_addr *return_iplist = NULL;
1274 return internal_resolve_name(group, name_type, ip_list, count);
1277 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1278 if (strequal(name, "*"))
1279 return internal_resolve_name(group, name_type, ip_list, count);
1282 if (num_adresses == 0)
1283 return internal_resolve_name(group, name_type, ip_list, count);
1285 return_iplist = (struct in_addr *)malloc(num_adresses * sizeof(struct in_addr));
1286 if(return_iplist == NULL) {
1287 DEBUG(3,("get_dc_list: malloc fail !\n"));
1292 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1293 struct in_addr name_ip;
1294 if (resolve_name( name, &name_ip, 0x20) == False)
1296 return_iplist[(*count)++] = name_ip;
1298 *ip_list = return_iplist;
1299 return (*count != 0);
1301 return internal_resolve_name(group, name_type, ip_list, count);
1304 /********************************************************
1305 Get the IP address list of the Local Master Browsers
1306 ********************************************************/
1307 BOOL get_lmb_list(struct in_addr **ip_list, int *count)
1309 return internal_resolve_name( MSBROWSE, 0x1, ip_list, count);