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 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;
480 if (!fgets_slash(line,sizeof(pstring),fp))
492 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
494 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
496 if (next_token(&ptr,flags,NULL, sizeof(flags)))
498 if (next_token(&ptr,extra,NULL, sizeof(extra)))
504 if (count > 0 && count < 2)
506 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
512 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
516 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
518 if (strchr_m(flags,'G') || strchr_m(flags,'S'))
520 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
524 *ipaddr = *interpret_addr2(ip);
526 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
527 then only add that name type. */
528 if((ptr1 = strchr_m(name, '#')) != NULL)
533 *name_type = (int)strtol(ptr1, &endptr, 16);
535 if(!*ptr1 || (endptr == ptr1))
537 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
541 *(--ptr1) = '\0'; /* Truncate at the '#' */
550 /********************************************************
551 Finish parsing the lmhosts file.
552 *********************************************************/
554 void endlmhosts(XFILE *fp)
560 /********************************************************
561 Resolve via "bcast" method.
562 *********************************************************/
564 BOOL name_resolve_bcast(const char *name, int name_type,
565 struct in_addr **return_ip_list, int *return_count)
568 int num_interfaces = iface_count();
570 if (lp_disable_netbios()) {
571 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
575 *return_ip_list = NULL;
579 * "bcast" means do a broadcast lookup on all the local interfaces.
582 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
584 sock = open_socket_in( SOCK_DGRAM, 0, 3,
585 interpret_addr(lp_socket_address()), True );
587 if (sock == -1) return False;
589 set_socket_options(sock,"SO_BROADCAST");
591 * Lookup the name on all the interfaces, return on
592 * the first successful match.
594 for( i = num_interfaces-1; i >= 0; i--) {
595 struct in_addr sendto_ip;
597 /* Done this way to fix compiler error on IRIX 5.x */
598 sendto_ip = *iface_n_bcast(i);
599 *return_ip_list = name_query(sock, name, name_type, True,
600 True, sendto_ip, return_count, &flags, NULL);
601 if(*return_ip_list != NULL) {
611 /********************************************************
612 Resolve via "wins" method.
613 *********************************************************/
614 BOOL resolve_wins(const char *name, int name_type,
615 struct in_addr **return_iplist, int *return_count)
619 struct in_addr src_ip;
621 if (lp_disable_netbios()) {
622 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
626 *return_iplist = NULL;
629 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
631 if (wins_srv_count() < 1) {
632 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
636 /* we try a lookup on each of the WINS tags in turn */
637 wins_tags = wins_srv_tags();
640 /* huh? no tags?? give up in disgust */
644 /* the address we will be sending from */
645 src_ip = *interpret_addr2(lp_socket_address());
647 /* in the worst case we will try every wins server with every
649 for (t=0; wins_tags && wins_tags[t]; t++) {
650 int srv_count = wins_srv_count_tag(wins_tags[t]);
651 for (i=0; i<srv_count; i++) {
652 struct in_addr wins_ip;
656 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
658 if (global_in_nmbd && ismyip(wins_ip)) {
659 /* yikes! we'll loop forever */
663 /* skip any that have been unresponsive lately */
664 if (wins_srv_is_dead(wins_ip, src_ip)) {
668 DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
670 sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
675 *return_iplist = name_query(sock,name,name_type, False,
676 True, wins_ip, return_count, &flags,
678 if (*return_iplist != NULL) {
684 /* Timed out wating for WINS server to respond. Mark it dead. */
685 wins_srv_died(wins_ip, src_ip);
687 /* The name definately isn't in this
688 group of WINS servers. goto the next group */
694 wins_srv_tags_free(wins_tags);
698 wins_srv_tags_free(wins_tags);
703 /********************************************************
704 Resolve via "lmhosts" method.
705 *********************************************************/
707 static BOOL resolve_lmhosts(const char *name, int name_type,
708 struct in_addr **return_iplist, int *return_count)
711 * "lmhosts" means parse the local lmhosts file.
717 struct in_addr return_ip;
719 *return_iplist = NULL;
722 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
724 fp = startlmhosts(dyn_LMHOSTSFILE);
726 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
727 if (strequal(name, lmhost_name) &&
728 ((name_type2 == -1) || (name_type == name_type2))
731 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
732 if(*return_iplist == NULL) {
733 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
736 **return_iplist = return_ip;
747 /********************************************************
748 Resolve via "hosts" method.
749 *********************************************************/
751 static BOOL resolve_hosts(const char *name,
752 struct in_addr **return_iplist, int *return_count)
755 * "host" means do a localhost, or dns lookup.
759 *return_iplist = NULL;
762 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
764 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
765 struct in_addr return_ip;
766 putip((char *)&return_ip,(char *)hp->h_addr);
767 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
768 if(*return_iplist == NULL) {
769 DEBUG(3,("resolve_hosts: malloc fail !\n"));
772 **return_iplist = return_ip;
779 /********************************************************
780 Internal interface to resolve a name into an IP address.
781 Use this function if the string is either an IP address, DNS
782 or host name or NetBIOS name. This uses the name switch in the
783 smb.conf to determine the order of name resolution.
784 *********************************************************/
786 static BOOL internal_resolve_name(const char *name, int name_type,
787 struct in_addr **return_iplist, int *return_count)
789 pstring name_resolve_list;
792 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
793 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
794 BOOL is_address = is_ipaddress(name);
796 struct in_addr *nodupes_iplist;
799 *return_iplist = NULL;
802 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
804 if (allzeros || allones || is_address) {
805 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
806 if(*return_iplist == NULL) {
807 DEBUG(3,("internal_resolve_name: malloc fail !\n"));
811 /* if it's in the form of an IP address then get the lib to interpret it */
812 (*return_iplist)->s_addr = inet_addr(name);
814 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
820 /* Check netbios name cache */
822 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
824 /* This could be a negative response */
826 return (*return_count > 0);
829 pstrcpy(name_resolve_list, lp_name_resolve_order());
830 ptr = name_resolve_list;
834 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
835 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
836 if (name_type == 0x20) {
837 if (resolve_hosts(name, return_iplist, return_count)) {
842 /* Store negative lookup result */
844 namecache_store(name, name_type, 0, NULL);
847 } else if(strequal( tok, "lmhosts")) {
848 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
852 } else if(strequal( tok, "wins")) {
853 /* don't resolve 1D via WINS */
854 if (name_type != 0x1D &&
855 resolve_wins(name, name_type, return_iplist, return_count)) {
859 } else if(strequal( tok, "bcast")) {
860 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
865 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
869 /* All of the resolve_* functions above have returned false. */
871 SAFE_FREE(*return_iplist);
878 /* Remove duplicate entries. Some queries, notably #1c (domain
879 controllers) return the PDC in iplist[0] and then all domain
880 controllers including the PDC in iplist[1..n]. Iterating over
881 the iplist when the PDC is down will cause two sets of timeouts. */
883 if (*return_count && (nodupes_iplist = (struct in_addr *)
884 malloc(sizeof(struct in_addr) * (*return_count)))) {
885 int nodupes_count = 0;
887 /* Iterate over return_iplist looking for duplicates */
889 for (i = 0; i < *return_count; i++) {
890 BOOL is_dupe = False;
893 for (j = i + 1; j < *return_count; j++) {
894 if (ip_equal((*return_iplist)[i],
895 (*return_iplist)[j])) {
903 /* This one not a duplicate */
905 nodupes_iplist[nodupes_count] = (*return_iplist)[i];
910 /* Switcheroo with original list */
912 free(*return_iplist);
914 *return_iplist = nodupes_iplist;
915 *return_count = nodupes_count;
918 /* Save in name cache */
920 namecache_store(name, name_type, *return_count, *return_iplist);
922 /* Display some debugging info */
924 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
927 for (i = 0; i < *return_count; i++)
928 DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
935 /********************************************************
936 Internal interface to resolve a name into one IP address.
937 Use this function if the string is either an IP address, DNS
938 or host name or NetBIOS name. This uses the name switch in the
939 smb.conf to determine the order of name resolution.
940 *********************************************************/
942 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
944 struct in_addr *ip_list = NULL;
947 if (is_ipaddress(name)) {
948 *return_ip = *interpret_addr2(name);
952 if (internal_resolve_name(name, name_type, &ip_list, &count)) {
954 /* only return valid addresses for TCP connections */
955 for (i=0; i<count; i++) {
956 char *ip_str = inet_ntoa(ip_list[i]);
958 strcmp(ip_str, "255.255.255.255") != 0 &&
959 strcmp(ip_str, "0.0.0.0") != 0) {
960 *return_ip = ip_list[i];
970 /********************************************************
971 Find the IP address of the master browser or DMB for a workgroup.
972 *********************************************************/
974 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
976 struct in_addr *ip_list = NULL;
979 if (lp_disable_netbios()) {
980 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
984 if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
985 *master_ip = ip_list[0];
989 if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
990 *master_ip = ip_list[0];
999 /********************************************************
1000 Lookup a DC name given a Domain name and IP address.
1001 *********************************************************/
1003 BOOL lookup_dc_name(const char *srcname, const char *domain,
1004 struct in_addr *dc_ip, char *ret_name)
1006 #if !defined(I_HATE_WINDOWS_REPLY_CODE)
1010 if (lp_disable_netbios()) {
1011 DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
1016 * Due to the fact win WinNT *sucks* we must do a node status
1017 * query here... JRA.
1022 ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1024 if(ret && *dc_name) {
1025 fstrcpy(ret_name, dc_name);
1031 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1033 JRA - This code is broken with BDC rollover - we need to do a full
1034 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1037 int retry_time = 2000;
1038 struct timeval tval;
1039 struct packet_struct p;
1040 struct dgram_packet *dgram = &p.packet.dgram;
1044 struct sockaddr_in sock_name;
1045 int sock_len = sizeof(sock_name);
1046 const char *mailslot = NET_LOGON_MAILSLOT;
1047 char *mailslot_name;
1050 int dgm_id = generate_trn_id();
1051 int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1056 /* Find out the transient UDP port we have been allocated. */
1057 if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1058 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1065 * Create the request data.
1068 memset(buffer,'\0',sizeof(buffer));
1070 SSVAL(bufp,0,QUERYFORPDC);
1072 fstrcpy(bufp,srcname);
1073 bufp += (strlen(bufp) + 1);
1074 slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1075 mailslot_name = bufp;
1076 bufp += (strlen(bufp) + 1);
1077 bufp = ALIGN2(bufp, buffer);
1078 bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
1081 SSVAL(bufp,4,0xFFFF);
1082 SSVAL(bufp,6,0xFFFF);
1084 len = PTR_DIFF(bufp,buffer);
1086 memset((char *)&p,'\0',sizeof(p));
1088 /* DIRECT GROUP or UNIQUE datagram. */
1089 dgram->header.msg_type = 0x10;
1090 dgram->header.flags.node_type = M_NODE;
1091 dgram->header.flags.first = True;
1092 dgram->header.flags.more = False;
1093 dgram->header.dgm_id = dgm_id;
1094 dgram->header.source_ip = *iface_ip(*pdc_ip);
1095 dgram->header.source_port = ntohs(sock_name.sin_port);
1096 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1097 dgram->header.packet_offset = 0;
1099 make_nmb_name(&dgram->source_name,srcname,0);
1100 make_nmb_name(&dgram->dest_name,domain,0x1C);
1102 ptr = &dgram->data[0];
1104 /* Setup the smb part. */
1105 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1107 set_message(ptr,17,17 + len,True);
1110 CVAL(ptr,smb_com) = SMBtrans;
1111 SSVAL(ptr,smb_vwv1,len);
1112 SSVAL(ptr,smb_vwv11,len);
1113 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1114 SSVAL(ptr,smb_vwv13,3);
1115 SSVAL(ptr,smb_vwv14,1);
1116 SSVAL(ptr,smb_vwv15,1);
1117 SSVAL(ptr,smb_vwv16,2);
1119 pstrcpy(p2,mailslot);
1120 p2 = skip_string(p2,1);
1122 memcpy(p2,buffer,len);
1125 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1128 p.port = DGRAM_PORT;
1130 p.timestamp = time(NULL);
1131 p.packet_type = DGRAM_PACKET;
1133 GetTimeOfDay(&tval);
1135 if (!send_packet(&p)) {
1136 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1144 struct timeval tval2;
1145 struct packet_struct *p_ret;
1147 GetTimeOfDay(&tval2);
1148 if (TvalDiff(&tval,&tval2) > retry_time) {
1151 if (!send_packet(&p)) {
1152 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1156 GetTimeOfDay(&tval);
1160 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1161 struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1165 buf = &dgram2->data[0];
1168 if (CVAL(buf,smb_com) != SMBtrans) {
1169 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1170 CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1175 len = SVAL(buf,smb_vwv11);
1176 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1179 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1184 DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1185 nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1186 inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1188 if(SVAL(buf2,0) != QUERYFORPDC_R) {
1189 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1190 (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1196 /* Note this is safe as it is a bounded strcpy. */
1197 fstrcpy(ret_name, buf2);
1198 ret_name[sizeof(fstring)-1] = '\0';
1207 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1210 /********************************************************
1211 Get the IP address list of the primary domain controller
1213 *********************************************************/
1215 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1217 struct in_addr *ip_list;
1220 /* Look up #1B name */
1222 if (!internal_resolve_name(domain, 0x1b, &ip_list, &count))
1225 SMB_ASSERT(count == 1);
1233 /********************************************************
1234 Get the IP address list of the domain controllers for
1236 *********************************************************/
1238 BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *ordered)
1243 /* If it's our domain then use the 'password server' parameter. */
1245 if (strequal(domain, lp_workgroup())) {
1247 char *pserver = lp_passwordserver(); /* UNIX charset. */
1249 int num_addresses = 0;
1250 int local_count, i, j;
1251 struct in_addr *return_iplist = NULL;
1252 struct in_addr *auto_ip_list = NULL;
1253 BOOL done_auto_lookup = False;
1258 return internal_resolve_name(
1259 domain, 0x1C, ip_list, count);
1264 * if '*' appears in the "password server" list then add
1265 * an auto lookup to the list of manually configured
1266 * DC's. If any DC is listed by name, then the list should be
1267 * considered to be ordered
1270 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1271 if (strequal(name, "*")) {
1272 if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count) )
1273 num_addresses += auto_count;
1274 done_auto_lookup = True;
1275 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1281 /* if we have no addresses and haven't done the auto lookup, then
1282 just return the list of DC's */
1284 if ( (num_addresses == 0) && !done_auto_lookup )
1285 return internal_resolve_name(domain, 0x1C, ip_list, count);
1287 return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr));
1289 if (return_iplist == NULL) {
1290 DEBUG(3,("get_dc_list: malloc fail !\n"));
1297 /* fill in the return list now with real IP's */
1299 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) )
1301 struct in_addr name_ip;
1303 /* copy any addersses from the auto lookup */
1305 if ( strequal(name, "*") ) {
1306 for ( j=0; j<auto_count; j++ )
1307 return_iplist[local_count++] = auto_ip_list[j];
1311 /* explicit lookup */
1313 if ( resolve_name( name, &name_ip, 0x20) ) {
1314 return_iplist[local_count++] = name_ip;
1320 /* need to remove duplicates in the list if we have
1321 any explicit password servers */
1325 int hole_index = -1;
1327 /* one loop to remove duplicates */
1328 for ( i=0; i<local_count; i++ )
1330 if ( is_zero_ip(return_iplist[i]) )
1333 for ( j=i+1; j<local_count; j++ ) {
1334 if ( ip_equal( return_iplist[i], return_iplist[j]) )
1335 zero_ip(&return_iplist[j]);
1339 /* one loop to clean up any holes we left */
1340 /* first ip can never be a zero_ip() */
1342 while ( i<local_count )
1344 if ( !is_zero_ip(return_iplist[i]) ) {
1352 while ( i<local_count ) {
1353 if ( !is_zero_ip(return_iplist[i]) )
1354 return_iplist[hole_index++] = return_iplist[i];
1358 /* we should exit the loop implicitly here, but ... */
1362 local_count = hole_index;
1365 *ip_list = return_iplist;
1366 *count = local_count;
1368 DEBUG(8,("get_dc_list: return %d ip addresses\n", *count));
1370 return (*count != 0);
1373 return internal_resolve_name(domain, 0x1C, ip_list, count);