[merge] remove assert(count ==1) for multi-homed PDCs; CR 1277
authorGerald Carter <jerry@samba.org>
Wed, 4 Dec 2002 19:00:29 +0000 (19:00 +0000)
committerGerald Carter <jerry@samba.org>
Wed, 4 Dec 2002 19:00:29 +0000 (19:00 +0000)
(This used to be commit 157b5ab198670c6999f22d6b49072fdebc84be0d)

source3/libsmb/namequery.c

index 7aaa7d5908c9c809b893ba011d3c59f5caa0521c..f446453b9a5eb648363d6179a6a041b159b58bee 100644 (file)
@@ -1001,7 +1001,6 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip)
 BOOL lookup_dc_name(const char *srcname, const char *domain, 
                    struct in_addr *dc_ip, char *ret_name)
 {
-#if !defined(I_HATE_WINDOWS_REPLY_CODE)        
        fstring dc_name;
        BOOL ret;
 
@@ -1025,184 +1024,6 @@ BOOL lookup_dc_name(const char *srcname, const char *domain,
        }
        
        return False;
-
-#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
-
-JRA - This code is broken with BDC rollover - we need to do a full
-NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
-
-       int retries = 3;
-       int retry_time = 2000;
-       struct timeval tval;
-       struct packet_struct p;
-       struct dgram_packet *dgram = &p.packet.dgram;
-       char *ptr,*p2;
-       char tmp[4];
-       int len;
-       struct sockaddr_in sock_name;
-       int sock_len = sizeof(sock_name);
-       const char *mailslot = NET_LOGON_MAILSLOT;
-       char *mailslot_name;
-       char buffer[1024];
-       char *bufp;
-       int dgm_id = generate_trn_id();
-       int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
-       
-       if(sock == -1)
-               return False;
-       
-       /* Find out the transient UDP port we have been allocated. */
-       if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
-               DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
-                        strerror(errno)));
-               close(sock);
-               return False;
-       }
-
-       /*
-        * Create the request data.
-        */
-
-       memset(buffer,'\0',sizeof(buffer));
-       bufp = buffer;
-       SSVAL(bufp,0,QUERYFORPDC);
-       bufp += 2;
-       fstrcpy(bufp,srcname);
-       bufp += (strlen(bufp) + 1);
-       slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
-       mailslot_name = bufp;
-       bufp += (strlen(bufp) + 1);
-       bufp = ALIGN2(bufp, buffer);
-       bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);        
-       
-       SIVAL(bufp,0,1);
-       SSVAL(bufp,4,0xFFFF); 
-       SSVAL(bufp,6,0xFFFF); 
-       bufp += 8;
-       len = PTR_DIFF(bufp,buffer);
-
-       memset((char *)&p,'\0',sizeof(p));
-
-       /* DIRECT GROUP or UNIQUE datagram. */
-       dgram->header.msg_type = 0x10;
-       dgram->header.flags.node_type = M_NODE;
-       dgram->header.flags.first = True;
-       dgram->header.flags.more = False;
-       dgram->header.dgm_id = dgm_id;
-       dgram->header.source_ip = *iface_ip(*pdc_ip);
-       dgram->header.source_port = ntohs(sock_name.sin_port);
-       dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
-       dgram->header.packet_offset = 0;
-       
-       make_nmb_name(&dgram->source_name,srcname,0);
-       make_nmb_name(&dgram->dest_name,domain,0x1C);
-       
-       ptr = &dgram->data[0];
-       
-       /* Setup the smb part. */
-       ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
-       memcpy(tmp,ptr,4);
-       set_message(ptr,17,17 + len,True);
-       memcpy(ptr,tmp,4);
-
-       CVAL(ptr,smb_com) = SMBtrans;
-       SSVAL(ptr,smb_vwv1,len);
-       SSVAL(ptr,smb_vwv11,len);
-       SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
-       SSVAL(ptr,smb_vwv13,3);
-       SSVAL(ptr,smb_vwv14,1);
-       SSVAL(ptr,smb_vwv15,1);
-       SSVAL(ptr,smb_vwv16,2);
-       p2 = smb_buf(ptr);
-       pstrcpy(p2,mailslot);
-       p2 = skip_string(p2,1);
-       
-       memcpy(p2,buffer,len);
-       p2 += len;
-       
-       dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
-       
-       p.ip = *pdc_ip;
-       p.port = DGRAM_PORT;
-       p.fd = sock;
-       p.timestamp = time(NULL);
-       p.packet_type = DGRAM_PACKET;
-       
-       GetTimeOfDay(&tval);
-       
-       if (!send_packet(&p)) {
-               DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
-               close(sock);
-               return False;
-       }
-       
-       retries--;
-       
-       while (1) {
-               struct timeval tval2;
-               struct packet_struct *p_ret;
-               
-               GetTimeOfDay(&tval2);
-               if (TvalDiff(&tval,&tval2) > retry_time) {
-                       if (!retries)
-                               break;
-                       if (!send_packet(&p)) {
-                               DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
-                               close(sock);
-                               return False;
-                       }
-                       GetTimeOfDay(&tval);
-                       retries--;
-               }
-
-               if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
-                       struct dgram_packet *dgram2 = &p_ret->packet.dgram;
-                       char *buf;
-                       char *buf2;
-
-                       buf = &dgram2->data[0];
-                       buf -= 4;
-
-                       if (CVAL(buf,smb_com) != SMBtrans) {
-                               DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
-                                        CVAL(buf,smb_com), (unsigned int)SMBtrans ));
-                               free_packet(p_ret);
-                               continue;
-                       }
-                       
-                       len = SVAL(buf,smb_vwv11);
-                       buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
-                       
-                       if (len <= 0) {
-                               DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
-                               free_packet(p_ret);
-                               continue;
-                       }
-
-                       DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
-                                nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
-                                inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
-
-                       if(SVAL(buf2,0) != QUERYFORPDC_R) {
-                               DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
-                                        (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
-                               free_packet(p_ret);
-                               continue;
-                       }
-
-                       buf2 += 2;
-                       /* Note this is safe as it is a bounded strcpy. */
-                       fstrcpy(ret_name, buf2);
-                       ret_name[sizeof(fstring)-1] = '\0';
-                       close(sock);
-                       free_packet(p_ret);
-                       return True;
-               }
-       }
-       
-       close(sock);
-       return False;
-#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
 }
 
 /********************************************************
@@ -1214,15 +1035,34 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
 {
        struct in_addr *ip_list;
        int count;
+       int i = 0;
 
        /* Look up #1B name */
 
        if (!internal_resolve_name(domain, 0x1b, &ip_list, &count))
                return False;
 
-       SMB_ASSERT(count == 1);
+       /* if we get more than 1 IP back we have to assume it is a
+          multi-homed PDC and not a mess up */
+          
+       if ( count > 1 ) {
+               DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
+                               
+               /* look for a local net */
+               for ( i=0; i<count; i++ ) {
+                       if ( is_local_net( ip_list[i] ) )
+                               break;
+               }
+               
+               /* if we hit then end then just grab the first 
+                  one from the list */
+                  
+               if ( i == count )
+                       i = 0;
+       }
 
-       *ip = ip_list[0];
+       *ip = ip_list[i];
+       
        SAFE_FREE(ip_list);
 
        return True;
@@ -1305,7 +1145,7 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *
                                continue;
                        }
                        
-                       /* explicit lookup */
+                       /* explicit lookup; resolve_name() will handle names & IP addresses */
                                        
                        if ( resolve_name( name, &name_ip, 0x20) ) {
                                return_iplist[local_count++] = name_ip;