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 /* A netbios node status array element. */
32 /* nmbd.c sets this to True. */
33 BOOL global_in_nmbd = False;
35 /****************************************************************************
36 generate a random trn_id
37 ****************************************************************************/
38 static int generate_trn_id(void)
43 sys_srandom(getpid());
46 trn_id = sys_random();
48 return trn_id % (uint_t)0x7FFF;
52 /****************************************************************************
53 parse a node status response into an array of structures
54 ****************************************************************************/
55 static struct node_status *parse_node_status(char *p, int *num_names)
57 struct node_status *ret;
60 *num_names = CVAL(p,0);
62 if (*num_names == 0) return NULL;
64 ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names));
65 if (!ret) return NULL;
68 for (i=0;i< *num_names;i++) {
69 StrnCpy(ret[i].name,p,15);
70 trim_string(ret[i].name,NULL," ");
71 ret[i].type = CVAL(p,15);
74 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
75 ret[i].type, ret[i].flags));
81 /****************************************************************************
82 do a NBT node status query on an open socket and return an array of
83 structures holding the returned names or NULL if the query failed
84 **************************************************************************/
85 struct node_status *node_status_query(int fd,struct nmb_name *name,
86 struct in_addr to_ip, int *num_names)
90 int retry_time = 2000;
92 struct packet_struct p;
93 struct packet_struct *p2;
94 struct nmb_packet *nmb = &p.packet.nmb;
95 struct node_status *ret;
99 nmb->header.name_trn_id = generate_trn_id();
100 nmb->header.opcode = 0;
101 nmb->header.response = False;
102 nmb->header.nm_flags.bcast = False;
103 nmb->header.nm_flags.recursion_available = False;
104 nmb->header.nm_flags.recursion_desired = False;
105 nmb->header.nm_flags.trunc = False;
106 nmb->header.nm_flags.authoritative = False;
107 nmb->header.rcode = 0;
108 nmb->header.qdcount = 1;
109 nmb->header.ancount = 0;
110 nmb->header.nscount = 0;
111 nmb->header.arcount = 0;
112 nmb->question.question_name = *name;
113 nmb->question.question_type = 0x21;
114 nmb->question.question_class = 0x1;
119 p.timestamp = time(NULL);
120 p.packet_type = NMB_PACKET;
124 if (!send_packet(&p))
130 struct timeval tval2;
131 GetTimeOfDay(&tval2);
132 if (TvalDiff(&tval,&tval2) > retry_time) {
135 if (!found && !send_packet(&p))
141 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
142 struct nmb_packet *nmb2 = &p2->packet.nmb;
143 debug_nmb_packet(p2);
145 if (nmb2->header.opcode != 0 ||
146 nmb2->header.nm_flags.bcast ||
147 nmb2->header.rcode ||
148 !nmb2->header.ancount ||
149 nmb2->answers->rr_type != 0x21) {
150 /* XXXX what do we do with this? could be a
151 redirect, but we'll discard it for the
157 ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
167 /****************************************************************************
168 find the first type XX name in a node status reply - used for finding
169 a servers name given its IP
170 return the matched name in *name
171 **************************************************************************/
173 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name)
175 struct node_status *status = NULL;
176 struct nmb_name nname;
181 if (lp_disable_netbios()) {
182 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
186 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
187 q_type, inet_ntoa(to_ip)));
189 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
193 /* W2K PDC's seem not to respond to '*'#0. JRA */
194 make_nmb_name(&nname, q_name, q_type);
195 status = node_status_query(sock, &nname, to_ip, &count);
200 for (i=0;i<count;i++) {
201 if (status[i].type == type)
207 pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
213 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
216 DEBUGADD(10, (", ip address is %s", inet_ntoa(to_ip)));
225 comparison function used by sort_ip_list
227 int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
229 int max_bits1=0, max_bits2=0;
230 int num_interfaces = iface_count();
233 for (i=0;i<num_interfaces;i++) {
236 ip = *iface_n_bcast(i);
237 bits1 = matching_quad_bits((uint8_t *)&ip1->s_addr, (uint8_t *)&ip.s_addr);
238 bits2 = matching_quad_bits((uint8_t *)&ip2->s_addr, (uint8_t *)&ip.s_addr);
239 max_bits1 = MAX(bits1, max_bits1);
240 max_bits2 = MAX(bits2, max_bits2);
243 /* bias towards directly reachable IPs */
244 if (iface_local(*ip1)) {
247 if (iface_local(*ip2)) {
251 return max_bits2 - max_bits1;
255 sort an IP list so that names that are close to one of our interfaces
256 are at the top. This prevents the problem where a WINS server returns an IP that
257 is not reachable from our subnet as the first match
259 static void sort_ip_list(struct in_addr *iplist, int count)
265 qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
269 /****************************************************************************
270 Do a netbios name query to find someones IP.
271 Returns an array of IP addresses or NULL if none.
272 *count will be set to the number of addresses returned.
273 *timed_out is set if we failed by timing out
274 ****************************************************************************/
275 struct in_addr *name_query(int fd,const char *name,int name_type,
276 BOOL bcast,BOOL recurse,
277 struct in_addr to_ip, int *count, int *flags,
282 int retry_time = bcast?250:2000;
284 struct packet_struct p;
285 struct packet_struct *p2;
286 struct nmb_packet *nmb = &p.packet.nmb;
287 struct in_addr *ip_list = NULL;
289 if (lp_disable_netbios()) {
290 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
298 memset((char *)&p,'\0',sizeof(p));
302 nmb->header.name_trn_id = generate_trn_id();
303 nmb->header.opcode = 0;
304 nmb->header.response = False;
305 nmb->header.nm_flags.bcast = bcast;
306 nmb->header.nm_flags.recursion_available = False;
307 nmb->header.nm_flags.recursion_desired = recurse;
308 nmb->header.nm_flags.trunc = False;
309 nmb->header.nm_flags.authoritative = False;
310 nmb->header.rcode = 0;
311 nmb->header.qdcount = 1;
312 nmb->header.ancount = 0;
313 nmb->header.nscount = 0;
314 nmb->header.arcount = 0;
316 make_nmb_name(&nmb->question.question_name,name,name_type);
318 nmb->question.question_type = 0x20;
319 nmb->question.question_class = 0x1;
324 p.timestamp = time(NULL);
325 p.packet_type = NMB_PACKET;
329 if (!send_packet(&p))
335 struct timeval tval2;
336 struct in_addr *tmp_ip_list;
338 GetTimeOfDay(&tval2);
339 if (TvalDiff(&tval,&tval2) > retry_time) {
342 if (!found && !send_packet(&p))
348 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
349 struct nmb_packet *nmb2 = &p2->packet.nmb;
350 debug_nmb_packet(p2);
352 /* If we get a Negative Name Query Response from a WINS
353 * server, we should report it and give up.
355 if( 0 == nmb2->header.opcode /* A query response */
356 && !(bcast) /* from a WINS server */
357 && nmb2->header.rcode /* Error returned */
361 /* Only executed if DEBUGLEVEL >= 3 */
362 DEBUG(3,("Negative name query response, rcode 0x%02x: ", nmb2->header.rcode ));
363 switch( nmb2->header.rcode ) {
365 DEBUG(3,("Request was invalidly formatted.\n" ));
368 DEBUG(3,("Problem with NBNS, cannot process name.\n"));
371 DEBUG(3,("The name requested does not exist.\n" ));
374 DEBUG(3,("Unsupported request error.\n" ));
377 DEBUG(3,("Query refused error.\n" ));
380 DEBUG(3,("Unrecognized error code.\n" ));
388 if (nmb2->header.opcode != 0 ||
389 nmb2->header.nm_flags.bcast ||
390 nmb2->header.rcode ||
391 !nmb2->header.ancount) {
393 * XXXX what do we do with this? Could be a
394 * redirect, but we'll discard it for the
401 tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
402 * ( (*count) + nmb2->answers->rdlength/6 ) );
405 DEBUG(0,("name_query: Realloc failed.\n"));
409 ip_list = tmp_ip_list;
412 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
413 for (i=0;i<nmb2->answers->rdlength/6;i++) {
414 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
415 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
423 /* We add the flags back ... */
424 if (nmb2->header.response)
425 (*flags) |= NM_FLAGS_RS;
426 if (nmb2->header.nm_flags.authoritative)
427 (*flags) |= NM_FLAGS_AA;
428 if (nmb2->header.nm_flags.trunc)
429 (*flags) |= NM_FLAGS_TC;
430 if (nmb2->header.nm_flags.recursion_desired)
431 (*flags) |= NM_FLAGS_RD;
432 if (nmb2->header.nm_flags.recursion_available)
433 (*flags) |= NM_FLAGS_RA;
434 if (nmb2->header.nm_flags.bcast)
435 (*flags) |= NM_FLAGS_B;
438 * If we're doing a unicast lookup we only
439 * expect one reply. Don't wait the full 2
440 * seconds if we got one. JRA.
451 /* sort the ip list so we choose close servers first if possible */
452 sort_ip_list(ip_list, *count);
457 /********************************************************
458 Start parsing the lmhosts file.
459 *********************************************************/
461 XFILE *startlmhosts(char *fname)
463 XFILE *fp = x_fopen(fname,O_RDONLY, 0);
465 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
466 fname, strerror(errno)));
472 /********************************************************
473 Parse the next line in the lmhosts file.
474 *********************************************************/
476 BOOL getlmhostsent( TALLOC_CTX *mem_ctx,
477 XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
481 while(!x_feof(fp) && !x_ferror(fp)) {
482 pstring ip,flags,extra;
489 if (!fgets_slash(line,sizeof(pstring),fp))
501 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
503 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
505 if (next_token(&ptr,flags,NULL, sizeof(flags)))
507 if (next_token(&ptr,extra,NULL, sizeof(extra)))
513 if (count > 0 && count < 2)
515 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
521 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
525 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
527 if (strchr_m(flags,'G') || strchr_m(flags,'S'))
529 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
533 *ipaddr = interpret_addr2(ip);
535 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
536 then only add that name type. */
537 if((ptr1 = strchr_m(name, '#')) != NULL)
542 *name_type = (int)strtol(ptr1, &endptr, 16);
544 if(!*ptr1 || (endptr == ptr1))
546 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
550 *(--ptr1) = '\0'; /* Truncate at the '#' */
559 /********************************************************
560 Finish parsing the lmhosts file.
561 *********************************************************/
563 void endlmhosts(XFILE *fp)
569 /********************************************************
570 Resolve via "bcast" method.
571 *********************************************************/
573 BOOL name_resolve_bcast(const char *name, int name_type,
574 struct in_addr **return_ip_list, int *return_count)
577 int num_interfaces = iface_count();
579 if (lp_disable_netbios()) {
580 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
584 *return_ip_list = NULL;
588 * "bcast" means do a broadcast lookup on all the local interfaces.
591 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
593 sock = open_socket_in( SOCK_DGRAM, 0, 3,
594 interpret_addr(lp_socket_address()), True );
596 if (sock == -1) return False;
598 set_socket_options(sock,"SO_BROADCAST");
600 * Lookup the name on all the interfaces, return on
601 * the first successful match.
603 for( i = num_interfaces-1; i >= 0; i--) {
604 struct in_addr sendto_ip;
606 /* Done this way to fix compiler error on IRIX 5.x */
607 sendto_ip = *iface_n_bcast(i);
608 *return_ip_list = name_query(sock, name, name_type, True,
609 True, sendto_ip, return_count, &flags, NULL);
610 if(*return_ip_list != NULL) {
620 /********************************************************
621 Resolve via "wins" method.
622 *********************************************************/
623 BOOL resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type,
624 struct in_addr **return_iplist, int *return_count)
628 struct in_addr src_ip;
630 if (lp_disable_netbios()) {
631 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
635 *return_iplist = NULL;
638 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
640 if (wins_srv_count() < 1) {
641 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
645 /* we try a lookup on each of the WINS tags in turn */
646 wins_tags = wins_srv_tags();
649 /* huh? no tags?? give up in disgust */
653 /* the address we will be sending from */
654 src_ip = interpret_addr2(lp_socket_address());
656 /* in the worst case we will try every wins server with every
658 for (t=0; wins_tags && wins_tags[t]; t++) {
659 int srv_count = wins_srv_count_tag(wins_tags[t]);
660 for (i=0; i<srv_count; i++) {
661 struct in_addr wins_ip;
665 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
667 if (global_in_nmbd && ismyip(wins_ip)) {
668 /* yikes! we'll loop forever */
672 /* skip any that have been unresponsive lately */
673 if (wins_srv_is_dead(wins_ip, src_ip)) {
677 DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
679 sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
684 *return_iplist = name_query(sock,name,name_type, False,
685 True, wins_ip, return_count, &flags,
687 if (*return_iplist != NULL) {
693 /* Timed out wating for WINS server to respond. Mark it dead. */
694 wins_srv_died(wins_ip, src_ip);
696 /* The name definately isn't in this
697 group of WINS servers. goto the next group */
703 wins_srv_tags_free(wins_tags);
707 wins_srv_tags_free(wins_tags);
712 /********************************************************
713 Resolve via "hosts" method.
714 *********************************************************/
716 static BOOL resolve_hosts(const char *name,
717 struct in_addr **return_iplist, int *return_count)
720 * "host" means do a localhost, or dns lookup.
724 *return_iplist = NULL;
727 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
729 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
730 struct in_addr return_ip;
731 putip((char *)&return_ip,(char *)hp->h_addr);
732 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
733 if(*return_iplist == NULL) {
734 DEBUG(3,("resolve_hosts: malloc fail !\n"));
737 **return_iplist = return_ip;
744 /********************************************************
745 Internal interface to resolve a name into an IP address.
746 Use this function if the string is either an IP address, DNS
747 or host name or NetBIOS name. This uses the name switch in the
748 smb.conf to determine the order of name resolution.
749 *********************************************************/
751 static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int name_type,
752 struct in_addr **return_iplist, int *return_count)
754 char *name_resolve_list;
757 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
758 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
759 BOOL is_address = is_ipaddress(name);
761 struct in_addr *nodupes_iplist;
764 *return_iplist = NULL;
767 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
769 if (allzeros || allones || is_address) {
770 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
771 if(*return_iplist == NULL) {
772 DEBUG(3,("internal_resolve_name: malloc fail !\n"));
776 /* if it's in the form of an IP address then get the lib to interpret it */
777 if (((*return_iplist)->s_addr = inet_addr(name)) == 0xFFFFFFFF ){
778 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
782 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
788 /* Check netbios name cache */
790 if (namecache_fetch(mem_ctx, name, name_type, return_iplist, return_count)) {
792 /* This could be a negative response */
794 return (*return_count > 0);
797 name_resolve_list = talloc_strdup(mem_ctx, lp_name_resolve_order());
798 ptr = name_resolve_list;
802 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
803 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
804 if (name_type == 0x20) {
805 if (resolve_hosts(name, return_iplist, return_count)) {
810 } else if(strequal( tok, "lmhosts")) {
811 /* REWRITE: add back in? */
812 DEBUG(2,("resolve_name: REWRITE: add lmhosts back?? %s\n", tok));
813 } else if(strequal( tok, "wins")) {
814 /* don't resolve 1D via WINS */
815 if (name_type != 0x1D &&
816 resolve_wins(mem_ctx, name, name_type, return_iplist, return_count)) {
820 } else if(strequal( tok, "bcast")) {
821 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
826 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
830 /* All of the resolve_* functions above have returned false. */
832 SAFE_FREE(*return_iplist);
839 /* Remove duplicate entries. Some queries, notably #1c (domain
840 controllers) return the PDC in iplist[0] and then all domain
841 controllers including the PDC in iplist[1..n]. Iterating over
842 the iplist when the PDC is down will cause two sets of timeouts. */
844 if (*return_count && (nodupes_iplist = (struct in_addr *)
845 malloc(sizeof(struct in_addr) * (*return_count)))) {
846 int nodupes_count = 0;
848 /* Iterate over return_iplist looking for duplicates */
850 for (i = 0; i < *return_count; i++) {
851 BOOL is_dupe = False;
854 for (j = i + 1; j < *return_count; j++) {
855 if (ip_equal((*return_iplist)[i],
856 (*return_iplist)[j])) {
864 /* This one not a duplicate */
866 nodupes_iplist[nodupes_count] = (*return_iplist)[i];
871 /* Switcheroo with original list */
873 free(*return_iplist);
875 *return_iplist = nodupes_iplist;
876 *return_count = nodupes_count;
879 /* Save in name cache */
880 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
881 DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name,
882 name_type, inet_ntoa((*return_iplist)[i])));
884 namecache_store(mem_ctx, name, name_type, *return_count, *return_iplist);
886 /* Display some debugging info */
888 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
891 for (i = 0; i < *return_count; i++)
892 DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
899 /********************************************************
900 Internal interface to resolve a name into one IP address.
901 Use this function if the string is either an IP address, DNS
902 or host name or NetBIOS name. This uses the name switch in the
903 smb.conf to determine the order of name resolution.
904 *********************************************************/
905 BOOL resolve_name(TALLOC_CTX *mem_ctx, const char *name, struct in_addr *return_ip, int name_type)
907 struct in_addr *ip_list = NULL;
910 if (is_ipaddress(name)) {
911 *return_ip = interpret_addr2(name);
915 if (internal_resolve_name(mem_ctx, name, name_type, &ip_list, &count)) {
917 /* only return valid addresses for TCP connections */
918 for (i=0; i<count; i++) {
919 char *ip_str = inet_ntoa(ip_list[i]);
921 strcmp(ip_str, "255.255.255.255") != 0 &&
922 strcmp(ip_str, "0.0.0.0") != 0) {
923 *return_ip = ip_list[i];
933 /********************************************************
934 Find the IP address of the master browser or DMB for a workgroup.
935 *********************************************************/
937 BOOL find_master_ip(TALLOC_CTX *mem_ctx, const char *group, struct in_addr *master_ip)
939 struct in_addr *ip_list = NULL;
942 if (lp_disable_netbios()) {
943 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
947 if (internal_resolve_name(mem_ctx, group, 0x1D, &ip_list, &count)) {
948 *master_ip = ip_list[0];
952 if(internal_resolve_name(mem_ctx, group, 0x1B, &ip_list, &count)) {
953 *master_ip = ip_list[0];
962 /********************************************************
963 Lookup a DC name given a Domain name and IP address.
964 *********************************************************/
966 BOOL lookup_dc_name(const char *srcname, const char *domain,
967 struct in_addr *dc_ip, char *ret_name)
969 #if !defined(I_HATE_WINDOWS_REPLY_CODE)
973 if (lp_disable_netbios()) {
974 DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
979 * Due to the fact win WinNT *sucks* we must do a node status
985 ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
987 if(ret && *dc_name) {
988 fstrcpy(ret_name, dc_name);
994 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
996 JRA - This code is broken with BDC rollover - we need to do a full
997 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1000 int retry_time = 2000;
1001 struct timeval tval;
1002 struct packet_struct p;
1003 struct dgram_packet *dgram = &p.packet.dgram;
1007 struct sockaddr_in sock_name;
1008 int sock_len = sizeof(sock_name);
1009 const char *mailslot = NET_LOGON_MAILSLOT;
1010 char *mailslot_name;
1013 int dgm_id = generate_trn_id();
1014 int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1019 /* Find out the transient UDP port we have been allocated. */
1020 if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1021 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1028 * Create the request data.
1031 memset(buffer,'\0',sizeof(buffer));
1033 SSVAL(bufp,0,QUERYFORPDC);
1035 fstrcpy(bufp,srcname);
1036 bufp += (strlen(bufp) + 1);
1037 slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1038 mailslot_name = bufp;
1039 bufp += (strlen(bufp) + 1);
1040 bufp = ALIGN2(bufp, buffer);
1041 bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
1044 SSVAL(bufp,4,0xFFFF);
1045 SSVAL(bufp,6,0xFFFF);
1047 len = PTR_DIFF(bufp,buffer);
1049 memset((char *)&p,'\0',sizeof(p));
1051 /* DIRECT GROUP or UNIQUE datagram. */
1052 dgram->header.msg_type = 0x10;
1053 dgram->header.flags.node_type = M_NODE;
1054 dgram->header.flags.first = True;
1055 dgram->header.flags.more = False;
1056 dgram->header.dgm_id = dgm_id;
1057 dgram->header.source_ip = *iface_ip(*pdc_ip);
1058 dgram->header.source_port = ntohs(sock_name.sin_port);
1059 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1060 dgram->header.packet_offset = 0;
1062 make_nmb_name(&dgram->source_name,srcname,0);
1063 make_nmb_name(&dgram->dest_name,domain,0x1C);
1065 ptr = &dgram->data[0];
1067 /* Setup the smb part. */
1068 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1070 set_message(ptr,17,17 + len,True);
1073 CVAL(ptr,smb_com) = SMBtrans;
1074 SSVAL(ptr,smb_vwv1,len);
1075 SSVAL(ptr,smb_vwv11,len);
1076 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1077 SSVAL(ptr,smb_vwv13,3);
1078 SSVAL(ptr,smb_vwv14,1);
1079 SSVAL(ptr,smb_vwv15,1);
1080 SSVAL(ptr,smb_vwv16,2);
1082 pstrcpy(p2,mailslot);
1083 p2 = skip_string(p2,1);
1085 memcpy(p2,buffer,len);
1088 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1091 p.port = DGRAM_PORT;
1093 p.timestamp = time(NULL);
1094 p.packet_type = DGRAM_PACKET;
1096 GetTimeOfDay(&tval);
1098 if (!send_packet(&p)) {
1099 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1107 struct timeval tval2;
1108 struct packet_struct *p_ret;
1110 GetTimeOfDay(&tval2);
1111 if (TvalDiff(&tval,&tval2) > retry_time) {
1114 if (!send_packet(&p)) {
1115 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1119 GetTimeOfDay(&tval);
1123 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1124 struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1128 buf = &dgram2->data[0];
1131 if (CVAL(buf,smb_com) != SMBtrans) {
1132 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (uint_t)
1133 CVAL(buf,smb_com), (uint_t)SMBtrans ));
1138 len = SVAL(buf,smb_vwv11);
1139 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1142 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1147 DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1148 nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1149 inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1151 if(SVAL(buf2,0) != QUERYFORPDC_R) {
1152 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1153 (uint_t)SVAL(buf,0), (uint_t)QUERYFORPDC_R ));
1159 /* Note this is safe as it is a bounded strcpy. */
1160 fstrcpy(ret_name, buf2);
1161 ret_name[sizeof(fstring)-1] = '\0';
1170 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1173 /********************************************************
1174 Get the IP address list of the primary domain controller
1176 *********************************************************/
1178 BOOL get_pdc_ip(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr *ip)
1180 struct in_addr *ip_list;
1184 /* Look up #1B name */
1186 if (!internal_resolve_name(mem_ctx, domain, 0x1b, &ip_list, &count))
1189 /* if we get more than 1 IP back we have to assume it is a
1190 multi-homed PDC and not a mess up */
1193 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1195 /* look for a local net */
1196 for ( i=0; i<count; i++ ) {
1197 if ( is_local_net( ip_list[i] ) )
1201 /* if we hit then end then just grab the first
1202 one from the list */
1215 /********************************************************
1216 Get the IP address list of the domain controllers for
1218 *********************************************************/
1220 BOOL get_dc_list(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr **ip_list, int *count, int *ordered)
1225 /* If it's our domain then use the 'password server' parameter. */
1227 if (strequal(domain, lp_workgroup())) {
1229 const char *pserver = lp_passwordserver(); /* UNIX charset. */
1231 int num_addresses = 0;
1232 int local_count, i, j;
1233 struct in_addr *return_iplist = NULL;
1234 struct in_addr *auto_ip_list = NULL;
1235 BOOL done_auto_lookup = False;
1240 return internal_resolve_name(mem_ctx,
1241 domain, 0x1C, ip_list, count);
1246 * if '*' appears in the "password server" list then add
1247 * an auto lookup to the list of manually configured
1248 * DC's. If any DC is listed by name, then the list should be
1249 * considered to be ordered
1252 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1253 if (strequal(name, "*")) {
1254 if ( internal_resolve_name(mem_ctx, domain, 0x1C, &auto_ip_list, &auto_count) )
1255 num_addresses += auto_count;
1256 done_auto_lookup = True;
1257 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1263 /* if we have no addresses and haven't done the auto lookup, then
1264 just return the list of DC's */
1266 if ( (num_addresses == 0) && !done_auto_lookup )
1267 return internal_resolve_name(mem_ctx, domain, 0x1C, ip_list, count);
1269 return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr));
1271 if (return_iplist == NULL) {
1272 DEBUG(3,("get_dc_list: malloc fail !\n"));
1279 /* fill in the return list now with real IP's */
1281 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1282 struct in_addr name_ip;
1284 /* copy any addersses from the auto lookup */
1286 if ( strequal(name, "*") ) {
1287 for ( j=0; j<auto_count; j++ )
1288 return_iplist[local_count++] = auto_ip_list[j];
1292 /* explicit lookup; resolve_name() will handle names & IP addresses */
1294 if ( resolve_name( mem_ctx, name, &name_ip, 0x20) ) {
1295 return_iplist[local_count++] = name_ip;
1301 SAFE_FREE(auto_ip_list);
1303 /* need to remove duplicates in the list if we have
1304 any explicit password servers */
1307 /* one loop to remove duplicates */
1308 for ( i=0; i<local_count; i++ ) {
1309 if ( is_zero_ip(return_iplist[i]) )
1312 for ( j=i+1; j<local_count; j++ ) {
1313 if ( ip_equal( return_iplist[i], return_iplist[j]) )
1314 zero_ip(&return_iplist[j]);
1318 /* one loop to clean up any holes we left */
1319 /* first ip should never be a zero_ip() */
1320 for (i = 0; i<local_count; ) {
1321 if ( is_zero_ip(return_iplist[i]) ) {
1322 if (i != local_count-1 )
1323 memmove(&return_iplist[i], &return_iplist[i+1],
1324 (local_count - i - 1)*sizeof(return_iplist[i]));
1332 *ip_list = return_iplist;
1333 *count = local_count;
1335 DEBUG(8,("get_dc_list: return %d ip addresses\n", *count));
1337 return (*count != 0);
1340 return internal_resolve_name(mem_ctx, domain, 0x1C, ip_list, count);