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(getpid());
38 trn_id = sys_random();
40 return trn_id % (uint_t)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 if (lp_disable_netbios()) {
174 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
178 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
179 q_type, inet_ntoa(to_ip)));
181 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
185 /* W2K PDC's seem not to respond to '*'#0. JRA */
186 make_nmb_name(&nname, q_name, q_type);
187 status = node_status_query(sock, &nname, to_ip, &count);
192 for (i=0;i<count;i++) {
193 if (status[i].type == type)
199 pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
205 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
208 DEBUGADD(10, (", ip address is %s", inet_ntoa(to_ip)));
217 comparison function used by sort_ip_list
219 int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
221 int max_bits1=0, max_bits2=0;
222 int num_interfaces = iface_count();
225 for (i=0;i<num_interfaces;i++) {
228 ip = *iface_n_bcast(i);
229 bits1 = matching_quad_bits((uint8_t *)&ip1->s_addr, (uint8_t *)&ip.s_addr);
230 bits2 = matching_quad_bits((uint8_t *)&ip2->s_addr, (uint8_t *)&ip.s_addr);
231 max_bits1 = MAX(bits1, max_bits1);
232 max_bits2 = MAX(bits2, max_bits2);
235 /* bias towards directly reachable IPs */
236 if (iface_local(*ip1)) {
239 if (iface_local(*ip2)) {
243 return max_bits2 - max_bits1;
247 sort an IP list so that names that are close to one of our interfaces
248 are at the top. This prevents the problem where a WINS server returns an IP that
249 is not reachable from our subnet as the first match
251 static void sort_ip_list(struct in_addr *iplist, int count)
257 qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
261 /****************************************************************************
262 Do a netbios name query to find someones IP.
263 Returns an array of IP addresses or NULL if none.
264 *count will be set to the number of addresses returned.
265 *timed_out is set if we failed by timing out
266 ****************************************************************************/
267 struct in_addr *name_query(int fd,const char *name,int name_type,
268 BOOL bcast,BOOL recurse,
269 struct in_addr to_ip, int *count, int *flags,
274 int retry_time = bcast?250:2000;
276 struct packet_struct p;
277 struct packet_struct *p2;
278 struct nmb_packet *nmb = &p.packet.nmb;
279 struct in_addr *ip_list = NULL;
281 if (lp_disable_netbios()) {
282 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
290 memset((char *)&p,'\0',sizeof(p));
294 nmb->header.name_trn_id = generate_trn_id();
295 nmb->header.opcode = 0;
296 nmb->header.response = False;
297 nmb->header.nm_flags.bcast = bcast;
298 nmb->header.nm_flags.recursion_available = False;
299 nmb->header.nm_flags.recursion_desired = recurse;
300 nmb->header.nm_flags.trunc = False;
301 nmb->header.nm_flags.authoritative = False;
302 nmb->header.rcode = 0;
303 nmb->header.qdcount = 1;
304 nmb->header.ancount = 0;
305 nmb->header.nscount = 0;
306 nmb->header.arcount = 0;
308 make_nmb_name(&nmb->question.question_name,name,name_type);
310 nmb->question.question_type = 0x20;
311 nmb->question.question_class = 0x1;
316 p.timestamp = time(NULL);
317 p.packet_type = NMB_PACKET;
321 if (!send_packet(&p))
327 struct timeval tval2;
328 struct in_addr *tmp_ip_list;
330 GetTimeOfDay(&tval2);
331 if (TvalDiff(&tval,&tval2) > retry_time) {
334 if (!found && !send_packet(&p))
340 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
341 struct nmb_packet *nmb2 = &p2->packet.nmb;
342 debug_nmb_packet(p2);
344 /* If we get a Negative Name Query Response from a WINS
345 * server, we should report it and give up.
347 if( 0 == nmb2->header.opcode /* A query response */
348 && !(bcast) /* from a WINS server */
349 && nmb2->header.rcode /* Error returned */
353 /* Only executed if DEBUGLEVEL >= 3 */
354 DEBUG(3,("Negative name query response, rcode 0x%02x: ", nmb2->header.rcode ));
355 switch( nmb2->header.rcode ) {
357 DEBUG(3,("Request was invalidly formatted.\n" ));
360 DEBUG(3,("Problem with NBNS, cannot process name.\n"));
363 DEBUG(3,("The name requested does not exist.\n" ));
366 DEBUG(3,("Unsupported request error.\n" ));
369 DEBUG(3,("Query refused error.\n" ));
372 DEBUG(3,("Unrecognized error code.\n" ));
380 if (nmb2->header.opcode != 0 ||
381 nmb2->header.nm_flags.bcast ||
382 nmb2->header.rcode ||
383 !nmb2->header.ancount) {
385 * XXXX what do we do with this? Could be a
386 * redirect, but we'll discard it for the
393 tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
394 * ( (*count) + nmb2->answers->rdlength/6 ) );
397 DEBUG(0,("name_query: Realloc failed.\n"));
401 ip_list = tmp_ip_list;
404 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
405 for (i=0;i<nmb2->answers->rdlength/6;i++) {
406 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
407 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
415 /* We add the flags back ... */
416 if (nmb2->header.response)
417 (*flags) |= NM_FLAGS_RS;
418 if (nmb2->header.nm_flags.authoritative)
419 (*flags) |= NM_FLAGS_AA;
420 if (nmb2->header.nm_flags.trunc)
421 (*flags) |= NM_FLAGS_TC;
422 if (nmb2->header.nm_flags.recursion_desired)
423 (*flags) |= NM_FLAGS_RD;
424 if (nmb2->header.nm_flags.recursion_available)
425 (*flags) |= NM_FLAGS_RA;
426 if (nmb2->header.nm_flags.bcast)
427 (*flags) |= NM_FLAGS_B;
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.
443 /* sort the ip list so we choose close servers first if possible */
444 sort_ip_list(ip_list, *count);
449 /********************************************************
450 Start parsing the lmhosts file.
451 *********************************************************/
453 XFILE *startlmhosts(char *fname)
455 XFILE *fp = x_fopen(fname,O_RDONLY, 0);
457 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
458 fname, strerror(errno)));
464 /********************************************************
465 Parse the next line in the lmhosts file.
466 *********************************************************/
468 BOOL getlmhostsent( TALLOC_CTX *mem_ctx,
469 XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
473 while(!x_feof(fp) && !x_ferror(fp)) {
474 pstring ip,flags,extra;
481 if (!fgets_slash(line,sizeof(pstring),fp))
493 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
495 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
497 if (next_token(&ptr,flags,NULL, sizeof(flags)))
499 if (next_token(&ptr,extra,NULL, sizeof(extra)))
505 if (count > 0 && count < 2)
507 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
513 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
517 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
519 if (strchr_m(flags,'G') || strchr_m(flags,'S'))
521 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
525 *ipaddr = interpret_addr2(ip);
527 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
528 then only add that name type. */
529 if((ptr1 = strchr_m(name, '#')) != NULL)
534 *name_type = (int)strtol(ptr1, &endptr, 16);
536 if(!*ptr1 || (endptr == ptr1))
538 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
542 *(--ptr1) = '\0'; /* Truncate at the '#' */
551 /********************************************************
552 Finish parsing the lmhosts file.
553 *********************************************************/
555 void endlmhosts(XFILE *fp)
561 /********************************************************
562 Resolve via "bcast" method.
563 *********************************************************/
565 BOOL name_resolve_bcast(const char *name, int name_type,
566 struct in_addr **return_ip_list, int *return_count)
569 int num_interfaces = iface_count();
571 if (lp_disable_netbios()) {
572 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
576 *return_ip_list = NULL;
580 * "bcast" means do a broadcast lookup on all the local interfaces.
583 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
585 sock = open_socket_in( SOCK_DGRAM, 0, 3,
586 interpret_addr(lp_socket_address()), True );
588 if (sock == -1) return False;
590 set_socket_options(sock,"SO_BROADCAST");
592 * Lookup the name on all the interfaces, return on
593 * the first successful match.
595 for( i = num_interfaces-1; i >= 0; i--) {
596 struct in_addr sendto_ip;
598 /* Done this way to fix compiler error on IRIX 5.x */
599 sendto_ip = *iface_n_bcast(i);
600 *return_ip_list = name_query(sock, name, name_type, True,
601 True, sendto_ip, return_count, &flags, NULL);
602 if(*return_ip_list != NULL) {
612 /********************************************************
613 Resolve via "wins" method.
614 *********************************************************/
615 BOOL resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type,
616 struct in_addr **return_iplist, int *return_count)
620 struct in_addr src_ip;
622 if (lp_disable_netbios()) {
623 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
627 *return_iplist = NULL;
630 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
632 if (wins_srv_count() < 1) {
633 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
637 /* we try a lookup on each of the WINS tags in turn */
638 wins_tags = wins_srv_tags();
641 /* huh? no tags?? give up in disgust */
645 /* the address we will be sending from */
646 src_ip = interpret_addr2(lp_socket_address());
648 /* in the worst case we will try every wins server with every
650 for (t=0; wins_tags && wins_tags[t]; t++) {
651 int srv_count = wins_srv_count_tag(wins_tags[t]);
652 for (i=0; i<srv_count; i++) {
653 struct in_addr wins_ip;
657 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
659 if (global_in_nmbd && ismyip(wins_ip)) {
660 /* yikes! we'll loop forever */
664 /* skip any that have been unresponsive lately */
665 if (wins_srv_is_dead(wins_ip, src_ip)) {
669 DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
671 sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
676 *return_iplist = name_query(sock,name,name_type, False,
677 True, wins_ip, return_count, &flags,
679 if (*return_iplist != NULL) {
685 /* Timed out wating for WINS server to respond. Mark it dead. */
686 wins_srv_died(wins_ip, src_ip);
688 /* The name definately isn't in this
689 group of WINS servers. goto the next group */
695 wins_srv_tags_free(wins_tags);
699 wins_srv_tags_free(wins_tags);
704 /********************************************************
705 Resolve via "hosts" method.
706 *********************************************************/
708 static BOOL resolve_hosts(const char *name,
709 struct in_addr **return_iplist, int *return_count)
712 * "host" means do a localhost, or dns lookup.
716 *return_iplist = NULL;
719 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
721 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
722 struct in_addr return_ip;
723 putip((char *)&return_ip,(char *)hp->h_addr);
724 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
725 if(*return_iplist == NULL) {
726 DEBUG(3,("resolve_hosts: malloc fail !\n"));
729 **return_iplist = return_ip;
736 /********************************************************
737 Internal interface to resolve a name into an IP address.
738 Use this function if the string is either an IP address, DNS
739 or host name or NetBIOS name. This uses the name switch in the
740 smb.conf to determine the order of name resolution.
741 *********************************************************/
743 static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int name_type,
744 struct in_addr **return_iplist, int *return_count)
746 char *name_resolve_list;
749 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
750 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
751 BOOL is_address = is_ipaddress(name);
753 struct in_addr *nodupes_iplist;
756 *return_iplist = NULL;
759 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
761 if (allzeros || allones || is_address) {
762 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
763 if(*return_iplist == NULL) {
764 DEBUG(3,("internal_resolve_name: malloc fail !\n"));
768 /* if it's in the form of an IP address then get the lib to interpret it */
769 if (((*return_iplist)->s_addr = inet_addr(name)) == 0xFFFFFFFF ){
770 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
774 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
780 /* Check netbios name cache */
782 if (namecache_fetch(mem_ctx, name, name_type, return_iplist, return_count)) {
784 /* This could be a negative response */
786 return (*return_count > 0);
789 name_resolve_list = talloc_strdup(mem_ctx, lp_name_resolve_order());
790 ptr = name_resolve_list;
794 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
795 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
796 if (name_type == 0x20) {
797 if (resolve_hosts(name, return_iplist, return_count)) {
802 } else if(strequal( tok, "lmhosts")) {
803 /* REWRITE: add back in? */
804 DEBUG(2,("resolve_name: REWRITE: add lmhosts back?? %s\n", tok));
805 } else if(strequal( tok, "wins")) {
806 /* don't resolve 1D via WINS */
807 if (name_type != 0x1D &&
808 resolve_wins(mem_ctx, name, name_type, return_iplist, return_count)) {
812 } else if(strequal( tok, "bcast")) {
813 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
818 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
822 /* All of the resolve_* functions above have returned false. */
824 SAFE_FREE(*return_iplist);
831 /* Remove duplicate entries. Some queries, notably #1c (domain
832 controllers) return the PDC in iplist[0] and then all domain
833 controllers including the PDC in iplist[1..n]. Iterating over
834 the iplist when the PDC is down will cause two sets of timeouts. */
836 if (*return_count && (nodupes_iplist = (struct in_addr *)
837 malloc(sizeof(struct in_addr) * (*return_count)))) {
838 int nodupes_count = 0;
840 /* Iterate over return_iplist looking for duplicates */
842 for (i = 0; i < *return_count; i++) {
843 BOOL is_dupe = False;
846 for (j = i + 1; j < *return_count; j++) {
847 if (ip_equal((*return_iplist)[i],
848 (*return_iplist)[j])) {
856 /* This one not a duplicate */
858 nodupes_iplist[nodupes_count] = (*return_iplist)[i];
863 /* Switcheroo with original list */
865 free(*return_iplist);
867 *return_iplist = nodupes_iplist;
868 *return_count = nodupes_count;
871 /* Save in name cache */
872 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
873 DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name,
874 name_type, inet_ntoa((*return_iplist)[i])));
876 namecache_store(mem_ctx, name, name_type, *return_count, *return_iplist);
878 /* Display some debugging info */
880 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
883 for (i = 0; i < *return_count; i++)
884 DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
891 /********************************************************
892 Internal interface to resolve a name into one IP address.
893 Use this function if the string is either an IP address, DNS
894 or host name or NetBIOS name. This uses the name switch in the
895 smb.conf to determine the order of name resolution.
896 *********************************************************/
897 BOOL resolve_name(TALLOC_CTX *mem_ctx, const char *name, struct in_addr *return_ip, int name_type)
899 struct in_addr *ip_list = NULL;
902 if (is_ipaddress(name)) {
903 *return_ip = interpret_addr2(name);
907 if (internal_resolve_name(mem_ctx, name, name_type, &ip_list, &count)) {
909 /* only return valid addresses for TCP connections */
910 for (i=0; i<count; i++) {
911 char *ip_str = inet_ntoa(ip_list[i]);
913 strcmp(ip_str, "255.255.255.255") != 0 &&
914 strcmp(ip_str, "0.0.0.0") != 0) {
915 *return_ip = ip_list[i];
925 /********************************************************
926 Find the IP address of the master browser or DMB for a workgroup.
927 *********************************************************/
929 BOOL find_master_ip(TALLOC_CTX *mem_ctx, const char *group, struct in_addr *master_ip)
931 struct in_addr *ip_list = NULL;
934 if (lp_disable_netbios()) {
935 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
939 if (internal_resolve_name(mem_ctx, group, 0x1D, &ip_list, &count)) {
940 *master_ip = ip_list[0];
944 if(internal_resolve_name(mem_ctx, group, 0x1B, &ip_list, &count)) {
945 *master_ip = ip_list[0];
954 /********************************************************
955 Lookup a DC name given a Domain name and IP address.
956 *********************************************************/
958 BOOL lookup_dc_name(const char *srcname, const char *domain,
959 struct in_addr *dc_ip, char *ret_name)
961 #if !defined(I_HATE_WINDOWS_REPLY_CODE)
965 if (lp_disable_netbios()) {
966 DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
971 * Due to the fact win WinNT *sucks* we must do a node status
977 ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
979 if(ret && *dc_name) {
980 fstrcpy(ret_name, dc_name);
986 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
988 JRA - This code is broken with BDC rollover - we need to do a full
989 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
992 int retry_time = 2000;
994 struct packet_struct p;
995 struct dgram_packet *dgram = &p.packet.dgram;
999 struct sockaddr_in sock_name;
1000 int sock_len = sizeof(sock_name);
1001 const char *mailslot = NET_LOGON_MAILSLOT;
1002 char *mailslot_name;
1005 int dgm_id = generate_trn_id();
1006 int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1011 /* Find out the transient UDP port we have been allocated. */
1012 if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1013 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1020 * Create the request data.
1023 memset(buffer,'\0',sizeof(buffer));
1025 SSVAL(bufp,0,QUERYFORPDC);
1027 fstrcpy(bufp,srcname);
1028 bufp += (strlen(bufp) + 1);
1029 slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1030 mailslot_name = bufp;
1031 bufp += (strlen(bufp) + 1);
1032 bufp = ALIGN2(bufp, buffer);
1033 bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
1036 SSVAL(bufp,4,0xFFFF);
1037 SSVAL(bufp,6,0xFFFF);
1039 len = PTR_DIFF(bufp,buffer);
1041 memset((char *)&p,'\0',sizeof(p));
1043 /* DIRECT GROUP or UNIQUE datagram. */
1044 dgram->header.msg_type = 0x10;
1045 dgram->header.flags.node_type = M_NODE;
1046 dgram->header.flags.first = True;
1047 dgram->header.flags.more = False;
1048 dgram->header.dgm_id = dgm_id;
1049 dgram->header.source_ip = *iface_ip(*pdc_ip);
1050 dgram->header.source_port = ntohs(sock_name.sin_port);
1051 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1052 dgram->header.packet_offset = 0;
1054 make_nmb_name(&dgram->source_name,srcname,0);
1055 make_nmb_name(&dgram->dest_name,domain,0x1C);
1057 ptr = &dgram->data[0];
1059 /* Setup the smb part. */
1060 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1062 set_message(ptr,17,17 + len,True);
1065 CVAL(ptr,smb_com) = SMBtrans;
1066 SSVAL(ptr,smb_vwv1,len);
1067 SSVAL(ptr,smb_vwv11,len);
1068 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1069 SSVAL(ptr,smb_vwv13,3);
1070 SSVAL(ptr,smb_vwv14,1);
1071 SSVAL(ptr,smb_vwv15,1);
1072 SSVAL(ptr,smb_vwv16,2);
1074 pstrcpy(p2,mailslot);
1075 p2 = skip_string(p2,1);
1077 memcpy(p2,buffer,len);
1080 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1083 p.port = DGRAM_PORT;
1085 p.timestamp = time(NULL);
1086 p.packet_type = DGRAM_PACKET;
1088 GetTimeOfDay(&tval);
1090 if (!send_packet(&p)) {
1091 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1099 struct timeval tval2;
1100 struct packet_struct *p_ret;
1102 GetTimeOfDay(&tval2);
1103 if (TvalDiff(&tval,&tval2) > retry_time) {
1106 if (!send_packet(&p)) {
1107 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1111 GetTimeOfDay(&tval);
1115 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1116 struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1120 buf = &dgram2->data[0];
1123 if (CVAL(buf,smb_com) != SMBtrans) {
1124 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (uint_t)
1125 CVAL(buf,smb_com), (uint_t)SMBtrans ));
1130 len = SVAL(buf,smb_vwv11);
1131 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1134 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1139 DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1140 nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1141 inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1143 if(SVAL(buf2,0) != QUERYFORPDC_R) {
1144 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1145 (uint_t)SVAL(buf,0), (uint_t)QUERYFORPDC_R ));
1151 /* Note this is safe as it is a bounded strcpy. */
1152 fstrcpy(ret_name, buf2);
1153 ret_name[sizeof(fstring)-1] = '\0';
1162 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1165 /********************************************************
1166 Get the IP address list of the primary domain controller
1168 *********************************************************/
1170 BOOL get_pdc_ip(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr *ip)
1172 struct in_addr *ip_list;
1176 /* Look up #1B name */
1178 if (!internal_resolve_name(mem_ctx, domain, 0x1b, &ip_list, &count))
1181 /* if we get more than 1 IP back we have to assume it is a
1182 multi-homed PDC and not a mess up */
1185 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1187 /* look for a local net */
1188 for ( i=0; i<count; i++ ) {
1189 if ( is_local_net( ip_list[i] ) )
1193 /* if we hit then end then just grab the first
1194 one from the list */
1207 /********************************************************
1208 Get the IP address list of the domain controllers for
1210 *********************************************************/
1212 BOOL get_dc_list(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr **ip_list, int *count, int *ordered)
1217 /* If it's our domain then use the 'password server' parameter. */
1219 if (strequal(domain, lp_workgroup())) {
1221 const char *pserver = lp_passwordserver(); /* UNIX charset. */
1223 int num_addresses = 0;
1224 int local_count, i, j;
1225 struct in_addr *return_iplist = NULL;
1226 struct in_addr *auto_ip_list = NULL;
1227 BOOL done_auto_lookup = False;
1232 return internal_resolve_name(mem_ctx,
1233 domain, 0x1C, ip_list, count);
1238 * if '*' appears in the "password server" list then add
1239 * an auto lookup to the list of manually configured
1240 * DC's. If any DC is listed by name, then the list should be
1241 * considered to be ordered
1244 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1245 if (strequal(name, "*")) {
1246 if ( internal_resolve_name(mem_ctx, domain, 0x1C, &auto_ip_list, &auto_count) )
1247 num_addresses += auto_count;
1248 done_auto_lookup = True;
1249 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1255 /* if we have no addresses and haven't done the auto lookup, then
1256 just return the list of DC's */
1258 if ( (num_addresses == 0) && !done_auto_lookup )
1259 return internal_resolve_name(mem_ctx, domain, 0x1C, ip_list, count);
1261 return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr));
1263 if (return_iplist == NULL) {
1264 DEBUG(3,("get_dc_list: malloc fail !\n"));
1271 /* fill in the return list now with real IP's */
1273 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1274 struct in_addr name_ip;
1276 /* copy any addersses from the auto lookup */
1278 if ( strequal(name, "*") ) {
1279 for ( j=0; j<auto_count; j++ )
1280 return_iplist[local_count++] = auto_ip_list[j];
1284 /* explicit lookup; resolve_name() will handle names & IP addresses */
1286 if ( resolve_name( mem_ctx, name, &name_ip, 0x20) ) {
1287 return_iplist[local_count++] = name_ip;
1293 SAFE_FREE(auto_ip_list);
1295 /* need to remove duplicates in the list if we have
1296 any explicit password servers */
1299 /* one loop to remove duplicates */
1300 for ( i=0; i<local_count; i++ ) {
1301 if ( is_zero_ip(return_iplist[i]) )
1304 for ( j=i+1; j<local_count; j++ ) {
1305 if ( ip_equal( return_iplist[i], return_iplist[j]) )
1306 zero_ip(&return_iplist[j]);
1310 /* one loop to clean up any holes we left */
1311 /* first ip should never be a zero_ip() */
1312 for (i = 0; i<local_count; ) {
1313 if ( is_zero_ip(return_iplist[i]) ) {
1314 if (i != local_count-1 )
1315 memmove(&return_iplist[i], &return_iplist[i+1],
1316 (local_count - i - 1)*sizeof(return_iplist[i]));
1324 *ip_list = return_iplist;
1325 *count = local_count;
1327 DEBUG(8,("get_dc_list: return %d ip addresses\n", *count));
1329 return (*count != 0);
1332 return internal_resolve_name(mem_ctx, domain, 0x1C, ip_list, count);