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 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 static 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((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
230 bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&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 */
352 if( DEBUGLVL( 3 ) ) {
353 /* Only executed if DEBUGLEVEL >= 3 */
354 dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
355 switch( nmb2->header.rcode ) {
357 dbgtext( "Request was invalidly formatted.\n" );
360 dbgtext( "Problem with NBNS, cannot process name.\n");
363 dbgtext( "The name requested does not exist.\n" );
366 dbgtext( "Unsupported request error.\n" );
369 dbgtext( "Query refused error.\n" );
372 dbgtext( "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( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
472 while(!x_feof(fp) && !x_ferror(fp)) {
473 pstring ip,flags,extra;
479 if (!fgets_slash(line,sizeof(pstring),fp))
491 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
493 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
495 if (next_token(&ptr,flags,NULL, sizeof(flags)))
497 if (next_token(&ptr,extra,NULL, sizeof(extra)))
503 if (count > 0 && count < 2)
505 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
511 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
515 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
517 if (strchr_m(flags,'G') || strchr_m(flags,'S'))
519 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
523 *ipaddr = *interpret_addr2(ip);
525 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
526 then only add that name type. */
527 if((ptr = strchr_m(name, '#')) != NULL)
532 *name_type = (int)strtol(ptr, &endptr, 16);
534 if(!*ptr || (endptr == ptr))
536 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
540 *(--ptr) = '\0'; /* Truncate at the '#' */
549 /********************************************************
550 Finish parsing the lmhosts file.
551 *********************************************************/
553 void endlmhosts(XFILE *fp)
559 /********************************************************
560 Resolve via "bcast" method.
561 *********************************************************/
563 BOOL name_resolve_bcast(const char *name, int name_type,
564 struct in_addr **return_ip_list, int *return_count)
567 int num_interfaces = iface_count();
569 if (lp_disable_netbios()) {
570 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
574 *return_ip_list = NULL;
578 * "bcast" means do a broadcast lookup on all the local interfaces.
581 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
583 sock = open_socket_in( SOCK_DGRAM, 0, 3,
584 interpret_addr(lp_socket_address()), True );
586 if (sock == -1) return False;
588 set_socket_options(sock,"SO_BROADCAST");
590 * Lookup the name on all the interfaces, return on
591 * the first successful match.
593 for( i = num_interfaces-1; i >= 0; i--) {
594 struct in_addr sendto_ip;
596 /* Done this way to fix compiler error on IRIX 5.x */
597 sendto_ip = *iface_n_bcast(i);
598 *return_ip_list = name_query(sock, name, name_type, True,
599 True, sendto_ip, return_count, &flags, NULL);
600 if(*return_ip_list != NULL) {
610 /********************************************************
611 Resolve via "wins" method.
612 *********************************************************/
613 BOOL resolve_wins(const char *name, int name_type,
614 struct in_addr **return_iplist, int *return_count)
618 struct in_addr src_ip;
620 if (lp_disable_netbios()) {
621 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
625 *return_iplist = NULL;
628 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
630 if (wins_srv_count() < 1) {
631 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
635 /* we try a lookup on each of the WINS tags in turn */
636 wins_tags = wins_srv_tags();
639 /* huh? no tags?? give up in disgust */
643 /* the address we will be sending from */
644 src_ip = *interpret_addr2(lp_socket_address());
646 /* in the worst case we will try every wins server with every
648 for (t=0; wins_tags && wins_tags[t]; t++) {
649 int srv_count = wins_srv_count_tag(wins_tags[t]);
650 for (i=0; i<srv_count; i++) {
651 struct in_addr wins_ip;
655 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
657 if (global_in_nmbd && ismyip(wins_ip)) {
658 /* yikes! we'll loop forever */
662 /* skip any that have been unresponsive lately */
663 if (wins_srv_is_dead(wins_ip, src_ip)) {
667 DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
669 sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
674 *return_iplist = name_query(sock,name,name_type, False,
675 True, wins_ip, return_count, &flags,
677 if (*return_iplist != NULL) {
683 /* Timed out wating for WINS server to respond. Mark it dead. */
684 wins_srv_died(wins_ip, src_ip);
686 /* The name definately isn't in this
687 group of WINS servers. goto the next group */
693 wins_srv_tags_free(wins_tags);
697 wins_srv_tags_free(wins_tags);
702 /********************************************************
703 Resolve via "lmhosts" method.
704 *********************************************************/
706 static BOOL resolve_lmhosts(const char *name, int name_type,
707 struct in_addr **return_iplist, int *return_count)
710 * "lmhosts" means parse the local lmhosts file.
716 struct in_addr return_ip;
718 *return_iplist = NULL;
721 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
723 fp = startlmhosts(dyn_LMHOSTSFILE);
725 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
726 if (strequal(name, lmhost_name) &&
727 ((name_type2 == -1) || (name_type == name_type2))
730 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
731 if(*return_iplist == NULL) {
732 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
735 **return_iplist = return_ip;
746 /********************************************************
747 Resolve via "hosts" method.
748 *********************************************************/
750 static BOOL resolve_hosts(const char *name,
751 struct in_addr **return_iplist, int *return_count)
754 * "host" means do a localhost, or dns lookup.
758 *return_iplist = NULL;
761 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
763 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
764 struct in_addr return_ip;
765 putip((char *)&return_ip,(char *)hp->h_addr);
766 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
767 if(*return_iplist == NULL) {
768 DEBUG(3,("resolve_hosts: malloc fail !\n"));
771 **return_iplist = return_ip;
778 /********************************************************
779 Internal interface to resolve a name into an IP address.
780 Use this function if the string is either an IP address, DNS
781 or host name or NetBIOS name. This uses the name switch in the
782 smb.conf to determine the order of name resolution.
783 *********************************************************/
785 static BOOL internal_resolve_name(const char *name, int name_type,
786 struct in_addr **return_iplist, int *return_count)
788 pstring name_resolve_list;
791 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
792 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
793 BOOL is_address = is_ipaddress(name);
795 struct in_addr *nodupes_iplist;
798 *return_iplist = NULL;
801 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
803 if (allzeros || allones || is_address) {
804 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
805 if(*return_iplist == NULL) {
806 DEBUG(3,("internal_resolve_name: malloc fail !\n"));
810 /* if it's in the form of an IP address then get the lib to interpret it */
811 (*return_iplist)->s_addr = inet_addr(name);
813 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
819 pstrcpy(name_resolve_list, lp_name_resolve_order());
820 ptr = name_resolve_list;
824 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
825 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
826 if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
830 } else if(strequal( tok, "lmhosts")) {
831 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
835 } else if(strequal( tok, "wins")) {
836 /* don't resolve 1D via WINS */
837 if (name_type != 0x1D &&
838 resolve_wins(name, name_type, return_iplist, return_count)) {
842 } else if(strequal( tok, "bcast")) {
843 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
848 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
852 /* All of the resolve_* functions above have returned false. */
854 SAFE_FREE(*return_iplist);
861 /* Remove duplicate entries. Some queries, notably #1c (domain
862 controllers) return the PDC in iplist[0] and then all domain
863 controllers including the PDC in iplist[1..n]. Iterating over
864 the iplist when the PDC is down will cause two sets of timeouts. */
866 if (*return_count && (nodupes_iplist = (struct in_addr *)
867 malloc(sizeof(struct in_addr) * (*return_count)))) {
868 int nodupes_count = 0;
870 /* Iterate over return_iplist looking for duplicates */
872 for (i = 0; i < *return_count; i++) {
873 BOOL is_dupe = False;
876 for (j = i + 1; j < *return_count; j++) {
877 if (ip_equal((*return_iplist)[i],
878 (*return_iplist)[j])) {
886 /* This one not a duplicate */
888 nodupes_iplist[nodupes_count] = (*return_iplist)[i];
893 /* Switcheroo with original list */
895 free(*return_iplist);
897 *return_iplist = nodupes_iplist;
898 *return_count = nodupes_count;
901 /* Display some debugging info */
903 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
906 for (i = 0; i < *return_count; i++)
907 DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
914 /********************************************************
915 Internal interface to resolve a name into one IP address.
916 Use this function if the string is either an IP address, DNS
917 or host name or NetBIOS name. This uses the name switch in the
918 smb.conf to determine the order of name resolution.
919 *********************************************************/
921 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
923 struct in_addr *ip_list = NULL;
926 if (is_ipaddress(name)) {
927 *return_ip = *interpret_addr2(name);
931 if (internal_resolve_name(name, name_type, &ip_list, &count)) {
933 /* only return valid addresses for TCP connections */
934 for (i=0; i<count; i++) {
935 char *ip_str = inet_ntoa(ip_list[i]);
937 strcmp(ip_str, "255.255.255.255") != 0 &&
938 strcmp(ip_str, "0.0.0.0") != 0) {
939 *return_ip = ip_list[i];
949 /********************************************************
950 Find the IP address of the master browser or DMB for a workgroup.
951 *********************************************************/
953 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
955 struct in_addr *ip_list = NULL;
958 if (lp_disable_netbios()) {
959 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
963 if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
964 *master_ip = ip_list[0];
968 if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
969 *master_ip = ip_list[0];
978 /********************************************************
979 Lookup a DC name given a Domain name and IP address.
980 *********************************************************/
982 BOOL lookup_dc_name(const char *srcname, const char *domain,
983 struct in_addr *dc_ip, char *ret_name)
985 #if !defined(I_HATE_WINDOWS_REPLY_CODE)
989 if (lp_disable_netbios()) {
990 DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
995 * Due to the fact win WinNT *sucks* we must do a node status
1001 ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1003 if(ret && *dc_name) {
1004 fstrcpy(ret_name, dc_name);
1010 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1012 JRA - This code is broken with BDC rollover - we need to do a full
1013 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1016 int retry_time = 2000;
1017 struct timeval tval;
1018 struct packet_struct p;
1019 struct dgram_packet *dgram = &p.packet.dgram;
1023 struct sockaddr_in sock_name;
1024 int sock_len = sizeof(sock_name);
1025 const char *mailslot = NET_LOGON_MAILSLOT;
1026 char *mailslot_name;
1029 int dgm_id = generate_trn_id();
1030 int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1035 /* Find out the transient UDP port we have been allocated. */
1036 if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1037 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1044 * Create the request data.
1047 memset(buffer,'\0',sizeof(buffer));
1049 SSVAL(bufp,0,QUERYFORPDC);
1051 fstrcpy(bufp,srcname);
1052 bufp += (strlen(bufp) + 1);
1053 slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1054 mailslot_name = bufp;
1055 bufp += (strlen(bufp) + 1);
1056 bufp = ALIGN2(bufp, buffer);
1057 bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
1060 SSVAL(bufp,4,0xFFFF);
1061 SSVAL(bufp,6,0xFFFF);
1063 len = PTR_DIFF(bufp,buffer);
1065 memset((char *)&p,'\0',sizeof(p));
1067 /* DIRECT GROUP or UNIQUE datagram. */
1068 dgram->header.msg_type = 0x10;
1069 dgram->header.flags.node_type = M_NODE;
1070 dgram->header.flags.first = True;
1071 dgram->header.flags.more = False;
1072 dgram->header.dgm_id = dgm_id;
1073 dgram->header.source_ip = *iface_ip(*pdc_ip);
1074 dgram->header.source_port = ntohs(sock_name.sin_port);
1075 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1076 dgram->header.packet_offset = 0;
1078 make_nmb_name(&dgram->source_name,srcname,0);
1079 make_nmb_name(&dgram->dest_name,domain,0x1C);
1081 ptr = &dgram->data[0];
1083 /* Setup the smb part. */
1084 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1086 set_message(ptr,17,17 + len,True);
1089 CVAL(ptr,smb_com) = SMBtrans;
1090 SSVAL(ptr,smb_vwv1,len);
1091 SSVAL(ptr,smb_vwv11,len);
1092 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1093 SSVAL(ptr,smb_vwv13,3);
1094 SSVAL(ptr,smb_vwv14,1);
1095 SSVAL(ptr,smb_vwv15,1);
1096 SSVAL(ptr,smb_vwv16,2);
1098 pstrcpy(p2,mailslot);
1099 p2 = skip_string(p2,1);
1101 memcpy(p2,buffer,len);
1104 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1107 p.port = DGRAM_PORT;
1109 p.timestamp = time(NULL);
1110 p.packet_type = DGRAM_PACKET;
1112 GetTimeOfDay(&tval);
1114 if (!send_packet(&p)) {
1115 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1123 struct timeval tval2;
1124 struct packet_struct *p_ret;
1126 GetTimeOfDay(&tval2);
1127 if (TvalDiff(&tval,&tval2) > retry_time) {
1130 if (!send_packet(&p)) {
1131 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1135 GetTimeOfDay(&tval);
1139 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1140 struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1144 buf = &dgram2->data[0];
1147 if (CVAL(buf,smb_com) != SMBtrans) {
1148 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1149 CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1154 len = SVAL(buf,smb_vwv11);
1155 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1158 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1163 DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1164 nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1165 inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1167 if(SVAL(buf2,0) != QUERYFORPDC_R) {
1168 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1169 (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1175 /* Note this is safe as it is a bounded strcpy. */
1176 fstrcpy(ret_name, buf2);
1177 ret_name[sizeof(fstring)-1] = '\0';
1186 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1190 /********************************************************
1191 Get the IP address list of the PDC/BDC's of a Domain.
1192 *********************************************************/
1194 BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count)
1196 int name_type = pdc_only ? 0x1B : 0x1C;
1199 * If it's our domain then
1200 * use the 'password server' parameter.
1203 if (strequal(group, lp_workgroup())) {
1205 char *pserver = lp_passwordserver();
1207 int num_adresses = 0;
1208 struct in_addr *return_iplist = NULL;
1211 return internal_resolve_name(group, name_type, ip_list, count);
1214 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1215 if (strequal(name, "*"))
1216 return internal_resolve_name(group, name_type, ip_list, count);
1219 if (num_adresses == 0)
1220 return internal_resolve_name(group, name_type, ip_list, count);
1222 return_iplist = (struct in_addr *)malloc(num_adresses * sizeof(struct in_addr));
1223 if(return_iplist == NULL) {
1224 DEBUG(3,("get_dc_list: malloc fail !\n"));
1229 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1230 struct in_addr name_ip;
1231 if (resolve_name( name, &name_ip, 0x20) == False)
1233 return_iplist[(*count)++] = name_ip;
1235 *ip_list = return_iplist;
1236 return (*count != 0);
1238 return internal_resolve_name(group, name_type, ip_list, count);