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;
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 /* Check netbios name cache */
821 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
823 /* This could be a negative response */
825 return (*return_count > 0);
828 pstrcpy(name_resolve_list, lp_name_resolve_order());
829 ptr = name_resolve_list;
833 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
834 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
835 if (name_type == 0x20) {
836 if (resolve_hosts(name, return_iplist, return_count)) {
841 /* Store negative lookup result */
843 namecache_store(name, name_type, 0, NULL);
846 } else if(strequal( tok, "lmhosts")) {
847 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
851 } else if(strequal( tok, "wins")) {
852 /* don't resolve 1D via WINS */
853 if (name_type != 0x1D &&
854 resolve_wins(name, name_type, return_iplist, return_count)) {
858 } else if(strequal( tok, "bcast")) {
859 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
864 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
868 /* All of the resolve_* functions above have returned false. */
870 SAFE_FREE(*return_iplist);
877 /* Remove duplicate entries. Some queries, notably #1c (domain
878 controllers) return the PDC in iplist[0] and then all domain
879 controllers including the PDC in iplist[1..n]. Iterating over
880 the iplist when the PDC is down will cause two sets of timeouts. */
882 if (*return_count && (nodupes_iplist = (struct in_addr *)
883 malloc(sizeof(struct in_addr) * (*return_count)))) {
884 int nodupes_count = 0;
886 /* Iterate over return_iplist looking for duplicates */
888 for (i = 0; i < *return_count; i++) {
889 BOOL is_dupe = False;
892 for (j = i + 1; j < *return_count; j++) {
893 if (ip_equal((*return_iplist)[i],
894 (*return_iplist)[j])) {
902 /* This one not a duplicate */
904 nodupes_iplist[nodupes_count] = (*return_iplist)[i];
909 /* Switcheroo with original list */
911 free(*return_iplist);
913 *return_iplist = nodupes_iplist;
914 *return_count = nodupes_count;
917 /* Save in name cache */
919 namecache_store(name, name_type, *return_count, *return_iplist);
921 /* Display some debugging info */
923 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
926 for (i = 0; i < *return_count; i++)
927 DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
934 /********************************************************
935 Internal interface to resolve a name into one IP address.
936 Use this function if the string is either an IP address, DNS
937 or host name or NetBIOS name. This uses the name switch in the
938 smb.conf to determine the order of name resolution.
939 *********************************************************/
941 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
943 struct in_addr *ip_list = NULL;
946 if (is_ipaddress(name)) {
947 *return_ip = *interpret_addr2(name);
951 if (internal_resolve_name(name, name_type, &ip_list, &count)) {
953 /* only return valid addresses for TCP connections */
954 for (i=0; i<count; i++) {
955 char *ip_str = inet_ntoa(ip_list[i]);
957 strcmp(ip_str, "255.255.255.255") != 0 &&
958 strcmp(ip_str, "0.0.0.0") != 0) {
959 *return_ip = ip_list[i];
969 /********************************************************
970 Find the IP address of the master browser or DMB for a workgroup.
971 *********************************************************/
973 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
975 struct in_addr *ip_list = NULL;
978 if (lp_disable_netbios()) {
979 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
983 if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
984 *master_ip = ip_list[0];
988 if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
989 *master_ip = ip_list[0];
998 /********************************************************
999 Lookup a DC name given a Domain name and IP address.
1000 *********************************************************/
1002 BOOL lookup_dc_name(const char *srcname, const char *domain,
1003 struct in_addr *dc_ip, char *ret_name)
1005 #if !defined(I_HATE_WINDOWS_REPLY_CODE)
1009 if (lp_disable_netbios()) {
1010 DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
1015 * Due to the fact win WinNT *sucks* we must do a node status
1016 * query here... JRA.
1021 ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1023 if(ret && *dc_name) {
1024 fstrcpy(ret_name, dc_name);
1030 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1032 JRA - This code is broken with BDC rollover - we need to do a full
1033 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1036 int retry_time = 2000;
1037 struct timeval tval;
1038 struct packet_struct p;
1039 struct dgram_packet *dgram = &p.packet.dgram;
1043 struct sockaddr_in sock_name;
1044 int sock_len = sizeof(sock_name);
1045 const char *mailslot = NET_LOGON_MAILSLOT;
1046 char *mailslot_name;
1049 int dgm_id = generate_trn_id();
1050 int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1055 /* Find out the transient UDP port we have been allocated. */
1056 if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1057 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1064 * Create the request data.
1067 memset(buffer,'\0',sizeof(buffer));
1069 SSVAL(bufp,0,QUERYFORPDC);
1071 fstrcpy(bufp,srcname);
1072 bufp += (strlen(bufp) + 1);
1073 slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1074 mailslot_name = bufp;
1075 bufp += (strlen(bufp) + 1);
1076 bufp = ALIGN2(bufp, buffer);
1077 bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
1080 SSVAL(bufp,4,0xFFFF);
1081 SSVAL(bufp,6,0xFFFF);
1083 len = PTR_DIFF(bufp,buffer);
1085 memset((char *)&p,'\0',sizeof(p));
1087 /* DIRECT GROUP or UNIQUE datagram. */
1088 dgram->header.msg_type = 0x10;
1089 dgram->header.flags.node_type = M_NODE;
1090 dgram->header.flags.first = True;
1091 dgram->header.flags.more = False;
1092 dgram->header.dgm_id = dgm_id;
1093 dgram->header.source_ip = *iface_ip(*pdc_ip);
1094 dgram->header.source_port = ntohs(sock_name.sin_port);
1095 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1096 dgram->header.packet_offset = 0;
1098 make_nmb_name(&dgram->source_name,srcname,0);
1099 make_nmb_name(&dgram->dest_name,domain,0x1C);
1101 ptr = &dgram->data[0];
1103 /* Setup the smb part. */
1104 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1106 set_message(ptr,17,17 + len,True);
1109 CVAL(ptr,smb_com) = SMBtrans;
1110 SSVAL(ptr,smb_vwv1,len);
1111 SSVAL(ptr,smb_vwv11,len);
1112 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1113 SSVAL(ptr,smb_vwv13,3);
1114 SSVAL(ptr,smb_vwv14,1);
1115 SSVAL(ptr,smb_vwv15,1);
1116 SSVAL(ptr,smb_vwv16,2);
1118 pstrcpy(p2,mailslot);
1119 p2 = skip_string(p2,1);
1121 memcpy(p2,buffer,len);
1124 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1127 p.port = DGRAM_PORT;
1129 p.timestamp = time(NULL);
1130 p.packet_type = DGRAM_PACKET;
1132 GetTimeOfDay(&tval);
1134 if (!send_packet(&p)) {
1135 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1143 struct timeval tval2;
1144 struct packet_struct *p_ret;
1146 GetTimeOfDay(&tval2);
1147 if (TvalDiff(&tval,&tval2) > retry_time) {
1150 if (!send_packet(&p)) {
1151 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1155 GetTimeOfDay(&tval);
1159 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1160 struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1164 buf = &dgram2->data[0];
1167 if (CVAL(buf,smb_com) != SMBtrans) {
1168 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1169 CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1174 len = SVAL(buf,smb_vwv11);
1175 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1178 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1183 DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1184 nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1185 inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1187 if(SVAL(buf2,0) != QUERYFORPDC_R) {
1188 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1189 (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1195 /* Note this is safe as it is a bounded strcpy. */
1196 fstrcpy(ret_name, buf2);
1197 ret_name[sizeof(fstring)-1] = '\0';
1206 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1209 /********************************************************
1210 Get the IP address list of the primary domain controller
1212 *********************************************************/
1214 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1216 struct in_addr *ip_list;
1219 /* Look up #1B name */
1221 if (!internal_resolve_name(domain, 0x1b, &ip_list, &count))
1224 SMB_ASSERT(count == 1);
1232 /********************************************************
1233 Get the IP address list of the domain controllers for
1235 *********************************************************/
1237 BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count)
1240 * If it's our domain then
1241 * use the 'password server' parameter.
1244 if (strequal(domain, lp_workgroup())) {
1246 char *pserver = lp_passwordserver();
1248 int num_adresses = 0;
1249 struct in_addr *return_iplist = NULL;
1252 return internal_resolve_name(
1253 domain, 0x1C, ip_list, count);
1257 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1258 if (strequal(name, "*"))
1259 return internal_resolve_name(
1260 domain, 0x1C, ip_list, count);
1264 if (num_adresses == 0)
1265 return internal_resolve_name(
1266 domain, 0x1C, ip_list, count);
1268 return_iplist = (struct in_addr *)malloc(
1269 num_adresses * sizeof(struct in_addr));
1271 if (return_iplist == NULL) {
1272 DEBUG(3,("get_dc_list: malloc fail !\n"));
1279 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1280 struct in_addr name_ip;
1281 if (resolve_name( name, &name_ip, 0x20) == False)
1283 return_iplist[(*count)++] = name_ip;
1286 *ip_list = return_iplist;
1288 return (*count != 0);
1291 return internal_resolve_name(domain, 0x1C, ip_list, count);