2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1994-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 /* nmbd.c sets this to True. */
25 BOOL global_in_nmbd = False;
27 /****************************************************************************
28 generate a random trn_id
29 ****************************************************************************/
30 static int generate_trn_id(void)
35 sys_srandom(sys_getpid());
38 trn_id = sys_random();
40 return trn_id % (unsigned)0x7FFF;
44 /****************************************************************************
45 parse a node status response into an array of structures
46 ****************************************************************************/
47 static struct node_status *parse_node_status(char *p, int *num_names)
49 struct node_status *ret;
52 *num_names = CVAL(p,0);
54 if (*num_names == 0) return NULL;
56 ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names));
57 if (!ret) return NULL;
60 for (i=0;i< *num_names;i++) {
61 StrnCpy(ret[i].name,p,15);
62 trim_string(ret[i].name,NULL," ");
63 ret[i].type = CVAL(p,15);
66 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
67 ret[i].type, ret[i].flags));
73 /****************************************************************************
74 do a NBT node status query on an open socket and return an array of
75 structures holding the returned names or NULL if the query failed
76 **************************************************************************/
77 struct node_status *node_status_query(int fd,struct nmb_name *name,
78 struct in_addr to_ip, int *num_names)
82 int retry_time = 2000;
84 struct packet_struct p;
85 struct packet_struct *p2;
86 struct nmb_packet *nmb = &p.packet.nmb;
87 struct node_status *ret;
91 nmb->header.name_trn_id = generate_trn_id();
92 nmb->header.opcode = 0;
93 nmb->header.response = False;
94 nmb->header.nm_flags.bcast = False;
95 nmb->header.nm_flags.recursion_available = False;
96 nmb->header.nm_flags.recursion_desired = False;
97 nmb->header.nm_flags.trunc = False;
98 nmb->header.nm_flags.authoritative = False;
99 nmb->header.rcode = 0;
100 nmb->header.qdcount = 1;
101 nmb->header.ancount = 0;
102 nmb->header.nscount = 0;
103 nmb->header.arcount = 0;
104 nmb->question.question_name = *name;
105 nmb->question.question_type = 0x21;
106 nmb->question.question_class = 0x1;
111 p.timestamp = time(NULL);
112 p.packet_type = NMB_PACKET;
116 if (!send_packet(&p))
122 struct timeval tval2;
123 GetTimeOfDay(&tval2);
124 if (TvalDiff(&tval,&tval2) > retry_time) {
127 if (!found && !send_packet(&p))
133 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
134 struct nmb_packet *nmb2 = &p2->packet.nmb;
135 debug_nmb_packet(p2);
137 if (nmb2->header.opcode != 0 ||
138 nmb2->header.nm_flags.bcast ||
139 nmb2->header.rcode ||
140 !nmb2->header.ancount ||
141 nmb2->answers->rr_type != 0x21) {
142 /* XXXX what do we do with this? could be a
143 redirect, but we'll discard it for the
149 ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
159 /****************************************************************************
160 find the first type XX name in a node status reply - used for finding
161 a servers name given its IP
162 return the matched name in *name
163 **************************************************************************/
165 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name)
167 struct node_status *status = NULL;
168 struct nmb_name nname;
173 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
174 q_type, inet_ntoa(to_ip)));
176 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
180 /* W2K PDC's seem not to respond to '*'#0. JRA */
181 make_nmb_name(&nname, q_name, q_type);
182 status = node_status_query(sock, &nname, to_ip, &count);
187 for (i=0;i<count;i++) {
188 if (status[i].type == type)
194 pull_ascii(name, status[i].name, 15, -1, STR_TERMINATE);
200 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
203 DEBUGADD(10, (", ip address is %s", inet_ntoa(to_ip)));
212 comparison function used by sort_ip_list
214 static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
216 int max_bits1=0, max_bits2=0;
217 int num_interfaces = iface_count();
220 for (i=0;i<num_interfaces;i++) {
223 ip = *iface_n_bcast(i);
224 bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
225 bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
226 max_bits1 = MAX(bits1, max_bits1);
227 max_bits2 = MAX(bits2, max_bits2);
230 /* bias towards directly reachable IPs */
231 if (iface_local(*ip1)) {
234 if (iface_local(*ip2)) {
238 return max_bits2 - max_bits1;
242 sort an IP list so that names that are close to one of our interfaces
243 are at the top. This prevents the problem where a WINS server returns an IP that
244 is not reachable from our subnet as the first match
246 static void sort_ip_list(struct in_addr *iplist, int count)
252 qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
256 /****************************************************************************
257 Do a netbios name query to find someones IP.
258 Returns an array of IP addresses or NULL if none.
259 *count will be set to the number of addresses returned.
260 *timed_out is set if we failed by timing out
261 ****************************************************************************/
262 struct in_addr *name_query(int fd,const char *name,int name_type,
263 BOOL bcast,BOOL recurse,
264 struct in_addr to_ip, int *count, int *flags,
269 int retry_time = bcast?250:2000;
271 struct packet_struct p;
272 struct packet_struct *p2;
273 struct nmb_packet *nmb = &p.packet.nmb;
274 struct in_addr *ip_list = NULL;
280 memset((char *)&p,'\0',sizeof(p));
284 nmb->header.name_trn_id = generate_trn_id();
285 nmb->header.opcode = 0;
286 nmb->header.response = False;
287 nmb->header.nm_flags.bcast = bcast;
288 nmb->header.nm_flags.recursion_available = False;
289 nmb->header.nm_flags.recursion_desired = recurse;
290 nmb->header.nm_flags.trunc = False;
291 nmb->header.nm_flags.authoritative = False;
292 nmb->header.rcode = 0;
293 nmb->header.qdcount = 1;
294 nmb->header.ancount = 0;
295 nmb->header.nscount = 0;
296 nmb->header.arcount = 0;
298 make_nmb_name(&nmb->question.question_name,name,name_type);
300 nmb->question.question_type = 0x20;
301 nmb->question.question_class = 0x1;
306 p.timestamp = time(NULL);
307 p.packet_type = NMB_PACKET;
311 if (!send_packet(&p))
317 struct timeval tval2;
318 struct in_addr *tmp_ip_list;
320 GetTimeOfDay(&tval2);
321 if (TvalDiff(&tval,&tval2) > retry_time) {
324 if (!found && !send_packet(&p))
330 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
331 struct nmb_packet *nmb2 = &p2->packet.nmb;
332 debug_nmb_packet(p2);
334 /* If we get a Negative Name Query Response from a WINS
335 * server, we should report it and give up.
337 if( 0 == nmb2->header.opcode /* A query response */
338 && !(bcast) /* from a WINS server */
339 && nmb2->header.rcode /* Error returned */
342 if( DEBUGLVL( 3 ) ) {
343 /* Only executed if DEBUGLEVEL >= 3 */
344 dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
345 switch( nmb2->header.rcode ) {
347 dbgtext( "Request was invalidly formatted.\n" );
350 dbgtext( "Problem with NBNS, cannot process name.\n");
353 dbgtext( "The name requested does not exist.\n" );
356 dbgtext( "Unsupported request error.\n" );
359 dbgtext( "Query refused error.\n" );
362 dbgtext( "Unrecognized error code.\n" );
370 if (nmb2->header.opcode != 0 ||
371 nmb2->header.nm_flags.bcast ||
372 nmb2->header.rcode ||
373 !nmb2->header.ancount) {
375 * XXXX what do we do with this? Could be a
376 * redirect, but we'll discard it for the
383 tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
384 * ( (*count) + nmb2->answers->rdlength/6 ) );
387 DEBUG(0,("name_query: Realloc failed.\n"));
391 ip_list = tmp_ip_list;
394 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
395 for (i=0;i<nmb2->answers->rdlength/6;i++) {
396 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
397 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
405 /* We add the flags back ... */
406 if (nmb2->header.response)
407 (*flags) |= NM_FLAGS_RS;
408 if (nmb2->header.nm_flags.authoritative)
409 (*flags) |= NM_FLAGS_AA;
410 if (nmb2->header.nm_flags.trunc)
411 (*flags) |= NM_FLAGS_TC;
412 if (nmb2->header.nm_flags.recursion_desired)
413 (*flags) |= NM_FLAGS_RD;
414 if (nmb2->header.nm_flags.recursion_available)
415 (*flags) |= NM_FLAGS_RA;
416 if (nmb2->header.nm_flags.bcast)
417 (*flags) |= NM_FLAGS_B;
420 * If we're doing a unicast lookup we only
421 * expect one reply. Don't wait the full 2
422 * seconds if we got one. JRA.
433 /* sort the ip list so we choose close servers first if possible */
434 sort_ip_list(ip_list, *count);
439 /********************************************************
440 Start parsing the lmhosts file.
441 *********************************************************/
443 XFILE *startlmhosts(char *fname)
445 XFILE *fp = x_fopen(fname,O_RDONLY, 0);
447 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
448 fname, strerror(errno)));
454 /********************************************************
455 Parse the next line in the lmhosts file.
456 *********************************************************/
458 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
462 while(!x_feof(fp) && !x_ferror(fp)) {
463 pstring ip,flags,extra;
469 if (!fgets_slash(line,sizeof(pstring),fp))
481 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
483 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
485 if (next_token(&ptr,flags,NULL, sizeof(flags)))
487 if (next_token(&ptr,extra,NULL, sizeof(extra)))
493 if (count > 0 && count < 2)
495 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
501 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
505 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
507 if (strchr_m(flags,'G') || strchr_m(flags,'S'))
509 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
513 *ipaddr = *interpret_addr2(ip);
515 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
516 then only add that name type. */
517 if((ptr = strchr_m(name, '#')) != NULL)
522 *name_type = (int)strtol(ptr, &endptr, 16);
524 if(!*ptr || (endptr == ptr))
526 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
530 *(--ptr) = '\0'; /* Truncate at the '#' */
539 /********************************************************
540 Finish parsing the lmhosts file.
541 *********************************************************/
543 void endlmhosts(XFILE *fp)
549 /********************************************************
550 Resolve via "bcast" method.
551 *********************************************************/
553 BOOL name_resolve_bcast(const char *name, int name_type,
554 struct in_addr **return_ip_list, int *return_count)
557 int num_interfaces = iface_count();
559 *return_ip_list = NULL;
563 * "bcast" means do a broadcast lookup on all the local interfaces.
566 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
568 sock = open_socket_in( SOCK_DGRAM, 0, 3,
569 interpret_addr(lp_socket_address()), True );
571 if (sock == -1) return False;
573 set_socket_options(sock,"SO_BROADCAST");
575 * Lookup the name on all the interfaces, return on
576 * the first successful match.
578 for( i = num_interfaces-1; i >= 0; i--) {
579 struct in_addr sendto_ip;
581 /* Done this way to fix compiler error on IRIX 5.x */
582 sendto_ip = *iface_n_bcast(i);
583 *return_ip_list = name_query(sock, name, name_type, True,
584 True, sendto_ip, return_count, &flags, NULL);
585 if(*return_ip_list != NULL) {
595 /********************************************************
596 Resolve via "wins" method.
597 *********************************************************/
598 BOOL resolve_wins(const char *name, int name_type,
599 struct in_addr **return_iplist, int *return_count)
603 struct in_addr src_ip;
605 *return_iplist = NULL;
608 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
610 if (wins_srv_count() < 1) {
611 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
615 /* we try a lookup on each of the WINS tags in turn */
616 wins_tags = wins_srv_tags();
619 /* huh? no tags?? give up in disgust */
623 /* the address we will be sending from */
624 src_ip = *interpret_addr2(lp_socket_address());
626 /* in the worst case we will try every wins server with every
628 for (t=0; wins_tags && wins_tags[t]; t++) {
629 int srv_count = wins_srv_count_tag(wins_tags[t]);
630 for (i=0; i<srv_count; i++) {
631 struct in_addr wins_ip;
635 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
637 if (global_in_nmbd && ismyip(wins_ip)) {
638 /* yikes! we'll loop forever */
642 /* skip any that have been unresponsive lately */
643 if (wins_srv_is_dead(wins_ip, src_ip)) {
647 DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
649 sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
654 *return_iplist = name_query(sock,name,name_type, False,
655 True, wins_ip, return_count, &flags,
657 if (*return_iplist != NULL) {
663 /* Timed out wating for WINS server to respond. Mark it dead. */
664 wins_srv_died(wins_ip, src_ip);
666 /* The name definately isn't in this
667 group of WINS servers. goto the next group */
673 wins_srv_tags_free(wins_tags);
677 wins_srv_tags_free(wins_tags);
682 /********************************************************
683 Resolve via "lmhosts" method.
684 *********************************************************/
686 static BOOL resolve_lmhosts(const char *name, int name_type,
687 struct in_addr **return_iplist, int *return_count)
690 * "lmhosts" means parse the local lmhosts file.
696 struct in_addr return_ip;
698 *return_iplist = NULL;
701 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
703 fp = startlmhosts(dyn_LMHOSTSFILE);
705 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
706 if (strequal(name, lmhost_name) &&
707 ((name_type2 == -1) || (name_type == name_type2))
710 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
711 if(*return_iplist == NULL) {
712 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
715 **return_iplist = return_ip;
726 /********************************************************
727 Resolve via "hosts" method.
728 *********************************************************/
730 static BOOL resolve_hosts(const char *name,
731 struct in_addr **return_iplist, int *return_count)
734 * "host" means do a localhost, or dns lookup.
738 *return_iplist = NULL;
741 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
743 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
744 struct in_addr return_ip;
745 putip((char *)&return_ip,(char *)hp->h_addr);
746 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
747 if(*return_iplist == NULL) {
748 DEBUG(3,("resolve_hosts: malloc fail !\n"));
751 **return_iplist = return_ip;
758 /********************************************************
759 Internal interface to resolve a name into an IP address.
760 Use this function if the string is either an IP address, DNS
761 or host name or NetBIOS name. This uses the name switch in the
762 smb.conf to determine the order of name resolution.
763 *********************************************************/
765 static BOOL internal_resolve_name(const char *name, int name_type,
766 struct in_addr **return_iplist, int *return_count)
768 pstring name_resolve_list;
771 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
772 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
773 BOOL is_address = is_ipaddress(name);
775 struct in_addr *nodupes_iplist;
778 *return_iplist = NULL;
781 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
783 if (allzeros || allones || is_address) {
784 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
785 if(*return_iplist == NULL) {
786 DEBUG(3,("internal_resolve_name: malloc fail !\n"));
790 /* if it's in the form of an IP address then get the lib to interpret it */
791 (*return_iplist)->s_addr = inet_addr(name);
793 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
799 pstrcpy(name_resolve_list, lp_name_resolve_order());
800 ptr = name_resolve_list;
804 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
805 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
806 if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
810 } else if(strequal( tok, "lmhosts")) {
811 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
815 } else if(strequal( tok, "wins")) {
816 /* don't resolve 1D via WINS */
817 if (name_type != 0x1D &&
818 resolve_wins(name, name_type, return_iplist, return_count)) {
822 } else if(strequal( tok, "bcast")) {
823 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
828 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
832 /* All of the resolve_* functions above have returned false. */
834 SAFE_FREE(*return_iplist);
841 /* Remove duplicate entries. Some queries, notably #1c (domain
842 controllers) return the PDC in iplist[0] and then all domain
843 controllers including the PDC in iplist[1..n]. Iterating over
844 the iplist when the PDC is down will cause two sets of timeouts. */
846 if (*return_count && (nodupes_iplist = (struct in_addr *)
847 malloc(sizeof(struct in_addr) * (*return_count)))) {
848 int nodupes_count = 0;
850 /* Iterate over return_iplist looking for duplicates */
852 for (i = 0; i < *return_count; i++) {
853 BOOL is_dupe = False;
856 for (j = i + 1; j < *return_count; j++) {
857 if (ip_equal((*return_iplist)[i],
858 (*return_iplist)[j])) {
866 /* This one not a duplicate */
868 nodupes_iplist[nodupes_count] = (*return_iplist)[i];
873 /* Switcheroo with original list */
875 free(*return_iplist);
877 *return_iplist = nodupes_iplist;
878 *return_count = nodupes_count;
881 /* Display some debugging info */
883 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
886 for (i = 0; i < *return_count; i++)
887 DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
894 /********************************************************
895 Internal interface to resolve a name into one IP address.
896 Use this function if the string is either an IP address, DNS
897 or host name or NetBIOS name. This uses the name switch in the
898 smb.conf to determine the order of name resolution.
899 *********************************************************/
901 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
903 struct in_addr *ip_list = NULL;
906 if (is_ipaddress(name)) {
907 *return_ip = *interpret_addr2(name);
911 if (internal_resolve_name(name, name_type, &ip_list, &count)) {
913 /* only return valid addresses for TCP connections */
914 for (i=0; i<count; i++) {
915 char *ip_str = inet_ntoa(ip_list[i]);
917 strcmp(ip_str, "255.255.255.255") != 0 &&
918 strcmp(ip_str, "0.0.0.0") != 0) {
919 *return_ip = ip_list[i];
929 /********************************************************
930 Find the IP address of the master browser or DMB for a workgroup.
931 *********************************************************/
933 BOOL find_master_ip(char *group, struct in_addr *master_ip)
935 struct in_addr *ip_list = NULL;
938 if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
939 *master_ip = ip_list[0];
943 if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
944 *master_ip = ip_list[0];
953 /********************************************************
954 Lookup a DC name given a Domain name and IP address.
955 *********************************************************/
957 BOOL lookup_dc_name(const char *srcname, const char *domain,
958 struct in_addr *dc_ip, char *ret_name)
960 #if !defined(I_HATE_WINDOWS_REPLY_CODE)
966 * Due to the fact win WinNT *sucks* we must do a node status
972 ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
974 if(ret && *dc_name) {
975 fstrcpy(ret_name, dc_name);
981 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
983 JRA - This code is broken with BDC rollover - we need to do a full
984 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
987 int retry_time = 2000;
989 struct packet_struct p;
990 struct dgram_packet *dgram = &p.packet.dgram;
994 struct sockaddr_in sock_name;
995 int sock_len = sizeof(sock_name);
996 const char *mailslot = NET_LOGON_MAILSLOT;
1000 int dgm_id = generate_trn_id();
1001 int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1006 /* Find out the transient UDP port we have been allocated. */
1007 if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1008 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1015 * Create the request data.
1018 memset(buffer,'\0',sizeof(buffer));
1020 SSVAL(bufp,0,QUERYFORPDC);
1022 fstrcpy(bufp,srcname);
1023 bufp += (strlen(bufp) + 1);
1024 slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1025 mailslot_name = bufp;
1026 bufp += (strlen(bufp) + 1);
1027 bufp = ALIGN2(bufp, buffer);
1028 bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
1031 SSVAL(bufp,4,0xFFFF);
1032 SSVAL(bufp,6,0xFFFF);
1034 len = PTR_DIFF(bufp,buffer);
1036 memset((char *)&p,'\0',sizeof(p));
1038 /* DIRECT GROUP or UNIQUE datagram. */
1039 dgram->header.msg_type = 0x10;
1040 dgram->header.flags.node_type = M_NODE;
1041 dgram->header.flags.first = True;
1042 dgram->header.flags.more = False;
1043 dgram->header.dgm_id = dgm_id;
1044 dgram->header.source_ip = *iface_ip(*pdc_ip);
1045 dgram->header.source_port = ntohs(sock_name.sin_port);
1046 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1047 dgram->header.packet_offset = 0;
1049 make_nmb_name(&dgram->source_name,srcname,0);
1050 make_nmb_name(&dgram->dest_name,domain,0x1C);
1052 ptr = &dgram->data[0];
1054 /* Setup the smb part. */
1055 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1057 set_message(ptr,17,17 + len,True);
1060 CVAL(ptr,smb_com) = SMBtrans;
1061 SSVAL(ptr,smb_vwv1,len);
1062 SSVAL(ptr,smb_vwv11,len);
1063 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1064 SSVAL(ptr,smb_vwv13,3);
1065 SSVAL(ptr,smb_vwv14,1);
1066 SSVAL(ptr,smb_vwv15,1);
1067 SSVAL(ptr,smb_vwv16,2);
1069 pstrcpy(p2,mailslot);
1070 p2 = skip_string(p2,1);
1072 memcpy(p2,buffer,len);
1075 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1078 p.port = DGRAM_PORT;
1080 p.timestamp = time(NULL);
1081 p.packet_type = DGRAM_PACKET;
1083 GetTimeOfDay(&tval);
1085 if (!send_packet(&p)) {
1086 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1094 struct timeval tval2;
1095 struct packet_struct *p_ret;
1097 GetTimeOfDay(&tval2);
1098 if (TvalDiff(&tval,&tval2) > retry_time) {
1101 if (!send_packet(&p)) {
1102 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1106 GetTimeOfDay(&tval);
1110 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1111 struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1115 buf = &dgram2->data[0];
1118 if (CVAL(buf,smb_com) != SMBtrans) {
1119 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1120 CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1125 len = SVAL(buf,smb_vwv11);
1126 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1129 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1134 DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1135 nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1136 inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1138 if(SVAL(buf2,0) != QUERYFORPDC_R) {
1139 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1140 (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1146 /* Note this is safe as it is a bounded strcpy. */
1147 fstrcpy(ret_name, buf2);
1148 ret_name[sizeof(fstring)-1] = '\0';
1157 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1161 /********************************************************
1162 Get the IP address list of the PDC/BDC's of a Domain.
1163 *********************************************************/
1165 BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count)
1167 int name_type = pdc_only ? 0x1B : 0x1C;
1170 * If it's our domain then
1171 * use the 'password server' parameter.
1174 if (strequal(group, lp_workgroup())) {
1176 char *pserver = lp_passwordserver();
1178 int num_adresses = 0;
1179 struct in_addr *return_iplist = NULL;
1182 return internal_resolve_name(group, name_type, ip_list, count);
1185 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1186 if (strequal(name, "*"))
1187 return internal_resolve_name(group, name_type, ip_list, count);
1190 if (num_adresses == 0)
1191 return internal_resolve_name(group, name_type, ip_list, count);
1193 return_iplist = (struct in_addr *)malloc(num_adresses * sizeof(struct in_addr));
1194 if(return_iplist == NULL) {
1195 DEBUG(3,("get_dc_list: malloc fail !\n"));
1200 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1201 struct in_addr name_ip;
1202 if (resolve_name( name, &name_ip, 0x20) == False)
1204 return_iplist[(*count)++] = name_ip;
1206 *ip_list = return_iplist;
1207 return (*count != 0);
1209 return internal_resolve_name(group, name_type, ip_list, count);